Vladimir Krygin
Vladimir Krygin

Reputation: 635

How to save requests' response body using Playwright?

I need to intercept network request and save it's response body to variable, so I can perform assertions with values, that are displayed on UI, but when I try to access variable which is supposed to contain saved response body I receive [object Object] instead of a valid body.

JSON.stringify also doesn't fix the problem, as my variable becomes {"_type":"Page","_guid":"page@"} instead of an actual response.

Here's the code:

const resp = await page.on('response', async response => {
  if (response.url().includes('/some_url/') && response.status() === 200) {
    console.log('BODY() ' + (await response.body())); //logs valid JSON response body
    return await response.body();
  }
})
console.log('RESPONSE' + resp); //logs RESPONSE[object Object]

Upvotes: 11

Views: 35108

Answers (3)

Nir Alfasi
Nir Alfasi

Reputation: 53525

page.on sets an event of type 'response' to be handled by the arrow function that is set starting on the first line : async response => {....

When we set an event such as this one, we get output but the output is not the response itself. If you want to print the entire response you should do it inside the arrow function just before you return:

    ...
    console.log(JSON.stringify(response);
    return await response.body();

Nit: there's no need to await on a return, the last line can be rewritten to:

    return response.body();

Upvotes: 0

Vladimir Krygin
Vladimir Krygin

Reputation: 635

It's been nearly a year since I asked this question. There's also another way to save responses using async predicate functions (especially useful with graphql, where there's only one endpoint)

    const [response] = await Promise.all([
        page.waitForResponse(async response => {
            const text = await response.text();
            return text.includes(`some response text, that we need to intercept`);
        })
    ]);
    return response.json();

https://github.com/microsoft/playwright/issues/4535

Upvotes: 2

hardkoded
hardkoded

Reputation: 21617

I would use waitForResponse that will return the response matching the predicate. The predicate should return true or false. Once the and then you evaluate the response:

const response = await page.waitForResponse(response => response.url().includes('/some_url/') && response.status() === 200);
console.log('RESPONSE ' + (await response.body()));

Upvotes: 16

Related Questions