Free tools Windows power users keep installed
One-click scans. No signup required.
Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Use Playwright ARIA snapshots to assert the accessible structure that users and assistive technologies receive, rather than pinning a test to raw DOM markup. Write a nested YAML template with roles, accessible names, text, and relevant states, then compare it with toMatchAriaSnapshot() on a page or locator. Scope the assertion to the smallest useful region, keep default child matching partial when appropriate, and use /children: equal or deep-equal only when exact structure is a requirement.
What an ARIA snapshot represents
An ARIA snapshot is a YAML-like tree of accessible nodes. It is not a serialized DOM dump: the tree reflects roles, accessible names, visible text, and selected states or attributes exposed through the accessibility representation.
- heading "Title" [level=1]
- checkbox [checked]
- textbox "Email" [invalid]: not-an-email
Indentation expresses hierarchy. A node can have a role and optional accessible name, followed by properties in brackets and text after a colon. Because the snapshot models the user-facing accessibility tree, a refactor from nested div elements to a semantic nav can leave the test unchanged when the accessible structure remains correct.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Your first snapshot assertion
The main assertion is toMatchAriaSnapshot(). A page-level assertion checks the page body; a locator assertion checks only the selected region.
#1 Best Overall
import { test, expect } from '@playwright/test';
test('todo page has its primary controls', async ({ page }) => {
await page.goto('https://demo.playwright.dev/todomvc/');
await expect(page).toMatchAriaSnapshot(`
- heading "todos"
- textbox "What needs to be done?"
`);
});
Use a locator when the page contains unrelated content or when a component is the unit under test:
await expect(page.getByRole('main')).toMatchAriaSnapshot(`
- heading "Account settings"
- textbox "Email"
- button "Save changes"
`);
A locator-scoped assertion usually produces a more stable test because navigation, banners, and footer changes cannot alter the expected tree outside that region.
Nested roles and accessible names
Represent hierarchy with indentation. The following checks a named list containing two list items and links:
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Fix the driver behind crashes, sound loss and screen glitches3Clear out junk files and repair common Windows errorsawait expect(page.getByRole('navigation')).toMatchAriaSnapshot(`
- list "Links":
- listitem:
- link "Home"
- listitem:
- link "About"
`);
Names can come from visible text, an associated label, or composed content. Include the name when the label is part of the behavior you need to preserve. If a link destination is important, a URL property can be matched as well:
await expect(page.getByRole('link', { name: 'Docs' })).toMatchAriaSnapshot(`
- link "Docs":
- /url: /docs/
`);
Use role-only entries when the label is intentionally outside the test’s contract:
await expect(page.getByRole('main')).toMatchAriaSnapshot(`
- button
`);
This verifies that a button exists without coupling the test to a current label. Do not omit a name merely to make a test pass if the accessible name is the requirement.
Partial versus exact child matching
Default contain matching
By default, a template uses contain semantics. Specified children must be present in order, while additional children may appear. This is useful for a list that can gain unrelated items:
await expect(page.getByRole('list')).toMatchAriaSnapshot(`
- list:
- listitem: Feature A
`);
Exact children with equal
Use the /children property when the immediate child list must match exactly and in order:
await expect(page.getByRole('list')).toMatchAriaSnapshot(`
- list:
- /children: equal
- listitem: Feature A
- listitem: Feature B
`);
Deep exactness with deep-equal
deep-equal additionally requires nested descendants to match exactly. It is appropriate for a finite menu, wizard step, or other structure where an unexpected descendant is a defect. It is brittle for content that changes legitimately.
You can configure a global default through expect.toMatchAriaSnapshot.children, then override it in an individual snapshot. Prefer the least strict setting that still protects the behavior under test.
Dynamic text, regular expressions, and matching rules
Snapshot matching is case-sensitive, collapses whitespace, and remains order-sensitive. A regular expression handles values that legitimately vary:
await expect(page.getByRole('heading')).toMatchAriaSnapshot(`
- heading /Issues \d+/
`);
Regex is useful for counters, generated identifiers, and dates, but do not use a broad expression to hide a broken label. If only the role matters, omit the name instead; if a stable prefix matters, express that prefix in the pattern.
Capture a snapshot without asserting it
locator.ariaSnapshot() returns a promise containing the YAML string. This is useful when diagnosing a failure or inspecting a component before writing an assertion.
const snapshot = await page.getByRole('main').ariaSnapshot();
console.log(snapshot);
For JSON-oriented tooling, locator.ariaSnapshotJSON() is available in versions that provide that API. Treat the generated representation as a description of the current accessible tree, not as a substitute for deciding which parts are contractual.
Generate and update snapshots with the test runner
An empty template asks the runner to generate a snapshot:
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →await expect(page.getByRole('main')).toMatchAriaSnapshot('');
The runner waits up to the configured maximum expect timeout while the page settles. When the assertion fails, review the generated patch rather than blindly accepting it. Update snapshots with:
npx playwright test --update-snapshots
# short form
npx playwright test -u
Source updates can use patch (the default), 3way, or overwrite. A patch is generally safer: inspect additions, removals, and changed names before committing. Regenerate after an intentional accessibility change; investigate when a snapshot changes after an unrelated visual or DOM refactor.
Keep snapshots in separate files
Inline templates keep the expectation next to the test. A named file is easier to review when the tree is large or shared by a component test:
await expect(page.getByRole('main')).toMatchAriaSnapshot({
name: 'main.aria.yml'
});
The default location is a test-specific snapshot directory, and the path template is configurable. Use a descriptive filename and keep the file close to the test suite’s ownership boundary. A separate file is organizational—not a different matching algorithm.
Rank #4
Choosing the right scope and strictness
| Decision | Use this when | Main trade-off |
|---|---|---|
| Page assertion | The entire document’s accessible outline is a requirement | Any unrelated page change can fail the test |
| Locator assertion | A component, landmark, dialog, or region is the contract | Content outside the locator is not checked |
| Contain children | Extra children are valid or expected to evolve | Unexpected additional nodes can pass |
| Equal children | Immediate child count and order are fixed | Legitimate additions require updates |
| Deep-equal children | Every descendant is part of the contract | Most sensitive to content changes |
| Exact name | The announced label must not change | Copy edits require a snapshot update |
| Regex or omitted name | Text is dynamic or not central | Too much flexibility can hide regressions |
Version availability
Check the Playwright version installed in your project before adopting an example. The official API annotations identify locator.ariaSnapshot() as added in v1.49 and locator.ariaSnapshotJSON() as added in v1.63. The string-template form of locator assertions is marked v1.49, named-file assertions v1.50, and page-level toMatchAriaSnapshot() v1.60. If an API is missing or behaves differently, compare your installed version with those annotations and upgrade deliberately rather than changing the assertion syntax at random.
Troubleshooting failed assertions
The snapshot contains fewer or more nodes than expected
First print ariaSnapshot() for the same locator. Check whether the locator is too broad, a dialog is still open, or content is rendered conditionally. Narrow the locator or wait for a meaningful state instead of adding arbitrary delays.
The accessible name does not match
Names are case-sensitive and whitespace is collapsed. Inspect the rendered label, associated form label, and composed content. Use a regex only for genuinely variable text; otherwise fix the accessible name or the expectation.
Order changes between runs
Matching is order-sensitive. Stabilize the application ordering, scope to the intended container, or assert only the ordered subset that matters. Do not switch to a loose pattern if order itself conveys priority.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →A strict snapshot fails after adding a valid item
equal and deep-equal intentionally reject additions. Decide whether the new child is part of the requirement. If not, use the default contain mode; if yes, update the reviewed snapshot.
The generated snapshot is empty or incomplete
Ensure the locator resolves to the intended region and that the page has finished rendering. Use the configured expect timeout, wait for a selector that signals readiness, and capture again. A bot challenge, failed navigation, or application error must be fixed at the page level rather than encoded as an expected snapshot.
Best Value
Or skip the browser setup
If your goal is a clean image or PDF of a page rather than an accessibility assertion, ScreenshotNeo provides a website screenshot API and MCP server. It accepts consent banners like a visitor, removes more than 60 known consent platforms plus newsletter popups and chat widgets before capture, and lets each cleanup step be disabled. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed; response headers identify the page verdict and billing status. Its MCP tools—take_screenshot, get_page_info, and capture_pdf—work with Claude, Cursor, and other MCP clients.
One GET request is enough:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo documentation for all options, including full-page lazy-image loading, CSS-selector element capture, device presets, custom CSS and JavaScript, waits, request blocking, headers and cookies, geolocation, transparent backgrounds, resizing, caching, signed links, asynchronous webhooks, bulk capture, and PDF settings.
Python:
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
Node.js:
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
The Free plan includes 1,000 shots per month with no card. Paid plans start at $5 for 3,000 shots; every feature is included on every plan. Create a free ScreenshotNeo account.
FAQ
Can an ARIA snapshot replace role-based locators?
No. Use role-based locators to find and interact with controls; use snapshots to verify the resulting accessible structure.
Should snapshots include every page element?
Usually not. Assert the landmark or component whose accessibility contract the test owns, and include only names, states, and descendants that matter.
Are snapshot files portable between test projects?
They are text templates, but path conventions and update settings belong to the project. Move the file together with its test and verify the configured snapshot directory.
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallFrequently Asked Questions
Does an ARIA snapshot test visual styling?
No. It tests the accessible tree—roles, names, text, and selected states—not pixels, layout, colors, or typography.
When should I regenerate a snapshot?
Regenerate after an intentional accessibility or content-contract change, then review the patch. Do not automatically accept changes caused by an unexplained failure.
What is the safest default for a changing list?
Use locator scope with default contain matching, and add exact names or regex only for the items whose behavior is important.
The Bottom Line
Start with a locator-scoped toMatchAriaSnapshot(), keep matching partial unless exact children are a requirement, and inspect generated changes before updating files. Check your installed Playwright version whenever an API example is unavailable.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

