BeginnerSDET

Automate accessibility audits with axe-core and Playwright

Write Playwright tests that inject axe-core into each page, run a full accessibility analysis, assert there are no critical or serious violations, and output a readable violation report on failure. Integrate the check as a first-class test alongside your existing functional tests.

Why this matters

Manual accessibility audits are slow and inconsistent. axe-core running in Playwright catches 30-40% of WCAG issues automatically, runs in milliseconds, and produces machine-readable results that can block a PR. Adding accessibility checks to CI is the single highest-leverage accessibility practice a team can adopt; it prevents new violations from merging from the day it is set up.

Before you start

Step-by-step guide

  1. 1

    Install and run a basic analysis

    Run npm install @axe-core/playwright. Import AxeBuilder from @axe-core/playwright in your test file. Run const results = await new AxeBuilder({ page }).analyze(). Print results.violations.length. On a typical production site, expect 5-20 violations.

  2. 2

    Write the assertion

    Add expect(results.violations).toHaveLength(0). Run the test. It will probably fail; that is expected. The goal is to understand what you are asserting before deciding how to handle existing violations.

  3. 3

    Read the violation output

    For each violation, axe reports: id (the rule), impact (critical/serious/moderate/minor), help (plain-English description), and nodes (the failing elements). Print the violations array as JSON and read the first 3 carefully. Map each to a WCAG criterion.

  4. 4

    Scope the assertion to critical and serious

    Update the assertion to filter: const critical = results.violations.filter(v => v.impact === 'critical' || v.impact === 'serious'). Assert that critical has length 0. This is the pragmatic starting point; fix blocking issues first, track moderate issues separately.

  5. 5

    Add a custom reporter

    On test failure, format violations as a readable table: violation id, impact, affected element count, help URL. Write it to a file and attach it as a Playwright test attachment with testInfo.attach(). The readable report is what the developer gets when CI fails; make it actionable.

  6. 6

    Run across all pages

    Add the axe check to the beforeEach of your existing test suite, or write a dedicated accessibility spec that visits all key pages. Track the violation count per page over time. The goal is not zero violations on day one; the goal is no new violations per PR.

Relevant Axiom pages

What to do next

Back to Practice Lab