The Illustrated Guide to Using Promise.all in Playwright Tests

Playwright Communication

Playwright is running in two separate contexts:
- The Nodejs context is running the tests and sending the commands to the browser
- The Browser context is getting the commands, executing them together, and running your application code.

Browser and NodeJS are not synchronized in their actions
Playwright browser and node communication

Waiting for an Activity

Assume you have a button that clicking on it will trigger a server request. You want to catch that request to verify it contains proper information.

Attempt #1

Initially, you may write a fairly straightforward code:

await page.locator('button').click();
await page.waitForRequest('');

Attempt #2

Ok, so let’s send the request to check the network request before hitting the button.

await page.waitForRequest('');
await page.locator('button').click();

Attempt #3

The solution is to send both requests in parallel, using promise.all:

await Promise.all([

Short-Lived Element

The other example we will look into is a short-lived element. Think of a loader that appears on the page after a button is clicked and the requests are sent and disappear when everything is ready. The browser of the timeline looks as follows:

  • Click the button
  • Make sure that the loader appears
  • Make sure that the loader disappears.
await Promise.all([
await page.locator('#loader').waitFor({state: 'detached'};


Pkaywright is working in a really fast pace, and we cannot assume how the NodeJS and the Browser are synchronized. Promise.all( ) is extremely powerful in making your tests robust and reduce the flakiness.



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Tally Barak

Tally Barak


If you can’t explain it simply, you don’t understand it well enough.” — Einstein