expect), locators
(getByRole, getByTestId, CSS, XPath), a parallel test runner, and a trace
viewer. It’s well-suited to teams that want OSS, full programmatic control, and
have the bandwidth to maintain a locator-based codebase.
This page compares hand-written Playwright. For the coding-agent authoring
workflow that drives a browser and generates Playwright code, see Playwright
MCP.
Speed and caching
How the multi-modal cache works
A cached step stores more than one way to find the target: where it sits on screen, what it looks like, what text it contains, and the structural and accessibility attributes around it. Which of those signals matters for a given step is inferred from the natural-language description. “The red Cancel button below the Order Summary header” leans on visual and positional signals; “the Submit button in the form” leans on structure and role. When a step replays, the runner checks the stored signals against the live page and runs the action without invoking the LLM when there’s a match. On a miss, the locator agent (auto-heal) re-resolves the original description against the live page, updates the cache entry in place, and the run continues. A heal event is recorded against the run.What happens on replay
Take a passing Playwright spec, then the next day the team ships two changes: the welcome banner copy changes fromWelcome, Ada to Hi Ada, welcome back,
and the submit button’s data-testid is renamed from submit to submit-btn.
Playwright replay:
page.getByTestId("submit").click()auto-waits for actionability, then times out because the test id no longer exists. The action throws.expect(page.getByText("Welcome, Ada")).toBeVisible()auto-retries until the timeout, then fails. The copy no longer matches.- The CI job fails. A maintainer edits the locator and the assertion, opens a PR, gets it reviewed, and re-runs CI.
clicksteps hit the cache. On the renamed button the cached locator misses, so the locator agent re-resolves the original descriptionSign inagainst the live page, binds, and updates the entry in place. A heal event is recorded.assert: The dashboard chart is visible and not cut offis evaluated by the assertion agent against the current page state. The agent reasons over the intent of the assertion, not a literal string match, so the reworded banner doesn’t trip it.- The test passes. No code review needed.
Technical details
Technical details
Momentic smart waitingThe default smart wait is 3000ms and configurable per test. The runner waits on
a combination of navigation,
load, screenshots, DOM mutations, and same-origin
requests until the page is quiet or the timeout elapses.Playwright waiting, for contrast- Auto-waiting checks actionability (visible, stable, enabled, receives events) before each action, so timing alone rarely causes flakes.
expectassertions auto-retry until they pass or time out.- There is no built-in network-quiescence wait; the docs discourage
waitForLoadState("networkidle"). HardwaitForTimeoutis discouraged but common in quick or generated code.
Locators and AI primitives
Playwright locator trade-offs
Playwright locator trade-offs
getByRole/getByLabelare stable when ARIA roles and labels exist, but dynamic content often lacks them.getByTestIdrequires developers to add and maintaindata-testidattributes; they get renamed or removed under refactors.- CSS selectors break on restyle or restructure; XPath breaks on any structural change.
- No locator carries semantic intent. A failing locator has no description to recover from.
Recovery, quarantine, and CI
Authoring side-by-side
A more realistic test
The hello-world above doesn’t show the full simplified format surface. A representative checkout regression with module reuse, parameter inputs, typed extraction, and a conditional looks like this:checkout.test.yaml
../modules/sign-in.module.yaml