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 actions and web-first assertions
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
disabledattribute)

- 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.
Playwright’s web-first assertions
Auto-waiting Playwright actions help to avoid using hard waits when interacting with elements. But what if you want to wait for an element to appear on the page or reach a specific state before proceeding with your script? Playwright’s web-first assertions (toBe*) also provide auto-waiting capabilities. For example, to wait for an element to become visible, it’s recommended to use Playwright’s toBeVisible assertions. toBeVisible, toBeEnabled, toBeChecked and many more included assertions are asynchronous and wait for the elements to reach a certain state.
@playwright/test) and you want to wait for an element to be visible, use waitFor.
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, one of the otherwaitFor methods.
page.waitForLoadState
waitForLoadState waits until the required load state has been reached. It defaults to the page load event but can also be configured to wait for domcontentloaded or networkidle (discouraged).
page.waitForURL
waitForURL waits until a navigation to the target URL. It also defaults to the page load event but can be configured to wait for commit, domcontentloaded or networkidle (discouraged).
page.waitForRequest / page.waitForResponse
You can also wait until a request is sent or a response is received with waitForRequest and waitForResponse. These two methods are key for implementing request and response interception.
Waiting for page events
With Playwright, you can also directly wait forwaitForEvent.
Waiting for page functions
And for more advanced cases, you can pass a function to be evaluated within the browser context viawaitForFunction.
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.
Bugs don’t stop at CI/CD. Why would Playwright? 
Sign up and start using Playwright for end-to-end monitoring with Checkly.