Do you enjoy this platform? ❤️ Buy us a coffee
Playwright Async/Await — Easy Explained
Problem: Asynchronous (No waiting): Things Happen Out of Order 🚗
When writing JavaScript, some actions take time to complete — like loading a file, fetching data, or waiting.
These are asynchronous tasks. If we don’t manage them correctly, steps can happen out of order.
Let’s use a super simple example to understand and fix this.
You want to:
- 🔑 Start a car
- 🚙 Move the car
- 🛑 Stop the car

But starting the car takes 2 seconds. If we write normal code like this:
function startCar() {
setTimeout(() => {
console.log("Car started");
}, 2000);
}
function moveCar() {
console.log("Car is moving");
}
function stopCar() {
console.log("Car stopped");
}
startCar();
moveCar();
stopCar();
Output (WRONG ORDER):
Car is moving
Car stopped
Car started
Everything happens too early! The car moved and stopped before it even started! 😲
Fix 1: Using Callback
function startCar(callback) {
setTimeout(() => {
console.log("Car started");
callback();
}, 2000);
}
function moveCar(callback) {
console.log("Car is moving");
callback();
}
function stopCar() {
console.log("Car stopped");
}
// Run steps in correct order using callbacks
startCar(() => {
moveCar(() => {
stopCar();
});
});
Output:
Car started
Car is moving
Car stopped
Fix 2: Using Promise
function startCar() {
return new Promise((resolve) => {
setTimeout(() => {
console.log("Car started");
resolve();
}, 2000);
});
}
function moveCar() {
return new Promise((resolve) => {
console.log("Car is moving");
resolve();
});
}
function stopCar() {
console.log("Car stopped");
}
startCar()
.then(() => moveCar())
.then(() => stopCar());
Fix 3: Using CalAsync/Await (Cleanest way)
function startCar() {
return new Promise((resolve) => {
setTimeout(() => {
console.log("Car started");
resolve();
}, 2000);
});
}
function moveCar() {
return new Promise((resolve) => {
console.log("Car is moving");
resolve();
});
}
function stopCar() {
console.log("Car stopped");
}
async function driveCar() {
await startCar();
await moveCar();
stopCar();
}
driveCar();
Concepts Refresher
Concept | What It Means |
---|---|
Callback | “When you're done, call this function.” |
Promise | “I promise to tell you when I’m done.” |
Async/Await | “Wait for this step to finish.” |
Playwright Test Example: Async/Await in Action
Here’s a basic Playwright test demonstrating async/await to control browser steps:
import { test, expect } from "@playwright/test";
test.describe("Auth Tests", () => {
test("should be able to login with valid credentials", async ({ page }) => {
// Navigate to login page
await page.goto("https://practice.expandtesting.com/login");
// Fill username and password
await page.locator("#username").fill("practice");
await page.locator("#password").fill("SuperSecretPassword!");
// Click Login button
await page.getByRole("button", { name: "Login" }).click();
// Wait for URL to change after login
await page.waitForURL("https://practice.expandtesting.com/secure");
// Verify success message is visible and contains expected text
await expect(page.locator("div#flash-message")).toHaveText(/You logged into a secure area!/);
});
});