Cypress中如何等待匹配同一intercept规则的多个XHR请求完成
方案1:等待所有匹配的graphql请求完成
方法1:已知请求数量
如果你明确知道登录后会触发N个graphql同步请求,直接给cy.wait传入N个相同别名即可,Cypress会按顺序等待所有请求完成:
describe('Navigation', function () { beforeEach(function () { cy.intercept('POST', '**/graphql').as('dataStore'); cy.loginByCognitoApi(Cypress.env('cognito_username'), Cypress.env('cognito_password')); // 示例为等待5个请求,可根据实际数量调整 cy.wait(['@dataStore', '@dataStore', '@dataStore', '@dataStore', '@dataStore']); }); it('shows logged in', function () { cy.get('[data-test=logo]').should('be.visible'); }); });
方法2:未知请求数量
如果请求数量不固定,可以自定义命令递归等待,直到连续1秒没有新的graphql请求触发,就判定所有同步请求完成:
先在cypress/support/commands.js中添加自定义命令:
Cypress.Commands.add('waitForAllGraphql', () => { let requestCount = 0; // 监听所有graphql请求,触发时计数+1 cy.intercept('POST', '**/graphql', () => { requestCount++; }).as('dynamicGraphql'); // 递归等待空闲状态 const waitForIdle = () => { const prevCount = requestCount; cy.wait('@dynamicGraphql', { timeout: 1000 }) .then(() => { // 仍有新请求触发,继续等待 if (requestCount > prevCount) waitForIdle(); }) .catch(() => { // 1秒内无新请求,结束等待 cy.log('所有graphql同步请求已完成'); }); }; waitForIdle(); });
在测试中直接调用即可:
beforeEach(function () { cy.loginByCognitoApi(Cypress.env('cognito_username'), Cypress.env('cognito_password')); cy.waitForAllGraphql(); });
方案2:等待加载Spinner消失(更推荐)
这种方式更贴合实际用户使用逻辑,不需要关心后台请求数量,只要加载状态结束就可以继续测试,稳定性更高:
describe('Navigation', function () { beforeEach(function () { cy.loginByCognitoApi(Cypress.env('cognito_username'), Cypress.env('cognito_password')); // 先确认加载spinner出现,再等待它消失,超时时间可根据实际同步时长调整 cy.get('[data-test=loading-spinner]', { timeout: 10000 }).should('be.visible'); cy.get('[data-test=loading-spinner]', { timeout: 30000 }).should('not.exist'); // 可选添加短等待确保页面渲染完成 cy.wait(100); }); it('shows logged in', function () { cy.get('[data-test=logo]').should('be.visible'); }); });
如果你的加载spinner是用display: none隐藏而非直接移除DOM,把should('not.exist')改为should('not.be.visible')即可。
内容的提问来源于stack exchange,提问作者Martin Rojas
相关产品推荐
相关产品推荐

