The problem of hard waits and tools without auto-waiting
Hard waits and timeouts only do one thing: they instruct Playwright to wait for the specified time. This makes them dangerous: they are intuitive enough to be favored by beginners and inflexible enough to create serious issues. Let’s explore some issues in practical terms. Imagine a situation in which your script uses a tool without smart automatic waiting: then you need to wait until an element appears on a page to interact with it. To click a button you must ensure that this button is available in the current browser session. As a quick solution, you might consider adding a hard timeout. This could look something like the following:- You end up waiting a shorter time than the element takes to load!

- The element loads before your hard wait has expired.

Avoiding hard waits by relying on Playwright’s auto-waiting
To avoid these issues, you should forget that hard waits exist and adopt tools like Playwright, which provide auto-waiting mechanisms. Let’s revisit the previous example and use Playwright’s core functionality.wait
statement. Hard waits are unnecessary in Playwright scripts because when you call a Playwright action such as click
, fill
or selectOption
, Playwright automatically waits until a set of actionability checks pass.
Playwright’s actionability steps
To ensure your automation and testing actions behave correctly, Playwright enables you to forget about timings. Your job is to define browser actions and expected UI results; Playwright will figure out the rest. If you want to click an element, Playwright will only interact with it when the element is ready and actionable. The following checks evaluate actionability:- Does your defined locator resolve to exactly one element?
- Is the resulting element visible?
- Is the resulting element stable? (it’s not moving, animating or transitioning)
- Can the resulting element receive events? (it’s not covered or obscured by other elements)
- Is the resulting element enabled? (it doesn’t have a
disabled
attribute)

- Your Playwright scripts will be as quick as possible because Playwright will interact with elements whenever they’re ready.
- You can focus on defining UI actions and the expected results instead of worrying about network calls and timings.
Other waiting mechanisms
Generally, it’s recommended to rely on Playwright’s auto-waiting and built-in web-first assertions, but if you must, here are some other waiting mechanisms.Waiting on navigations and network conditions in Playwright
When you can’t wait for an element to appear on a page and want to explicitly wait for the network use the following. “ waits until the required load state has been reached. It defaults to the pageload
event but can also be configured to wait for domcontentloaded
or networkidle
(discouraged).
load
event but can be configured to wait for commit
, domcontentloaded
or networkidle
(discouraged).
Waiting for an element in Playwright
There are multiple ways to wait for a specific element to appear on the page. To wait for an element to be visible or reach a particular state it’s recommended to use Playwright’s web-first assertions.toBeVisible
, toBeEnabled
, toBeChecked
and many more included assertions are asynchronous and wait for the elements to change, appear or disappear.
@playwright/test
) and you want to wait for an element to be visible, use “.
Waiting for page events
With Playwright, you can also directly wait for `.Waiting for page functions
And for more advanced cases, you can pass a function to be evaluated within the browser context via “.Takeaways
- Never use hard waits or timeouts.
- Use auto-waiting instead.
- Combine auto-waiting actions with web-first assertions to test UI state instead of implementation details.