Auto-Waiting Explained

Every Playwright action waits for the element to be actionable before proceeding — no explicit waits needed for most cases.

Auto-wait in action

typescript
// Playwright waits until button is visible, enabled, and stable before clicking
await page.getByRole('button', { name: 'Submit' }).click();

// Waits until input is editable
await page.getByLabel('Username').fill('alice');

// Assertion auto-retries until timeout
await expect(page.getByText('Success')).toBeVisible();

// Custom timeout for a specific action
await page.getByRole('button').click({ timeout: 30_000 });

waitFor when you need it

typescript
// Wait for a network response
const [response] = await Promise.all([
  page.waitForResponse('**/api/users'),
  page.getByRole('button', { name: 'Load' }).click(),
]);

// Wait for navigation
await Promise.all([
  page.waitForURL('**/dashboard'),
  page.getByRole('button', { name: 'Login' }).click(),
]);

// Wait for element state
await page.getByRole('progressbar').waitFor({ state: 'hidden' });