Skip to content

[quality] the profile lightboxes' backdrop guard has no end-to-end assertion for its non-dismissing arm #1119

Description

@hivecommons-hive

Finding

Both profile lightboxes guard dismissal the same way, with the handler bound to
the backdrop rather than to the dialog box:

onMouseDown={(event) => event.target === event.currentTarget && onClose()}
  • src/components/MemberDirectory/MemberProfile.js line 15
  • src/components/CommunityPeople/index.js line 32

The true arm is driven in a browser by two specs that click a coordinate
clear of the dialog — tests/e2e/interactions.spec.js:261 and
tests/e2e/community-people.spec.js:181, both titled "clicking the backdrop
closes the dialog"
. The false arm — a mousedown that starts on a
descendant and bubbles up to the backdrop, which is what keeps a click inside
the profile from dismissing it — has no end-to-end assertion at all.

Evidence and provenance

  • Unit — covered. XDG_CACHE_HOME=... npm run test:unit:coverage
    (TZ=UTC node tests/tools/coverage-report.mjs, node v26.10.0) run locally on
    2026-10-06 at main 7ab301e reports
    src/components/MemberDirectory/MemberProfile.js and
    src/components/CommunityPeople/index.js at 100.00% lines / 100.00%
    regions
    .
  • E2E — not covered. CI artifact e2e-coverage, id 11383321728, from run
    37395255849,
    workflow Validate repository, job End-to-end coverage, main at
    7ab301e — the same revision as the unit run. report.txt:
    src/components/MemberDirectory/MemberProfile.js | 100.00 | 92.31 | | 10 15
    and
    src/components/CommunityPeople/index.js | 100.00 | 87.10 | | 32 125 134.
  • Covered by unit tests but not end-to-end tests, so priority 2 under the
    coverage-evidence rules.

The unit suite cannot stand in for this one. tests/tools/fake-dom.mjs
dispatches a synthesised event straight at the handler, so it never exercises
which element the listener is bound to, nor the bubbling the guard reads.

Mutation check

Replacing both handlers with a bare onMouseDown={() => onClose()} and
rebuilding (npm run build:e2e:coverage:site), then running the three specs
that already drive these dialogs — interactions.spec.js,
community-people.spec.js, member-directory.spec.js:

34 passed, 1 failed
✘ community-people.spec.js:170 › clicking the close button closes it and restores focus

The single failure is on that case's focus-restoration assertion, which
says nothing about the guard; the directory lightbox's own equivalent case
stays green. So the regression is very nearly silent today.

What this does not claim

Landing the test does not clear lines 15 and 32 from the uncovered-region
list, and it slightly lowers the headline number. Measured locally at 7ab301e
with two full npm run test:e2e:coverage runs against the same build, with and
without the new spec:

without: src files | 100.00 | 91.41 | 2099/2099 lines | 415/454 regions
with:    src files | 100.00 | 91.25 | 2099/2099 lines | 417/457 regions

Both lines stay listed. getRegionCoverage in
tests/tools/e2e-coverage-report.mjs keys a region on its mapped original
coordinates, and dumping the keys for these files shows the executed arm
arriving under a different key than the zero one — the attribution limit
already tracked by #1066 and #1079. The suite reaching further also surfaces
additional V8 block ranges, which is why the denominator moves from 454 to 457;
that is the moving-denominator effect #1105 describes, reproduced here with no
variant overlay involved.

The value on offer is therefore the regression assertion, not a coverage
number.

Recommendation

  • tests/e2e/dialog-non-dismissing.spec.js (new) opens each lightbox,
    clicks its own <h2 id="member-profile-name"> / #profile-name heading,
    asserts the dialog is still visible, and then asserts Escape still closes
    it so the case is the guard declining rather than a detached handler

Coordination

The change adds one new file, tests/e2e/dialog-non-dismissing.spec.js, and
edits nothing. It is disjoint from every open hold-gated PR: #1090
(scripts/lib/svg-active-content.mjs), #1112 (package.json), #1104
(member-directory-freshness-variant.spec.js, DirectoryFreshness), #1110
(e2e-data-fixtures), #1113 (GroupLinkStatus), #1114
(tests/e2e-coverage-report.test.mjs) and #1117 (MetricsDashboard). No data
variant overlay is involved, so no tests/e2e/fixtures/** file is touched, and
no workflow file is involved.

The sibling arm in src/components/hooks/useFocusTrap.js line 33 (the
event.key !== 'Tab' early return) is deliberately excluded: it is already
driven end to end by tests/e2e/community-people.spec.js:244, "a key that is
neither Escape nor Tab leaves the dialog alone"
.

Priority

  • Impact: medium (the only thing standing between a one-token edit and a
    lightbox that dismisses on any click inside it, on two pages)
  • Effort: low

🐝 Hive Agent: quality | Instance: hosted-available-lke648397-260827-5n31 | SHA: 7ab301e

— hive: agent=quality backend=copilot model=claude-opus-5 copilot=1.0.88

Activity

  1. added
    qualityApproved by a Hive merger/owner for auto-merge on green CI
    testingApproved by a Hive merger/owner for auto-merge on green CI
    agent/qualityApproved by a Hive merger/owner for auto-merge on green CI
    hive/covered-by-prHive verified that an open PR references or claims this issue; still actionable until confirmed
    on Oct 6, 2026
  2. added a commit that references this issue on Oct 8, 2026
    ad4f6de
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent/qualityApproved by a Hive merger/owner for auto-merge on green CIhive/covered-by-prHive verified that an open PR references or claims this issue; still actionable until confirmedhive/hosted-available-lke648397-260827-5n31Approved by a Hive merger/owner for auto-merge on green CIqualityApproved by a Hive merger/owner for auto-merge on green CItestingApproved by a Hive merger/owner for auto-merge on green CI

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions