Skip to content
Playwright · error message

Playwright: locator.click: Timeout 30000ms exceeded

RetryableActionability & click timeouts

Last verified

The exact message
TimeoutError: locator.click: Timeout 30000ms exceeded. Call log: - waiting for getByRole('button', { name: 'Submit' })

What it means

Playwright did not give up on the click immediately. It spent the whole timeout retrying and never reached a state where the click was safe to perform. Before every click, Playwright resolves the locator and then waits for the element to be visible, stable (not animating), able to receive events (not covered by another element) and enabled. The TimeoutError means one of those checks was still failing when the clock ran out. The same message shape appears for locator.fill, locator.check, locator.hover and other actions, with that method name in front.

The headline never says which check failed; the call log underneath does. If the last line is waiting for getByRole(...), the locator matched nothing. If you see element is not visible, element is not stable or ... intercepts pointer events followed by retrying click action, the element exists but is hidden, moving or covered.

Raising the 30-second default rarely helps; it usually just makes the failure slower.

What it looks like

// JavaScript (Playwright 1.5x)
const banner = page.getByRole('button', { name: 'Accept all' });
if (await banner.isVisible()) await banner.click();

const submit = page.getByRole('button', { name: 'Submit' });
await expect(submit).toBeEnabled();
await submit.click();

# Python
page.add_locator_handler(
    page.get_by_role("button", name="Accept all"),
    lambda loc: loc.click(),
)
page.get_by_role("button", name="Submit").click()

Why it happens

  • The locator matches nothing: a typo, changed text, a different role, or the element is inside an iframe the locator does not enter (use page.frameLocator()).
  • The element exists but is hidden (display:none, visibility:hidden, zero size, collapsed menu or inactive tab).
  • A cookie banner, modal backdrop, sticky header or loading overlay covers the element so it cannot receive the click.
  • The element stays disabled because a form validation or prerequisite step has not completed.

How to fix it

  1. Read the Call log beneath the error and find the last check that was logged; that is the condition that never passed.
  2. If the log only says waiting for the locator, open the trace or run with headed mode and the Inspector (PWDEBUG=1) and test the locator with the Pick Locator tool.
  3. If an overlay intercepts the click, dismiss it first (accept the cookie banner, close the modal) or register page.addLocatorHandler() for overlays that appear at random.
  4. If the element is disabled, perform the step that enables it, then assert await expect(locator).toBeEnabled() before clicking.

How to stop it recurring

Prefer user-facing locators (getByRole, getByLabel, getByTestId) over long CSS chains that break on markup changes. Handle consent banners and interstitials once, at the start of the flow or with addLocatorHandler. Record traces on retry (trace: 'on-first-retry') so every timeout comes with a DOM snapshot that shows what was really on screen.

Official documentation: playwright.dev/docs/actionability. See all Playwright error messages.

Related errors

Definitions

Quick answers

What does "locator.click: Timeout 30000ms exceeded" mean in Playwright?

Playwright did not give up on the click immediately. It spent the whole timeout retrying and never reached a state where the click was safe to perform. Before every click, Playwright resolves the locator and then waits for the element to be visible, stable (not animating), able to receive events (not covered by another element) and enabled.

How do I fix "locator.click: Timeout 30000ms exceeded"?

1. Read the Call log beneath the error and find the last check that was logged; that is the condition that never passed. 2. If the log only says waiting for the locator, open the trace or run with headed mode and the Inspector (PWDEBUG=1) and test the locator with the Pick Locator tool. 3. If an overlay intercepts the click, dismiss it first (accept the cookie banner, close the modal) or register page.addLocatorHandler() for overlays that appear at random. 4. If the element is disabled, perform the step that enables it, then assert await expect(locator).toBeEnabled() before clicking.

Run browser automation you can watch and take over

Autonoly runs each job in a real cloud Chromium browser driven by Playwright. Timeouts and detached elements still happen; the difference is that you can watch the run live, see the step that failed, and take control of the browser to finish it.

Also see Live browser control.