Imagine clicking a "Submit" button. Simple, right? But what if the button has not rendered yet? What if it is rendered but disabled? What if there is an overlay blocking it? In Selenium, you handle all of this yourself. In Playwright, every single action auto-waits for the element to be ready.
Element is attached to the DOM
Element is visible (not display:none, not zero-size)
Element is stable (not mid-animation)
Element is enabled (not disabled attribute)
Element is not obscured by another element (no overlay blocking it)
Element receives the click event (scrolls into view if needed)
All six checks happen automatically. Every time. For every action -- click, fill, check, select. No Thread.sleep(). No WebDriverWait. No flaky timing hacks.
// SELENIUM -- you have to wait manually
await driver.wait(
until.elementLocated(By.css('#submit-btn')),
10000
);
await driver.wait(
until.elementIsVisible(driver.findElement(By.css('#submit-btn'))),
10000
);
await driver.wait(
until.elementIsEnabled(driver.findElement(By.css('#submit-btn'))),
10000
);
await driver.findElement(By.css('#submit-btn')).click();
// PLAYWRIGHT -- just click. It handles all the waiting.
await page.getByRole('button', { name: 'Submit' }).click();Auto-wait has a default timeout of 30 seconds. If the element does not become actionable within that time, the test fails with a clear error message telling you exactly which check failed. No more "element not interactable" with zero context.
Key Point: Auto-wait is not a feature you enable. It is how Playwright works. Every action, every time. This alone eliminates 80% of the flaky tests you have seen in Selenium projects.
Key Point: Auto-wait checks 6 conditions before every action. No explicit waits needed. This is the #1 reason Playwright tests are more reliable.