vue.js 我在表中创建了一个包含信息的新行,但在Cypress e2e测试中无法获取最后一行(新行)

gywdnpxw  于 2022-11-25  发布在  Vue.js
关注(0)|答案(2)|浏览(119)

我正在一个应用程序中使用Cypress进行e2e测试我想要测试的这个特定行为是:
1.在表单中输入信息。
1.按提交。
1.将创建新字段并将其放置在表的底部。
1.检查最后一个字段是否具有我在上一个表单中输入的值。
一切正常,但测试时我没有得到最后一个值,而是得到了前一个值,就像没有完成创建一样。

cy.get("button").contains("Submit").click();
cy.url().should("include", "/advertisers");

cy.get("tr").last().should("contain.text", "New Advertiser");
cy.get("tr").last().should("contain.text", "Lom Yolk");
cy.get("tr").last().should("contain.text", "500");
cy.get("tr").last().should("contain.text", "Prepaid");

弹出的错误是关于它应该将数据与最后一行匹配,但它检测到的是来自上面一行的信息
是我的网速,还是我应该把一个。然后在某个地方,以某种方式?
先谢了

41zrol4v

41zrol4v1#

如果“提交”操作添加了一行,请尝试检查行计数是否增加了一。
.should('have.length', initialLength + 1)将不断重新检查,直到超时。
但可能不是超时,而是应用程序中的后台处理。为此,还需要添加cy.wait(0)

cy.get('tr').then($current => {

  const initialLength = $current.length;

  cy.get('button').contains('Submit').click();
  cy.wait(0);  // for background processing in the app

  cy.get('tr', {timeout: 10_000}).should('have.length', initialLength + 1)

  cy.url().should("include", "/advertisers");

  cy.get("tr").last().should("contain.text", "New Advertiser");
  cy.get("tr").last().should("contain.text", "Lom Yolk");
  cy.get("tr").last().should("contain.text", "500");
  cy.get("tr").last().should("contain.text", "Prepaid");
})

另一个可以工作的变体(基于下面的示例应用)

近似包含()

在不检查行数的情况下,使用cy.contains()检查表单数据。

cy.get('button').contains('Submit').click();
cy.url().should("include", "/advertisers");
cy.contains("tr", "New Advertiser");
cy.contains("tr", "Lom Yolk");
cy.contains("tr", "500");
cy.contains("tr", "Prepaid");

最小可重现示例

这是一个简单的网页,其中有一个按钮,可以异步地将行添加到表中。
按下按钮后检查行数,测试通过。

应用程序

<body>
  <table>
    <tbody>
      <tr><td>one</td></tr>
      <tr><td>two</td></tr>
    </tbody>
  </table>
  <button>Add row</button>

  <script>
    const button = document.querySelector('button')

    function addRow() {
      setTimeout(() => {
        const tbody = document.querySelector('tbody')
        const tr = document.createElement('tr')
        const td = document.createElement('td')
        td.innerText = 'three'
        tr.appendChild(td)
        tbody.appendChild(tr)
      }, 2000)
    }
    button.addEventListener('click', addRow)
  </script>
</body>

测试

cy.get('tr').then($tr => {
  const initialCount = $tr.length
  cy.get('button').click()
  cy.get('tr').should('have.length', initialCount + 1)
  cy.get('tr').last().should('contain.text', 'three')
})
whitzsjs

whitzsjs2#

我猜Submit发出了一个依赖于某个服务器的异步请求。
当你使用cy.get("tr").last()时,它会立即执行,因为如果你在页面上已经有了最后一个tr元素,并且在vue更新DOM之前执行。
您可以在继续之前检查长度(随机选择7个)

// this should wait until the 7th row is added
cy.get("tr").should("have.length", 7);

// then these can assume the DOM was already updated
cy.get("tr").last().should("contain.text", "New Advertiser");
cy.get("tr").last().should("contain.text", "Lom Yolk");
cy.get("tr").last().should("contain.text", "500");
cy.get("tr").last().should("contain.text", "Prepaid");

一个稍微简单一点的选择是使用cy.get(tr:last),因为只使用带有选择器的get将重新测试DOM更改,而使用cy.get("tr").last()则不会

cy.get("tr:last").should("contain.text", "New Advertiser");
cy.get("tr:last").should("contain.text", "Lom Yolk");
cy.get("tr:last").should("contain.text", "500");
cy.get("tr:last").should("contain.text", "Prepaid");

不过我的建议是还包括wait

// create the alias
cy.intercept('/my-api-call/*').as('myApiCall')

//...
cy.get("button").contains("Submit").click();

// wait for the alias to have been called
cy.wait('@myApiCall')

// then make the other assertions but assume still that the DOM may not have updated yet

包括API等待(尤其是模拟它)可以帮助减少测试的脆弱性。如果你使用数字等待时间或完全跳过它们,如果你依赖于外部API,你可能会随机中断。

相关问题