This project includes comprehensive accessibility testing using @axe-core/playwright to ensure WCAG 2.1 AA compliance.

Overview

Accessibility testing is integrated into the E2E test suite using:

  • @axe-core/playwright: Automated accessibility testing
  • WCAG 2.1 AA Standards: Web Content Accessibility Guidelines Level AA
  • Keyboard Navigation Testing: Manual keyboard accessibility tests
  • Mobile Accessibility: Touch target and navigation testing

Table of Contents

Test Categories

1. Automated Accessibility Audits (@a11y tag)

Run automated accessibility tests:

npm run test:a11y # Run all accessibility tests npm run test:a11y:headed # Run with browser UI

2. Manual Accessibility Tests

The following manual accessibility checks are included:

  • Keyboard navigation flow
  • Focus management
  • Screen reader compatibility
  • Color contrast verification
  • Semantic markup validation

3. Mobile Accessibility

Mobile-specific accessibility tests include:

  • Touch target sizing (minimum 44px)
  • Mobile navigation accessibility
  • Responsive design compliance

WCAG 2.1 Compliance

Level A Requirements

  • ✅ Non-text content has alternatives
  • ✅ Captions for multimedia content
  • ✅ Content is adaptable
  • ✅ Color is not the only visual means of conveying information
  • ✅ Audio control available
  • ✅ Keyboard accessible
  • ✅ No seizure-inducing content
  • ✅ Bypass blocks mechanism
  • ✅ Page titles
  • ✅ Focus order
  • ✅ Link purpose
  • ✅ Language of page

Level AA Requirements

  • ✅ Captions for live content
  • ✅ Audio descriptions
  • ✅ Color contrast (4.5:1 normal text, 3:1 large text)
  • ✅ Visual presentation controls
  • ✅ Keyboard accessible (no keyboard traps)
  • ✅ Timing adjustable
  • ✅ Pause, stop, hide
  • ✅ Three flashes or below threshold
  • ✅ Navigation mechanisms
  • ✅ Headings and labels
  • ✅ Focus visible
  • ✅ Language of parts

Test Structure

Accessibility Test Files

e2e/
├── accessibility.spec.ts               # Main accessibility tests
├── documentation-accessibility.spec.ts # Documentation-specific tests
├── homepage.spec.ts                    # Includes accessibility checks
├── documentation.spec.ts               # Includes accessibility checks
└── navigation.spec.ts                  # Includes accessibility checks

Test Patterns

Basic Accessibility Audit

test("should pass accessibility audit @a11y", async ({ page }) => {
  await page.goto("/");

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

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

Keyboard Navigation Test

test("should be keyboard accessible @a11y", async ({ page }) => {
  await page.goto("/");

  await page.keyboard.press("Tab");
  const focusedElement = await page.evaluate(() => document.activeElement?.tagName);
  expect(["A", "BUTTON", "INPUT"]).toContain(focusedElement);
});

Specific Rule Testing

test("should have proper color contrast @a11y", async ({ page }) => {
  await page.goto("/");

  const accessibilityScanResults = await new AxeBuilder({ page }).withRules(["color-contrast"]).analyze();

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

Configuration

Package.json Scripts

{
  "test:a11y": "playwright test --grep @a11y",
  "test:a11y:headed": "playwright test --grep @a11y --headed"
}

Playwright Configuration

The accessibility tests use the same Playwright configuration with additional axe-core integration.

Best Practices

1. Semantic HTML

  • Use proper HTML5 semantic elements (<main>, <nav>, <header>, <footer>)
  • Ensure proper heading hierarchy (h1 → h2 → h3)
  • Use lists (<ul>, <ol>) for grouped content

2. ARIA Attributes

  • Add aria-label for elements without visible text
  • Use aria-describedby for additional descriptions
  • Implement aria-expanded for collapsible content
  • Use role attributes where semantic HTML is insufficient

3. Keyboard Navigation

  • Ensure all interactive elements are focusable
  • Provide visible focus indicators
  • Implement logical tab order
  • Add skip links for main content

4. Images and Media

  • Provide meaningful alt text for images
  • Use empty alt="" for decorative images
  • Add captions for videos
  • Provide transcripts for audio content

5. Forms

  • Associate labels with form controls
  • Provide clear error messages
  • Group related form fields with <fieldset> and <legend>
  • Indicate required fields clearly

Common Issues and Solutions

1. Color Contrast

Issue: Text doesn’t meet 4.5:1 contrast ratio
Solution: Use darker text colors or lighter backgrounds

2. Missing Alt Text

Issue: Images without alt attributes
Solution: Add descriptive alt text or use alt="" for decorative images

3. Keyboard Navigation

Issue: Elements not accessible via keyboard
Solution: Ensure tabindex is properly set and add keyboard event handlers

4. Heading Hierarchy

Issue: Skipped heading levels (h1 → h3)
Solution: Use proper heading sequence (h1 → h2 → h3)

5. Form Labels

Issue: Form inputs without associated labels
Solution: Use <label for="input-id"> or aria-label attributes

Integration with CI/CD

Accessibility tests can be integrated into continuous integration:

# .github/workflows/accessibility.yml
- name: Run Accessibility Tests
  run: |
    npm install
    npm run test:a11y

Tools and Resources

Testing Tools

Browser Extensions

  • axe DevTools: Browser extension for accessibility testing
  • WAVE: Web accessibility evaluation tool
  • Lighthouse: Includes accessibility audits

Guidelines and Standards

Reporting and Monitoring

Test Reports

Accessibility test results are included in standard Playwright reports:

  • HTML report: playwright-report/index.html
  • JSON report: test-results/results.json
  • JUnit report: test-results/junit.xml

Continuous Monitoring

Consider implementing:

  • Regular accessibility audits in CI/CD pipeline
  • Accessibility monitoring in production
  • User testing with assistive technologies
  • Periodic manual accessibility reviews

Last Updated: July 29, 2025
WCAG Version: 2.1 Level AA
Testing Framework: Playwright + axe-core