notes

Accessibility

Accessibility Testing in Playwright

Checking labels, headings, keyboard access, and WCAG issues with Axe.

Accessibility testing ensures that web applications are usable by everyone, including people with disabilities who rely on screen readers, keyboard navigation, or other assistive technologies.

1. Common Accessibility Issues

Missing Alt Text

Images should have meaningful alternative text so screen readers can describe them to users who cannot see them.

test('images should have accessible descriptions', async ({ page }) => {
  await page.goto('/');

  const image = page.getByRole('img', { name: 'Company logo' });

  await expect(image).toBeVisible();
});

Missing Form Labels

Form inputs should have accessible names so assistive technologies can identify their purpose.

test('form inputs should have accessible labels', async ({ page }) => {
  await page.goto('/login');

  await expect(page.getByLabel('Email')).toBeVisible();
  await expect(page.getByLabel('Password')).toBeVisible();
});

Heading Hierarchy

Headings should follow a logical structure to help users navigate page sections.

test('page should have a main heading', async ({ page }) => {
  await page.goto('/');

  await expect(
    page.getByRole('heading', { level: 1 })
  ).toBeVisible();
});

Keyboard Accessibility

Interactive elements should be reachable and usable with a keyboard.

test('login button should be keyboard accessible', async ({ page }) => {
  await page.goto('/login');

  await page.keyboard.press('Tab');

  // Verify focus behavior according to the expected tab order.
  await expect(page.locator(':focus')).toBeVisible();
});

2. Automated Accessibility Testing with Axe

Axe Core is a popular accessibility testing engine that detects many WCAG-related accessibility violations.

Install the Playwright integration:

npm install --save-dev @axe-core/playwright

Example:

import { test, expect } from '@playwright/test';
import AxeBuilder from '@axe-core/playwright';

test('should have no detectable accessibility violations', async ({ page }) => {
  await page.goto('/');

  const accessibilityScan = await new AxeBuilder({ page }).analyze();

  expect(accessibilityScan.violations).toEqual([]);
});

How it works:

  • AxeBuilder configures an accessibility scan for the current page.
  • .analyze() runs the accessibility checks.
  • violations contains detected accessibility issues.
  • expect(...).toEqual([]) fails the test if any violations are found.

Axe detects many common issues, but passing the scan does not guarantee full accessibility or WCAG compliance.

3. Other Useful Testing Techniques

Check Image Alternative Text

const images = page.getByRole('img');

await expect(images).toHaveCount(2);
await expect(
  page.getByRole('img', { name: 'Company logo' })
).toBeVisible();

Check Keyboard Focus

await page.getByLabel('Email').focus();

await expect(page.getByLabel('Email')).toBeFocused();

Check Accessible Button Names

await expect(
  page.getByRole('button', { name: 'Submit' })
).toBeVisible();

Note: These assertions verify specific accessibility-related properties. They do not replace a complete accessibility audit.

4. Testing Tools

Tool Purpose
Playwright Automates accessibility-related behavior and assertions
Axe Core Detects many common accessibility violations
Lighthouse Audits accessibility alongside other quality metrics
Lighthouse CI Runs Lighthouse audits in continuous integration pipelines
Screen readers Tests the experience using assistive technology

5. Why Accessibility Testing Matters

  • Inclusion: Makes applications usable by people with different abilities.
  • Usability: Improves navigation, forms, and interactions for everyone.
  • Compliance: Helps identify issues related to applicable accessibility standards and legal requirements.
  • Quality assurance: Detects accessibility regressions during development.

6. Best Practices

  • Use semantic HTML elements such as <button>, <nav>, and <main>.
  • Provide meaningful alternative text for informative images.
  • Associate form inputs with accessible labels.
  • Maintain a logical heading hierarchy.
  • Ensure interactive elements work with keyboard navigation.
  • Check focus visibility and focus order.
  • Run automated accessibility scans regularly.
  • Supplement automated tests with manual keyboard and screen-reader testing.

7. Running Accessibility Tests

# Run all tests
npx playwright test

# Run a specific accessibility test file
npx playwright test tests/accessibility.spec.ts

# Run with a visible browser
npx playwright test tests/accessibility.spec.ts --headed

# Debug accessibility tests
npx playwright test tests/accessibility.spec.ts --debug

Key takeaway: Use Playwright for automated accessibility assertions, Axe Core for detecting common WCAG violations, and manual testing to validate real keyboard and screen-reader experiences.

#playwright#accessibility#axe#wcagcreated 12 Oct 2026

Local graph