8

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]
hardkoded
  • 18,915
  • 3
  • 52
  • 64
Vladimir Krygin
  • 439
  • 2
  • 6
  • 18

3 Answers3

13

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()));
hardkoded
  • 18,915
  • 3
  • 52
  • 64
  • Quite hard to follow the code here in the comment. What are you trying to accomplish? – hardkoded May 13 '21 at 12:27
  • 1
    nevermind, I fixed the problem by reading your answer to another question https://stackoverflow.com/a/67020417/11540378 Thanks a lot for your help – Vladimir Krygin May 13 '21 at 12:34
1

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

Vladimir Krygin
  • 439
  • 2
  • 6
  • 18
0

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();
Ijaz Ur Rahim
  • 368
  • 4
  • 18
Nir Alfasi
  • 53,191
  • 11
  • 86
  • 129