Таймауты и их настройка

Таймауты в Cypress — это критически важный инструмент для управления временем ожидания различных операций, таких как загрузка страниц, поиск элементов, выполнение асинхронных действий и запросов к серверу. Правильная настройка таймаутов обеспечивает стабильность тестов и предотвращает ложные ошибки, вызванные временными задержками.


Виды таймаутов в Cypress

  1. Command Timeout (defaultCommandTimeout) Определяет максимальное время ожидания выполнения команды Cypress, например cy.get() или cy.click(). Если элемент не найден или действие не выполнено в течение указанного времени, тест завершится с ошибкой.

    Пример настройки на уровне конфигурации:

    // cypress.config.js
    module.exports = {
      e2e: {
        defaultCommandTimeout: 8000, // 8 секунд
      }
    }

    Можно переопределить таймаут для конкретной команды:

    cy.get('.submit-button', { timeout: 10000 }).click();
  2. Page Load Timeout (pageLoadTimeout) Таймаут ожидания полной загрузки страницы после вызова cy.visit(). По умолчанию равен 60 секунд. Если страница не загружается за указанное время, тест будет прерван.

    Настройка в конфиге:

    pageLoadTimeout: 120000 // 2 минуты
  3. Response Timeout (responseTimeout) Влияет на время ожидания ответа от сервера при использовании cy.request() или при автоматическом ожидании сетевых запросов (cy.intercept()).

    Пример:

    cy.request({ url: '/api/data', timeout: 15000 }).then((response) => {
      expect(response.status).to.eq(200);
    });
  4. Retry Timeout (retries) Позволяет автоматически повторять тесты при временных сбоях. Часто используется вместе с таймаутами для повышения стабильности тестов.

    Настройка на уровне теста:

    it('повторяемый тест', { retries: 2 }, () => {
      cy.get('.dynamic-element').should('be.visible');
    });

Механизм ожидания и повторов

Cypress использует встроенный механизм retries для команд с ожиданием. Команды вроде cy.get(), cy.contains(), cy.should() будут периодически проверять условие до истечения таймаута.

Принципы работы:

  • Cypress проверяет состояние элемента каждые 50 мс (интервал фиксирован).
  • Если условие выполнено, команда завершается сразу.
  • Если таймаут истёк, тест падает с подробным сообщением об ошибке.

Пример ожидания появления элемента:

cy.get('.notification', { timeout: 10000 })
  .should('contain.text', 'Успешно');

В этом случае Cypress будет проверять наличие текста каждую 50-ю миллисекунду в течение 10 секунд.


Таймауты в асинхронных тестах

Асинхронные операции, такие как загрузка данных через API или динамическая подгрузка элементов, требуют корректной настройки таймаутов. Без увеличения таймаута часто возникают фальшивые падения тестов.

Пример ожидания загрузки списка после API-запроса:

cy.intercept('GET', '/api/items').as('getItems');
cy.visit('/items');
cy.wait('@getItems', { timeout: 15000 });
cy.get('.item').should('have.length.greaterThan', 0);

Здесь cy.wait() ждет завершения сетевого запроса до 15 секунд.


Локальная и глобальная настройка таймаутов

  • Глобальная — в cypress.config.js, влияет на все тесты.
  • Локальная — через опции команды или теста (timeout, retries), позволяет настраивать таймаут для конкретного случая.

Пример сочетания:

// глобально
defaultCommandTimeout: 5000

// локально для одной команды
cy.get('.slow-element', { timeout: 20000 }).should('be.visible');

Советы по оптимальной настройке таймаутов

  1. Не использовать чрезмерно большие таймауты — это увеличивает время выполнения тестового набора. Лучше разнести ожидания локально.
  2. Использовать cy.intercept() для асинхронных операций — позволяет точно контролировать сетевые задержки и уменьшить общие таймауты.
  3. Комбинировать с retries — помогает справляться с нестабильными окружениями, особенно в CI/CD.
  4. Логирование — включение детального логирования помогает понять, какие таймауты реально исчерпываются и где тесты зависают.

Особенности работы с динамическим контентом

Для элементов, которые появляются с задержкой, стандартный таймаут команд может быть недостаточным. Использование цепочек should() с увеличенным таймаутом — лучший подход.

Пример:

cy.get('.lazy-load', { timeout: 20000 })
  .should('be.visible')
  .and('contain.text', 'Загружено');

Также можно комбинировать с cy.wait() для ожидаемого события или ответа сервера, что делает тест более стабильным без увеличения глобальных таймаутов.


Взаимодействие таймаутов и ошибок

При превышении таймаута Cypress генерирует детализированную ошибку, включающую:

  • описание команды,
  • ожидаемое состояние,
  • фактическое состояние элемента,
  • полный стек вызовов.

Это позволяет быстро определить причину падения и корректировать таймауты локально, не увеличивая глобальные значения без необходимости.


Настройка таймаутов в Cypress — это баланс между стабильностью тестов и скоростью их выполнения. Комбинирование глобальных параметров, локальных таймаутов для команд и повторов позволяет создавать надежные автоматизированные сценарии даже для сложных асинхронных интерфейсов.