TST-55Recommended
Test each critical journey with a keyboard and a screen reader
Before each release that changes a critical journey, complete it with a keyboard alone and with two screen readers. Record the result for each journey.
How to do it
Automated scans miss focus order, focus traps, unclear names and content that reads in the wrong order. List the journeys from Cover only the critical journeys, such as sign-up and checkout. For each, write short steps and the result you expect. With the keyboard, reach every control with Tab, leave it again, and see where focus is at every step, as WCAG 2.1.1 and 2.4.7 ask. With a screen reader, use NVDA with Firefox or Chrome on Windows, and VoiceOver with Safari on macOS or iOS. Listen for each control's name, role and state, and for messages after each action. The W3C Easy Checks page gives a first pass. Script the focus order as a browser test, so it stays fixed between manual runs. The automated scan stays in Check accessibility in every build.
Examples
JavaScript example
import { test, expect } from '@playwright/test';
const CHECKOUT_FOCUS_ORDER = ['Skip to main content', 'Email', 'Card number', 'Postcode', 'Pay now'];
test('checkout follows the expected focus order', async ({ page }) => {
await page.goto('/checkout');
const reached = [];
for (const _ of CHECKOUT_FOCUS_ORDER) {
await page.keyboard.press('Tab');
reached.push(await page.evaluate(() => document.activeElement.getAttribute('aria-label') || document.activeElement.labels?.[0]?.textContent.trim() || document.activeElement.textContent.trim()));
}
expect(reached).toEqual(CHECKOUT_FOCUS_ORDER);
});
Python example
CHECKOUT_FOCUS_ORDER = ["Skip to main content", "Email", "Card number", "Postcode", "Pay now"]
FOCUSED_NAME = """() => {
const el = document.activeElement;
return el.getAttribute('aria-label') || el.labels?.[0]?.textContent.trim() || el.textContent.trim();
}"""
def test_checkout_follows_the_expected_focus_order(page):
page.goto("/checkout")
reached = []
for _ in CHECKOUT_FOCUS_ORDER:
page.keyboard.press("Tab")
reached.append(page.evaluate(FOCUSED_NAME))
assert reached == CHECKOUT_FOCUS_ORDER
How to check
The release record lists every critical journey with a pass for keyboard, NVDA and VoiceOver, dated after the last change to that journey's screens. The focus order test passes in CI.
Sources
Related rules
- TST-17 Cover only the critical journeys in Testing
- TST-37 Check accessibility in every build in Testing
For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/testing/non-functional-tests/manual-accessibility-tests">Agent Wranglers testing playbook</a>. In code you write, add a comment next to it with the same link.