簡體   English   中英

賽普拉斯等待一個元素被加載到一個 foo 循環中

[英]Cypress wait for an element to be loaded inside a foor loop

我有一個數組,其中的項目是一堆按鈕元素。 我想調用一個按鈕,然后等待一個元素(在 dom 中)被加載。

加載該元素后,只有我想進入下一次迭代(單擊下一個按鈕/元素)

在我當前的實現中,一次單擊所有按鈕。 但我希望一次單擊一個按鈕。

  cy.document().then(document => {
      const arra = [...document.querySelectorAll('.instances__action')];

      for (let i = 1; i <= arra.length; i++) {
        let state = document.querySelector(
          `#root > section > section > main > div > div > section.instances > div > div > div > div > div > div > table > tbody > tr:nth-child(${i}) > td:nth-child(3) > span`
        ).innerText;

        document
          .querySelector(
            `#root > section > section > main > div > div > section.instances > div > div > div > div > div > div > table > tbody > tr:nth-child(${i}) > td:nth-child(7) > div > button.ant-btn.ant-btn-primary.ant-btn-sm`
          )
          .click();
        cy.wait(2000);
        cy.waitUntil(() => {
          cy.get(
            `#root > section > section > main > div > div > section.instances > div > div > div > div > div > div > table > tbody > tr:nth-child(${i +
              1}) > td:nth-child(3) > span`
          ).contains('Finished');
        });
      }
    });
  });

@jmargolisvt 是正確的,如果您將 .click .click()操作更改為 Cypress 命令,您應該獲得正確的操作序列。

命令執行順序和測試循環

可以這樣想——上面的測試代碼像普通的 javascript 一樣運行,每個cy.X()命令都會將一個命令放入隊列中。 命令保證按隊列順序依次運行,但不與測試代碼同步。

因此, cy.wait(2000)並沒有減慢 for 循環的速度,而是暫停了隊列執行。

等待斷言

另請注意,命令具有對其斷言的內置等待,因此在這種情況下您可能不需要cy.wait()cy.waitUntil() 您可以使用timeout選項控制等待的長時間。

循環

如果將內部部分轉換為命令,for 循環將正常工作,但您也可以將循環本身轉換為 IMO 更簡潔的cy.get().each()命令。

測試異步內容

最后,在等待異步內容時,更喜歡cy.contains('mySelector', 'myContent')命令而cy.get('mySelector').contains('myContent')命令。

原因是cy.get('mySelector').contains('myContent')只等待元素mySelector ,但它已經在 DOM 中。 如果內容正在異步更改,此命令將立即測試舊內容(假設為空)並通過測試失敗。

const tbodySelector = '#root > section > section > main > div > div > section.instances > div > div > div > div > div > div > table > tbody';
const buttonSelector = 'td:nth-child(7) > div > button.ant-btn.ant-btn-primary.ant-btn-sm';
const spanSelector = 'td:nth-child(3) > span'

cy.get('.instances__action').each(($el, i) => {

    cy.get(`${tbodySelector} > tr:nth-child(${i+1}) > ${buttonSelector}`)
      .click();

    cy.contains(
      `${tbodySelector} > tr:nth-child(${i+1}) > ${spanSelector}`, 
      'Finished', 
      { timeout: 2000 }  // increase timeout if a longer wait is required
    );  

});

注意jQuery 的:nth-child(index)選擇器從索引 1 開始,但是.each(($el, i) =>具有從零開始的索引,因此必須在這些選擇器中使用i+1


這是我用來測試的模擬 DOM。 在一個干凈的 Cypress 項目中,將它放在文件夾<project root>/app

<table>
  <tbody>
    <tr class="instances__action">
      <td>
        <button id="myBtn1"></button>
      </td>
      <td>
        <span id="mySpan1"></span>
      </td>
    </tr>

    <tr class="instances__action">
      <td>
        <button id="myBtn2"></button>
      </td>
      <td>
        <span id="mySpan2"></span>
      </td>
    </tr>
  </tbody>
</table>
<script>
  document.getElementById("myBtn1").addEventListener("click", function() {
    setTimeout(() => {
      document.getElementById("mySpan1").innerHTML = "Finished";
    }, 1000)
  });
  document.getElementById("myBtn2").addEventListener("click", function() {
    setTimeout(() => {
      document.getElementById("mySpan2").innerHTML = "Finished";
    }, 500)
  });
</script>

注意上面的嵌套被簡化了,所以我適當地改變了選擇器的內容。

測試上面的 HTML 片段

it('clicks buttons and waits for finished flag', () => {

  cy.visit('app/iterate-table-buttons.html')

  const tbodySelector = 'tbody';
  const buttonSelector = 'td:nth-child(1) > button';
  const spanSelector = 'td:nth-child(2) > span'

  cy.get('.instances__action').each(($el, i) => {

      console.log(`starting #${i}`)

      cy.get(`${tbodySelector} > tr:nth-child(${i+1}) > ${buttonSelector}`)
        .then(() => console.log(`clicking #${i}`))
        .click();

      cy.contains(
        `${tbodySelector} > tr:nth-child(${i+1}) > ${spanSelector}`, 
        'Finished',
        { timeout: 2000 }  // increase timeout if a longer wait is required
      )
      .then(() => console.log(`asserting #${i}`))

  });
})

柏樹日志

這就是 Cypress 日志的樣子。
全部為綠色,並且只有在完成文本出現后才能看到點擊。

  1. 訪問 app/iterate-table-buttons.html
  2. 獲取 .instances__action
  3. 獲取 tbody > tr:nth-child(1) > td:nth-child(1) > 按鈕
  4. 點擊
  5. 包含 tbody > tr:nth-child(1) > td:nth-child(2) > 跨度,完成
  6. 獲取 tbody > tr:nth-child(2) > td:nth-child(1) > 按鈕
  7. 點擊
  8. 包含 tbody > tr:nth-child(2) > td:nth-child(2) > 跨度,完成

控制台日志

這就是控制台日志的樣子。

循環在命令隊列開始之前執行到完成,但沒關系,因為命令仍在以正確的順序執行。

開始#0
開始#1
點擊#0
斷言#0
點擊#1
斷言#1

暫無
暫無

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

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