我正在尝试从用户注册中捕获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)
})
这些文档给予了一个拦截请求并对其执行操作的示例:
await page.setRequestInterception(true);
page.on('request', request => {
request.respond({
status: 404,
contentType: 'text/plain',
body: 'Not Found!'
});
});
我已经尝试了一个类似的模式,但没有效果,沿着许多其他模式。我所做的一切都返回page
,一个巨大的对象,上面没有我可以看到的状态。任何帮助都非常感谢。
成功案例:
感谢@tomahaug指引我正确的方向。我的第一个问题是放置,侦听器需要在请求发出之前设置好,我在请求之后就有了它。有道理。我最大的问题是将侦听器分配给一个变量,这样我就可以调用expect作为我的最后一行。将它赋给一个变量会导致返回page
。我需要做的只是在侦听器中运行测试。虽然使用done()
抛出和错误为我关闭了我的测试如下,我的代码的工作版本:
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()
})
希望这对其他人有帮助!
4条答案
按热度按时间1tuwyuhd1#
我相信你应该沿着这些思路做一些事情。注意回调函数
done
。这段代码所做的是附加一个侦听器来接收响应,然后单击提交按钮,当收到响应时,它检查状态代码,Assert它,并通过调用
done
来终止测试。您可能需要一个
if
-语句来检查回调中检查的是来自表单的实际响应,因为响应处理程序可能会为其他并发请求发出事件。我还没有测试代码,但它应该给予你正确的想法。
编辑:调整以反映最终的结果。
bfrts1fy2#
如果需要操作请求/响应,请使用
page.setRequestInterception(true)
和page.on
/page.once
(如文档所述)。但是,如果您所需要的只是Assert关于响应的某些内容,那么最简单、最惯用的方法是使用
page.waitForResponse
:这允许测试流保持线性,并避免在
page.on
处理程序接收到response
事件之前关闭测试的模糊性。xzlaal3s3#
接受的答案(也被编辑到问题中)是不正确的。它引入了争用条件,因为单击调用会增加1秒的延迟。最好的情况下,这会不必要地降低测试套件的速度,最坏的情况下,如果请求需要超过1秒才能解决,则会生成假失败(如果请求被嘲笑,则不太可能,但这不会改变代码不安全的事实)。
每当Jest测试用例中有回调时,确保它已被执行并且所有依赖于它的Assert已被触发而不添加人工延迟的正确方法是从回调中调用
done()
。如果回调中有一个抛出使done
不可达,则在错误处理程序中调用done(error)
以向Jest报告测试用例失败。为此,您需要将
done
作为参数添加到传递给it
、test
或only
函数的回调函数中,以便它在块中可用。这允许Jest的测试运行器将测试视为异步的,并且在调用done
之前不解析它。测试套件忽略回调的Assert。async
/await
没有帮助,因为它是一个与回调不同的异步链。您只需指定
done
作为参数或返回一个promise(async
隐式返回一个承诺),但决不能两者都有。您可能仍然希望使用await
而不是then
来调用Puppeteer库。您可以使用async
IIFE,当所有Assert都被触发时,它最终触发done()
调用,以获得两个方面的最佳效果。例如,
考虑到这一点,this answer展示了一个可能更好的方法,使用
waitForResponse
,它允许您完全跳过回调和done
。对waitForResponse
的回调是一个字符串URL或函数 predicate ,它应该为正在等待的目标响应返回true:我还应该提到,在上面的代码片段中,
waitFor
被弃用,waitForSelector
和.url
是函数。它的存在是为了与原始帖子相关联并显示高级模式。最小示例
一米二十四分一秒
这是我们正在测试的网页。
index.test.js
(async
/await
版本):index.test.js
(then
版本):index.test.js
(done
版本):vaj7vani4#
response.url
是一个函数,你必须调用它:对于
response.request().method
也是如此: