Playwright automatically waits for elements to be ready before actions and retries assertions until they pass. Understanding this mechanism is key to stable tests.
What Gets Auto-Waited
Before click(), Playwright checks element is attached, visible, stable (not animating), enabled, and receives pointer events. Before fill(), editable state is verified.
Assertions poll the same conditions — a test rarely needs waitForTimeout if locators and expectations are well chosen.
// No sleep needed — click waits for button to be actionable
await page.getByRole('button', { name: 'Load data' }).click();
await expect(page.getByRole('row')).toHaveCount(10);
The row count assertion retries until 10 rows appear or timeout.
'networkidle' is discouraged for SPAs with websockets — assert UI instead.
Actionability Checks Before Clicks
Playwright verifies elements are attached, visible, stable (not animating), enabled, and not obscured before clicking — all part of auto-waiting without extra code.
Common Mistakes
Adding waitForTimeout everywhere 'just in case'.
Assuming auto-wait applies to custom JS variables.
Using networkidle on apps with persistent connections.
Force-clicking instead of waiting for overlay to close.
Key Takeaways
Actions wait for actionability; assertions retry until pass.
Manual sleeps are a last resort in Playwright.
Assert on user-visible outcomes, not arbitrary timing.
Understand load states but prefer DOM assertions.
Pro Tip
If a test needs waitForTimeout, treat it as a smell — record a trace and find what condition is missing.
Continue with waitFor to build on what you learned here.