等待API请求在Cypress中完成



我知道如何使用拦截和别名等待测试中的应用程序发送的请求,并等待这个别名。

但是如何等待cy.request()发出的请求呢?

我可以给它分配一个别名:

cy.request('POST', '/Sessions', USER_CREDENTIALS_ADMIN).as('login').then(response => {
....
});
cy.wait('@login');

但是我有一个错误:

cy.wait() only accepts aliases for routes. The alias: login did not match a route.

如果没有cy.wait('@login');,它将执行预期操作(登录用户(。

Cypress自动等待cy.request()完成。

使用deelay.me伪造慢速请求

it('Cypress waits for request to complete', () => {

// delay request response by 3 seconds
cy.request('https://deelay.me/3000/https://jsonplaceholder.typicode.com/todos/1')
.then(() => console.log('Request complete'))
cy.visit('http://example.com', {
onBeforeLoad: () => console.log('Before visit')
})
})

日志:

  • 请求完成✅
  • 访问前

但是,如果我对请求的结果进行了一些异步处理,它不会等待

it('Cypress waits for request to complete', () => {

cy.request('https://deelay.me/3000/https://jsonplaceholder.typicode.com/todos/1')
.then(() => {
setTimeout(() => console.log('Timeout complete'), 2000)
})
.then(() => console.log('Request complete'))
cy.visit('http://example.com', {
onBeforeLoad: () => console.log('Before visit')
})
})

日志:

  • 请求完成
  • 访问前
  • 超时完成❌

它可以通过包装Promise来修复,因为Cypress会自动等待Promise

it('Cypress waits for request to complete', () => {

cy.request('https://deelay.me/3000/https://jsonplaceholder.typicode.com/todos/1')
.then(() => {
return new Cypress.Promise(resolve => {
setTimeout(() => { 
console.log('Timeout complete')
resolve()
}, 2000)
})
})
.then(() => console.log('Request complete'))
cy.visit('http://example.com', {
onBeforeLoad: () => console.log('Before visit')
})
})

日志:

  • 超时完成✅
  • 请求完成
  • 访问前

我认为实现这样的功能的最佳方法是将其添加为自定义命令,并使该命令可链接。

Cypress.Commands.add('requestSessions', () => {
return cy.request(...).then((res) => {...});
});

如果您在Cypress命名空间中声明自定义命令,则可以省略返回类型。

declare global {
namespace Cypress {
interface Chainable {
requestSessions();
}
}
}

您应该能够简单地使用Cypress链中的函数,并让Cypress等待命令完成后再继续。

cy.requestSessions()
.visit('/foo');

最新更新