Playwright JS , how to intercept on HTTP calls on button click

382 Views Asked by At

I am new to Playwright, need some help on intercepting http calls.

I have scenario, on clicking on button , will get 2 requests
request 1 -> baseurl/session/
request 2 -> sessiondata

I need to verify if request1 got 200 response and also from request 2 I need to validate request payload. In cypress I can achieve this by:

cy.intercept(request1).as(req1)
cy.intecpt(requrest2).as (req2)
cy.get(button).click()
cy.get(req1) .its('response.statusCode')
      .should('eq', 200);
cy.get(req2).its("request.body")
        .then((body) => {
console.log(body);
});

I am struggling to achieve the same in Playwright, confused with waitforRequest & waitforResponse,


Thanks for response, but getting I am request body is [obj][obj], request2.header is undefined, what am I missing here?

const requestPromise1 = this.page.waitForResponse((res) => 
  res.url().includes("url1")&& res.status() === 202);
const requestPromise2 = this.page.waitForResponse((res) => 
  res.url().includes("url2")&& res.status() === 204);

await page.locator("<button locator>").click();
                                                                                
const request1 = await requestPromise1;
const request2 = await requestPromise2;

expect(request1.status()).toBe(202);
expect(request2.status()).toBe(204);

console.log("headerheader"+request2.header)
console.log("request2"+await request2.request());                       

Note: Url1 is POST , Url2 is PATCH with 204 response from which I need to get payload

2

There are 2 best solutions below

0
agoff On

Playwright can use waitForResponse. The general workflow is to define the wait as a variable, do the action that triggers the network request, then await the wait.

const responsePromise = page.waitForResponse('/call-1'); // note no 'await' here
await page.getByText('button').click();
const response = await responsePromise;

Then response variable is a Playwright Response type, which means we can check the status from that variable. I think the easiest way would be to just use .ok(), which "Contains a boolean stating whether the response was successful (status in the range 200-299) or not."

expect(response.ok()).toBeTruthy();

If we needed to check a specific status number, we could use .status().

expect(response.status()).toEqual(200);

Additionally, if you need the request associated with the response, that can be found by .request()

const { foo } = response.request().postDataJSON();
expect(foo).toEqual('foo');
1
I.sh. On

Here's a way in Playwright to acomplish exactly what you did while using Cypress.

Here I'm using waitForResponse method to intercept those requests, clicking the btn, checking the status, and finally extracting the request body using res.json().

As mentioned in earlier answer, make sure you do not await the waitForResponse functions:

test("intercept http requests on click", async ({ page }) => {
  // Intercept requests
  const responsePromise1 = page.waitForResponse("/endpoint1"); // no await
  const responsePromise2 = page.waitForResponse("/endpoint2"); // no await

  // Click your button
  await page.locator("<button locator>").click();

  // Await those intercepted requests now
  const response1 = await responsePromise1;
  const response2 = await responsePromise2;

  // Check requests status
  expect(response1.status()).toBe(200);
  expect(response2.status()).toBe(200);

  // Get the request's body and print it
  const data = await response2.json();
  console.log(data);
});