Автоматическое ожидание в Cypress

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

Принцип работы автоматического ожидания

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

Пример:

cy.get('#submit-button').click();

Если кнопка #submit-button ещё не появилась на странице, Cypress продолжит попытки найти её до истечения таймаута. Это делает тесты устойчивыми к задержкам загрузки элементов или асинхронным операциям.

Команды, поддерживающие автоматическое ожидание

Не все команды ведут себя одинаково. Основные типы команд с автоматическим ожиданием:

  • Поиск элементов: cy.get(), cy.contains(), cy.find().
  • Утверждения: should(), and().
  • Взаимодействие с элементами: click(), type(), select().

Пример использования утверждений с автоматическим ожиданием:

cy.get('.notification')
  .should('be.visible')
  .and('contain.text', 'Успешно сохранено');

Cypress будет повторять проверку .should('be.visible') и .and('contain.text', 'Успешно сохранено') до тех пор, пока условие не станет истинным или не истечёт таймаут.

Настройка таймаутов

Каждая команда и утверждение имеют индивидуальный таймаут, который можно переопределить:

cy.get('#loader', { timeout: 10000 }).should('not.exist');

Здесь Cypress будет ожидать до 10 секунд, пока элемент с id loader исчезнет со страницы.

Также можно глобально изменить таймауты для всех команд через конфигурацию:

Cypress.config('defaultCommandTimeout', 8000);
Cypress.config('pageLoadTimeout', 60000);

Полезные паттерны с автоматическим ожиданием

  1. Ожидание появления элемента перед взаимодействием
cy.get('#username').should('be.visible').type('admin');
cy.get('#password').should('be.visible').type('123456');
cy.get('#login').should('not.be.disabled').click();

Здесь Cypress автоматически дождётся, пока поля станут видимыми и кнопка активной.

  1. Ожидание исчезновения элементов
cy.get('.spinner').should('not.exist');
cy.get('.content').should('be.visible');

Подход полезен при работе с асинхронными загрузками данных.

  1. Комбинированные проверки состояния
cy.get('.alert')
  .should('exist')
  .and('have.class', 'alert-success')
  .and('contain.text', 'Операция выполнена');

Все условия будут проверяться автоматически в цикле до выполнения или таймаута.

Отличие от явного ожидания

Использование cy.wait() или setTimeout() создаёт жёсткую задержку, которая замедляет тесты и делает их менее гибкими. Автоматическое ожидание работает адаптивно, проверяя состояние элемента столько раз, сколько нужно, что обеспечивает скорость и надёжность.

Автоматическое ожидание запросов

Cypress поддерживает ожидание сетевых запросов через cy.intercept():

cy.intercept('GET', '/api/data').as('getData');
cy.visit('/dashboard');
cy.wait('@getData').its('response.statusCode').should('eq', 200);

Cypress автоматически ждёт завершения запроса до проверки ответа, исключая необходимость ручного wait.

Ограничения автоматического ожидания

  • Cypress повторяет только асинхронные команды и утверждения, но не произвольный код JavaScript.
  • Команды, возвращающие примитивные значения (например, .then() с вычислением числа), не поддерживают автоматическое ожидание.
  • Необходимо избегать смешивания Cypress с внешними таймерами или jQuery-анимациями без синхронизации, так как Cypress может не распознать момент готовности элемента.

Итоговые рекомендации по использованию

  • Использовать встроенное ожидание через cy.get() и .should(), избегая жёстких задержек.
  • Настраивать таймауты локально для команд с потенциально долгой загрузкой элементов.
  • Сочетать ожидание элементов с ожиданием сетевых запросов через cy.intercept().
  • Проверять видимость, доступность и содержимое элемента перед взаимодействием.

Автоматическое ожидание в Cypress является фундаментальной особенностью, обеспечивающей надёжность тестов и устойчивость к асинхронным процессам, что особенно важно для современных веб-приложений с динамическим контентом.