patternjavascriptMajor
Testing with axe-core — automated accessibility linting in CI
Viewed 0 times
axe-core 4.x, jest-axe 8.x
axe-corejest-axeautomated accessibilitya11y testingCI accessibilityplaywright axe
Problem
Accessibility regressions are introduced silently because there is no automated check in the development or CI pipeline. Manual reviews are inconsistent and miss rules that tools can reliably catch.
Solution
Integrate axe-core into your test suite and CI pipeline. It catches ~30-40% of WCAG issues automatically.
// jest-axe (unit / component level)
import { axe, toHaveNoViolations } from 'jest-axe';
expect.extend(toHaveNoViolations);
test('Button is accessible', async () => {
const { container } = render(<Button>Click me</Button>);
expect(await axe(container)).toHaveNoViolations();
});
// Playwright + axe (integration level)
import { checkA11y } from 'axe-playwright';
test('Home page passes axe', async ({ page }) => {
await page.goto('/');
await checkA11y(page, undefined, {
detailedReport: true,
detailedReportOptions: { html: true },
});
});
// Browser DevTools — install axe DevTools extension
// or run: new axe.Axe().analyze() in the console
// jest-axe (unit / component level)
import { axe, toHaveNoViolations } from 'jest-axe';
expect.extend(toHaveNoViolations);
test('Button is accessible', async () => {
const { container } = render(<Button>Click me</Button>);
expect(await axe(container)).toHaveNoViolations();
});
// Playwright + axe (integration level)
import { checkA11y } from 'axe-playwright';
test('Home page passes axe', async ({ page }) => {
await page.goto('/');
await checkA11y(page, undefined, {
detailedReport: true,
detailedReportOptions: { html: true },
});
});
// Browser DevTools — install axe DevTools extension
// or run: new axe.Axe().analyze() in the console
Why
Automated testing enforces a baseline and prevents regressions. It is far cheaper to catch contrast errors and missing labels in CI than in a manual audit or after a user complaint.
Gotchas
- axe-core does not catch all WCAG violations — supplement with manual keyboard testing and screen reader review
- Run axe on the fully rendered DOM, not on server-rendered HTML that may differ from hydrated state
- axe can produce false positives in test environments with JSDOM — some rules require a real browser rendering context
- Suppress known false positives explicitly with axe.run({ rules: { 'rule-id': { enabled: false } } }) and document the reason
Context
Any project with a test suite and CI pipeline
Revisions (0)
No revisions yet.