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

时间:2019-02-06 15:36:59

标签: coffeescript cypress

我正在尝试使用以下双重命令作为查找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相同?

2 个答案:

答案 0 :(得分:1)

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

我想到的最简单的方法(有点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}]`)
})

另一种选择是使用第三方Cypress Pipe而不是自定义命令。

  

cy.pipe可以用作赛普拉斯自定义命令的简单替代方法-您只需编写函数即可。

     

cy.pipe的工作方式与cy.then非常相似,不同之处在于:

     
      
  • 管道将尝试在命令日志中记录函数名称(仅适用于命名函数)
  •   
  • 管道将创建DOM快照以帮助调试   如果传递给管道的函数同步解析(不包含Cypress命令)
  •   
    •   
    • AND返回一个jQuery元素,管道将重试,直到jQuery元素列表不为空(大多数赛普拉斯命令都这样做)
    •   
  •   
    •   
    • AND后跟一个cy。应该重试该函数,直到声明通过或超时(大多数Cypress命令都这样做)
    •   
  •   


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

当测试(最终)成功时,此模式可以正常工作,但是当测试失败时,我无法让它停止重试(它应该超时,但我不知道怎么做)。

答案 1 :(得分:1)

改为执行此操作

咖啡脚本:

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

javascript:

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