CoursePart 1 — JavaScript for PlaywrightLesson 1.14
Lesson 1.14Part 1 — JavaScript for Playwright

Promises

The ticket system JavaScript uses to handle 'I'll have that ready soon.'

Lesson 1.14of 24
Next

Step 1

The idea

01

In Lesson 1.13 we learned that the web is asynchronous — things take time. But how does JavaScript actually handle that?

The answer is a Promise: an object that represents a task that hasn't finished yet.

Think of ordering food at a restaurant. When you order, the waiter doesn't bring you the food instantly. They give you a ticket — a promise that the food is coming. That ticket is in one of three states:

  • pending— kitchen is working on it, not done yet
  • fulfilled— food arrived successfully
  • rejected— something went wrong (they're out of that dish)

A JavaScript Promise works exactly the same way.

Step 2

See it run

02
Output
Ordering food...
[2 seconds pass]
Food arrived: Pizza Margherita
Payment processed: 12.50
promises.js
// A function that returns a Promise
function orderFood(item) {
  return new Promise((resolve, reject) => {
    console.log(`Ordering ${item}...`);

    // Simulate a 2-second wait (like a network request)
    setTimeout(() => {
      if (item !== "poison") {
        resolve(`Food arrived: ${item}`);   // success
      } else {
        reject("Kitchen refused to make that");  // failure
      }
    }, 2000);
  });
}

// Handle the promise with .then() and .catch()
orderFood("Pizza Margherita")
  .then(result => console.log(result))
  .catch(error => console.log("Error:", error));

// You can chain promises
orderFood("Pizza Margherita")
  .then(result => {
    console.log(result);
    return processPayment(12.50);    // another async step
  })
  .then(payment => console.log(payment))
  .catch(error => console.log("Error:", error));

function processPayment(amount) {
  return Promise.resolve(`Payment processed: ${amount}`);
}
Terminal
$ node promises.js
ℹ️Note
Don't worry about memorising new Promise() syntax — you'll rarely write it from scratch. What matters is being able to read a Promise and understand what it's doing.

Step 3

Now you try

03

Run the file above. Then change "Pizza Margherita" to "poison". The .catch() block should trigger and print the error message.

This demonstrates the rejected state. In Playwright, the "rejection" happens when an element isn't found, a timeout expires, or an assertion fails.

Step 4

Why a tester cares

04

Promises are the standard way to handle anything that takes time in JavaScript — file reads, network requests, timers. Here's a real pattern: loading user data, then using it:

load-user.js
// Simulating a database lookup that takes some time
function fetchUser(id) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (id > 0) {
        resolve({ id, name: "Priya", email: "priya@example.com" });
      } else {
        reject(new Error("User ID must be positive"));
      }
    }, 500);
  });
}

// Use .then() to work with the result when it arrives
fetchUser(42)
  .then(user => console.log(`Loaded: ${user.name} (${user.email})`))
  .catch(err  => console.log(`Error: ${err.message}`));

fetchUser(-1)
  .then(user => console.log(`Loaded: ${user.name}`))
  .catch(err  => console.log(`Error: ${err.message}`));
Terminal
$ node load-user.js
Output
Loaded: Priya (priya@example.com)
Error: User ID must be positive

This pattern — "try to get data, handle success with .then(), handle failure with .catch()" — is what every network call in JavaScript looks like under the hood.

Recap

3 key points
  • 1A Promise is an object representing an async task — pending, fulfilled, or rejected.
  • 2.then() runs when the Promise resolves. .catch() runs when it rejects.
  • 3All Playwright methods return Promises — that's why you always use await with them.