Cypress ожидание загрузки элемента внутри цикла foor - PullRequest
0 голосов
/ 21 марта 2020

У меня есть массив, элементы которого являются связкой элементов кнопки. Я хочу вызвать кнопку, затем дождаться загрузки элемента (который находится в dom).

после загрузки этого элемента, тогда только я хочу go до следующей итерации (нажмите на следующую кнопка / элемент)

В моей текущей реализации все кнопки нажимаются одновременно. но я хочу, чтобы одна кнопка была нажата за раз.

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

1 Ответ

1 голос
/ 21 марта 2020

@ jmargolisvt правильно, если вы измените операцию .click() на команду Cypress, вы должны получить правильную последовательность действий.

Последовательность выполнения команд и циклы тестирования

Подумайте об этом так: тестовый код, приведенный выше, работает как обычно javascript, и каждая команда cy.X() помещает команду в очередь. Команды гарантированно выполняются последовательно в порядке очереди, но не синхронно с тестовым кодом.

Итак, cy.wait(2000) не замедляет for-l oop, а приостанавливает выполнение очереди.

Ожидание подтверждений

Обратите внимание, что команды имеют встроенные средства ожидания для своих утверждений, поэтому вам, вероятно, не нужны ни cy.wait(), ни cy.waitUntil() в этом сценарии. Вы можете контролировать максимум время ожидания с опцией timeout.

Цикл

Для l oop будет работать нормально, если вы преобразуете внутренние части в команды, но вы также можете преобразовать сам l oop в cy.get (). Each () команда, которая намного лучше IMO.

Тестирование асинхронного c содержимого

Наконец, предпочитайте команду cy.contains('mySelector', 'myContent') команде cy.get('mySelector').contains('myContent') при ожидании асинхронного c содержимого.

Причина в том, что 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
    );  

});

NOTE jQuery 's :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

Вот как выглядит журнал Cypress.
Все зеленые, и видны щелчки происходит только после появления текста «Готово».

  1. ПОСЕТИТЬ кнопки приложения / iterate-table. html
  2. GET .instances__action
  3. GET tbody> tr: nth -child (1)> td: nth-child (1)> кнопка
  4. CLICK
  5. СОДЕРЖИТ tbody> tr: nth-child (1)> td: nth-child (2)> span, Finished
  6. GET tbody> tr: nth-child (2)> td: nth-child (1)> кнопка
  7. CLICK
  8. СОДЕРЖИТ tbody> tr: nth -child (2)> td: nth-child (2)> span, Finished

Журнал консоли

Вот так выглядят журналы консоли.

l oop выполняется до завершения даже до очереди команд начинается, но это нормально, потому что команды все еще выполняются в правильном порядке.

начало # 0
начало # 1
нажатие # 0
подтверждение # 0
нажатие # 1
утверждая # 1

...