@real-a11y-dev/testing
TL;DR — Accessibility-tree snapshots, structural assertions, custom
expectmatchers, and a fluentflow()interaction chain. Works in jsdom (Vitest / Jest) out of the box; add@real-a11y-dev/testing/playwrightfor real-browser E2E. Reach for this in your test suite — unit and e2e alike.
Headless accessibility audit helpers for Vitest, Jest, and Playwright. No browser required for the core helpers — they work in jsdom.
Install
sh
npm install -D @real-a11y-dev/testingWhat's in the box
| Area | What it does | Page |
|---|---|---|
| Snapshots | Deterministic strings of the a11y tree, heading outline, and tab order — diff-friendly, safe to commit. | Snapshots → |
| Assertions | assert* functions that throw descriptive errors on broken structure. | Assertions → |
| Matchers | The same checks as ergonomic expect matchers, plus the a11ySnapshot() serializer. Vitest + Jest. | Matchers → |
| Flow API | Fluent interaction chains that assert about the tree after each step. | Flow API → |
| Playwright adapter | Run every helper against a real browser page via attach(page). | Playwright → |
New to the idea of snapshotting the accessibility tree? Start with the concept: Accessibility Snapshots.
Which do I reach for?
- Catch regressions in CI → Snapshots (
auditSnapshot,outlineSnapshot,tabSequenceSnapshot) committed withtoMatchSnapshot(). For headless page-set audits of a deployed site — no test suite — reach for@real-a11y-dev/cli'ssnapshot/diffinstead. - Assert a specific invariant ("one
<h1>", "no unlabeled buttons") → Assertions or, forexpectstyle, Matchers. - Test an interaction (open a menu, submit a form, dismiss a modal) → Flow API.
- Assert what an interaction changed (options appeared,
aria-expandedflipped, focus moved) →capture+a11yDifforflow().expectChanges. - Audit a real, rendered page (not jsdom) → Playwright adapter.
See it running
- Vitest + jsdom —
examples/testing-vitest/: snapshot tests, the custom matchers,flow()interactions, tab-sequence structure assertions. - Jest + ts-jest —
examples/testing-jest/: the minimal Jest setup for the matchers. - Playwright E2E —
examples/playwright/: a "good fixture" where every assertion passes and a "broken fixture" where each throws — the pattern to keep in CI. - CI tree-diff bot — the CI Diff Bot recipe runs
@real-a11y-dev/cli'sreal-a11y snapshot(each audited page → one diffable JSON artifact) andreal-a11y diff(new / changed / fixed findings) in a PR workflow.