Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the proper way to capture a HTTP response with Puppeteer?

I am trying to capture the http response status from a user sign-up.

My code looks like this:

  it.only('returns a 400 response if email is taken', async () => {
    await page.goto(`${process.env.DOMAIN}/sign-up`)
    await page.waitFor('input[id="Full Name"]')

    await page.type('input[id="Full Name"]', 'Luke Skywalker')
    await page.type('input[id="Email"]', '[email protected]')
    await page.type('input[id="Password"]', 'LukeSkywalker123', {delay: 100})
    await page.click('input[type="submit"]', {delay: 1000})

    const response = await page.on('response', response => response)

    console.log('request status', response.status)
    // expect(response).toEqual(400)
  })

The docs give an example of intercepting the request and doing things with it:

await page.setRequestInterception(true);
page.on('request', request => {
  request.respond({
    status: 404,
    contentType: 'text/plain',
    body: 'Not Found!'
  });
});

And I have tried a similar pattern to no avail, along with many other patterns. Everything I do returns the page, a huge object with no status on it that I can see. Any help is much appreciated.

WHAT WORKED:

thank you to @tomahaug for steering me in the correct direction. My first problem was placement, the listener needs to go be set up before the request is made, I had it just after the request. Makes sense. My biggest issue was assigning the listener to a variable, so that I could call the expect as my last line. Assigning it to a variable caused the page to be returned. What I needed to do was just run the test inside the listener. While using done() throws and error for me I closed off my test as follows below, the working version of my code:

it.only('returns a 400 response if email is taken', async () => {
    await page.goto(`${process.env.DOMAIN}/sign-up`)
    await page.waitFor('input[id="Full Name"]')

    await page.type('input[id="Full Name"]', 'Luke Skywalker')
    await page.type('input[id="Email"]', '[email protected]')
    await page.type('input[id="Password"]', 'LukeSkywalker123', {delay: 100})

    await page.on('response', response => {
      if (response.request().method === 'POST' && response.url === `${process.env.USERS_API_DOMAIN}/sessions`) {
        expect(response.status).toEqual(400)
      }
    })

    await page.click('input[type="submit"]', {delay: 1000})
  })

  after(async function () {
    await browser.close()
  })

Hope this helps someone else!

like image 975
HolyMoly Avatar asked Nov 01 '17 02:11

HolyMoly


People also ask

What are HTTP response methods?

An HTTP response is made by a server to a client. The aim of the response is to provide the client with the resource it requested, or inform the client that the action it requested has been carried out; or else to inform the client that an error occurred in processing its request.

Which HTTP code used to identify a success response?

HTTP response status codes indicate whether a specific HTTP request has been successfully completed. Responses are grouped in five classes: Informational responses ( 100 – 199 ) Successful responses ( 200 – 299 )

What is situation in puppeteer?

Situation: In Puppeteer, one sometimes needs to wait for a particular HXR request (e.g., a particular URL has been called to happen) after a particular action (e.g., clicking a button), and you need the HTTP response object of that particular request.

How do I use the puppeteer recorder?

Using the Puppeteer recorder is easy and it's a great way to quickly generate Puppeteer scripts, which you can then configure to run automated flows on your own browser or on a cloud based grid such as TestingBot. To find out more about enabling the Puppeteer Recorder, and how to use it, please see our Puppeteer Recorder documentation.

How do I view Har files with puppeteer?

With Puppeteer, this is possible by using the puppeteer-har package. Once you've generated a HAR file, you can easily inspect the details of the HAR file with any of the available HAR viewers that you can find online.

How do I set up codeceptjs with puppeteer?

Setting up CodeceptJS is straightforward, simply follow the QuickStart guide on their website and configure the Puppeteer helper in codecept.conf.js with the correct browserWSEndpoint . Once configured, you can create and run your first basic CodeceptJS test via Puppeteer:


1 Answers

I believe you should do something along those lines. Note the callback function done.

What the code does, is that it attaches a listener for responses, then clicks the submit button. When a response is received it checks the status code, asserts it, and terminates the test by calling done.

You might want to have an if-statement that checks that it is the actual response from your form that you are checking in the callback, as the response handler might emit events for other concurrent requests.

it.only('returns a 400 response if email is taken', () => {
  await page.goto(`${process.env.DOMAIN}/sign-up`)
  await page.waitFor('input[id="Full Name"]')

  await page.type('input[id="Full Name"]', 'Luke Skywalker')
  await page.type('input[id="Email"]', '[email protected]')
  await page.type('input[id="Password"]', 'LukeSkywalker123', {delay: 100})

  page.on('response', (response) => {
    if (
      response.request().method === 'POST' && 
      response.url === `${process.env.USERS_API_DOMAIN}/sessions`) 
    {
      expect(response.status).toEqual(400)
    }
  })

  await page.click('input[type="submit"]', {delay: 1000})
})

I have not tested the code, but it should give you the right idea.

Edit: Adjusted to reflect what worked out in the end.

like image 114
tomahaug Avatar answered Sep 27 '22 17:09

tomahaug