playwright/docs/src/aria-snapshot.md

9.6 KiB

id title
aria-snapshot Accessibility snapshots

Overview

Accessibility snapshots in Playwright are a YAML representation of elements on the page. These snapshots can be stored and later compared to check if the page structure remains consistent or meets specified expectations.

The YAML format for accessibility trees is used to describe the hierarchical structure of the elements on a web page, including their roles, attributes, values and text content. The YAML structure follows a tree-like syntax where each node represents an accessible element, and indentation reflects nesting within the hierarchy.

Matching snapshots

The [method: LocatorAssertions.toMatchAriaSnapshot] assertion is a method used in Playwright to match the accessible structure of a page against a defined accessibility snapshot template. This helps in verifying that the page's state meets testing expectations.

Example: Match a heading element

await page.setContent(`<h1>title</h1>`);
await expect(page.locator('body')).toMatchAriaSnapshot(`
  - heading "title"
`);
page.set_content("<h1>title</h1>")
page.locator("body").to_match_aria_snapshot("""
  - heading "title"
""")
await page.set_content("<h1>title</h1>")
await page.locator("body").to_match_aria_snapshot("""
  - heading "title"
""")
page.setContent("<h1>title</h1>");
page.locator("body").expect().toMatchAriaSnapshot("""
  - heading "title"
""");
await page.SetContentAsync("<h1>title</h1>");
await Expect(page.Locator("body")).ToMatchAriaSnapshotAsync(@"
  - heading ""title""
");

Example: Match list

Lists can be matched partially.

await page.setContent(`
  <ul aria-label="my list">
    <li>one</li>
    <li>two</li>
    <li>three</li>
    <li>four</li>
    <li>five</li>
  </ul>
`);
await expect(page.locator('body')).toMatchAriaSnapshot(`
  - list "my list":
    - listitem: one
    - listitem: three
    - listitem: five
`);
page.set_content("""
    <ul aria-label="my list">
      <li>one</li>
      <li>two</li>
      <li>three</li>
      <li>four</li>
      <li>five</li>
    </ul>
""")
page.locator("body").to_match_aria_snapshot("""
  - list "my list":
    - listitem: one
    - listitem: two
""")
await page.set_content("""
    <ul aria-label="my list">
      <li>one</li>
      <li>two</li>
      <li>three</li>
      <li>four</li>
      <li>five</li>
    </ul>
""")
await page.locator("body").to_match_aria_snapshot("""
  - list "my list":
    - listitem: one
    - listitem: three
    - listitem: five
""")
page.setContent("""
    <ul aria-label="my list">
      <li>one</li>
      <li>two</li>
      <li>three</li>
      <li>four</li>
      <li>five</li>
    </ul>
""");
page.locator("body").expect().toMatchAriaSnapshot("""
  - list "my list":
    - listitem: one
    - listitem: three
    - listitem: five
""");
await page.SetContentAsync(@"
    <ul aria-label=""my list"">
      <li>one</li>
      <li>two</li>
      <li>three</li>
      <li>four</li>
      <li>five</li>
    </ul>
");
await Expect(page.Locator("body")).ToMatchAriaSnapshotAsync(@"
  - list ""my list"":
    - listitem: one
    - listitem: three
    - listitem: five
");

Example: Matching Elements with Attributes

Test elements with ARIA attributes, such as checked, disabled, expanded, level, pressed and selected, by specifying the attribute within square brackets.

await page.setContent(`
  <input type='checkbox' checked />
`);

await expect(page.locator('body')).toMatchAriaSnapshot(`
  - checkbox [checked=true]
`);
page.set_content("<input type='checkbox' checked />")
page.locator("body").to_match_aria_snapshot("""
  - checkbox [checked=true]
""")
await page.set_content("<input type='checkbox' checked />")
await page.locator("body").to_match_aria_snapshot("""
  - checkbox [checked=true]
""")
page.setContent("<input type='checkbox' checked />");
page.locator("body").expect().toMatchAriaSnapshot("""
  - checkbox [checked=true]
""");
await page.SetContentAsync("<input type='checkbox' checked />");
await Expect(page.Locator("body")).ToMatchAriaSnapshotAsync(@"
  - checkbox [checked=true]
");

Example: Matching with Regular Expressions

Use regular expressions to match elements with dynamic or varying text content.

await page.setContent(`<h1>Issues 12</h1>`);
await expect(page.locator('body')).toMatchAriaSnapshot(`
  - heading /Issues \\d+/
`);
page.set_content("<h1>Issues 12</h1>")
page.locator("body").to_match_aria_snapshot("""
  - heading /Issues \\d+/
""")
await page.set_content("<h1>Issues 12</h1>")
await page.locator("body").to_match_aria_snapshot("""
  - heading /Issues \\d+/
""")
page.setContent("<h1>Issues 12</h1>");
page.locator("body").expect().toMatchAriaSnapshot("""
  - heading /Issues \\d+/
""");
await page.SetContentAsync("<h1>Issues 12</h1>");
await Expect(page.Locator("body")).ToMatchAriaSnapshotAsync(@"
  - heading /Issues \\d+/
");

Accessibility Tree

Syntax Overview

Each accessible element in the accessibility tree is represented as a YAML node with the following structure:

- role "name" [attribute=value]
  • role: Specifies the ARIA or HTML role of the element, such as heading, list, listitem, button, etc.
  • "name" (optional): Accessible name of the element. Quoted strings represent exact value, while regex patterns (e.g., /pattern/) match values dynamically.
  • [attribute=value] (optional): Attributes and their values, enclosed in square brackets. Attributes include checked, disabled, expanded, level, pressed and selected, as specified by ARIA or HTML semantics.

When capturing the accessibility tree, these values are either extracted from the ARIA attributes, or are computed from the HTML semantics.

You can use Chrome DevTools Accessibility Pane to inspect the accessibility tree of a page and identify the roles, name, attributes, and text content of accessible elements.

Example: Headings with level attributes indicate heading levels

<h1>Title</h1>
<h2>Subtitle</h2>

accessibility tree

- heading "Title" [level=1]
- heading "Subtitle" [level=2]

Example: Text Nodes capture standalone or descriptive text elements

<div>Sample accessible name</div>

accessibility tree

- text: Sample accessible name

Example: Flattening of the multiline text

<p>Line 1<br>Line 2</p>

accessibility tree

- paragraph: Line 1 Line 2

Example: Links represent hyperlinks with text or composed text from pseudo-elements

<a href="#more-info">Read more about Accessibility</a>

accessibility tree

- link "Read more about Accessibility"

Example: Buttons represent interactive button elements, supporting states like pressed or disabled

<button disabled>Submit</button>

accessibility tree

- button "Submit" [disabled=true]

Example: Textboxes capture input elements, with the value attribute reflecting the content

<input type="text" value="Enter your name">

accessibility tree

- textbox: Enter your name

Composite Structures

Accessibility tree follows DOM hierarchy. It does not include presentation and none roles and inlines text content from the generic nodes.

Example: Lists capture ordered and unordered lists with list items

<ul aria-label="Main Features">
  <li>Feature 1</li>
  <li>Feature 2</li>
</ul>

accessibility tree

- list "Main Features":
  - listitem: Feature 1
  - listitem: Feature 2

Example: Groups capture grouped elements, such as details elements with summary text.

<details>
  <summary>Summary</summary>
  <p>Detail content here</p>
</details>

accessibility tree

- group: Summary

Attributes and States

Attributes such as checked, disabled, expanded, level, pressed, and selected represent control states.

Example: Checkbox with checked attribute

<input type="checkbox" checked>

accessibility tree

- checkbox [checked=true]

or

- checkbox [checked]

Example: Button with pressed attribute

<button aria-pressed="true">Toggle</button>
- button "Toggle" [pressed=true]

or

- button "Toggle" [pressed]

Full Document Examples

Example: Heading and Paragraph

<h1>Welcome</h1>
<p>This is a sample paragraph</p>

accessibility tree

- heading "Welcome" [level=1]
- paragraph: This is a sample paragraph

Example: Interactive List with Nested Elements

<h2>Features</h2>
<ul aria-label="Main Features">
  <li><a href="#feature1">Feature 1</a></li>
  <li><a href="#feature2">Feature 2</a></li>
</ul>

accessibility tree

- heading "Features" [level=2]
- list "Main Features":
  - listitem:
    - link "Feature 1"
  - listitem:
    - link "Feature 2"

Example: Complex Document with Pseudo-Elements and Attributes

<style>
  p:before { content: 'hello '; }
</style>
<h1>Title</h1>
<p>Introductory text</p>
<a href="#more-info">Read more</a>

accessibility tree

- heading "Title" [level=1]
- text: hello Introductory text
- link "Read more"

Example: Button with State Attributes

<button aria-expanded="true">Toggle</button>

accessibility tree

- button "Toggle" [expanded=true]