Skip to main content
Cypress应用

wait

在继续执行下一个命令之前,等待指定的毫秒数或等待别名的资源解析完成。

语法

cy.wait(time)
cy.wait(alias)
cy.wait(aliases)
cy.wait(time, options)
cy.wait(alias, options)
cy.wait(aliases, options)
// 为别名的拦截请求指定请求和响应类型
type UserReq = {}
type UserRes = {}
type ActivityReq = {}
type ActivityRes = {}

cy.intercept('/users/*').as('getUsers')
cy.intercept('/activities/*').as('getActivities')

// 作为模板类型:
cy.wait<UserReq, UserRes>('@getUsers').then(({ request, response }) => {
request.body // 类型为 UserReq
response.body // 类型为 UserRes
})

// 作为推断类型,使用 `cypress/types/net-stubbing` 中的 `Interception` 类型
cy.wait('@getUsers').then(
({ request, response }: Interception<UserReq, UserRes>) => {
request.body // 类型为 UserReq
response.body // 类型为 UserRes
}
)

// 当传递别名数组时,必须推断类型:
cy.wait(['@getUsers', 'getActivities']).then(
(
interceptions: Array<
Interception<UserReq | ActivityReq, UserRes | ActivityRes>
>
) => {
interceptions.forEach(({ request, response }) => {
request.body // 类型为 UserReq | ActivityReq
response.body // 类型为 UserRes | ActivityRes
})
}
)

用法

正确用法

cy.wait(500)
cy.wait('@getProfile')

参数

time (Number)

等待的毫秒数。

alias (String)

使用 .as() 命令定义的别名路由,并通过 @ 字符和别名名称引用。

aliases (Array)

使用 .as() 命令定义的别名路由数组,并通过 @ 字符和别名名称引用。

options (Object)

传入一个选项对象以更改 cy.wait() 的默认行为。

选项默认值描述
logtrue命令日志 中显示命令
timeoutrequestTimeout, responseTimeout等待 cy.wait() 解析的超时时间,超过则 超时
requestTimeoutrequestTimeout覆盖此请求的全局 requestTimeout。默认为 timeout
responseTimeoutresponseTimeout覆盖此请求的全局 responseTimeout。默认为 timeout

生成结果 了解主题管理

当给定 time 参数时:

  • cy.wait() 返回与传入时相同的主题。
  • .wait() 之后链接依赖于该主题的进一步命令是 不安全的

当给定 alias 参数时:

  • cy.wait() 返回一个包含请求的HTTP请求和响应属性的对象。

示例

时间

等待任意毫秒数:

cy.wait(2000) // 等待2秒
caution
反模式

您几乎 不需要 等待任意时间。在Cypress中总有更好的表达方式。

阅读关于 最佳实践 的更多信息。

此外,在调试测试代码时,使用 cy.debug()cy.pause() 通常更加方便。

别名

关于别名的详细解释,请阅读更多关于等待路由的信息

等待特定请求响应

// 等待别名 'getAccount' 响应
// 不更改或存根其响应
cy.intercept('/accounts/*').as('getAccount')
cy.visit('/accounts/123')
cy.wait('@getAccount').then((interception) => {
// 现在可以访问包含请求体、
// 响应体、状态等的低级拦截对象
})

等待自动递增的响应

每次我们使用 cy.wait() 等待一个别名时,Cypress会等待第n个匹配的请求。

// 存根对书籍请求的空响应
cy.intercept('GET', '/books', []).as('getBooks')
cy.get('#search').type('Peter Pan')

// 等待第一个响应完成
cy.wait('@getBooks')

// 结果应为空,因为我们
// 首先返回了一个空数组
cy.get('#book-results').should('be.empty')

// 现在请求(再次别名为 `getBooks`)将返回一本书
cy.intercept('GET', '/books', [{ name: 'Peter Pan' }]).as('getBooks')

