Files
magnus919_agent-skills/playwright/references/07-accessibility-and-debugging.md
T
Magnus Hedemarkandfactory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com> b0845776a1 chore(docs): pin npx package versions in skill docs (Fixes #381)
Pin copy-pasteable npx invocations to explicit versions so agents
executing them verbatim get reproducible behavior:

- playwright docs: npx playwright@1.62.1 (SKILL.md, README.md,
  references 02-selectors / 05-ci-integration / 07-accessibility)
- mermaid-diagrams: @mermaid-js/mermaid-cli@11.16.0 (SKILL.md,
  references/pdf-rendering-pipeline.md)
- hugo-theme seo-outputs-testing: @axe-core/cli@4.13.0
- agent-skills using-scripts.md: strengthen version-pinning bullet
  into a normative rule for copy-pasteable commands

Reword the anydoc cli-reference "Version pinning" prose so the
anti-pattern is explained didactically without presenting an unpinned
command as a recipe; the @0.1.6 house pin is unchanged.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
2026-08-22 22:07:49 -04:00

3.5 KiB

Accessibility and Debugging

Last Updated: 2026-08-03

Two workflows that share one tool feature set: asserting accessibility via the accessibility tree, and debugging tests with the inspector, codegen, and traces.

Accessibility snapshot checks

Full scans with axe-core

@axe-core/playwright runs the axe engine against the rendered page:

import AxeBuilder from '@axe-core/playwright';

const results = await new AxeBuilder({ page }).analyze();
// results.violations: [{ id, impact, nodes, ... }]
expect(results.violations.filter((v) => v.impact === 'critical' || v.impact === 'serious'))
  .toEqual([]);
  • Scan every route that matters, ideally in CI; scan the full page or use .include() / .exclude() to scope.
  • Triage by impact: fix critical/serious; track moderate/minor in a backlog.
  • False positives happen (e.g., contrast rules on known-brand colors) — scope them out deliberately, never with a blanket disableRules(['color-contrast']).

Aria snapshots (snapshot-based accessibility assertions)

expect(page).toMatchAriaSnapshot() asserts against the accessibility tree, not the DOM:

await expect(page).toMatchAriaSnapshot(`
  - heading "Store front" [level=1]
  - button "Add to cart"
`);
  • These read like spec assertions ("the heading is X, the button is Y") and catch regressions in structure, labels, and semantics — not just contrast.
  • They are stable: inline text changes show up as a reviewable diff.
  • Update deliberately. Run npx playwright@1.62.1 test --update-snapshots only after inspecting what changed; never blind-update to make CI green (hard boundary in SKILL.md).
  • Requires Playwright 1.49+ (see 00-source-index.md for version notes).

Headed debugging

When a test fails or a locator matches nothing:

  1. Read the failure firstscripts/pwrun report --report <json> --json gives the failing spec and the error message from the last retry.

  2. Run headed with slow-mo to watch the actual page:

    npx playwright@1.62.1 test <spec> --headed --slow-mo 300
    
  3. The inspector (--debug or PWDEBUG=1) pauses before each action and shows the current locator; page.pause() drops a breakpoint mid-test.

  4. Codegen to prototype a flow quickly:

    npx playwright@1.62.1 codegen https://example.com
    

    Generate starter tests, then harden the emitted selectors into user-facing locators (02-selectors.md).

  5. Traces are the evidence record: with trace: 'on-first-retry' (or --trace on), every failed run produces a trace you can open in the Trace Viewer — network, DOM snapshots, console, and the failing action, frame by frame. This is the primary artifact to attach to a bug report.

Debugging checklist

Symptom First move
Locator resolves to 0 elements --debug; check async render — assert on a container first
Locator matches 2+ elements Narrow with filter({ hasText }) or scope to a container
Timeout on click() Trace: is something covering the element (overlay)? is it disabled?
Passes locally, fails CI Compare env: browser deps (install --with-deps), baseURL, shard isolation
Flaky across retries --repeat-each=5 --workers=1 to measure; then fix the selector
Console errors before failure Trace console tab; check for unhandled rejections the test should assert
  • Authoring and assertions: 01-e2e-authoring.md.
  • Selector repair loop: 02-selectors.md.
  • CI trace/artifact wiring: 05-ci-integration.md.