Introduction: What Does a Playwright Timeout Error Mean?
A Playwright timeout error means Playwright waited for an operation to complete, but the expected condition did not happen within the allowed time.
For example:
TimeoutError: locator.click: Timeout 30000ms exceeded
or:
Error: expect(locator).toBeVisible: Timeout 5000ms exceeded
A timeout is not always caused by a slow application. It can also indicate:
- An incorrect locator
- An element that never appears
- A hidden element
- A wrong URL
- Slow navigation
- Authentication failure
- An API request that never completes
- CI/CD resource limitations
- Shared-state problems during parallel execution
This playwright test timeout error fix guide explains how to identify the actual root cause instead of simply increasing the timeout.
Common Playwright Timeout Error Messages
You may encounter errors such as:
Timeout 30000ms exceeded.
locator.click: Timeout 30000ms exceeded
locator.waitFor: Timeout 30000ms exceeded
expect(locator).toBeVisible: Timeout 5000ms exceeded
page.goto: Timeout exceeded
The wording tells you which category of timeout you should investigate.
| Timeout | Typical meaning |
| Test timeout | Entire test exceeded its limit |
| Locator/action timeout | Element wasn’t ready for an action |
| Assertion timeout | Expected condition didn’t become true |
| Navigation timeout | Navigation didn’t finish |
| waitFor timeout | Requested state/event wasn’t reached |
Main Causes of Playwright Test Timeouts
Before increasing a timeout, ask:
1. Is the locator correct?
await page.getByRole(‘button’, {
name: ‘Submit’
}).click();
If the actual button says Save, the locator can wait until it times out.
2. Is the element actually rendered?
A locator may exist in the application code but not yet be visible.
3. Is another element blocking it?
Playwright’s actionability checks include visibility, stability, receiving events, and enabled state. If those conditions aren’t satisfied, Playwright waits and eventually fails.
4. Is the page still loading?
A slow backend, API, image, authentication request, or third-party service can delay the UI.
5. Does the test depend on another test?
Parallel tests that share accounts, files, carts, or database records can create unpredictable delays.
Playwright Default Timeout Explained
This is one of the most important parts of a playwright test timeout error fix.
Playwright has several different timeout categories.
| Timeout | Current default |
| Test timeout | 30 seconds |
| Assertion timeout | 5 seconds |
| Action timeout | 0 / no separate limit |
| Navigation timeout | 0 / no separate limit |
| Global timeout | None |
The test timeout covers the test function and related setup such as beforeEach; Playwright documents a default of 30 seconds. Assertions have their own default of 5 seconds.
This distinction matters.
A test can have a 30-second test timeout while an individual expect() has a 5-second assertion timeout.
How to Increase the Playwright Test Timeout
If the operation is legitimately slow, configure a larger test timeout.
Configuration-level timeout
import { defineConfig } from ‘@playwright/test’;
export default defineConfig({
timeout: 60_000
});
Now each test can run for up to 60 seconds.
Single-test timeout
import { test, expect } from ‘@playwright/test’;
test(‘slow checkout test’, async ({ page }) => {
test.setTimeout(60_000);
await page.goto(‘/checkout’);
await expect(
page.getByRole(‘heading’, {
name: ‘Checkout’
})
).toBeVisible();
});
Playwright also provides test.slow() when a test is expected to take substantially longer than normal.
Important
Don’t make every test:
test.setTimeout(300000);
A large timeout can hide genuine defects and make failures take much longer to diagnose.
Configure Action and Navigation Timeouts
You can configure action and navigation timeouts independently.
import { defineConfig } from ‘@playwright/test’;
export default defineConfig({
use: {
actionTimeout: 10_000,
navigationTimeout: 30_000
}
});
Playwright currently documents actionTimeout as having a default of 0, meaning no separate action limit, while navigationTimeout can be configured independently.
For one action:
await page.getByRole(‘button’, {
name: ‘Submit’
}).click({
timeout: 10_000
});
For navigation:
await page.goto(‘/dashboard’, {
timeout: 30_000
});
Playwright Locator Timeout Fix
Incorrect locators are among the most common causes of timeout errors.
Suppose this fails:
await page.locator(‘#submit-button’).click();
Instead of immediately increasing the timeout, inspect the application.
A better locator might be:
await page.getByRole(‘button’, {
name: ‘Submit’
}).click();
Or:
await page.getByTestId(‘submit-button’).click();
Debug the locator
Check whether it exists:
const button = page.getByRole(‘button’, {
name: ‘Submit’
});
console.log(await button.count());
If the result is:
0
the problem isn’t that Playwright is too fast. The locator doesn’t currently match anything.
Recommended approach
Timeout
↓
Check locator
↓
Check page URL
↓
Check element state
↓
Check application/API
↓
Only then adjust timeout
Fixing Element Not Visible Errors
Consider:
await page.getByRole(‘button’, {
name: ‘Checkout’
}).click();
The button may exist but be hidden behind a modal.
Instead:
await page.getByRole(‘button’, {
name: ‘Close’
}).click();
await page.getByRole(‘button’, {
name: ‘Checkout’
}).click();
Or wait for the meaningful state:
const checkout = page.getByRole(‘button’, {
name: ‘Checkout’
});
await expect(checkout).toBeVisible();
await checkout.click();
Playwright automatically waits for the conditions required for actions, so explicit waits are often unnecessary.
Playwright Assertion Timeout Fix
Assertions have their own timeout.
Example:
await expect(
page.getByText(‘Order confirmed’)
).toBeVisible();
By default, async assertions wait up to 5 seconds.
If the application legitimately takes longer:
await expect(
page.getByText(‘Order confirmed’)
).toBeVisible({
timeout: 15_000
});
Or configure globally:
export default defineConfig({
expect: {
timeout: 10_000
}
});
Don’t do this blindly
If the text never appears because checkout failed, changing:
5000 ms → 30000 ms
doesn’t fix the application or test.
It only delays the failure.
Fixing waitFor and Navigation Timeout Errors
A common anti-pattern is:
await page.waitForTimeout(5000);
Playwright explicitly discourages fixed timeout waits in production tests because they are inherently flaky.
Instead of:
await page.click(‘#login’);
await page.waitForTimeout(5000);
use:
await page.getByRole(‘button’, {
name: ‘Login’
}).click();
await expect(page).toHaveURL(/dashboard/);
For a specific URL:
await page.waitForURL(‘**/dashboard’);
Playwright recommends page.waitForURL() instead of the deprecated, inherently racy page.waitForNavigation().
Slow navigation
If navigation is genuinely slow:
await page.goto(‘/reports’, {
timeout: 60_000
});
You can also configure:
use: {
navigationTimeout: 60_000
}
Auto-Waiting vs Explicit Waits
This is a common Playwright interview question.
Bad approach
await page.waitForTimeout(3000);
await page.getByRole(‘button’, {
name: ‘Submit’
}).click();
Better approach
const submit = page.getByRole(‘button’, {
name: ‘Submit’
});
await expect(submit).toBeVisible();
await submit.click();
Playwright automatically waits for locator actions to become actionable. For click(), that includes checks such as uniqueness, visibility, stability, receiving events, and enabled state.
Rule of thumb
Wait for application state, not arbitrary time.
Good:
await expect(page.getByText(‘Loaded’)).toBeVisible();
Less desirable:
await page.waitForTimeout(5000);
Debugging Timeout Errors with Inspector
When troubleshooting a Playwright timeout error, use Playwright’s debugging tools.
Run:
npx playwright test –debug
You can also temporarily pause execution:
await page.pause();
Example:
test(‘debug login’, async ({ page }) => {
await page.goto(‘/login’);
await page.pause();
await page.getByRole(‘button’, {
name: ‘Login’
}).click();
});
This lets you inspect the page and understand what Playwright actually sees.
Debugging with Screenshots and Trace Viewer
Configure:
import { defineConfig } from ‘@playwright/test’;
export default defineConfig({
use: {
screenshot: ‘only-on-failure’,
trace: ‘retain-on-failure’
}
});
After failure:
npx playwright show-report
The trace can help answer:
- What was the last successful action?
- What URL was open?
- Was the locator found?
- Was the element visible?
- Was another element covering it?
- Did navigation happen?
- Did the application return an error?
For timeout troubleshooting, a trace is often more useful than simply increasing the timeout.
Real-World Playwright Timeout Troubleshooting Examples
Scenario 1: Element is not visible
Symptom:
Timeout waiting for locator
Root cause: Modal or overlay is blocking the button.
Solution:
await page.getByRole(‘button’, {
name: ‘Close’
}).click();
await page.getByRole(‘button’, {
name: ‘Submit’
}).click();
Practice: Investigate page state before increasing timeouts.
Scenario 2: Incorrect locator
Symptom:
locator.click: Timeout
Root cause: Locator matches zero elements.
Solution:
await page.getByRole(‘button’, {
name: ‘Save’
}).click();
Use count(), Playwright Inspector, or locator debugging to verify the selector.
Scenario 3: Slow API response
Symptom: UI element appears after 10 seconds.
Root cause: Backend response is slow.
Solution:
await expect(
page.getByText(‘Report generated’)
).toBeVisible({
timeout: 20_000
});
But also investigate the API performance.
Practice: A timeout should accommodate a known legitimate condition, not conceal a broken backend.
Scenario 4: Authentication/session problem
Symptom:
Expected dashboard
Received login page
Root cause: Session expired or authentication state wasn’t loaded.
Solution: Verify login and storage state before debugging the dashboard locator.
For authenticated projects, inspect cookies/storage state and confirm that the test account is valid.
Scenario 5: Test passes locally but fails in CI/CD
Symptom:
Local: PASS
CI: Timeout
Common causes include:
- Slower CPU
- Network latency
- Missing environment variables
- Different browser version
- Resource contention
- Missing dependencies
- Parallel workers
Fix
Collect traces and screenshots in CI:
use: {
trace: ‘retain-on-failure’,
screenshot: ‘only-on-failure’
}
Then inspect the exact failing step.
Don’t immediately increase every CI timeout.
Scenario 6: Parallel execution causes timeouts
Symptom: Tests become flaky when workers increase.
Root cause: Tests share:
- Accounts
- Files
- Database records
- Shopping carts
- Ports
- Test data
Solution: Isolate test data.
For example:
Worker 1 → user001
Worker 2 → user002
Worker 3 → user003
Then rerun the suite.
Common Mistakes and Solutions
| Mistake | Better approach |
| waitForTimeout() everywhere | Use web assertions |
| Huge global timeout | Increase only legitimate slow operations |
| Weak CSS selectors | Prefer user-facing locators |
| Ignore CI differences | Collect traces and artifacts |
| Shared test accounts | Isolate test data |
| force: true as a fix | Investigate why element isn’t actionable |
| timeout: 0 everywhere | Keep meaningful limits |
| Repeated login | Reuse authentication state where appropriate |
| Ignore API delays | Investigate backend/network behavior |
| Retry everything | Fix the underlying flaky condition |
Playwright Timeout Best Practices
Use this checklist for a reliable playwright test timeout error fix.
Locator checklist
- Is the locator correct?
- Does it match exactly one intended element?
- Is the element visible?
- Is it enabled?
- Is another element covering it?
Application checklist
- Did navigation complete?
- Did authentication succeed?
- Did the API return successfully?
- Is dynamic content loaded?
- Is the backend unusually slow?
Framework checklist
- Are tests isolated?
- Is parallel execution safe?
- Are CI resources sufficient?
- Are browser versions consistent?
Timeout checklist
- Is this a test timeout?
- Action timeout?
- Assertion timeout?
- Navigation timeout?
- Fixture timeout?
The timeout category determines the appropriate fix. Playwright documents these timeout types separately.
Playwright Timeout Interview Questions
1. What is the default Playwright test timeout?
The default test timeout is 30 seconds.
2. What is the default assertion timeout?
The default timeout for retrying expect assertions is 5 seconds.
3. How do you increase the timeout for one test?
test.setTimeout(60_000);
4. How do you configure assertion timeout?
expect: {
timeout: 10_000
}
5. What causes a locator timeout?
Usually an incorrect locator, missing element, hidden element, blocked element, unstable page state, or application issue.
6. Should you use waitForTimeout() to fix flaky tests?
No. Fixed waits are discouraged for production tests because they can make tests flaky and unnecessarily slow.
7. How do you debug a timeout?
Use:
–debug
page.pause()
Screenshots
8. Why does a test pass locally but timeout in CI?
CI may have different performance, network conditions, environment variables, browser dependencies, or resource contention.
FAQs: Playwright Test Timeout Error Fix
What is a Playwright test timeout error?
It means a Playwright operation or test did not complete within its configured timeout.
Why does Playwright test timeout?
Common reasons include incorrect locators, slow application responses, navigation problems, authentication failures, dynamic elements, and CI resource constraints.
How do I fix a Playwright timeout error?
First identify the timeout type and root cause. Verify the locator, page state, network/API response, authentication, and CI environment. Increase the timeout only when the operation is legitimately slow.
How do I fix a Playwright locator timeout?
Check that the locator matches the intended element and that the element is visible, stable, enabled, and able to receive events.
How do I fix a Playwright waitFor timeout?
Prefer waiting for a meaningful application condition using locator assertions or waitForURL() rather than arbitrary delays.
How do I fix Playwright timeout in CI/CD?
Capture screenshots and traces, compare CI and local environments, verify environment variables and browser dependencies, and check parallel-test resource contention.
Is increasing the Playwright timeout a good fix?
Only when the operation is legitimately slow. Increasing timeouts without investigating the root cause can hide real defects and make failures slower.
