【问题标题】:Cypress - delete all rows from table赛普拉斯 - 从表中删除所有行
【发布时间】:2021-09-29 13:47:20
【问题描述】:

我正在对元素列表(HTML 表格)编写一组测试。

由于测试仍在进行中,我收到了很多垃圾数据,我想在每次运行前清理这些数据。

所以,我正在尝试删除 before() 挂钩中的所有行。我想删除的过程应该是:

  1. 按名称搜索产品
  2. 点击第一行中的删除图标
  3. 等待确认对话框
  4. 点击“是”
  5. 从步骤 2 重复,直到没有剩余行

这是迄今为止我在输入搜索输入后调用的函数:

 function deleteAllFoundProducts() {
        cy.get('tbody tr').then(rows => {
            if (rows.length < 1) return // if no rows remain, terminate recursion
            cy.get('span[title="Delete"]', {timeout: 10000}).first().click()
            cy.get('.tBtn[title="Yes"]').click().then(() => {
                cy.get('.loader', {timeout: 10000}).should('not.exist') // wait for list to reappear
                deleteAllFoundProducts() // try again
            })
        })
    }

问题是——即使在删除最后一行后,该函数仍继续运行,并且由于没有 span[title="Delete"] 而出错。

[编辑]

仔细检查后,我发现一张空表仍然只有一行 - 带有 No records found 文本。我以为这根本不是一个行。因此,错误是由不包含删除图标的行引起的。我应该早点注意到的。

这是删除了不必要的 Angular 内容的相关 HTML:

<tbody class="p-element p-datatable-tbody" ng-reflect-value="" ng-reflect-template="[object Object]">
    <tr>
        <td colspan="6">
            <my-loader ng-reflect-loading="false">
            </my-loader>
            <div class="p-2">No matching records found. </div>
        </td>
    </tr>
</tbody>

我想,解决方案是检查该行是否包含带有文本“未找到记录”的元素,如果不包含则执行删除。但我不知道该怎么做。任何帮助仍将不胜感激。

【问题讨论】:

  • 你能分享一下你的表格的 HTML 吗?
  • 您是否考虑过从后端删除数据(假设您正在使用一个)?即通过公开一个删除数据的端点,然后在赛普拉斯生命周期挂钩中调用该端点。这样你就可以让你的测试用例相对简单。

标签: javascript cypress


【解决方案1】:

使用这个递归函数,您只需要传递一个递减(或可能递增到最大值)的变量

function deleteAllFoundProducts(rowCount) {
  if (rowCount < 1) return // if no rows remain, terminate recursion
  cy.get('span[title="Delete"]', {timeout: 10000}).first().click()
  cy.get('.tBtn[title="Yes"]').click().then(() => {
    cy.get('.loader', {timeout: 10000}).should('not.exist') // wait for list to reappear
    deleteAllFoundProducts(--rowCount) // try again
  })
}

cy.get('tbody tr')
  .then(rows => deleteAllFoundProducts(rows.length))  // first call here

当删除所有行后添加 “未找到匹配记录” 行时,这仍然有效,因为在删除开始之前获得了 rowCount

【讨论】:

  • 如果表格最初是空的(即 No matching records found被显示),这将不起作用。
  • @dzenesiz 是的,如果桌子是空的,不要这样做!这就是赛普拉斯命令的本质——它们不能是有条件的。
  • 赛普拉斯建议了解确切地了解测试正在处理的数据
  • 所以,您是说开发“清理垃圾数据”的功能实际上没有意义,因为垃圾数据从一开始就不应该发生? :)
  • 哦,是的 - 对不起,你在回应我关于确定性测试的咆哮。也许吧,但是你不想在测试之间简单地清理数据库吗?
【解决方案2】:

递归是更安全的迭代方式,特别是当 DOM 在循环期间发生更改或测试中有条件部分时。使用 .each() 可能会给您“与 DOM 分离”错误。

有一个库 https://github.com/bahmutov/cypress-recurse 使它更容易一些。

你可以这样应用它

import { recurse } from 'cypress-recurse'

before(() => {
  recurse(
    () => {
      return cy.get('tbody tr').eq(0).then($row => {
        const $deleteButton = $row.find('button[title="Delete"]')
        if ($deleteButton.length) {
          $deleteButton[0].click()
        }
        return $deleteButton   // return this to signal end of iteration
      })
    },
    ($deleteButton) => $deleteButton.length === 0  // end if no delete button
  )
})

【讨论】:

    【解决方案3】:

    所以这是一个假设,如果这不起作用,那么我需要查看 HTML 表格,所以我假设在您的表格中您有不同的行,并且在每一行中您都有一个删除按钮,一旦您删除该行被删除的按钮。您可以使用内置的 cypress 命令each()

    cy.get('tbody tr').each(($ele) => {
      cy.wrap($ele).within(() => {
        cy.get('span[title="Delete"]', {timeout: 10000}).first().click()
      })
      cy.get('.tBtn[title="Yes"]').click()
      cy.get('.loader', {timeout: 10000}).should('not.exist')
    })
    

    或者,当显示“未找到记录”时,退出循环。

    cy.get('tbody tr').each(($ele) => {
      if ($ele.find('div.p-2').text().trim().includes('No records found')) {
        return false
      } else {
        cy.wrap($ele).within(() => {
          cy.get('span[title="Delete"]', {timeout: 10000}).first().click()
        })
      cy.get('.tBtn[title="Yes"]').click()
      cy.get('.loader', {timeout: 10000}).should('not.exist')
      }
    })
    

    【讨论】:

    • 我实际上发现“未找到记录”消息也是tr。您的答案有效,但在这种情况下除外。我在上面编辑了我的问题。更新您的答案以便我接受它会很麻烦吗?无论如何感谢您的帮助!
    • 我已经更新了答案。
    • 感谢您更新答案。不幸的是,它永远不会进入if 块,所以它仍然会出错。
    • 请分享您的 HTML。这样我就可以正确地纠正代码了。
    • td 元素下是否有文本“未找到记录”?是的,因为 $ele 是一个 jquery 元素
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-19
    • 1970-01-01
    相关资源
    最近更新 更多