What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

In Playwright, await the action that starts navigation, then wait for the destination or visible UI state your test actually needs. Add page.waitForLoadState('domcontentloaded') or page.waitForLoadState('load') only when that browser event is itself a required checkpoint. For most tests, a locator assertion is more reliable than a fixed delay or waiting for every network request to stop.

Wait for the condition that proves the page is ready

Playwright automatically waits for navigation when an action such as clicking a link initiates it. It also auto-waits before actions and retries web-first assertions. That means you usually do not need to add a separate load-state wait after every click. Instead, assert the destination and the page state that matters to the test:

import { test, expect } from '@playwright/test';

test('opens Reports', async ({ page }) => {
  await page.goto('https://example.com');

  await page.getByRole('link', { name: 'Reports' }).click();
  await expect(page).toHaveURL(/reports/);
  await expect(page.getByRole('heading', { name: 'Reports' })).toBeVisible();
});

The click is awaited, and the assertions describe what “ready” means to this test. If the heading is the important outcome, waiting for an unrelated image or background request adds delay without making the test more meaningful. If the URL or heading assertion times out, its message also points to the condition that failed.

When to add an explicit load-state wait

Use page.waitForLoadState() when your test specifically depends on a document lifecycle milestone—for example, when testing that an event fired or when a resource-dependent check must not begin until the load event. Most of the time, the method is unnecessary because Playwright auto-waits before actions.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
await page.goto('https://example.com', { waitUntil: 'domcontentloaded' });
await page.waitForLoadState('load');
await expect(page.getByRole('main')).toBeVisible();

This example first waits for the DOM to be parsed, then explicitly waits for the load event before checking the main content. Keep only the checkpoint the test needs: if parsed HTML is enough, waiting for load as well can make the test slower without improving its assertion.

Do not replace a condition with a sleep

A fixed delay such as waitForTimeout(3000) guesses how long the application will take. It can be unnecessarily slow on a fast run and still too short on a slow one. Prefer a locator assertion that retries until its condition is true:

await expect(page.getByTestId('results')).toBeVisible({ timeout: 10_000 });
await expect(page.getByRole('status')).toHaveText('Ready', { timeout: 10_000 });

Likewise, use locator-based assertions instead of page.waitForSelector() for ordinary UI readiness. The assertion states the expected result and provides a useful failure if the result never appears.

What the Playwright load states mean

The waitUntil navigation options mark different points in a document’s lifecycle. They are not interchangeable definitions of “the page is ready.” Choose according to what the test needs to observe.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
State What it waits for Good fit Limitation
commit The response is received and the document has started loading. A test that needs to know navigation has begun or a response has arrived. It does not mean the DOM is parsed or visible content is ready.
domcontentloaded The document’s DOM has been parsed. Tests that can proceed with parsed HTML and do not need all resources to finish. Images, stylesheets, and other resources may still be loading.
load The document’s load event has fired. Tests that require resources tied to that event to have finished loading. It still does not prove that an application-specific action or asynchronous data load is complete.
networkidle There have been no network connections for at least 500 ms. Rare cases where network quiescence is itself the condition under test. Playwright discourages it for testing; background requests can keep a page from reaching it, and the state does not prove the needed UI is ready.

For routine navigation and readiness, prefer a web assertion over networkidle. Pages that poll, stream updates, or make other continuing requests may never become idle even when the interface is usable. Conversely, a quiet network does not prove that the right heading, result, or status is visible.

Wait for a popup or a new page

When a click opens a popup, begin waiting for the popup event before clicking so the event is not missed. Once the new page exists, wait for the milestone the test needs and assert its content:

const popupPromise = page.waitForEvent('popup');
await page.getByRole('button', { name: 'Open report' }).click();
const popup = await popupPromise;
await popup.waitForLoadState('domcontentloaded');
await expect(popup).toHaveTitle(/Report/);

The popup is a separate page, so perform subsequent checks against popup, not the original page. If the title is not the meaningful ready condition, replace or supplement it with an assertion for the popup’s relevant content.

