Follow-up to #16. That bug reached production with a green a11y suite, so the suite has two holes worth closing.
1. Form pages are not scanned
e2e/a11y.spec.ts scans:
const PAGES = ['/', '/pricing', '/terms', '/privacy', '/dashboard', '/notes', '/admin', '/account']
/notes/new is absent, and it is the most form-dense authenticated page in the app. Adding it would have caught #16 on the first run.
Candidates to add: /notes/new, /notes/[id], /billing.
2. axe passed /admin despite a visibly unnamed input
This one is the more worrying half. /admin is in PAGES and axe passed it in CI, but a direct DOM check found its invite field visible with no accessible name:
[...document.querySelectorAll('input,textarea')].map(el => ({
named: !!(el.getAttribute('aria-label') || el.getAttribute('aria-labelledby')
|| (el.id && document.querySelector(`label[for="${CSS.escape(el.id)}"]`))),
visible: el.getBoundingClientRect().height > 0,
}))
// → [{ type: 'email', named: false, visible: true }]
axe's label rule should flag that. Either the rule is not firing, or the page differs under axe (timing, or the field not yet rendered when the scan runs).
Worth resolving: if axe cannot catch an unlabelled field, the a11y suite is weaker than it looks and the badge is misleading.
3. e2e only runs on a schedule
e2e-a11y runs twice daily, not on PRs, so a regression surfaces up to twelve hours after the change that caused it, detached from its diff. Worth considering a reduced run (smoke + a11y, no screenshots) on PRs that touch app/, layers/ or e2e/.
Follow-up to #16. That bug reached production with a green a11y suite, so the suite has two holes worth closing.
1. Form pages are not scanned
e2e/a11y.spec.tsscans:/notes/newis absent, and it is the most form-dense authenticated page in the app. Adding it would have caught #16 on the first run.Candidates to add:
/notes/new,/notes/[id],/billing.2. axe passed
/admindespite a visibly unnamed inputThis one is the more worrying half.
/adminis inPAGESand axe passed it in CI, but a direct DOM check found its invite field visible with no accessible name:axe's
labelrule should flag that. Either the rule is not firing, or the page differs under axe (timing, or the field not yet rendered when the scan runs).Worth resolving: if axe cannot catch an unlabelled field, the a11y suite is weaker than it looks and the badge is misleading.
3. e2e only runs on a schedule
e2e-a11yruns twice daily, not on PRs, so a regression surfaces up to twelve hours after the change that caused it, detached from its diff. Worth considering a reduced run (smoke + a11y, no screenshots) on PRs that touchapp/,layers/ore2e/.