簡體   English   中英

我在表格中創建了一個包含信息的新行,但我無法在 Cypress e2e 測試中獲取最后一行(新行)

[英]I create a new row with info in a table but I can' t get the last one (the new one) on Cypress e2e test

我在應用程序中使用 Cypress 進行 e2e 測試我要測試的這種特定行為是:

  1. 在表格中輸入信息。
  2. 按提交。
  3. 新字段已創建並放置在表格的底部。
  4. 檢查最后一個字段是否包含我在上一個表單中輸入的值。

一切都很好,但在測試時我沒有得到最后一個值,而是前一個值,就像沒有完成創建它一樣。

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");

並且彈出的錯誤應該與最后一行的數據匹配,但它檢測到的是來自上一行的信息

是我的 inte.net 速度,還是我應該將 a.then 放在某個地方以某種方式?

提前致謝

如果提交操作添加了一行,請嘗試檢查行數是否增加了 1。

.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.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");

最小的可重現示例

這是一個簡單的 web 頁面,其中包含一個異步向表中添加行的按鈕。

按下按鈕后檢查行數,測試通過。

應用程序

<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')
})

我猜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 等待(尤其是 mocking 等待)可以幫助減少測試不穩定。 如果您使用數字等待時間或完全跳過它們,如果您依賴外部 API,您可能會隨機中斷。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM