How do you get a response value of an underlying network request when running a Playwright Test?
Often when I'm interacting with a web application that creates new things, I find myself wanting the id
or unique identifier of something that was just created for an assertion or to use in another action. Typically these are found in the network responses that happen form an action on the UI layer. Today I'll walk you through an example of how to grab the network response and use it in an assertion.
For this test we will use https://automationintesting.online/ a booking site, and the specific value we will grab today is after login, there is a message notification count that is visible after logging in that can change based on what other actions are going on in the system. The steps to see this are visit the above website, find admin login link, and use un: admin / pw: password and click login. You'll see the notification box at the top of the page, and if you are watching the network tab of chrome dev tools you'll also see the network request.
For my Playwright test I plan to intercept traffic by using the page.route method. If the request URL includes **/message/count
then I set the response to response
variable, then get the json from the response
variable and save it as a variable named message.
One thing to note in this example is I am creating the message
variable at the test level, this allows me to have access to the variable within the test scope (not just in the page.route scope). If for some reason you are running into an issue where your variable is undefined, make sure you are creating the variable at the correct level.
Another thing to note is I am using a let
variable for message
. This allows me to assign/re-assign the value as needed.
Below is a working example of where I route the message/count endpoint and set the message value to the json response. I then use that message variable to make an assertion on what should be on the screen. This let's me not have to worry about creating or ensuring the message count number. Whatever value that is returned from the API, is what we will check for in the DOM. This really helps us solve a test data problem without mocking.
import { test, expect } from "@playwright/test";
test.describe("/admin Checks", async () => {
test(`Validate Message Count is correct`, async ({ page }) => {
let message;
await page.route("**/message/count", async (route) => {
const response = await route.fetch();
message = await response.json();
route.continue();
});
await page.goto("https://automationintesting.online/");
await page.getByRole("button", { name: "Let me hack!" }).click();
await page.getByRole("link", { name: "Admin panel" }).click();
await page.locator('[data-testid="username"]').fill("admin");
await page.locator('[data-testid="password"]').fill("password");
await page.locator('[data-testid="submit"]').click();
await expect(page.getByRole("link", { name: "Logout" })).toHaveText(
"Logout"
);
const messageCountSpan = page
.locator('[href*="#/admin/messages"]')
.locator("span");
// Wait for the message count to be updated before making an assertion
await page.waitForResponse("**/message/count")
await expect(messageCountSpan).toHaveText(`${message.count}`);
});
});
The code for this can be found in the Playwright-Demo repository
If you want an example where you do mock the response that can be found here
An amazing writeup by Tim Deschryver with many more examples can be found here
Thanks for reading! If you found this helpful, reach out and let me know on LinkedIn or consider buying me a cup of coffee. If you want more content delivered to you in your inbox subscribe below, and be sure to leave a ❤️ to show some love.