Agent Wranglers

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

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.