当相同的元素包含不同的文本时,我可以通过什么方式验证元素包含文本而不会使测试失败?

问题描述 投票:0回答:3

我有一个场景,其中表格上的元素从一个文本(例如“staging..”)更改为日期(例如今天的日期“10/03/2023”)。它不会自动更改,因此您必须单击应用按钮才能看到它是否已更改,更改大约需要 30 / 40 秒。我想通过单击“应用”按钮每 8 秒检查一次该列从“暂存”更改为今天的日期。

所以我实现了如下代码-

就每 8 秒持续单击“应用”按钮而言,代码工作正常。但是,由于断言 -cy.get('td').eq(1).contains(

Staging...
) 更改而失败。

有什么办法可以避免断言并检查这个条件,这样它就不会失败吗?

提前非常感谢:)

javascript cypress cypress-testing-library cypress-custom-commands
3个回答
1
投票

您可以结合使用递归和生成的 JQuery 元素来完成此操作。

Cypress.Commands.add('isElementUpdated', (selector, retry = 0) => {
  // We'll always check if it contains 'Staging...'
  cy.get(selector).first().within(() => {
    // Yield the element that may or may not contain 'Staging...'
    cy.get('td').eq(1).then(($el) => {
      // Check if element contains 'Staging...'
      // If retry is at the maximum, we won't run this and instead will just validate the date
      if ($el.text().includes('Staging...' && retry < 10) {
        cy.wait(8000);
        cy.get('ApplyButton').click({ force: true });
        cy.isElementUpdated(selector, retry + 1);
      }
    }
  });
  cy.get(selector)
    .should('be.visible')
    .first()
    .within(() => {
      cy.get('td').eq(1).should('contain', todaysDate);
    });
});

0
投票

如果您不希望您的测试在 cy.contains() 上失败,您可以集成条件测试:

cy.get(selector).first().then(
    ($selector) => {
    if ($selector.text() === "Something 1") {
    // Do everything you want here
}
else if {$selector.text() === "Something 2"} {
    // Do everything you want here
}
else {
    // Do everything you want here
}
}

0
投票

我会使用 cypress-recurse 来处理你在 Cypress 中的递归。

API有点坑爹,总结一下

  • 第一个参数只是一个选择器,它不能像
    .contains()
    那样有隐式断言,否则递归将在第一次迭代时失败
  • 第二个参数是你需要为真的断言
  • 您的
    else
    代码可以进入可选的
    post
    回调
recurse(
  () => cy.get(selector).first().find('td').first(),  // this part is just selecting,
                                                      // no assertion here

  ($td) => $td.text() !== 'Staging...',               // assertion here, 
                                                      // recurses if fails

  // after recursion run the post function
  {
    postLastValue: true,                              // $td after staging is passed
                                                      // into post: as value

    post: ({ value, success }) => {                   
      cy.wrap(value).should('contain', todayDate)     // confirm text after change
    }
  }
})

如果你反转逻辑,你可以删除

post
,

cy.get(selector).first().find('td').first().should('contain', 'Staging...')

recurse(
  () => cy.get(selector).first().find('td').first(),  
  ($td) => $td.text() === todayDate,                 // repeat until true
)

可重现的例子

在本地服务器上运行此 HTML

<table>
  <tbody>
    <tr>
      <td>Staging...</td>
    </tr>
  </tbody>
</table>
<script>
  setTimeout(() => {
    const td = document.querySelector('td')
    td.innerText = '...Finished'
  },2000)
</script>

这是(类似的)测试

cy.get('tr').first().find('td').first()
  .should('contain', 'Staging...')

recurse(
  () => cy.get('tr').first().find('td').first(),  
  ($td) => $td.text() === '...Finished',               
)

这是日志

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