Chapter 20 · Accessibility Testing and Aria Snapshot
Chapter goals: Understand the source and YAML syntax of aria snapshots, learn to assert a page's accessible structure with
to_match_aria_snapshot(), and bake accessibility checks into daily tests and CI.
20.1 Why Automate Accessibility Testing
Accessibility (a11y) is not a "nice-to-have" — it directly affects whether screen-reader users can use your product, and is increasingly a legal requirement in many regions. More importantly, pages that are machine-friendly tend to be more human-friendly too: a button without a proper role and accessible name is just as much a disaster for test automation as for assistive technology.
Traditional a11y audit tools (like axe) scan for "are there violations?"; Playwright offers a complementary视角: snapshot the page's accessibility tree and assert it as a structural contract — if the semantic structure is wrong, the test turns red.
20.2 Understanding Aria Snapshot: YAML-Formatted Accessibility Tree
Aria snapshot is Playwright's YAML representation of an element/page's accessibility tree, available since v1.49. Each node describes one accessible element:
- role "name" [attribute=value]role: ARIA or HTML implicit role, e.g.heading,button,listitem;"name": accessible name (exact string;/regex/for pattern match);[attribute=value]: state attributes likechecked,disabled,expanded,level,pressed,selected.
View the current page's snapshot directly in code:
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page()
page.goto("https://playwright.dev/python/docs/intro")
# Print the accessibility structure of the entire sidebar (YAML string)
print(page.get_by_role("navigation").aria_snapshot())
browser.close()Output looks like:
- navigation "Docs":
- list:
- listitem:
- link "Intro"
- listitem:
- link "Writing tests"Indentation expresses hierarchical nesting — this is the world a screen reader "sees".
20.3 to_match_aria_snapshot(): Structural Assertions
The core assertion is expect(page).to_match_aria_snapshot() (full page) or expect(locator).to_match_aria_snapshot() (local region):
from playwright.sync_api import expect
def test_heading_structure(page):
page.goto("https://example.com")
# Full-page assertion: heading hierarchy is correct
expect(page).to_match_aria_snapshot("""
- heading "Example Domain"
- paragraph
""")
def test_nav_structure(page):
page.goto("https://example.com")
# Local assertion: care only about the nav area, with [level] attribute check
expect(page.get_by_role("contentinfo")).to_match_aria_snapshot("""
- contentinfo:
- link /更多/
""")Four matching rules, all from the official docs:
- Case-sensitive, but whitespace is collapsed (indentation and newlines do not affect comparison);
- Order-sensitive: node order in the template must match the actual tree;
- Partial match supported: omitting a name or attribute checks only the concerned部分;
/regex/syntax for flexible name matching.
20.4 Baking a11y Checks into CI
Run aria snapshot assertions alongside your regular tests — they catch regressions before they reach production:
def test_page_accessibility_snapshot(page):
page.goto("/")
expect(page).to_match_aria_snapshot() # Auto-generate baseline on first runIntegrate into CI with --update-snapshots on authorized branches; any dev push that changes the accessible structure will fail the check and force a review.
20.5 Chapter Summary
- Aria snapshot = YAML representation of the accessibility tree; each node has role, name, and state attributes;
to_match_aria_snapshot()asserts structural correctness with auto-retry;- Matching is case-sensitive, order-sensitive, supports partial match and
/regex/; - Bake into CI: baseline on main, reject structural regressions on feature branches.
🧪 随堂测验
点击你认为正确的选项。答错时会展示正确答案与原因解析。
1. What does an aria snapshot node look like?
2. What happens when you call expect(page).to_match_aria_snapshot() without arguments on the first run?
3. Which matching property is NOT true for aria snapshot comparison?
4. What is the recommended CI strategy for aria snapshot tests?
🛠️ Hands-On Exercises
- Visit any site; print its
aria_snapshot()and manually inspect the YAML tree for missing roles or names. - Write an
to_match_aria_snapshot()assertion for a component; change one attribute in the HTML and observe the failure diff. - Add an aria snapshot test to your CI workflow; verify that a structural regression fails the pipeline.
Proceed to Chapter 21: WebSocket and Real-Time Application Testing.