test(frontend): assert the two WCAG 2.2 criteria that were satisfied but unguarded - #80
Merged
Merged
Conversation
…four accepted The owner declined the manual theme toggle (ADR-032 §3) and deferred localisation (ADR-033 §4) on 2026-09-27. With ADR-030 and ADR-031 already accepted, all four ADRs from the frontend audit are now decided and **nothing in the roadmap waits on a decision.** Both ADRs record what acceptance does *not* mean, because that is where a document starts overstating itself: - **ADR-032** settles the theme mechanism — one media query, semantic tokens, no stored preference, and a test that fails if a `data-theme` selector appears. It does not close roadmap A4: nobody has looked at a dark-mode scrollbar or an autofilled field. And declining the toggle is not forbidding one — a real user request supersedes the ADR, and §3 records the cost so that conversation starts from a number. - **ADR-033** defers the interface language. It does **not** license writing English-only assumptions into the code, which is the whole point of §2's habit, and it does not close §3: `<track>` still lacks `srclang` and `label`. That is a defect rather than a decision and it is blocked on backend modelling, because the correct value is not knowable from the frontend. Deferring the interface language and failing to say what language the captions are in are different problems and only one of them is settled. **The practice worth keeping is recorded in STATUS.** Both of these ADRs were split before being decided, each having mixed "this is broken" with "what should we do" — and the broken half never needed the decision. `color-scheme` and the logical properties shipped hours ahead of the questions they had been sitting behind. When an ADR contains both, split it. The defect table is rewritten by state rather than by count: two fixed, one open, one blocked, plus a fifth found while fixing the fourth. It also keeps the corrections — measurement disproved part of ADR-032 §2, because Tailwind's Preflight already resets form controls; and ADR-033's "about four" utilities were nine. Docs only. 425 frontend tests still pass, unchanged. Every ADR id and doc path resolves, and no document still describes any of the four as proposed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…but unguarded
Roadmap C3 and two of C4's three tests, the first work to follow from ADR-030 being
accepted. No behaviour changes — these pin properties the audit found already true,
which by ADR-023 §1 means they were not yet controls.
**3.3.8 Accessible Authentication.** A password manager must be able to fill these
forms, and `autocomplete` is how a field says what it is. The regression is not
hypothetical: stripping `autocomplete` from a login form is a folk security
measure, it looks like hardening, and it breaks the exact mechanism the criterion
relies on. Nothing here would have noticed.
Asserted across all four auth pages, on the *values* rather than mere presence —
a manager offers a saved password for `current-password` and a generated one for
`new-password`, and swapping those two is the failure that looks like it works.
Rendered rather than grepped, because `Field` is what actually puts the attribute
on the input and a source check would pass if it stopped forwarding the prop. Also
asserts no CAPTCHA: that is the other half of the criterion, and bot traffic is
already handled by `django-axes` lockout and per-IP throttling rather than by
asking a user to read distorted letters.
**2.5.8 Target Size.** 24×24 is the floor. Asserted against the variant strings,
not a rendered box — jsdom computes no layout, so `getBoundingClientRect` returns
zeroes and a rendered assertion would be measuring nothing. `Button` had no test
file at all; it now also covers `aria-busy` on the pending state, which is the
other accessibility-relevant thing it does.
One assertion there is about a bug rather than a criterion: the base's
`border border-transparent` keeps a bordered variant the same height as an
unbordered one beside it. A minimum height does not fix that, because a minimum is
a floor and not a cap — measured when the landing page's two calls to action came
out 44px and 46px.
**C3** is one line: `contrast.test.ts` now cites 2.2. Its arithmetic is untouched
because 2.2 changes no contrast threshold, which is the useful thing to record — the
target moved and this file needed nothing.
Four provocations, all failing the right test: stripping `autoComplete`, swapping
`current-password` for `new-password`, removing `sm`'s minimum height, removing the
transparent border.
Two of my own slips, both caught by running things: `getAllByRole("textbox")` throws
rather than returning an empty list, and reset-password has no textbox — only a
password field. And `querySelectorAll` is `Element`, which does not satisfy `concat`
on an `HTMLElement[]`; the tests passed while `tsc` did not.
**The third C4 test waits on A2.** There is no 2.4.11 remedy to test until somebody
reproduces the fault, and ADR-006 forbids fixing what has not been seen.
438 frontend tests across 39 files, tsc, eslint, verify:css, verify:a11y and
verify:static all pass.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
Roadmap C3 and two of C4's three tests — the first work to follow from ADR-030 being accepted. No behaviour changes. These pin properties the audit found already true, which by ADR-023 §1 means they weren't yet controls.
3.3.8 Accessible Authentication
A password manager must be able to fill these forms, and
autocompleteis how a field says what it is.The regression isn't hypothetical. Stripping
autocompletefrom a login form is a folk security measure — it looks like hardening, and it breaks the exact mechanism this criterion relies on. Nothing in this repository would have noticed.Asserted across all four auth pages on the values, not mere presence: a manager offers a saved password for
current-passwordand a generated one fornew-password, and swapping those two is the failure that looks like it works. Rendered rather than grepped, becauseFieldis what actually puts the attribute on the input — a source check would pass if it stopped forwarding the prop.Also asserts no CAPTCHA, the other half of the criterion. Bot traffic is already handled by
django-axeslockout and per-IP throttling rather than by asking a user to read distorted letters.2.5.8 Target Size
24×24 is the floor. Asserted against the variant strings, not a rendered box — jsdom computes no layout, so
getBoundingClientRectreturns zeroes and a rendered assertion there would be measuring nothing.Buttonhad no test file at all; it now also coversaria-busyon the pending state, the other accessibility-relevant thing it does. One assertion is about a bug rather than a criterion: the base'sborder border-transparentkeeps a bordered variant the same height as an unbordered one beside it. A minimum height doesn't fix that — a minimum is a floor, not a cap, measured when the landing page's two CTAs came out 44px and 46px.C3 is one line, and the useful part is what didn't change
contrast.test.tsnow cites 2.2. Its arithmetic is untouched, because 2.2 changes no contrast threshold — the target moved and this file needed nothing, which is worth recording rather than leaving someone to wonder whether it was missed.Provocations
autoCompletestripped from the password fieldcurrent-passwordswapped fornew-passwordsmloses its minimum heightTwo of my own slips, both caught by running things
getAllByRole("textbox")throws rather than returning an empty list, and reset-password has no textbox — only a password field.querySelectorAllis typedElement, which doesn't satisfyconcaton anHTMLElement[]. The tests passed whiletscdid not — a reminder that a green suite isn't a green build.What still waits
The third C4 test waits on A2. There is no 2.4.11 remedy to test until somebody reproduces the fault, and ADR-006 forbids fixing what hasn't been seen.
Section A of the roadmap is untouched and still needs a person — starting with the reduced-motion check, outstanding since 2026-09-25.
438 frontend tests across 39 files, tsc, eslint,
verify:css,verify:a11y,verify:staticall pass.🤖 Generated with Claude Code