Playwright · Reliable end-to-end tests

How do you test accessibility in Playwright?

MediumaccessibilityaxeariaUpdated Oct 2026
Quiz this track

Short answer

Use role-based locators and accessible assertions for behaviour, and run axe with @axe-core/playwright for automated WCAG checks. Automated scans still need manual keyboard and screen-reader testing.

Accessibility testing has two layers. The first is functional: can a keyboard user reach and operate the control, and does it have a correct accessible name. The second is static: does the page violate known WCAG rules. Playwright can help with both, but neither replaces a real assistive-technology pass.

ts
import AxeBuilder from "@axe-core/playwright";

test("home page has no serious accessibility violations", async ({ page }) => {
  await page.goto("/");

  const results = await new AxeBuilder({ page })
    .withTags(["wcag2a", "wcag2aa"])
    .analyze();

  expect(results.violations).toEqual([]);
});
Axe runs in the browser and returns violations with impact, nodes and remediation links.

Built-in accessibility support

  • getByRole and getByLabel require accessible names and roles to work
  • toHaveAccessibleName and toHaveAccessibleDescription assert on the accessibility tree
  • toMatchAriaSnapshot compares a YAML snapshot of the aria structure
  • page.accessibility.snapshot() exposes a lower-level tree for custom checks
  • Axe catches many structural issues but not keyboard flow or confusing announcements

Combine automated checks with targeted tests: tab through a dialog and assert that focus is trapped and restored, press Escape and verify it closes, and confirm that an error is announced through a live region. These behaviours are difficult for a scanner to judge.

An axe run with zero violations is not proof of accessibility. It means the automated rules passed. Manual keyboard, zoom, contrast and screen-reader checks are still required for a meaningful assessment.

Follow-ups you should expect

Interviewers use these to check whether the first answer was understanding or memorisation.

  1. 1What does axe-core catch that role locators do not?
  2. 2How do you assert an accessible name?
  3. 3Why is a zero-violation axe run not enough?
  4. 4How would you test focus trapping in a dialog?

Say it in the interview

I use role-based locators and accessible assertions to verify names and structure, and I run axe through @axe-core/playwright for automated WCAG checks. Axe is good at structural rules, but it cannot tell whether a keyboard flow or an announcement makes sense. So I also test focus trapping, Escape handling and live-region errors directly. Zero axe violations is a useful signal, not proof of accessibility.

Use this as a model, not a script. Saying it in your own words is what makes it survive follow-up pressure.

Related questions

Reading is step one

Now say it out loud.

Understanding an answer and delivering it under pressure are different skills. Rehearse this topic in a live Playwright mock interview and get scored feedback on depth, clarity and confidence.