Tim Deschryver

The different retry APIs from Playwright

profile
Tim Deschryver
timdeschryver.dev

Wait what? Isn't there a built-in Playwright retry mechanism? Yes, you're totally right, there are a couple retry functions that automatically retry a condition, but there's also an explicit retry API that can be used in special cases. In this post, let's take a look at the different retry APIs that Playwright has to offer.

Retry Test Cases link

The first retry ability that Playwright has is the global retry ability for test cases. This means that when a test fails, Playwright automatically retries the test up to the configured times before failing the test.

To set the global retry ability, we can use the retries option in the Playwright config file.

This can be overridden by setting using the retries flag.

If needed, this can also be configured per test block:

This is great, because sometimes you want to exclude problems with the infrastructure or backend, and this way we can retry the test and hope that the issues are resolved and the test passes.

You can also detect when a test is retried by using the testInfo object that is passed to the test block.

Retry Locators and Matchers link

As already mentioned, Playwright has a built-in auto-waiting and retry-ability mechanism. This is used within locators to find elements (e.g. page.getByRole()), or when matcher are run (e.g. toBeVisible()) to check an expectation. For these cases, Playwright runs that logic over and over again until the condition is met or until the timeout limit is reached.

This is useful because it helps to reduce or remove the flakiness of a condition. For example, you don't need to manually specify a wait time before running some code e.g. wait for a second until you think that a request should have responded.

To know the specific timeout limit, see the Playwright timeout documentation

Wait for Conditions link

But, what if we want to wait until a condition is met that is not related to the UI? For example, we want to verify that an asynchronous process has been completed, or that a value is written to the browser's storage.

This can be solved by using Playwright's Retrying and Polling APIs, where we explicitly specify a condition that is awaited until it is met.

If you're familiar with the Testing Library API, you can compare these Playwright functions to the Testing Library waitFor method.

The Retry API uses a normal expect method and uses the toPass(options) method to retry the assertion within the expect block. If the assertion fails, the expect block is retried until the timeout limit is reached, or until it finally passes. In the example below the test waits until a value is written to local storage.

The Poll API is similar to the Retry API, but instead of using a normal expect block it uses the expect.poll method. expect.poll also returns a result, which is used to invoke the matcher. In the example below the test waits until the process state is completed.

Both APIs can also be configured with a custom timeout and interval durations.

Conclusion link

Playwright has options to make your tests more resilient and less flaky. The built-in retry mechanism for locators and matchers is useful and covers most of your daily cases.

But, sometimes an assertion needs to wait for an external condition. In these cases, you can use the explicit retry and polling APIs to wait until the condition is met.

You can also use the global retry mechanism for test cases, to remove the inconsistencies that are caused by the conditions that you can't control.

Follow me

You can find me on Twitter, LinkedIn, and GitHub.

Support me

I appreciate it if you would support me if have you enjoyed this post and found it useful, thank you in advance.

Buy Me a Coffee at ko-fi.com PayPal logo
Support the blog Share on Twitter Discuss on Twitter Edit on GitHub