Cypress如何检测未完成网络请求 解决随机抛出undefined错误问题
Cypress 未完成网络请求检测与随机报错修复方案
问题根因
after钩子中定义的cy.intercept注册时机晚于/api/gradebook/scores/请求的发起时间,因此cy.wait('@getApi2')无法捕获到测试用例执行过程中已经发起的请求,会直接执行后续logout操作,导致请求被中断返回400错误。
修复方案
方案1:提前拦截指定接口并等待
分数查询接口属于测试用例执行过程中发起的请求,需要提前注册拦截规则,在测试用例结束前显式等待该请求完成:
describe("/gradebook/", () => { // 全局注册拦截,覆盖整个测试生命周期内的分数查询请求 beforeEach(() => { cy.intercept("GET", "/api/gradebook/scores/**").as("getGradebookScores") }) before(() => { cy.login("username", "password"); cy.intercept("GET", "/api/**").as("getApi"); cy.visit("/home/"); cy.wait("@getApi"); cy.log("111"); }); it("Loads Page Title: Gradebook", () => { cy.log("222"); // 用例执行末尾等待分数查询请求完成,可根据实际情况调整超时时间 cy.wait("@getGradebookScores", {timeout: 15000}) }); after(() => { cy.log("333"); cy.logout(); }); });
方案2:通用未完成请求检测方法
如果需要统一检测所有待完成的网络请求,可自定义Cypress全局命令:
- 在
cypress/support/e2e.js中添加请求计数逻辑:
Cypress.on('window:before:load', (win) => { // 统计fetch请求数量 const originalFetch = win.fetch; win._pendingFetch = 0; win.fetch = (...args) => { win._pendingFetch++; return originalFetch(...args) .finally(() => win._pendingFetch--); }; // 统计XHR请求数量 const originalXhrOpen = win.XMLHttpRequest.prototype.open; win._pendingXhr = 0; win.XMLHttpRequest.prototype.open = function(...args) { win._pendingXhr++; this.addEventListener('loadend', () => win._pendingXhr--); originalXhrOpen.apply(this, args); }; });
- 在
cypress/support/commands.js中添加自定义等待命令:
Cypress.Commands.add('waitForAllPendingRequests', (timeout = 30000) => { const startTime = Date.now(); const checkPending = () => { return cy.window().then(win => { const pendingTotal = win._pendingFetch + win._pendingXhr; if (pendingTotal > 0 && Date.now() - startTime < timeout) { return cy.wait(200).then(checkPending); } }) } return checkPending(); }
- 在
logout前调用自定义命令等待所有请求完成:
after(() => { cy.waitForAllPendingRequests(); cy.log("333"); cy.logout(); })
注意事项
- 不要使用通配符
/api/**拦截后仅调用一次cy.wait,如果页面同时发起多个匹配通配符的请求时,cy.wait仅会等待第一个匹配到的请求,剩余未完成的请求仍会导致后续操作报错。 - 可以通过
cy.wait(['@getApi', '@getApi'])的方式显式指定需要等待的请求次数,避免遗漏请求。
内容的提问来源于stack exchange,提问作者Rio Weber
相关产品推荐
相关产品推荐

