Playwright

Lesson 14 of 17

Lesson ยท 25 min

Wait for requests and call the API

What goes over the network

When you click Add to cart, the page sends a request to the server, and the server answers. Most bugs in a web app are not about what the page shows. They are about what the page sends, or what it receives. A test can look at both.

Wait for a request or a response

page.waitForResponse and page.waitForRequest wait for one message and give it to you. You say which one with a function that returns true for the right message, or with a URL pattern.

const responsePromise = page.waitForResponse(
  (response) => response.url().includes('/api/cart') && response.request().method() === 'POST',
);
await card.getByRole('button', { name: 'Add to cart' }).click();
const response = await responsePromise;

Look at the order. You start the wait first, and you await it after the click. The wait is a promise. If you start it after the click, the response can arrive before you listen, and the test waits for ever.

A response has status(), ok(), json(), and text(). A request has url(), method(), headers(), postData(), and postDataJSON().

Use generic assertions on these values

response.status() and response.json() give plain values, not locators. They do not retry. Use expect(value).toBe(...) for them. It is correct here, because the response does not change after it has arrived.

Call the API without a page

The request fixture sends HTTP requests without a browser. It is fast, and it is the base of API tests, which you will meet in a later course.

test('lists six products', async ({ request }) => {
  const response = await request.get('/api/products');
  expect(response.ok()).toBeTruthy();
  const products = await response.json();
  expect(products).toHaveLength(6);
});

request.post(url, { data }) sends a body as JSON.

Prepare data through the API

Testers use the API to set up a test. To test the cart page, you could open the shop, find the product, and click. It is faster to send one request that puts the product in the cart, and then open the cart page. The page test checks only what it is about, and it does not depend on the steps before.

Your turn

Write four tests. Two of them watch the traffic of the page, and two use the request fixture.

Tasks

4 to do

  1. Task 1, not checked yet. Add a test named sends the product to the cart. Start to wait for the response of the request that adds a product (POST to /api/cart) with page.waitForResponse. Then click Add to cart on Blue Mug. Check that the status of the response is 200, and that the cart in its JSON has 1 item.

  2. Task 2, not checked yet. Add a test named sends the id of the product. Wait for the request with page.waitForRequest. Click Add to cart on Notebook. Check that the data that the page sent is { productId: 2 }. Use request.postDataJSON().

  3. Task 3, not checked yet. Add a test named lists six products. Use the request fixture, the way to send requests without a page. Send a GET request to /api/products with request.get. Check that the answer is ok, and that the JSON is a list of 6 products. Check that the first product is Blue Mug.

  4. Task 4, not checked yet. Add a test named shows a product that was added through the API. Use request.post to send { data: { productId: 4 } } to /api/cart. Then open /cart with page.goto. Check that the page shows Backpack and that the total is $59.00.

Task 1 of 4

Add a test named sends the product to the cart. Start to wait for the response of the request that adds a product (POST to /api/cart) with page.waitForResponse. Then click Add to cart on Blue Mug. Check that the status of the response is 200, and that the cart in its JSON has 1 item.

All tasks

example.spec.js

Ctrl+Enter runs your tests. Ctrl+Shift+Enter checks it. Press Esc, then Tab, to leave the editor.

Practice browser

The sample app is ready

The results of your tests show here. Press Run tests to watch them run in the practice browser.