Skip to main content

Why Playwright Scripts Break When the Site Changes

By Steven Van ·

A guide from Browser Use covers locator fixes for common Playwright failures and four ways to repair scripts on sites you don't control.

Playwright scripts that fail after a site redesign usually do so because they find elements by how the page is built: CSS classes, DOM position, XPath or generated IDs. A new guide from the makers of Browser Use lists the common causes, the fixes, and what to do on sites you don't control. Its advice is to find elements by what a user sees (role, label, text, or a test ID you own) and let Playwright wait for them.

Causes and fixes

  • Brittle selectors: Playwright does not recommend CSS or XPath. Use getByRole, getByLabel and getByText. Codegen picks role, text and test ID locators automatically.
  • Generated class names and dynamic IDs: never select on values such as .css-1x2y3z or #input-4821. In your own app, add a test ID and use getByTestId, which Playwright calls the most resilient option.
  • Timing and races: actions on locators wait until the element is visible, stable, receives events and is enabled. Replace waitForTimeout with web-first assertions such as toBeVisible().
  • Multiple matches: locators are strict, so an action throws if a new element also matches. Narrow with filter() or chaining, and avoid first() and nth(), which may click an unintended element after the page changes.
  • Copy changes: in your own app, a test ID survives text and role changes. On someone else's site, match the stable part of the name with a regex.
  • A/B tests and layout variants: locate by a role and name present in every variant, or force one variant in test setup on your own app.
  • iframes and shadow DOM: use frameLocator() for iframes. Locators pierce open shadow roots, except with XPath. Closed roots are not supported.
  • Expired sessions: check the URL after goto and fail loudly. Playwright's auth guidance is to delete the stored state when it expires.
  • Cookie banners and popups: for overlays that appear unpredictably, page.addLocatorHandler() (since v1.42) runs a handler before an action when the overlay is visible. Predictable ones can be dismissed in the normal flow.

When selectors drift anyway

On sites you don't control you can't add test IDs, so the guide says to expect drift: detect it, alert, repair. It lists four options, from manual to self-healing:

  • Fix by hand: open the trace and pick a new locator with codegen. The catch is developer time on every break.
  • Playwright healer agent: replays the failing steps, inspects the current UI, suggests a patch such as a locator update, and reruns until it passes or its guardrails stop it. It is built for Playwright Test suites and run from an AI coding tool, and its patch needs review.
  • Agent fallback you write (Browser Use): keep your Playwright steps, and when one fails, an agent in the same Chrome re-finds the element from the task. Both share one browser over CDP. The catch is model tokens on each fallback, and the agent's actions should be checked.
  • Rerunnable script (Browser Use Cloud): an agent saves a working script. Later runs reuse it and, when the task asks, repair it if the site changed. Every run still starts a model and uses tokens.

The fallback example

The guide includes a Python example. It tries a role-based click on an "Export CSV" button with a 10-second timeout. On a Playwright timeout it prints a message and hands the task to a Browser Use Agent running on the same Chrome. Chrome starts with --remote-debugging-port=9222 --user-data-dir=/tmp/pw-profile, because since Chrome 136 the port is ignored on the default profile. Browser(cdp_url=...) attaches to that Chrome, and ChatBrowserUse reads BROWSER_USE_API_KEY.

Browser Use
Browser Use
Open-source browser automation platform for AI agents — let LLMs drive a real browser to research, fill forms, scrape, and complete multi-step tasks.
View Browser Use →
Sources

Original source

Read Why Playwright Scripts Break When the Site Changes on Creators Toolbox