Use Playwright plus @axe-core/playwright.
Axe helps, but does not prove full WCAG compliance.
When to Use
- Writing a11y tests
- Reviewing axe failures
- Checking WCAG A/AA tags
- Testing ARIA names and roles
- Auditing critical pages or flows
Goal
Scan meaningful user states. Fix root causes. Document temporary exclusions.
Rules
- Test critical flows, not only homepage.
- Scan after UI reaches real user state.
- Use
AxeBuilder. - Scope noisy scans with
include(). - Avoid
exclude()anddisableRules()unless justified. - Snapshot fingerprints only.
- Pair with manual keyboard/focus checks.
Pattern
import { test, expect } from '@playwright/test'
import AxeBuilder from '@axe-core/playwright'
test('home page has no detectable a11y violations', async ({ page }) => {
await page.goto('/')
const results = await new AxeBuilder({ page }).analyze()
expect(results.violations).toEqual([])
})
WCAG tags:
const results = await new AxeBuilder({ page })
.withTags(['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa'])
.analyze()
Flow
- Pick critical page or flow.
- Navigate and interact to target state.
- Run axe scan.
- Inspect
id,impact,target,failureSummary. - Fix label, contrast, ARIA, semantics, or duplicate ID.
- Rerun test.
- Report automated limits.
Output
## A11y Test Review
Scope: [page/flow]
Scan state: [when scan runs]
WCAG tags: [tags if used]
Findings:
- [rule id]: [impact], target [selector], fix [change]
Exclusions:
- [selector/rule]: [reason], follow-up [ticket]
Limitations:
- Manual keyboard/focus/screen-reader check still needed.