如何使自定义子命令自动重试
How to make a custom child command automatically retry
我正在尝试使用以下双重命令作为查找 dom 个元素的快捷方式。
Cypress.Commands.add "el", prevSubject: "optional", (subject, id) =>
if subject?
subject.find("[data-cy=#{id}]")
else
cy.get("[data-cy=#{id}]")
问题是如果我正在寻找的元素需要一段时间才能出现,该命令不会重试。
以下所有方法都有效
cy.wait(1000) # wait for element to appear
cy.get("parent").el("mark")
cy.get("parent").find("[data-cy=mark]") # or type out what the command does
cy.el("mark") # or use the command as parent command
但只是 cy.get("parent").el("mark")
没有等待元素出现并失败。
如果我像这样将命令定义为子命令,我会遇到同样的问题
Cypress.Commands.add "el", prevSubject: true, (subject, id) =>
subject.find("[data-cy=#{id}]")
有没有办法让我的自定义命令的行为方式与 find
相同?
这很令人惊讶,但我能够验证你的结果。
我想到的最简单的解决方法(有点 hack)是在自定义命令中重新获取主题。
Cypress.Commands.add('el_with_ReGet', {prevSubject: true}, (subject, id) => {
const selector = subject.selector || subject.prevObject.selector;
return cy.get(selector).find(`[data-cy=${id}]`)
})
另一种选择是使用第 3 方 Cypress Pipe 而不是自定义命令。
cy.pipe can be used as a simpler replacement for Cypress Custom Commands - you just write functions.
cy.pipe works very similarly to cy.then except for a few key differences:
- pipe will try to document the function name in the Command log (only works on named functions)
- pipe will create DOM snapshots to aid in debugging
If the function passed to pipe resolves synchronously (doesn't contain Cypress commands)
- AND returns a jQuery element, pipe will retry until the jQuery element list is not empty (most Cypress commands do this)
- AND is followed by a cy.should, the function will be retried until the assertion passes or times out (most Cypress commands do this)
import 'cypress-pipe';
it('should find child by id by pipe (replacing custom command)', () => {
const elFn = (id) => (subject) => subject.find(`[data-cy=${id}]`)
cy.visit(...)
cy.get('parent')
.pipe(elFn('mark'))
.then(result => {
console.log('find result', result)
expect(result.length).to.eq(1)
})
})
这里有一个讨论 Cypress.Commands.add needs option to force retry on that command #2670 有一个来自 Gleb Bahmutov 的例子使用 cy.verifyUpcomingAssertions()
但它看起来很复杂。
当测试(最终)成功时,此模式工作正常,但当测试失败时我无法让它停止重试(它应该超时,但我不知道如何超时)。
改为这样做
咖啡脚本:
cy.wrap(subject).find("[data-cy=#{id}]")
javascript:
cy.wrap(subject).find(`[data-cy=${id}]`)
我正在尝试使用以下双重命令作为查找 dom 个元素的快捷方式。
Cypress.Commands.add "el", prevSubject: "optional", (subject, id) =>
if subject?
subject.find("[data-cy=#{id}]")
else
cy.get("[data-cy=#{id}]")
问题是如果我正在寻找的元素需要一段时间才能出现,该命令不会重试。
以下所有方法都有效
cy.wait(1000) # wait for element to appear
cy.get("parent").el("mark")
cy.get("parent").find("[data-cy=mark]") # or type out what the command does
cy.el("mark") # or use the command as parent command
但只是 cy.get("parent").el("mark")
没有等待元素出现并失败。
如果我像这样将命令定义为子命令,我会遇到同样的问题
Cypress.Commands.add "el", prevSubject: true, (subject, id) =>
subject.find("[data-cy=#{id}]")
有没有办法让我的自定义命令的行为方式与 find
相同?
这很令人惊讶,但我能够验证你的结果。
我想到的最简单的解决方法(有点 hack)是在自定义命令中重新获取主题。
Cypress.Commands.add('el_with_ReGet', {prevSubject: true}, (subject, id) => {
const selector = subject.selector || subject.prevObject.selector;
return cy.get(selector).find(`[data-cy=${id}]`)
})
另一种选择是使用第 3 方 Cypress Pipe 而不是自定义命令。
cy.pipe can be used as a simpler replacement for Cypress Custom Commands - you just write functions.
cy.pipe works very similarly to cy.then except for a few key differences:
- pipe will try to document the function name in the Command log (only works on named functions)
- pipe will create DOM snapshots to aid in debugging If the function passed to pipe resolves synchronously (doesn't contain Cypress commands)
- AND returns a jQuery element, pipe will retry until the jQuery element list is not empty (most Cypress commands do this)
- AND is followed by a cy.should, the function will be retried until the assertion passes or times out (most Cypress commands do this)
import 'cypress-pipe';
it('should find child by id by pipe (replacing custom command)', () => {
const elFn = (id) => (subject) => subject.find(`[data-cy=${id}]`)
cy.visit(...)
cy.get('parent')
.pipe(elFn('mark'))
.then(result => {
console.log('find result', result)
expect(result.length).to.eq(1)
})
})
这里有一个讨论 Cypress.Commands.add needs option to force retry on that command #2670 有一个来自 Gleb Bahmutov 的例子使用 cy.verifyUpcomingAssertions()
但它看起来很复杂。
当测试(最终)成功时,此模式工作正常,但当测试失败时我无法让它停止重试(它应该超时,但我不知道如何超时)。
改为这样做
咖啡脚本:
cy.wrap(subject).find("[data-cy=#{id}]")
javascript:
cy.wrap(subject).find(`[data-cy=${id}]`)