@@ -11,36 +11,24 @@ import {
1111import { expect , test , type Page } from '@playwright/test' ;
1212
1313/**
14- * The accessibility gate: axe-core for structure and semantics, `auditContrast`
15- * for colour. One navigation feeds both, so a page is loaded once per theme
16- * rather than once per audit .
14+ * axe for structure and semantics, `auditContrast` for colour, both against one
15+ * loaded page per theme. `pnpm test:tokens` proves the token file is sound;
16+ * this proves the pages reached for it, and both floors come from the package .
1717 *
18- * `pnpm test:tokens` proves the token file is sound; this proves the pages
19- * reached for the right token, and that the markup around them is navigable.
20- * Both floors come from the package, so a retuned ramp moves this suite with
21- * it. Neither half is redundant with the Lighthouse accessibility score:
22- * Lighthouse 13.4 runs 76 audits — 66 real axe rules plus 10 manual checklist
23- * items that never execute — against axe's 104, weighted into an average
24- * rather than a per-rule verdict.
18+ * Not covered by the Lighthouse suite: that runs 76 audits — 66 real axe rules
19+ * plus 10 manual items that never execute — against axe's 104, weighted into
20+ * an average rather than a per-rule verdict.
2521 *
26- * Public pages only — the `(tests)` route group renders deliberately broken
27- * usage for the e2e suite and holding it to a marketing page's standards
28- * produces failures nobody should act on.
22+ * Public pages only — the `(tests)` group renders deliberately broken usage for
23+ * the e2e suite, and its failures are not ones anyone should act on.
2924 */
3025const PAGES = [ '/' , '/react-router' , '/remix' ] ;
3126
32- /**
33- * Rules axe declines to decide. Anything not listed fails the run, so a new
34- * "needs review" finding gets looked at once rather than living unnoticed in a
35- * section of the report nobody reads.
36- */
27+ /** Rules axe declines to decide. Anything unlisted fails, so a new one gets a
28+ * decision once instead of living unread in the report. */
3729const REVIEWED_INCOMPLETE : string [ ] = [ ] ;
3830
39- /**
40- * Both audits on one loaded page, every assertion soft: an axe violation must
41- * not hide a contrast failure on the same page, or fixing one at a time turns
42- * a single run into three.
43- */
31+ /** Every assertion soft, so one half cannot hide the other. */
4432async function auditBoth ( page : Page , minNodes : number ) {
4533 const axe = await auditA11y ( page , { tags : COMPREHENSIVE_TAGS } ) ;
4634 // A selector typo that scoped the scan to nothing would otherwise pass.
@@ -55,8 +43,8 @@ async function auditBoth(page: Page, minNodes: number) {
5543 . toEqual ( [ ] ) ;
5644
5745 const { findings, unresolved } = await auditContrast ( page ) ;
58- // Without these, a gradient over the whole page would leave the suite green
59- // having measured nothing.
46+ // A gradient over the page would otherwise leave the suite green having
47+ // measured nothing.
6048 expect . soft ( findings . length ) . toBeGreaterThan ( minNodes ) ;
6149 expect . soft ( unresolved ) . toBeLessThan ( findings . length ) ;
6250 expect
@@ -65,12 +53,11 @@ async function auditBoth(page: Page, minNodes: number) {
6553}
6654
6755test . describe ( 'accessibility (landing only)' , ( ) => {
68- // Chromium only: the contrast half composites colours on a canvas and waits
69- // out `document.getAnimations()`, both of which the other engines serialise
70- // differently.
56+ // Chromium only: the contrast half composites on a canvas and waits out
57+ // `document.getAnimations()`, which the other engines serialise differently.
7158 test . skip ( ( { browserName } ) => browserName !== 'chromium' , 'Chromium only' ) ;
7259
73- // `<html data-theme="dark">` is unconditional here , so an OS preference must
60+ // `<html data-theme="dark">` is unconditional, so an OS preference must
7461 // change nothing. It did once elsewhere: an opt-in selector missing its
7562 // `:root` prefix let a light ramp leak into a dark page.
7663 for ( const colorScheme of [ 'dark' , 'light' ] as const ) {
@@ -86,7 +73,7 @@ test.describe('accessibility (landing only)', () => {
8673 } ) ;
8774 }
8875
89- // A tag only takes its accent fill once selected, so a page load never
76+ // A tag takes its accent fill only once selected, so a page load never
9077 // renders the pairing that fill has to carry.
9178 test ( 'a selected tag clears both' , async ( { page } ) => {
9279 await page . goto ( '/' ) ;
0 commit comments