如何使自定义子命令自动重试

问题描述 投票:1回答:2

我正在尝试使用以下双命令作为查找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 cypress
2个回答
1
投票

这样做

CoffeeScript的:

cy.wrap(subject).find("[data-cy=#{id}]")

JavaScript的:

cy.wrap(subject).find(`[data-cy=${id}]`)

1
投票

这是非常令人惊讶的,但我能够验证您的结果。

我提出的最简单的工作(有点黑客)是在自定义命令中重新获取主题。

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()的例子,但它看起来很复杂。

当测试(最终)成功时,这个模式工作正常,但是当测试失败时我无法让它停止重试(它应该超时,但我无法弄清楚如何)。

© www.soinside.com 2019 - 2024. All rights reserved.