Repository navigation
test: cover the keys useFocusTrap deliberately ignores - #1126
Merged
Merged
Conversation
useFocusTrap installs one document-level keydown listener for the lifetime of an open lightbox, so it sees every key pressed on the page. Its Escape arm and both Tab wrap arms are driven in a browser already; the early return at line 33 that makes it indifferent to every other key had no end-to-end assertion, and the e2e coverage report listed region 33 as uncovered. Each case opens a lightbox, Shift+Tab's to the dialog's last focusable -- the only position from which removing the guard is observable, since a key falling through would then satisfy the forward wrap and pull focus back to the close button -- presses a non-Tab, non-Escape key, and asserts focus has not moved. Escape afterwards shows the listener was still attached. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: quality <quality@hive.kubestellar.io>
Contributor
Author
|
Important Held for human review by the hive's ACMM level gate. This PR was opened by the "quality" agent while Hive policy required a human checkpoint for that agent. Non-outreach agents are held at ACMM L3–L5; the Hive will keep the |
This was referenced Oct 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Test Improvement
Adds
tests/e2e/focus-trap-indifferent-keys.spec.js(new file, nothing elsetouched): two cases, one per lightbox, that assert
src/components/hooks/useFocusTrap.jsignores a key that is neither Tab norEscape.
The hook installs one document-level
keydownlistener for the lifetime ofan open dialog, so it sees every key pressed anywhere on the page. Its Escape
arm (
community-people.spec.js:191,member-directory.spec.js) and both Tabwrap arms (
community-people.spec.js:202,interactions.spec.js:217) arealready driven in a browser. The early return at line 33 was not:
Without it, a keystroke made with focus on the dialog's last focusable
element satisfies
!event.shiftKey && document.activeElement === lastand pullsfocus back to the close button — typing in a dialog, or arrow-scrolling it,
would bounce focus on every keypress. Each case therefore Shift+Tabs to the last
focusable before pressing its indifferent key, which is the only position from
which the guard's removal is observable, reads focus back as an index into the
same
button, a[href]list the trap queries (so the assertion is "focus did notmove", not "something is focused"), and presses Escape afterwards to show the
listener was still attached.
Verification
All run locally at
7ab301eagainstnpm run build:e2e:coverage:npx playwright test tests/e2e/focus-trap-indifferent-keys.spec.js— 2 passed.npm run test:e2e:coveragewith the spec in place — 324 passed.npm run test:unit— 1966 passed, 0 failed.npx prettier --checkon the new file — clean.running this spec plus
community-people.spec.js,member-directory.spec.jsand
interactions.spec.js: 4 failed, 33 passed. Both new cases fail, asdo the two pre-existing Shift+Tab wrap cases (the bare
Shiftkeydown nowfalls through and fires the backward wrap before Tab is ever pressed) — which
is the same defect seen from a different angle, not this guard's own coverage.
Region effect. Two full
test:e2e:coverageruns against the same build:Unlike #1097 and #1120, region 33 does leave the uncovered list: no second
build is involved, so there is no region-attribution mismatch (#1066, #1079).
The denominator still moves (456 → 453), the moving-denominator effect described
in #1105. Both figures clear
--check-source-regions 80(
.github/workflows/ci.yml:233) and the86proposed in #1105.Scope
Lines 35 and 51 of the hook stay uncovered and are out of scope: every
shipped dialog contains a close button, so
!focusable?.lengthhas nobrowser-reachable case, and both call sites always pass a live
triggerRef, sothe
previousFocusfallback has none either. Nothing is left for #1125 to trackonce this merges.
Coordination
Claims only
tests/e2e/focus-trap-indifferent-keys.spec.js(new) and onlyregion
src/components/hooks/useFocusTrap.js:33. Disjoint from #1120, whichclaims
tests/e2e/dialog-non-dismissing.spec.jsand the backdroponMouseDownguards at
MemberProfile.js:15/CommunityPeople/index.js:32. No overlayunder
tests/e2e/fixtures/(#1104, #1117, #1124), notests/tools/e2e-coverage-report.mjs(#1040, #1070, #1114), notests/tools/e2e-data-fixtures.cjs(#1110), no workflow file.Related Issue
Closes #1125
Human review required.
— hive: agent=quality backend=copilot model=claude-opus-5 copilot=1.0.88