Playwright Auto-Waiting

One of the most powerful features in Playwright is its auto-waiting capability. Playwright provides automatic waiting for most action and assertion methods. This means Playwright automatically waits until an element is visible, actionable, and stable before performing any interaction.

Because of this built-in behavior, we usually do not need to write manual waits before performing every actions such as click, fill, or assertions. Auto-waiting also has a default timeout, which can be configured in the playwright.config.js file. 

Example Scenario

Let's say when we wrote a script to click a button and then the button loads 2 seconds late:

     - Playwright waits for the element to appear
     - Ensures the element is visible
     - Verifies it is stable and clickable
     - Then performs the click

No explicit wait is required.

Importance of Auto-Waiting

Without auto-waiting, automation tests often become flaky because elements may load:

     - Late
     - With animations
     - After an API response
     - After page transitions

Playwright handles all of this automatically, which is one of the main reasons Playwright tests are more stable.

Where Auto-Waiting Applies

Auto-waiting applies to many Playwright methods, especially actions, locators, and assertions.

Commonly Used Auto-Waiting Methods

     - Navigation: page.goto()
     - Click actions: page.click()
     - Filling inputs: page.fill()
     - Locator actions: locator.click(), locator.fill()
     - Assertions: await expect(locator).toBeVisible()

Example Usage

const loginBtn = page.getByRole('button', { name: 'Login' });
await loginBtn.click(); // auto-waiting happens here


For the click() action, Playwright automatically waits for:

     - The element to appear
     - The element to be visible
     - The element to be stable
     - The element to receive pointer events

Page Load Auto-Waiting

Playwright can also wait for different page load states:

'load': Page load event fired
'domcontentloaded': DOM is ready
'networkidle': No ongoing network requests

await page.goto('https://example.com');
await page.waitForLoadState('networkidle');


This is useful when:

     - The page loads additional data via AJAX
     - Dynamic content appears after API calls
     - You want the page to be fully stable before interacting

Custom Wait

While Playwright’s auto-waiting works well in most cases using global timeouts from playwright.config.js, there are scenarios where a specific action needs more time than the default. In such cases, Playwright allows you to override the timeout per action.

This is called a custom wait or action-level timeout.

Using Custom Timeout on Actions

You can pass a timeout option directly to actions like click(), fill(), type(), etc.

Example:

await page.click('#submit', { timeout: 15000 });


In this example:

Playwright will wait up to 15 seconds, even when the config.js file says to wait for 5 seconds. If the conditions are not met within 15 seconds, the action fails

Locator-Level Custom Timeout

Using locators is the recommended Playwright practice:

const submitBtn = page.getByRole('button', { name: 'Submit' });
await submitBtn.click({ timeout: 15000 });


This is useful when:

     - A button appears after a long API response
     - The page has heavy animations
     - The environment is slow (staging / pre-prod)

Custom Timeout for Assertions

You can also apply custom timeouts to assertions:

await expect(page.locator('#successMessage')).toBeVisible({ timeout: 10000 });


This overrides the global expect.timeout only for this assertion.

Adding Manual Waits

Sometimes small pauses are useful for demos or animations: await page.waitForTimeout(2000);

Do not overuse this. Manual waits slow down tests and can introduce flakiness. Use manual waint only when needed,

Configuring Auto-Waiting and Timeouts in playwright.config.js

Playwright’s auto-waiting works automatically, also the timeouts used by auto-waiting can be configured globally in the playwright.config.js file. This allows you to control how long Playwright waits for actions, navigations, and assertions before failing.

Action Auto-Wait Timeout

Controls how long Playwright waits for actions such as click(), fill(), and type() to complete.

use: {
  actionTimeout: 10000 // waits up to 10 seconds for actions
}


Navigation Auto-Wait Timeout

Controls how long Playwright waits for page navigation and load states.

use: {
  navigationTimeout: 30000 // waits up to 30 seconds for page loads
}


Assertion Auto-Wait Timeout

Controls how long Playwright retries assertions before failing.

expect: {
  timeout: 5000 // waits up to 5 seconds for assertions
}


Test Timeout

Defines the maximum time allowed for a single test to complete.

timeout: 60000 // 60 seconds per test


Using playwright.config.js allows you to set default auto-wait behavior once, instead of adding waits in every test. This keeps tests clean, stable, and easier to maintain.

Example auto-waiting configuration in playwright.config.js

import { defineConfig } from '@playwright/test';
export default defineConfig({
  timeout: 60000, // max time per test
  expect: {
    timeout: 5000, // assertion auto-wait timeout
  },
  use: {
    actionTimeout: 10000,     // auto-wait for actions
    navigationTimeout: 30000 // auto-wait for page loads
  },
});

 

Related Tutorials