In a Playwright aria snapshot template, how do you express a node's role, accessible name and heading level?
answer
- One list item per node
- Role first, then quoted name
- State goes in square brackets
- Indentation expresses nesting
- Slashes make a value a regex
basics
~20 sEach node is one YAML list item: the role, then the accessible name in double quotes, then state in square brackets, as in a heading line reading role heading, name October statement, level=1. Indentation nests children.
solid answer
~40 sA template line is `- role "accessible name" [attributes]`, for example `- heading "October statement" [level=1]` or `- button "Export CSV" [disabled]`. Children nest by indentation under a parent line ending in a colon, and loose text becomes `- text: Closing balance`. Supported attributes are `level`, `checked`, `disabled`, `expanded`, `pressed` and `selected`; anything you omit is not asserted, so `- button` matches a button of any name. Names and text can be regular expressions written between slashes, such as `- text: /Closing balance/`, which is how a statement page's changing figures stay assertable. Generate the YAML with `locator.ariaSnapshot()` and trim it rather than typing nesting by hand.
code
yaml · 6 lines- heading "October statement" [level=1]
- region "Balance":
- heading "Balance" [level=2]
- text: /Closing balance/
- table "Transactions"
- button "Export CSV" [disabled]go deeper
Learn to read a template line: role, then the name in quotes, then bracketed state. Recognise that indentation means nesting and that a text line starts with the word text and a colon.
Be able to write one from scratch and name the attributes available, level, checked, disabled, expanded, pressed and selected, and explain that omitted properties are simply not asserted.
Choose precision per node: exact name where the label is a contract, bare role where it is not, regex where only part is stable. Explain why generating and trimming beats hand-writing nesting.
Treat the template as a reviewable artefact and set expectations for how tight it should be, so reviewers can read a regenerated diff and judge intent rather than rubber-stamping it.
## The shape of a line Every node in an aria snapshot template is one YAML list item beginning with its **role**, optionally followed by its **accessible name** in double quotes, then optional **state attributes** in square brackets: ```yaml - heading "October statement" [level=1] - button "Export CSV" [disabled] - checkbox "Include pending" [checked] ``` Children are expressed by indentation under a parent that ends in a colon: ```yaml - region "Balance": - heading "Balance" [level=2] - text: Closing balance ``` Plain text that is not itself a named control is written as a `text` node, `- text: Closing balance`. ## Attributes you can assert | Attribute | Asserts | Typical node | | --- | --- | --- | | `[level=1]` | Heading level | `heading` | | `[checked]` | Checked state, also `[checked=mixed]` | `checkbox`, `radio` | | `[disabled]` | The control is disabled | `button`, `textbox` | | `[expanded]` | Disclosure is open | `button`, `combobox` | | `[pressed]` | Toggle button is pressed | `button` | | `[selected]` | Selection state | `option`, `tab` | An attribute you leave out is not asserted. Writing `- button "Export CSV"` says nothing about whether the button is disabled, so a template stays readable rather than exhaustive. ## Names, partial nodes and regular expressions Three levels of precision are available for a node's name, and choosing the right one is most of the skill: 1. **Exact name** in quotes, `- button "Export CSV"`, when the label is part of the contract you want to defend. 2. **No name at all**, `- button`, when you care that a button exists in that position but not what it says. 3. **A regular expression** between slashes, `- heading /October statement/ [level=1]` or `- text: /Closing balance/`, when only part of the string is stable. Regular expressions work for text nodes and for accessible names, which is what keeps a template usable on a page whose figures and dates move. ## Generate, then trim Hand-writing a template usually fails on nesting, because the indentation has to mirror the real tree, including wrapper regions and list structures you never think about. The reliable workflow is: - Call `ariaSnapshot()` on the locator you intend to assert, for example `await page.getByRole('main').ariaSnapshot()`, and read the YAML it returns. - Paste it into the test or into the `.yml` file. - Delete every line the test does not care about, and relax the volatile ones into regular expressions or bare roles. - Re-run, so the trimmed template is proved against the live page before it is committed. ## Why the format is worth learning The YAML is the reviewable artefact. Because it is text, a regenerated template shows up in a pull request as ordinary added and removed lines: a reviewer sees "the `[level=1]` became `[level=2]`" and can ask whether that was intended. That reviewability is the practical argument for a structural snapshot over an opaque baseline, and it only works if the people reviewing can read the grammar fluently.
- When would you deliberately write a node with no accessible name?When the test cares that a control of that role exists in that position but not what it is labelled. On a statement page, `- table` under the balance region defends the presence of the transaction table while leaving a caption reword free to change. It is the same relaxation as a regex, applied to the whole name.
- How do you assert that the export button is disabled until a date range is chosen?Add the state in brackets: `- button "Export CSV" [disabled]`. The attribute is asserted only because you wrote it, so a second snapshot taken after choosing the range can carry `- button "Export CSV"` with no attribute, or assert the enabled state through a targeted matcher instead.
saying these in an interview costs you the question
- Thinks the template is JSON rather than YAML
- Believes every attribute of every node must be listed
- Writes CSS selectors or tag names as template lines
- Assumes names cannot be regular expressions
- Hand-writes nesting instead of generating the tree