【发布时间】:2022-08-23 06:00:12
【问题描述】:
如何在 Cypress 中捕获和记录网络故障? 例如,如果任何网络请求的响应状态码为 500 或 404 或其他,我想记录该请求(有效负载和响应)。我怎样才能做到这一点?
-
当您说“日志”时,您是指终端、浏览器开发控制台还是测试运行程序级别?
-
终端或浏览器控制台,我只想能够看到这些错误
如何在 Cypress 中捕获和记录网络故障? 例如,如果任何网络请求的响应状态码为 500 或 404 或其他,我想记录该请求(有效负载和响应)。我怎样才能做到这一点?
一种方法是进行一般拦截,监听每个呼叫,并记录任何非 200/300 状态。这可以在调用返回后立即完成,也可以在任何测试结束时完成。
cy.intercept("**/**", (req) => { // matcher could be more specific to only your baseUrl
req.continue((res) => {
if (res.statusCode >= 400) {
console.log(res); // Cypress can't cy.log() here
}
});
}).as("myRequest"); // alias only needed if attempting to print failures after test
cy.get("@myRequest.all").then((calls: any) => { // grab all requests by the alias
calls.forEach((call) => {
if (call.response.statusCode >= 400) {
console.log(call.response); // We can console.log() or cy.log() here
cy.log(call.response);
}
});
});
此外,您可以将这些转换为自定义命令以实现可重用性,或者将它们放在支持文件中的 beforeEach() 和 afterEach() 中,以使它们在 before/afterEach 中表现为全局。
注意:将此拦截放在全局 beforeEach() 中很可能会覆盖您尝试在测试中使用的任何其他拦截。
第二个注意事项:cy.request() 无法被cy.intercept() 拦截,因此请记住,通过cy.request() 发出的任何请求都不会被捕获。
【讨论】:
赛普拉斯已经在运行器日志中记录网络故障,但如果您使用 cypress run 或只是想要一个失败请求的文件
const networkFails = []
const saveNetworkFails = () => {
cy.writeFile('cypress/fixtures/networkFails.json', networkFails)
}
it('tests a page with network failures', () => {
cy.intercept('*', (request) => {
request.continue(response => {
if(response.statusMessage !== "OK") {
networkFails.push({request, response})
}
})
})
cy.visit('/');
cy.get('divx') // incorrect select, fails the test
});
after(() => {
saveNetworkFails() // runs after all tests, even when test fails
})
after() 挂钩是收集故障的合适位置,因为您需要等待所有调用完成。
我的印象是,当测试失败时,after() 钩子没有运行。添加了一个故意的测试失败,并且仍然得到输出日志,因此问题似乎得到了解决。
这是日志的示例
[
{
"request": {
"headers": {
"host": "jsonplaceholder.typicode.com",
"connection": "keep-alive",
"sec-ch-ua": "\".Not/A)Brand\";v=\"99\", \"Google Chrome\";v=\"103\", \"Chromium\";v=\"103\"",
"sec-ch-ua-mobile": "?0",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36",
"sec-ch-ua-platform": "\"Windows\"",
"accept": "*/*",
"origin": "http://localhost:49299",
"sec-fetch-site": "cross-site",
"sec-fetch-mode": "cors",
"sec-fetch-dest": "empty",
"referer": "http://localhost:49299/",
"accept-encoding": "gzip, deflate, br",
"accept-language": "en-GB,en-US;q=0.9,en;q=0.8"
},
"url": "https://jsonplaceholder.typicode.com/todosx/200",
"method": "GET",
"httpVersion": "1.1",
"body": "",
"responseTimeout": 30000,
"query": {}
},
"response": {
"headers": {
"date": "Tue, 02 Aug 2022 00:44:04 GMT",
"content-type": "application/json; charset=utf-8",
"content-length": "2",
"connection": "keep-alive",
"x-powered-by": "Express",
"x-ratelimit-limit": "1000",
"x-ratelimit-remaining": "999",
"x-ratelimit-reset": "1659400611",
"access-control-allow-origin": "http://localhost:49299",
"vary": "Origin, Accept-Encoding",
"access-control-allow-credentials": "true",
"cache-control": "max-age=43200",
"pragma": "no-cache",
"expires": "-1",
"x-content-type-options": "nosniff",
"etag": "W/\"2-vyGp6PvFo4RvsFtPoIWeCReyIC8\"",
"via": "1.1 vegur",
"cf-cache-status": "HIT",
"age": "459",
"expect-ct": "max-age=604800, report-uri=\"https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct\"",
"report-to": "{\"endpoints\":[{\"url\":\"https:\\/\\/a.nel.cloudflare.com\\/report\\/v3?s=FXxz%2F6N6WpJOsocFL%2FL34evrZrqa0bnDtWnLpqtCSOFXmdlqeDBdeuKAmxmHrpc7rAGfyvytfm5jbXAcWxXpcwEMA8rt%2FnDJgm6HQzCV%2FXFbtNEXLofmEAk%2FD5xYVsVKc%2Flbb2F%2B0%2Bu0SDTwqovs\"}],\"group\":\"cf-nel\",\"max_age\":604800}",
"nel": "{\"success_fraction\":0,\"report_to\":\"cf-nel\",\"max_age\":604800}",
"server": "cloudflare",
"cf-ray": "7342c871cb55a8bf-SYD",
"alt-svc": "h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400"
},
"url": "https://jsonplaceholder.typicode.com/todosx/200",
"method": null,
"httpVersion": "1.1",
"statusCode": 404,
"statusMessage": "Not Found",
"body": {}
}
}
]
【讨论】: