Skip to content

fix(admin): name every accounts-row control after the row it acts on - #62

Merged
guarzo merged 1 commit into
mainfrom
fix/accounts-controls-name-their-row
Aug 4, 2026
Merged

fix(admin): name every accounts-row control after the row it acts on#62
guarzo merged 1 commit into
mainfrom
fix/accounts-controls-name-their-row

Conversation

@guarzo

@guarzo guarzo commented Aug 4, 2026

Copy link
Copy Markdown
Owner

Carried out of #59 as item 2: restName={revoke admin for ${identity}} landed on REVOKE during a rebase conflict resolution, outside that PR's scope. The question was keep it, or revert and land it deliberately alongside an audit of the page. Conclusion: keep it, and finish the sweep it started.

The audit

REVOKE was the most visible gap, not the only one. The split ran exactly along the drawer boundary:

control where named its row before
tier ×3, auto, wake, freeze, note field drawer
revoke row ✅ (added by #59, the thing under review)
grant row
sync now row
save note drawer

Nothing about those three makes them less anonymous out of their row than "freeze" was — on a table with one row per account the visible word names the verb and nothing else, and a speech-input or screen-reader user never sees the pinned Name column that supplies the object. So REVOKE stays and the other three get the same treatment:

  • grantgrant admin to <identity>
  • sync nowsync now for <identity>
  • save notesave note for <identity>

Each leads with its visible label, so speech input still reaches the control by the word written on it (WCAG 2.5.3).

The page's remaining controls — the tier/status filters and the column-sort links — act on the whole list rather than a row, and are already inside labelled role="group"s. Correctly unswept.

One consequence

save note for X contains the note field's own Note for X as a substring, and getByLabel matches on a substring, so six existing assertions were quietly resolving to the field and the button. They're exact now, with a comment saying why. The nesting itself is fine for a screen reader — a field and a button, different roles, the same way freeze X and confirm freeze X already coexist — but it's not fine for an assertion that means to be about the field.

Test

the tier and cryo controls name the row they act onevery per-account control names the row it acts on, now covering all four swept controls. It fails closed: drop an aria-label and the exact-name lookup finds the bare visible text instead, so the count assertion fails rather than silently passing.

Verification

  • npm run typecheck — clean
  • npm testTest Files 52 passed (52), Tests 430 passed (430) (scoped DB per docs/ops.md; the shared :5433 lock was held)
  • npx playwright test56 passed (1.3m)
  • npm run lint — 0 errors, 5 pre-existing no-img-element warnings
  • npx prettier --check — clean

Summary by CodeRabbit

  • Accessibility
    • Improved admin account controls with accessible names that identify the affected account.
    • Added clearer labels for grant, revoke, sync, and note actions, including during pending states.
    • Preserved visible button text while improving support for screen readers and drawer-based controls.
  • Tests
    • Expanded accessibility coverage for admin account actions and note fields.

PR #59 put `restName="revoke admin for <identity>"` on REVOKE while
resolving a rebase conflict, which was outside its scope. It was the right
name — a row-per-account table makes the bare word "revoke" identical on
every row, and `ConfirmSubmit`'s docblock already argues the case — but it
was reached by noticing one gap next to a labelled neighbour, not by
looking at the page.

Looking at the page: REVOKE was the most visible gap, not the only one.
Every control inside the drawer named its row already — tier, auto, wake,
freeze, and the note field — and every control in the row itself did not.
`grant`, `sync now` and `save note` were all bare, and nothing about them
is less anonymous out of their row than "freeze" was. So REVOKE stays and
the other three join it, which is the sweep rather than the accident.

Each name leads with the visible label, so speech input still reaches the
control by the word written on it (WCAG 2.5.3).

One consequence worth stating: "save note for X" contains the note
field's own "Note for X" as a substring, and `getByLabel` matches on a
substring, so six existing assertions were quietly counting the pair.
They are `exact` now. The nesting is fine for a screen reader — the two
are a field and a button with different roles, the same way "freeze X"
and "confirm freeze X" already coexist — but it is not fine for an
assertion that means to be about the field.

The test covering this grew from tier-and-cryo to all four swept
controls and is renamed to say so. It fails closed: with an aria-label
dropped, the exact-name lookup finds the bare visible text instead and
the count assertion fails.
@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 41cdaa01-e4a2-4f56-8a51-a55f411749d0

📥 Commits

Reviewing files that changed from the base of the PR and between 4eac053 and 04099aa.

📒 Files selected for processing (3)
  • e2e/admin.spec.ts
  • src/app/_components/submit.tsx
  • src/app/admin/accounts/page.tsx

📝 Walkthrough

Walkthrough

The admin accounts page now adds account-specific accessible names to account controls and note-save actions while preserving visible labels. E2E tests use exact note-label matching and verify accessible names for grant, sync, save-note, and revoke controls.

Changes

Admin account accessibility

Layer / File(s) Summary
Account control accessible names
src/app/_components/submit.tsx, src/app/admin/accounts/page.tsx
Admin account controls and note-save actions now include the affected account identity in their accessible names. Visible labels and pending states remain in place. Accessibility comments document the labeling requirement.
Accessibility E2E coverage
e2e/admin.spec.ts
Note-field assertions now require exact labels. Tests verify identity-qualified accessible names for grant, sync, save-note, and revoke controls while retaining visible action text.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

  • guarzo/authGD#38: Modifies admin account controls and the Submit component to add account-specific accessible labels.
  • guarzo/authGD#59: Overlaps in the admin accounts page and E2E accessibility assertions.
  • guarzo/authGD#11: Refines accessible labels and pending-state behavior for account-row controls.

Poem

A rabbit checks each button’s name,
With every account called by name.
Notes match exactly, labels stay bright,
Sync and grant controls speak right.
Tests hop through the page with glee.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main accessibility change for admin account-row controls.
Description check ✅ Passed The description explains the change and rationale, documents testing results, and provides sufficient context for review.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/accounts-controls-name-their-row
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch fix/accounts-controls-name-their-row

Comment @coderabbitai help to get the list of available commands.

@guarzo
guarzo merged commit bec6ca9 into main Aug 4, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant