我正在尝试使用以下双命令作为查找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
相同?
这样做
CoffeeScript的:
cy.wrap(subject).find("[data-cy=#{id}]")
JavaScript的:
cy.wrap(subject).find(`[data-cy=${id}]`)
这是非常令人惊讶的,但我能够验证您的结果。
我提出的最简单的工作(有点黑客)是在自定义命令中重新获取主题。
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}]`)
})
另一个选择是使用第三方Cypress Pipe而不是自定义命令。
cy.pipe可以用作赛普拉斯自定义命令的简单替代品 - 您只需编写函数即可。
cy.pipe与cy.then的工作方式非常相似,除了一些关键的区别:
- 管道将尝试在命令日志中记录函数名称(仅适用于命名函数)
- 管道将创建DOM快照以帮助调试如果传递给管道的函数同步解析(不包含赛普拉斯命令)
- AND返回一个jQuery元素,管道将重试,直到jQuery元素列表不为空(大多数赛普拉斯命令执行此操作)
- 然后是一个cy.should,该函数将被重试,直到断言通过或超时(大多数赛普拉斯命令执行此操作)
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()
的例子,但它看起来很复杂。
当测试(最终)成功时,这个模式工作正常,但是当测试失败时我无法让它停止重试(它应该超时,但我无法弄清楚如何)。