用Puppeteer捕获HTTP响应的正确方法是什么?

Hol*_*oly 10 integration-testing google-chrome puppeteer

我正在尝试从用户注册中捕获http响应状态。

我的代码如下所示:

  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"]', 'LukeSkywalker@voyage.com')
    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)
  })
Run Code Online (Sandbox Code Playgroud)

该文档提供了拦截请求并对其进行处理的示例:

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

而且我尝试了类似的模式,但无济于事,还有许多其他模式。我所做的一切都会返回page,这是一个我看不到状态的巨大物体。任何帮助深表感谢。

工作原理:

感谢@tomahaug指导我正确的方向。我的第一个问题是放置,在提出请求之前就需要设置侦听器,而在请求之后就已经有了它。说得通。我最大的问题是将侦听器分配给变量,以便可以将期望作为最后一行。将其分配给变量会导致page返回。我需要做的就是在监听器中运行测试。在done()为我使用throws and error时,我关闭了我的测试,如下所示,这是我的代码的工作版本:

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"]', 'LukeSkywalker@voyage1.com')
    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()
  })
Run Code Online (Sandbox Code Playgroud)

希望这对别人有帮助!

tom*_*aug 7

我相信您应该按照这些原则做一些事情。注意回调函数done

该代码的作用是,它为侦听器附加了一个侦听器,然后单击“提交”按钮。收到响应后,它将检查状态代码,将其置为有效,然后通过调用终止测试done

您可能需要一个if-statement来检查它是您正在回调中检查的表单的实际响应,因为响应处理程序可能会为其他并发请求发出事件。

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"]', 'LukeSkywalker@voyage.com')
  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})
})
Run Code Online (Sandbox Code Playgroud)

我没有测试代码,但是它应该给您正确的想法。

编辑:调整以反映最终解决的问题。


eri*_*oco 5

如果您需要操作请求/响应,请使用page.setRequestInterception(true)page.on/ page.once如文档所述)。

但是,如果您只需要对响应进行断言,那么最简单和最惯用的方法是使用page.waitForResponse

const updateDashboardResponse = await page.waitForResponse(response =>
  response.url().includes('updateDashboard')
);
expect(updateDashboardResponse.status()).toBe(200);
Run Code Online (Sandbox Code Playgroud)

这允许测试流程保持线性并避免在page.on处理程序接收response事件之前关闭测试的歧义。