Files
2026-05-27 23:29:53 +01:00

2.5 KiB

Architecture

attachAxe is a thin, deterministic wrapper around @axe-core/playwright's AxeBuilder. The factory takes a Page and per-attach defaults, returns an AxeHandle whose two methods (assertNoViolations, getViolations) build a fresh AxeBuilder on each call so callers can scope per-assertion (e.g. exclude a known-noisy third-party widget for one check without leaking the override).

Adapter choice

@axe-core/playwright is the canonical Playwright adapter and ships the axe-core engine as a CDN-free script that is evaluate()-injected into the page. It matches the rest of the testing-e2e stack (Playwright primitives, no Node-only deps). Alternatives (axe-playwright, hand-rolled page.addScriptTag) were rejected: the former is community-maintained with weaker semver discipline, the latter duplicates work and forces us to track axe-core releases manually.

Defaults

  • Rule set: WCAG 2.1 AA (['wcag2a','wcag2aa','wcag21a','wcag21aa']). 2.2 tags are MAY-include via runOnly override, not default, until baseline runs prove no churn.
  • Impact gate: serious + critical fail by default. strict: true widens to all four (minor, moderate, serious, critical).
  • Scope: entire page unless include/exclude provided.

Reporter

Violations are written to playwright-report/a11y/<spec-name>.json keyed by rule id, with impact, nodes[].target, nodes[].html, helpUrl. The path is fixed so the release-readiness aggregator (owned by enterprise-testbed-verification) can glob a single directory.

Error model

A11yError extends TestingE2eError carrying { code, cause?, context: { violations, ruleSet, url } }. Codes:

  • TESTING_E2E.A11Y.VIOLATIONS_FOUND — assertion failed.
  • TESTING_E2E.A11Y.AXE_LOAD_FAILED — axe-core script injection failed (CSP, navigation race).
  • TESTING_E2E.A11Y.INVALID_RULESET — caller passed an unknown WCAG tag.

Baseline-update workflow

There is no baseline file. Either the page passes the rule set or it fails — drift is impossible by construction. To temporarily ignore a rule, disableRules: ['rule-id'] with a code-comment justification and an issue link is the only mechanism.

  • Release-readiness gate: ../enterprise-testbed-verification/proposal.md.
  • Audit driver: /mnt/s/web/genesis/docs/superpowers/specs/2026-04-25-test-suite-audit.md §2 row 1 and §7 row "Inspect browser console".
  • Project rules: /mnt/s/web/genesis/CLAUDE.md "Web App & Page Verification".