The European Accessibility Act deadline passed in June 2025, making WCAG 2.1 AA compliance a legal requirement for private sector companies selling in the EU. Most accessibility bugs are invisible during normal development: they surface when a keyboard user can't reach a modal, a screen reader announces an icon button as just "button", or a form field gives no context about what to enter. Catching them requires combining keyboard testing and basic screen reader usage with automated axe-core scans in Playwright CI.
Why accessibility testing matters in 2026
Roughly 15% of the global population lives with some form of disability. That's not a small edge case; it's a user segment larger than most companies' biggest demographics. But until recently, accessibility was treated as a design nicety or a legal checkbox reserved for government websites. That's changing fast.
The European Accessibility Act (EAA) deadline passed in June 2025. Private sector companies selling products or services in the EU must now meet accessibility requirements or face regulatory action and fines. The UK, Canada, and Australia have their own overlapping frameworks. In the United States, the ADA has been applied to digital products through litigation for years. WCAG 2.1 AA is the international benchmark that most of these frameworks reference.
The legal risk is real, but it's not the only reason to care. Inaccessible applications have higher bounce rates, generate more support requests, and expose companies to reputational damage. A checkout flow that can't be completed with a keyboard locks out users who can't use a mouse. A form with unlabeled inputs is useless to a screen reader user. These aren't hypothetical. They're patterns that appear in production applications every day, often for years before anyone notices.
QA engineers who can catch these issues before they ship are genuinely valuable. The tooling exists. The techniques are learnable. The gap is awareness.
WCAG 2.1 basics for testers: what POUR means in practice
WCAG 2.1 (Web Content Accessibility Guidelines) is organized around four principles, abbreviated as POUR: Perceivable, Operable, Understandable, and Robust.
Perceivable means users can perceive all content through at least one sense. Images need text alternatives. Videos need captions. Content can't rely on color alone to convey meaning ("required fields are shown in red" is a failure if red is the only indicator). Operable means all functionality is available without a mouse. Keyboard navigation must reach every interactive element. Users must have enough time to complete tasks (no auto-expiring sessions without warning). Nothing flashes more than three times per second (seizure risk). Understandable means the interface behaves predictably and error messages explain what went wrong. A form that says "Invalid input" is a failure. "Email must include an @ symbol" is not. Robust means the content can be interpreted by a wide range of assistive technologies, including current and future user agents. This is where semantic HTML matters: a is robust; a styled to look like a button usually isn't.
AA compliance, the standard required by the EAA and most legal frameworks, means all Level A and Level AA success criteria are met. A and AA together cover things like: images have alt text (A), color is not the only visual indicator (A), contrast ratio is at least 4.5:1 for normal text (AA), all functionality is keyboard-accessible (A), focus indicators are visible (AA), and form inputs have programmatically associated labels (A).
As a tester, you don't need to memorize the full spec. You need to know which criteria are most commonly violated and how to test for them.
Manual a11y testing: keyboard navigation and screen readers
No automated tool will catch all accessibility failures. Manual testing, particularly with a keyboard and a screen reader, is irreplaceable.
Keyboard navigation is the first thing to test. Unplug your mouse (or turn off pointer events in DevTools) and navigate your application using only Tab, Shift+Tab, Enter, Space, and the arrow keys. Every interactive element (links, buttons, form fields, dropdowns, modals, date pickers) must be reachable and operable. The tab order should follow a logical reading sequence, generally left-to-right, top-to-bottom. Focus should never get trapped (you press Tab and nothing moves) except intentionally inside a modal, where focus should be constrained until the modal is dismissed.
The most common keyboard failure pattern: a developer builds a modal dialog, but when you press Tab inside it, focus escapes to the background page. The modal is visually present but the keyboard user is now interacting with content behind it without knowing it.
Focus indicators are part of this test. Every focused element must have a visible indicator: the browser's default outline, a custom style, anything. Designs that remove :focus styles entirely with outline: none in CSS create invisible focus, which makes keyboard navigation completely unusable. Look for this in every sprint review.
Screen reader testing is harder and takes practice, but even basic familiarity is enormously valuable. The two most common free screen readers are NVDA (Windows, free) and VoiceOver (macOS and iOS, built-in). JAWS is common in enterprise environments but costs money.
Install NVDA and open your application. Turn off your monitor if you want the full experience. Navigate with Tab to reach interactive elements, and use NVDA's browse mode (arrow keys) to read through static content. Listen to what the screen reader announces. A button that says "Click here" tells the user nothing. A button that says "Submit payment" tells them exactly what will happen. An icon button with no aria-label announces its role as "button" but nothing about its function. An unlabeled form field is announced as "edit" with no context about what to enter.
You don't need to become a screen reader power user to find meaningful bugs. Spend 30 minutes navigating your main user flows with NVDA. The issues that make the experience broken or confusing will surface quickly.
The combination of keyboard testing and basic screen reader usage will find the majority of severe a11y bugs that exist in a typical web application.
Automated a11y testing with axe-core and Playwright
Automated tools can't replace manual testing, but they catch a reliable subset of issues (missing alt text, insufficient color contrast, missing form labels, improper ARIA usage) consistently and at scale. Running them in CI means you catch regressions before they reach testers.
The most widely used engine is axe-core, maintained by Deque Systems. It powers browser extensions (axe DevTools), Lighthouse, and a range of framework integrations. For teams already using Playwright, the @axe-core/playwright package adds a11y scanning with minimal setup.
Here's a basic Playwright test that scans a page for accessibility violations:
import { test, expect } from '@playwright/test';
import AxeBuilder from '@axe-core/playwright';
test('homepage should have no automatically detectable accessibility violations', async ({ page }) => {
await page.goto('/');
const accessibilityScanResults = await new AxeBuilder({ page }).analyze();
expect(accessibilityScanResults.violations).toEqual([]);
});
This fails the test if axe finds any violations. In practice, especially on an existing codebase, you'll want to start by tagging rather than blocking: log violations, fix incrementally, and add assertions as the backlog clears.
For more targeted scanning, you can scan specific components and filter to a particular WCAG level:
test('checkout form meets WCAG 2.1 AA', async ({ page }) => {
await page.goto('/checkout');
const results = await new AxeBuilder({ page })
.include('#checkout-form')
.withTags(['wcag2a', 'wcag2aa', 'wcag21aa'])
.analyze();
if (results.violations.length > 0) {
const violationDetails = results.violations.map(v => ({
id: v.id,
impact: v.impact,
description: v.description,
nodes: v.nodes.map(n => n.html),
}));
console.log('Violations:', JSON.stringify(violationDetails, null, 2));
}
expect(results.violations).toEqual([]);
});
The .withTags() filter limits the scan to specific WCAG criteria. wcag2a, wcag2aa, and wcag21aa together cover the AA conformance level. Add these tests to your CI pipeline alongside your existing functional tests.
axe-core catches roughly 30-40% of WCAG issues automatically. That's not a reason to skip it; catching a third of issues automatically at scale is genuinely valuable. But it means a green axe scan is not an accessibility certification. It's a floor, not a ceiling.
What automated tools can't catch
This is where the most critical a11y issues live, and it's why manual testing is non-negotiable.
Meaningful alt text is the clearest example. An automated tool can detect that an ![]()
element has no alt attribute. That's a pass/fail check. It cannot determine whether the alt text is accurate or meaningful. An image of a line chart showing declining revenue described as alt="chart" passes the automated check. A screen reader user hears "chart" and has no information. The failure is semantic, not structural.
Logical reading order is another. The DOM order determines how screen readers traverse the page. Visual styling can make elements appear in a completely different order than they exist in the DOM. A sighted user reads the "Add to cart" button after the product description because it's positioned below it. If the DOM order puts the button before the product title, a screen reader user hears the button before understanding what product they're interacting with. Automated tools can flag some reordering, but complex layouts require a human to evaluate the actual listening experience.
Color contrast in context is partially automatable but can produce false results. axe scans computed styles, but overlapping elements, background images, and gradient backgrounds can fool the scanner. Test contrast manually with the browser's contrast checker or tools like the WebAIM Contrast Checker when you see complex visual designs.
Accessible names for icon buttons are a consistent failure that tools partially catch. A containing only an SVG icon may pass automated checks if the icon has a title element, but whether that title is actually announced, and whether it's announced clearly in context, requires listening with a screen reader.
Focus management after dynamic content changes is almost entirely manual. When a modal opens, focus should move into it. When it closes, focus should return to the trigger element. When a single-page app navigates, focus should move to a logical starting point, often an or a skip link target. No tool reliably tests this flow. You have to tab through it.
Common a11y bugs QA engineers find
These patterns appear repeatedly across products at every scale. Knowing them means you'll recognize them on sight.
Missing form labels is the most common. A visible placeholder in an input is not an accessible label. When the user starts typing, the placeholder disappears, and a screen reader user who navigates back to the field hears only "edit" with no context. The fix is a element associated via for/id, or an aria-label or aria-labelledby attribute. Find these by tabbing to every form input and listening in NVDA.
Non-semantic interactive elements appear whenever a developer builds a clickable or instead of a . The element may look like a button and respond to mouse clicks, but it receives no focus via Tab, doesn't respond to Enter or Space, and announces itself to screen readers as generic text rather than a button. Any interactive element that isn't a native HTML control (, , , etc.) needs explicit role, tabindex, and keyboard event handlers to be accessible. These are expensive fixes; finding them early saves significant refactoring.
Poor focus management in modals and drawers shows up in almost every custom-built dialog component. The modal opens, but focus stays on the button that triggered it (now behind the overlay). Tab order leaks out to the background page. When the modal closes, focus drops to the top of the document instead of returning to the trigger. Test every modal by opening it with Tab+Enter and navigating entirely by keyboard.
Dynamic content updates with no announcement affects single-page apps heavily. A user submits a form, the page shows a success message, but the message appears in a different part of the DOM with no focus change and no live region. A screen reader user has no idea the submission worked. ARIA live regions (role="status" or aria-live="polite") solve this, but only if someone thought to add them.
Keyboard traps in custom widgets, particularly custom dropdowns, date pickers, and rich text editors, frequently trap keyboard focus or don't implement standard keyboard interactions (arrow keys for dropdown navigation, Escape to close). Test every custom interactive component with keyboard only.
How to write a11y bug reports
Accessibility bug reports need more context than standard UI bugs because the impact depends on which assistive technology is affected and which WCAG success criterion is violated. A vague report ("screen reader doesn't work here") gives developers nothing actionable.
A good a11y bug report includes:
The WCAG criterion violated. Every failure maps to a criterion. A missing label violates WCAG 1.3.1 (Info and Relationships) and 4.1.2 (Name, Role, Value). A missing focus indicator violates WCAG 2.4.7 (Focus Visible). Include the criterion ID and name. This tells the developer exactly what the requirement is, and it documents the compliance gap for any audit.
The assistive technology and browser used. "NVDA 2024.1 + Chrome 124 on Windows 11" is actionable. "Screen reader" is not. Different AT/browser combinations behave differently, and developers need the specific stack to reproduce the issue.
The expected vs. actual announcement. For screen reader bugs, write out what the AT announced and what it should have announced. "Announced: 'button'. Expected: 'Submit payment, button'." This is the actual failure description.
Reproduction steps that use AT, not the mouse. "Tab to the email field, listen to NVDA's announcement", not "click the email field." The steps must be reproducible using only the affected interaction method.
Impact rating. Use WCAG impact levels: critical (blocker for AT users), serious (major difficulty), moderate (some difficulty), minor. A missing modal label is critical. A suboptimal heading structure is minor to moderate. Impact guides fix priority.
Don't mark a11y bugs as "nice to have" unless they're genuinely minor. A form that can't be submitted via keyboard is a blocker for keyboard-only users. It has the same severity as a checkout button that doesn't work for sighted mouse users. Apply the same severity standards you'd apply to any functional failure.
How to apply this Monday morning
You don't need to audit your entire product in one sprint. Start small and build the habit.
This week: Install NVDA (free, Windows) or enable VoiceOver (macOS: Cmd+F5). Open one page of your application, ideally a form or a modal flow. Tab through it. Listen to what NVDA announces for each element. File anything that's confusing or silent.
This sprint: Add the @axe-core/playwright package to your project. Write one test that scans your most critical page: login, checkout, or onboarding. Run it in CI. Don't block the build yet; start by logging violations so the team sees the baseline.
Over the next month: Add keyboard navigation checks to your definition of done for new features. Include "tested with keyboard only" in your PR checklist. For each feature with forms or modals, spend ten minutes testing tab order and focus management.
For your a11y bug reports: Create a template in your bug tracker with fields for WCAG criterion, AT affected, and expected announcement. Using the template takes thirty seconds. Having that information in the report saves an hour of back-and-forth with the developer.
The EAA deadline has passed. Companies that haven't addressed accessibility are now operating under legal exposure. QA engineers who can identify, document, and track accessibility failures are directly reducing that risk. More importantly, the fixes you catch before production reach users who need them. A screen reader user completing a checkout without assistance, a keyboard user navigating a form without getting trapped: that's the outcome. The tooling is the means.
Start with one keyboard test. Build from there.
→ See also: Accessibility Testing with Playwright: Automated a11y Checks | Keyboard and Mouse Events in Playwright | Usability Testing Basics: What QA Engineers Need to Know