循环调用cy.intercept()拦截自动刷新API时仅执行一次的问题排查
问题原因分析
- Cypress命令队列与原生异步的冲突:你使用
setTimeout触发下一次循环,但setTimeout是浏览器原生异步API,会脱离Cypress的命令队列执行。Cypress的命令(如cy.intercept、cy.wait)是异步且按队列顺序执行的,setTimeout里的checkStatusAndLoop调用不会被Cypress正确纳入命令队列,导致后续的拦截和等待操作无法执行。 should命令的重试特性干扰:should会自动重试回调函数,可能导致计数逻辑混乱,且无法正确触发后续循环。
修复后的代码
export function stubBackendResponse(id: string): void { let iterations = 0; const maxIterations = 10; const intervalMs = 30000; function checkStatusAndLoop(): void { // 每次循环前设置API拦截 cy.intercept({ method: "GET", url: `/api/${id}`, }).as("data"); cy.wait("@data") .its("response.body") .then((data) => { const status = data[0].status; if (status === "completed") { // 状态达标,终止循环 return; } if (iterations >= maxIterations) { throw new Error("Max iterations reached. Status is not 'completed'."); } iterations++; // 用Cypress原生等待命令替代setTimeout,保持在命令队列内执行 cy.wait(intervalMs).then(checkStatusAndLoop); }); } checkStatusAndLoop(); }
关键修复点
- 替换
setTimeout为cy.wait(intervalMs).then(...):cy.wait是Cypress原生命令,会被纳入命令队列,确保后续的循环逻辑在Cypress的控制下执行,保证拦截和等待操作按预期运行。 - 用
then替代should处理业务逻辑:then是一次性执行回调,不会自动重试,避免计数逻辑被重复触发,更适合处理循环终止和迭代计数的场景。 - 优化逻辑判断顺序:先判断状态是否完成,再处理最大迭代次数,逻辑更清晰直观。
内容的提问来源于stack exchange,提问作者deanthe
相关产品推荐
相关产品推荐

