You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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全局命令:

  1. 在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);
  };
});
  1. 在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();
}
  1. 在logout前调用自定义命令等待所有请求完成:
after(() => {
  cy.waitForAllPendingRequests();
  cy.log("333");
  cy.logout();
})

注意事项

  • 不要使用通配符/api/**拦截后仅调用一次cy.wait,如果页面同时发起多个匹配通配符的请求时,cy.wait仅会等待第一个匹配到的请求,剩余未完成的请求仍会导致后续操作报错。
  • 可以通过cy.wait(['@getApi', '@getApi'])的方式显式指定需要等待的请求次数,避免遗漏请求。

内容的提问来源于stack exchange,提问作者Rio Weber

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 23:54:03