Ожидание элементов и условий

Cypress отличается от традиционных инструментов тестирования тем, что встроенная система ожиданий делает большинство асинхронных операций прозрачными для разработчика. Основное отличие заключается в автоматическом повторении команд и проверок до тех пор, пока не истечёт таймаут. Это позволяет избегать использования явных sleep и упрощает работу с динамическим контентом.


Автоматические ожидания (Implicit Waits)

В Cypress каждая команда автоматически повторяется, пока выполняется проверка условия:

cy.get('.button').click();

Команда get будет повторяться, пока элемент с классом .button не появится в DOM или не истечёт таймаут (по умолчанию 4 секунды). Это позволяет писать более стабильные тесты без ручного ожидания.

Ключевые моменты:

  • Таймауты можно настраивать через опцию timeout:
cy.get('.button', { timeout: 10000 }).should('be.visible');
  • Проверки через should также повторяются до выполнения условия или истечения таймаута.
  • Автоматическое ожидание работает с асинхронными элементами, которые появляются после загрузки страницы, запросов API или взаимодействий пользователя.

Явные ожидания (Explicit Waits)

В некоторых случаях требуется контролировать ожидание более гибко. Cypress предоставляет методы cy.wait и cy.intercept для работы с асинхронными запросами.

Ожидание конкретного времени:

cy.wait(2000); // ждем 2 секунды

Использование фиксированных задержек рекомендуется минимизировать, так как они увеличивают время выполнения тестов и делают их менее стабильными.

Ожидание ответа API:

cy.intercept('GET', '/api/data').as('getData');
cy.visit('/dashboard');
cy.wait('@getData').its('response.statusCode').should('eq', 200);
  • cy.intercept позволяет следить за сетевыми запросами и проверять их статус и содержимое.
  • cy.wait('@alias') останавливает выполнение до получения ответа.

Проверка условий на элементы

Методы should и then используются для верификации состояния элементов:

cy.get('.notification').should('be.visible').and('contain', 'Успешно');
  • should автоматически повторяет проверку до истечения таймаута.
  • then выполняет колбэк один раз после нахождения элемента:
cy.get('.list-item').then(($items) => {
  expect($items).to.have.length.greaterThan(3);
});

Использование then подходит для более сложной логики проверки или манипуляций с элементами.


Комбинации ожиданий

Можно сочетать ожидания появления элементов и их состояния:

cy.get('input[name="email"]', { timeout: 5000 })
  .should('be.visible')
  .and('be.enabled')
  .type('user@example.com');
  • Проверяется одновременно видимость и возможность ввода.
  • Любое условие будет повторяться до истечения таймаута.

Таймауты и конфигурация ожиданий

Cypress позволяет глобально и локально настраивать таймауты:

  • Глобально через cypress.config.js:
module.exports = {
  defaultCommandTimeout: 8000,
  pageLoadTimeout: 60000
};
  • Локально через опции каждой команды:
cy.get('.modal', { timeout: 10000 }).should('exist');

Важно помнить, что слишком короткие таймауты могут привести к ложным падениям тестов, а слишком длинные — к увеличению времени выполнения.


Ожидание условий без элемента

Иногда необходимо дождаться выполнения какого-либо состояния приложения, не связанного с конкретным DOM-элементом:

cy.window().its('app.isLoaded').should('eq', true);
  • cy.window() возвращает объект окна браузера.
  • its позволяет проверять свойства объекта.
  • should автоматически повторяет проверку, что избавляет от необходимости писать ручные циклы ожидания.

Использование цепочек команд

Цепочки команд позволяют комбинировать несколько условий и действий, сохраняя простоту синтаксиса:

cy.get('.todo-item')
  .should('have.length', 5)
  .first()
  .should('contain', 'Купить хлеб')
  .find('input[type="checkbox"]')
  .check();
  • Каждая команда внутри цепочки наследует таймаут и повторяется при необходимости.
  • Позволяет строить компактные и выразительные проверки.

Советы по надежному ожиданию

  1. Предпочитать should вместо wait для асинхронных операций.
  2. Использовать cy.intercept для сетевых запросов, чтобы тест зависел от фактического состояния данных.
  3. Избегать фиксированных задержек, чтобы тесты оставались быстрыми и стабильными.
  4. Комбинировать проверки видимости, активности и содержимого элементов, чтобы избежать ложноположительных результатов.
  5. Настраивать таймауты разумно, учитывая скорость загрузки страницы и асинхронные операции.

Эффективное использование ожиданий в Cypress позволяет создавать стабильные, предсказуемые и быстрые тесты, даже в сложных интерфейсах с динамическим контентом. Автоматические повторения команд и проверок избавляют от большинства ошибок, связанных с асинхронностью, а правильная комбинация should, then и intercept обеспечивает полный контроль над состоянием элементов и приложения.