Identify which timeout failed

Playwright has several timeout scopes. Raising one does not automatically raise the others, so first identify the timeout named in the error.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Timeout or error Documented default What to inspect
Playwright Test test timeout 30,000 ms The full test function and its fixture setup or teardown—not only the last line shown in the failure.
Auto-retrying expect assertion timeout 5,000 ms The locator, expected value, and whether the asserted state ever occurs. This is separate from the overall test timeout.
Navigation timeout No universal default is stated in the timeout table. The navigation URL, redirect behavior, response, chosen waitUntil condition, and any navigation-specific timeout setting.

The 30-second test and 5-second assertion defaults are Playwright Test defaults documented by Playwright. A message such as expect(...): Timeout usually directs attention to the assertion condition and its timeout; Timeout of 30000ms exceeded calls for checking the entire test and fixture path. Do not assume that changing the test timeout will make a shorter assertion wait longer.

Fix a navigation or page-load timeout step by step

  1. Reproduce the smallest failure. Reduce the test to the navigation or assertion that fails, then read the call log to see which action or condition was waiting.
  2. Check the URL and redirects. Confirm the page reaches the expected destination. A client-side redirect before load is followed by page.goto(); make sure the destination assertion matches where the page actually ends up.
  3. Replace arbitrary waits. Use a locator assertion, response condition, or other specific UI condition instead of a fixed sleep.
  4. Choose the narrowest meaningful milestone. Use domcontentloaded when parsed HTML suffices and load only when the load event matters. Avoid using networkidle as a general readiness signal.
  5. Adjust only the relevant timeout. Set a longer timeout on the slow operation or assertion only when there is a known reason it needs more time; avoid raising every timeout globally to hide the original problem.
  6. Collect diagnostics if it persists. Capture a trace, screenshot, or response details in the test environment. These are useful troubleshooting steps, not special timeout defaults.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Common timeout symptoms and fixes

  • Navigation timeout while waiting for load: Check whether the server responded, whether the URL redirected, and whether the document’s load event is the right milestone. If the test only needs parsed HTML, use domcontentloaded; if it needs an interface state, assert that state.
  • networkidle never arrives: Look for continuing background requests. Do not wait for network idleness unless it is specifically the behavior under test; assert the relevant visible result instead.
  • expect(...): Timeout: Check that the locator identifies the intended element, that the expected text or state is correct, and that the application reaches it in this scenario. Change the assertion timeout only if the condition is correct but predictably takes longer.
  • Timeout of 30000ms exceeded: Inspect the complete test and fixture setup or teardown. The slow or blocked work may occur before the line where the failure becomes visible.
  • A longer global timeout did not help: Confirm which timeout scope the error names. Test, assertion, action, and navigation waits are distinct; adjust the one governing the failed operation.

Or skip the browser setup

If your goal is to capture a website image or PDF rather than run a Playwright test, ScreenshotNeo provides a screenshot API and MCP server for developers. A single GET request can return a PNG, JPEG, WebP, or PDF. For example, save a screenshot of a target page with cURL:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Replace the example target URL and provide your API key. See the ScreenshotNeo API documentation for request options. ScreenshotNeo accepts cookie or consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and responses identify the page verdict and billing status in X-Page-Verdict and X-Billed headers. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots. Sign up free for 1,000 screenshots a month, with no card required.

Keep tests fast, diagnosable, and stable

  • Wait for a UI condition that corresponds to the user’s outcome, not every resource the page might request.
  • Use an explicit document milestone only when it is a real prerequisite for the test.
  • Keep timeout changes local where possible so one slow operation does not make every failure slower to report.
  • When a timeout recurs, inspect its scope and call log before increasing a limit. A timeout can be evidence that the page never reached the expected state, not merely that the test needs more time.

Frequently Asked Questions

Will page.goto() follow a client-side redirect before the load event?

Yes. Playwright’s navigation guidance says page.goto() follows a client-side redirect before load; assert the destination the test is meant to reach.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.