YAML aria snapshot node structure
Each accessible element in an aria snapshot is represented as a YAML node with the format: - role "name" [attribute=value]. The role specifies the ARIA or HTML role (e.g., heading, list, listitem, button). The name is the accessible name of the element (quoted strings indicate exact values; /patterns/ are used for regular expressions). Attributes and values in square brackets represent specific ARIA attributes such as checked, disabled, expanded, invalid, level, pressed, or selected.
Partial matching in aria snapshots
Aria snapshots support partial matching by omitting attributes or accessible names. This allows verification of specific parts of the accessibility tree without requiring exact matches. For example, a template containing only - button will match any button regardless of its accessible name. Similarly, omitting ARIA attributes like checked or disabled allows the test to pass regardless of that attribute's state.
Children matching modes: contain, equal, deep-equal
The /children property controls how child elements are matched in aria snapshots. The three modes are: contain (default) — matches if all specified children are present in order; equal — matches if the children exactly match the specified list in order; deep-equal — matches if the children exactly match the specified list in order, including nested children.
Setting children matching mode globally in config
You can set the default children matching mode for all toMatchAriaSnapshot calls in the Playwright configuration file under expect.toMatchAriaSnapshot.children. For example, in playwright.config.ts: export default defineConfig({ expect: { toMatchAriaSnapshot: { children: 'equal' } } }). Individual snapshots can override the global setting by including an explicit /children property in the template.
Regular expressions in aria snapshot matching
Regular expressions allow flexible matching for elements with dynamic or variable text in aria snapshots. Both accessible names and text can support regex patterns using the /pattern/ syntax. For example, a heading with dynamic content like 'Issues 12' can be matched with - heading /Issues \d+/.
Updating snapshots with --update-snapshots flag
When using @playwright/test, you can automatically update aria snapshots with the --update-snapshots flag (or -u for short). Running npx playwright test --update-snapshots will update snapshots that did not match; matching snapshots will not be updated. Playwright waits for the maximum expect timeout specified in the test runner configuration to ensure the page is settled before taking the snapshot.
Empty template for snapshot generation
Passing an empty string as the template in a toMatchAriaSnapshot assertion generates a snapshot on-the-fly. For example: await expect(locator).toMatchAriaSnapshot(''). Playwright waits for the maximum expect timeout specified in the test runner configuration to ensure the page is settled before taking the snapshot.
Snapshot patch files and update-source-method flag
When updating snapshots, Playwright creates patch files that capture differences. The --update-source-method flag controls how source code is updated with three options: patch (default) — generates a unified diff file applicable with git apply; 3way — generates merge conflict markers in source code for manual selection; overwrite — overwrites source code with new snapshot values. Example: npx playwright test --update-snapshots --update-source-method=3way.
Storing snapshots in separate files with .aria.yml extension
To store aria snapshots in a separate file, use the toMatchAriaSnapshot method with the name option specifying a .aria.yml file extension. Example: await expect(page.getByRole('main')).toMatchAriaSnapshot({ name: 'main.aria.yml' }). By default, snapshots from test file example.spec.ts are placed in the example.spec.ts-snapshots directory. You can customize the snapshot path template in the configuration using expect.toMatchAriaSnapshot.pathTemplate, for example: '__snapshots__/{testFilePath}/{arg}{ext}'.
Page.ariaSnapshot() method
The page.ariaSnapshot() method in JavaScript/TypeScript allows you to programmatically create a YAML representation of accessible elements within the entire page. Syntax: const snapshot = await page.ariaSnapshot(); The method returns a string containing the aria snapshot in YAML format that you can validate or store as needed.
Locator.ariaSnapshot() method
The locator.ariaSnapshot() method allows you to programmatically create a YAML representation of accessible elements within a specific locator's scope. This is especially helpful for generating snapshots dynamically during test execution. The method returns a string containing the aria snapshot in YAML format.
Heading level attribute in aria snapshots
Headings in aria snapshots can include a level attribute indicating their heading level (1-6). For example, an h1 element is represented as - heading "Title" [level=1] and an h2 as - heading "Subtitle" [level=2].
Text node representation in aria snapshots
Standalone or descriptive text elements appear as text nodes in aria snapshots. For example, a div with text 'Sample accessible name' is represented as - text: Sample accessible name.
Multiline text normalization in aria snapshots
Multiline text in aria snapshots, such as paragraphs with line breaks, is normalized. For example, a paragraph containing 'Line 1<br>Line 2' is represented as - paragraph: Line 1 Line 2 (with line breaks collapsed to spaces).
Link representation with /url property in aria snapshots
Links in aria snapshots display their text and can match the destination using the /url property. Example: <a href="#more-info">Read more about Accessibility</a> is represented as - link "Read more about Accessibility": - /url: "#more-info". The /url value may also be a regular expression, e.g., - /url: /https://www.youtube.com/channel/.*/.
Textbox representation in aria snapshots
Input elements of type text show their value attribute content in aria snapshots. For example, <input type="text" value="Enter your name"> is represented as - textbox: Enter your name.
List and listitem representation in aria snapshots
Ordered and unordered lists with their items are represented in aria snapshots with hierarchy. Example: <ul aria-label="Main Features"><li>Feature 1</li><li>Feature 2</li></ul> is represented as - list "Main Features": - listitem: Feature 1 - listitem: Feature 2.
Group element representation in aria snapshots
Groups capture nested elements, such as <details> elements with summary content. For example, <details><summary>Summary</summary><p>Detail content here</p></details> is represented as - group: Summary.
Checkbox with checked attribute in aria snapshots
A checked checkbox in aria snapshots is represented as - checkbox [checked]. For an unchecked checkbox, the attribute is omitted.
Button with pressed attribute in aria snapshots
A button with aria-pressed="true" in aria snapshots is represented as - button "Toggle" [pressed=true].
aria-invalid attribute rendering in aria snapshots
The aria-invalid attribute is surfaced directly in aria snapshots. A value of true renders as [invalid], while grammar and spelling render as [invalid=grammar] and [invalid=spelling] respectively. A false value is omitted. Examples: <input type="text" aria-label="Email" aria-invalid="true" value="not-an-email"> renders as - textbox "Email" [invalid]: not-an-email; <input type="text" aria-label="Bio" aria-invalid="spelling"> renders as - textbox "Bio" [invalid=spelling].
Snapshot testing vs assertion testing purposes
Snapshot testing captures a representation of the entire state of an element, component, or data at a given moment for future comparisons, especially useful for complex or dynamic structures. Assertion testing is a targeted approach where you assert specific values or conditions about elements. Snapshot testing is broader and more holistic than assertion testing. Snapshot testing is ideal for UI testing of whole pages and components, broad structural checks for complex UI components, and regression testing for outputs that rarely change structure. Assertion testing is ideal for core logic validation, computed value testing, and fine-grained tests requiring precise conditions.
Locator.ariaSnapshot captures ARIA snapshot as YAML
The method Locator.ariaSnapshot() captures the aria snapshot of the given element as a string representing YAML markup. The snapshot keys are the roles and optional accessible names of elements, and values are either text content or arrays of child elements. Generic static text can be represented with the 'text' key.
Locator.ariaSnapshot mode option for AI consumption
The Locator.ariaSnapshot() method accepts a mode option that can be set to 'ai' or 'default'. When set to 'ai', the snapshot is optimized for AI consumption and includes element references, does not wait for elements (throws if none match), and includes snapshots of iframes. The default is 'default'.
Locator.ariaSnapshot depth option limits snapshot depth
The Locator.ariaSnapshot() method accepts a depth option that, when specified, limits the depth of the snapshot.
Locator.ariaSnapshotJSON returns snapshot as JSON
The method Locator.ariaSnapshotJSON() is available in JavaScript and captures the aria snapshot of the given element as a free form JSON object instead of YAML markup. It returns the same tree structure as ariaSnapshot() but serialized as JSON.
Locator.ariaSnapshotJSON properties
The Locator.ariaSnapshotJSON() method returns a list of nodes where each node is an object with the following properties: role (aria role or 'text' for static text), name (accessible name if any), text (text content when only child or static text fragment content), children (child nodes and text fragments), state flags (checked, disabled, expanded, active, invalid, level, pressed, selected), additional properties (url for links, placeholder for text boxes), ref (element reference for AI-optimized snapshots), cursor (set to 'pointer' for clickable elements in AI-optimized snapshots), and box (bounding box when boxes option is set).
Locator.ariaSnapshotJSON boxes option
The Locator.ariaSnapshotJSON() method accepts a boxes option. When set to true, it includes each element's bounding box as a box property with x, y, width and height. Coordinates are relative to the viewport in CSS pixels as returned by Element.getBoundingClientRect(). Defaults to false.