我知道如何使用拦截和别名等待测试中的应用程序发送的请求,并等待这个别名。
但是如何等待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');