Accessibility Testing
What it is
Section titled “What it is”Accessibility testing checks that people using assistive technology — screen readers, keyboards, switch devices, magnification — can use the interface. The reference standard is WCAG, organised around four principles.
Perceivable ─ can I take it in? (alt text, contrast, captions) Operable ─ can I drive it? (keyboard, focus, no traps) Understandable ─ do I get it? (labels, errors, consistency) Robust ─ does it work with AT? (semantics, valid ARIA)Automated tools catch roughly a third of issues. The rest needs a keyboard, a screen reader, and real people.
When to use it / when to avoid it
Section titled “When to use it / when to avoid it”Use it for
- Any user-facing UI, especially forms, navigation and interactive widgets
- Every PR: a cheap automated scan (axe) in CI catches regressions
- Before release: a manual keyboard and screen-reader pass on key flows
- Legal or procurement requirements that mandate WCAG 2.2 AA conformance
Avoid or reduce it when
- You rely on an automated scan alone and call it “accessible”
- The control has no semantic equivalent (a canvas-only UI) without a fallback
- You test only the happy path and skip error states and empty states
- You ignore focus order and let the keyboard user get trapped
Frameworks & tools
Section titled “Frameworks & tools”| Tool | Ecosystem | Notes |
|---|---|---|
| axe-core | JS/TS, browser | The engine behind many tools; rules tagged by WCAG level |
| jest-axe | JS/TS tests | Assert no violations in component tests |
| pa11y | Node CLI | Scriptable page checks, CI-ready |
| Lighthouse | Chrome | Accessibility score within a broader audit |
| WAVE | Browser ext / API | Visual overlay of issues on the page |
| Accessibility Insights | Browser ext | Guided manual checks plus automated |
| NVDA / VoiceOver | Screen readers | Free, essential for manual testing |
| HTML validator | Any | A valid document is a robust document |
Quick setup
Section titled “Quick setup”npm install -D axe-core @axe-core/playwright jest-axe vitest-axe// in a component testimport { axe } from 'vitest-axe';pip install playwright axe-playwright-pythongo install github.com/fortio/fortio@latest # generic HTTP probingnpm install -g pa11y-ci # pa11y for any stack# Selenium WebDriver + axe via a node bridgemvn org.apache.maven.plugins:maven-dependency-plugin:get \ -Dartifact=org.seleniumhq.selenium:selenium-java:4.25.0dotnet add package Selenium.WebDriver# run axe-core from the injected scriptExample
Section titled “Example”import AxeBuilder from '@axe-core/playwright';import { test, expect } from '@playwright/test';
test('home page has no accessibility violations', async ({ page }) => { await page.goto('/'); const results = await new AxeBuilder({ page }) .withTags(['wcag2a', 'wcag2aa']) .analyze(); expect(results.violations).toEqual([]);});from axe_playwright_python.sync_playwright import Axefrom playwright.sync_api import sync_playwright
with sync_playwright() as p: page = p.chromium.launch().new_page() page.goto("http://localhost:4321/") results = Axe().run(page) assert not results.violationspa11y --standard WCAG2AA --reporter json http://localhost:4321/AxeBuilder axe = new AxeBuilder().withTags(Arrays.asList("wcag2a", "wcag2aa"));AxeResults results = axe.analyze(driver);assertTrue(results.getViolations().isEmpty());var axe = new AxeBuilder(driver).WithTags("wcag2a", "wcag2aa");var results = axe.Analyze();Assert.Empty(results.Violations);Anti-patterns & best practices
Section titled “Anti-patterns & best practices”- Automate the detectable, test the rest by hand. Tools are a floor, not a ceiling.
- Use semantic HTML first. A
<button>beats a<div role="button">you must keep patching with ARIA. - Check colour contrast with real values. Many “designed” greys fail 4.5:1.
- Test the keyboard-only path. Tab order, visible focus, no traps, skip links.
- Give images real alt text. Decorative images take
alt=""; icons carrying meaning need a name. - Include people with disabilities. Automated checks plus screen-reader users find what neither finds alone.
Self-assessment quiz
Section titled “Self-assessment quiz”Self-assessment quiz
Pick one answer per question, then press Check answers.