Cypress 使用多个包含查找 DOM 元素

Cypress finding DOM element using multiple contains

我需要select列表中的第一封电子邮件,但我不知道它什么时候到达。

为电子邮件到达设置较长的超时时间可能会奏效,但我正在寻找更好的解决方案。

我需要 select 第一行,其中 .subjectconfirm your email address,时间字段是 a few seconds ago

这是我试过的:


cy.contains('a few seconds ago')
  .closest('.row') // get the container
  .contains('confirm your email address')

此解决方案的问题是,如果有一封主题为 reset your password 的电子邮件,它将首先找到它,然后等待最后一个包含超时。

似乎Cypress 没有重新检查整个调用链,只是最后一个失败了。 (所以它不会从第一个 .get('a few seconds ago') 重新开始,而是只等到 .contains('confirm your email address') 超时。

我也可以 运行 一些 jquery 检查,但是我自己写超时和重试,这是 no-go in Cypress...

如何让 Cypress 找到满足两个 contains 要求的第一行?


编辑:

如果我在 should 中写多个断言:


  cy.get(".msglist-message", { timeout: 10_000 })
    .should(($row) => {
      // either fails triggers retry
      expect($row.text()).to.match(/a few seconds ago/i);
      expect($row.text()).to.match(new RegExp(subject, "i"));
    })
    .click();

click() 仍将引用所有行(匹配 .msglist-message),这出乎我的意料:

cy.click() can only be called on a single element. Your subject contained 7 elements. Pass { multiple: true } if you want to serially click each element

所以基本上我只是断言有一行匹配 row 给定我的多个 contains 标准,但我仍然不能在其上使用 Cypress 命令,例如 click,我没有关于那个元素的参考。

好像也是shouldcannot yield a new value with lambda.

当我尝试在 should 内部单击时,出现了无限重试循环:


  cy.get(".msglist-message", { timeout: 10_000 })
    .should(($row) => {
      // either fails triggers retry
      expect($row.text()).to.match(/a few seconds ago/i);
      expect($row.text()).to.match(new RegExp(subject, "i"));

      cy.wrap($row).click()
    })

也许颠倒顺序就能捕捉到它?

cy.contains('confirm your email address')
  .closest('.row') // get the container
  .contains('a few seconds ago')          // do you even need this? timeout === 4 seconds
        

否则,.should(() => expect()...)将重试

cy.get('.row')
  .should($row => {
    // either fails triggers retry
    expect($row.text()).to.match(/a few seconds ago/i)
    expect($row.text()).to.match(/confirm your email address/i)
  })

缩小行列表

如您所述,.should() 不会更改主题,因此后续链会看到所有行。

要缩小范围,请使用 .contains() 选择一行

cy.contains('.row', 'Confirm your email address')
  .should($row => {
    // either fails triggers retry
    expect($row.text()).to.match(/a few seconds ago/i)
    expect($row.text()).to.match(/confirm your email address/i)
  })
  .contains('.row', 'Confirm your email address') 
  .click()

或者您可以在顶部应用 .contains()

cy.contains('.row', 'Confirm your email address')
  .should($row => {
    expect($row.text()).to.match(/a few seconds ago/i)
  })
  .click()

或者(逻辑上)“几秒钟前”收到的消息将位于顶部

cy.contains('.row', 'Confirm your email address')
  .should($row => {
    // either fails triggers retry
    expect($row.text()).to.match(/a few seconds ago/i)
    expect($row.text()).to.match(/confirm your email address/i)
  })
  .eq(0) 
  .click()