cy.get('#search').type('Peter Pan')

// 当我们再次等待 'getBooks' 时,Cypress
// 会自动知道等待第二个响应
cy.wait('@getBooks')

// 第二次我们返回了一本书
cy.get('#book-results').should('have.length', 1)

别名数组

可以传递一个别名数组,Cypress会在解析前等待所有请求完成。

当传递一个别名数组给 cy.wait() 时,Cypress会在给定的 requestTimeoutresponseTimeout 内等待所有请求完成。

cy.intercept('/users/*').as('getUsers')
cy.intercept('/activities/*').as('getActivities')
cy.intercept('/comments/*').as('getComments')
cy.visit('/dashboard')

cy.wait(['@getUsers', '@getActivities', '@getComments']).then(
(interceptions) => {
// interceptions 现在是一个匹配请求的数组
// interceptions[0] <-- getUsers
// interceptions[1] <-- getActivities
// interceptions[2] <-- getComments
}
)

使用 .spread() 将数组展开为多个参数。

cy.intercept('/users/*').as('getUsers')
cy.intercept('/activities/*').as('getActivities')
cy.intercept('/comments/*').as('getComments')
cy.wait(['@getUsers', '@getActivities', '@getComments']).spread(
(getUsers, getActivities, getComments) => {
// 每个拦截现在是一个单独的参数
}
)

注意事项

嵌套

Cypress会自动等待网络调用完成后再继续执行下一个命令。

// 反模式:将Cypress命令放在.then回调中
cy.wait('@alias')
.then(() => {
cy.get(...)
})

// 推荐做法:按顺序编写Cypress命令
cy.wait('@alias')
cy.get(...)

// 示例:在继续之前从cy.intercept()断言状态
cy.wait('@alias').its('response.statusCode').should('eq', 200)
cy.get(...)

阅读 指南:Cypress简介

超时

requestTimeoutresponseTimeout

当与别名一起使用时,cy.wait() 会经历两个独立的“等待”阶段。

第一个阶段等待匹配的请求离开浏览器。此持续时间由 requestTimeout 选项配置,默认值为 5000 毫秒。

这意味着当您开始等待一个别名的请求时,Cypress将等待最多5秒以创建匹配的请求。如果未找到匹配的请求,您将看到类似以下的错误消息:

未找到匹配请求的错误

一旦Cypress检测到匹配的请求已开始,它将切换到第二个等待阶段。此持续时间由 responseTimeout 选项配置,默认值为 30000 毫秒。

这意味着Cypress现在将等待最多30秒以获取外部服务器对此请求的响应。如果未检测到响应,您将看到类似以下的错误消息:

等待请求响应的超时错误

这为您提供了两全其美的方案——当请求从未发出时快速反馈错误,以及实际外部响应的更长等待时间。

使用别名数组

当传递一个别名数组给 cy.wait() 时,Cypress会在给定的 requestTimeoutresponseTimeout 内等待所有请求完成。

规则

要求 了解命令链

  • 当传递 time 参数时,cy.wait() 可以链接到 cy 或另一个命令。
  • 当传递 alias 参数时,cy.wait() 必须链接到 cy

断言 了解断言

  • cy.wait() 只会运行您链接的断言一次,并且不会 重试

超时设置 了解超时机制

  • cy.wait() 可能会因等待请求发出而超时。
  • cy.wait() 可能会因等待响应返回而超时。

命令日志

等待对用户的PUT请求解析。

cy.intercept('PUT', /users/, {}).as('userPut')
cy.get('form').submit()
cy.wait('@userPut').its('request.url').should('include', 'users')

cy.wait() 将在命令日志中显示为:

命令日志等待

当点击命令日志中的 wait 时,控制台将输出以下内容:

控制台日志等待

历史

版本变更
3.1.3添加了 requestTimeoutresponseTimeout 选项
< 0.3.3添加了 cy.wait() 命令

另请参阅