如何使用Cypress拦截同一端点的多个XHR请求并分别处理
问题原因
你重复注册5次相同匹配规则的cy.intercept()的写法不符合Cypress的拦截逻辑设计:Cypress的同规则拦截器会按注册顺序依次被请求消费,若请求触发时机和注册逻辑不匹配就会出现漏拦截的问题,该写法也会产生冗余代码。
解决方案
你仅需注册1次全局拦截器,等待时传入对应次数的拦截别名数组,就能按顺序获取所有匹配请求的返回结果,单独处理每个请求:
- 仅声明1次拦截规则,绑定统一别名
cy.wait()传入由N个相同别名组成的数组,N等于你要拦截的请求总数- 等待完成后返回的数组按请求触发顺序存储所有拦截结果,可通过下标单独处理每个请求的返回值
修正后的完整代码
describe(Cypress.env('label') + 'TestSuite', function () { beforeEach(function () { cy.login_api(Cypress.env('username'), Cypress.env('password')) }) it('General data queries', function () { // 仅注册一次拦截器即可 cy.intercept({ method: 'GET', path: '/API/query/*' }).as('apiQuery') cy.visit('/') // 等待5个匹配的请求,按顺序返回拦截结果 cy.wait(['@apiQuery', '@apiQuery', '@apiQuery', '@apiQuery', '@apiQuery']).then((interceptions) => { // interceptions[0] 对应第一个请求 即你之前的call1 // interceptions[1] 对应第二个请求 即你之前的call2 以此类推 const call1Res = interceptions[0] expect(call1Res.response.statusCode).to.eq(200) const valuesV3 = call1Res.response.body.values cy.setCookie('forceversion', '4') cy.intercept({ method: 'GET', path: '/galileo/data/*' }).as('call11') cy.wait('@call11').then(res => { expect(res.response.statusCode).to.eq(200) const valuesV4 = res.response.body.values // 修复原代码拼写错误 alert(valuesV4) for (var i = 0; i < Object.keys(valuesV3).length; i++) { let x = Object.values(valuesV3[i]) let y = Object.values(valuesV4[i]) function compare(arr1, arr2) { return arr1.every(item => arr2.includes(item)) } assert(compare(x, y), `第${i}项数据不匹配`) } }) }) }) })
拓展说明
如果需要对每个请求做不同的前置拦截处理(比如修改不同请求的返回值),可以给每个拦截器添加times配置指定匹配次数:
// 第一个拦截器仅匹配1次,处理第一个请求 cy.intercept({method: 'GET', path: '/API/query/*', times: 1}, (req) => { // 自定义处理第一个请求逻辑 }).as('call1') // 第二个拦截器仅匹配1次,处理第二个请求 cy.intercept({method: 'GET', path: '/API/query/*', times: 1}, (req) => { // 自定义处理第二个请求逻辑 }).as('call2') // 后续拦截器以此类推
内容的提问来源于stack exchange,提问作者Mohammad Osama
相关产品推荐
相关产品推荐

