在 cy.wait('@alias')
后直接附加 .catch()
是不可行的,但你可以参考这个关于请求轮询的示例,并稍作修改来达到目的。
以下示例中,cy.catchAlias()
代替了 cy.wait('@alias')
来轮询拦截器。
测试中有两个拦截器,但只有第一个会被触发。
对于“未发生”的拦截,返回 null
而不是让测试失败,你可以根据返回值来执行失败时的动作。
Cypress.Commands.add('catchAlias', (alias, { timeout = Cypress.config('defaultCommandTimeout'), start = Date.now() }) => {
if (start + timeout < Date.now()) return null;
cy.get(alias, { log: false }).then(interception => {
if (interception?.response) return interception;
cy.catchAlias(alias, { timeout, start });
});
});
// 设置拦截器
cy.intercept('/todos/1').as('api1');
cy.intercept('/todos/2').as('api2');
// 触发API调用(仅第一个)
cy.window().then(win => {
win.fetch('https://jsonplaceholder.typicode.com/todos/1');
});
// 检查第一个
cy.catchAlias('@api1', { timeout: 2000 })
.should(interception => {
expect(interception.response.body.title).to.eq('delectus aut autem');
});
// 检查第二个
cy.catchAlias('@api2', { timeout: 2000 })
.should('eq', null);
cypress-wait-if-happens 插件
Gleb Bahmutov 开发了一个插件cypress-wait-if-happens,提供了更多选项以实现相同功能。
如果请求在超时时间内未发生,则返回 undefined。
import 'cypress-wait-if-happens';
cy.waitIfHappens({
alias: '@users',
timeout: 100,
lastCall: true,
yieldResponseBody: true,
})
// 我们应该得到包含4个用户的列表
// 因为那是实际发生的最后一次调用
.should('have.length', 4);