Команда cy.wait()

Команда cy.wait() является одной из ключевых в арсенале инструментов Cypress для управления синхронизацией тестов. Она позволяет тестам корректно ожидать завершения асинхронных операций, будь то сетевые запросы, анимации, таймеры или задержки на стороне приложения. Понимание правильного применения cy.wait() критично для написания стабильных и предсказуемых тестов.


Основные формы использования cy.wait()

  1. Ожидание фиксированного времени
cy.wait(2000); // пауза на 2 секунды
  • Принимает значение в миллисекундах.
  • Используется для простых случаев, когда нужно дать приложению время на завершение процессов.
  • Недостаток: жесткая зависимость от времени может делать тесты медленными или ненадежными при изменении производительности среды.
  1. Ожидание сетевых запросов по алиасу
cy.intercept('GET', '/api/users').as('getUsers');
cy.visit('/users');
cy.wait('@getUsers');
  • Создание алиаса через cy.intercept() позволяет ожидать конкретный HTTP-запрос.
  • cy.wait('@alias') блокирует выполнение до получения ответа.
  • Можно указать таймаут:
cy.wait('@getUsers', { timeout: 10000 }); // ждём до 10 секунд
  • Возвращает объект ответа запроса, что удобно для проверки данных:
cy.wait('@getUsers').then((interception) => {
  expect(interception.response.statusCode).to.eq(200);
  expect(interception.response.body).to.have.length.greaterThan(0);
});
  1. Ожидание нескольких запросов одновременно
cy.wait(['@getUsers', '@getPosts']).then((responses) => {
  const usersResponse = responses[0];
  const postsResponse = responses[1];

  expect(usersResponse.response.statusCode).to.eq(200);
  expect(postsResponse.response.statusCode).to.eq(200);
});
  • Позволяет синхронизировать тест с несколькими параллельными запросами.

Особенности работы с таймаутами

  • По умолчанию Cypress ждёт 4 секунды для cy.wait('@alias').
  • Таймаут можно изменить как глобально, так и локально.
  • Глобальная настройка:
Cypress.config('defaultCommandTimeout', 10000);
  • Локальная настройка через опцию:
cy.wait('@getUsers', { timeout: 15000 });

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

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

Комбинированное использование с другими командами

cy.intercept('POST', '/api/login').as('loginRequest');
cy.get('#loginButton').click();
cy.wait('@loginRequest').then((interception) => {
  expect(interception.response.statusCode).to.eq(200);
});
cy.get('#dashboard').should('be.visible');
  • Здесь cy.wait() гарантирует, что переход на страницу дашборда произойдет только после успешного завершения запроса.

Особенности возврата значений

  • cy.wait() возвращает Chainable объект, что позволяет продолжать цепочку команд Cypress.
  • Для сетевых запросов это объект interception с подробной информацией о запросе и ответе.
  • Использование then() обеспечивает доступ к данным для последующих проверок.

Типичные ошибки при использовании cy.wait()

  1. Использование фиксированных таймеров вместо алиасов — делает тесты хрупкими.
  2. Неуказание алиаса после cy.intercept()cy.wait() не сможет ожидать конкретный запрос.
  3. Игнорирование возврата данных из cy.wait() — теряется возможность проверить статус и содержимое запроса.
  4. Слишком короткие таймауты при медленных API — тесты будут нестабильными.

Рекомендации по структуре теста

  • Сначала определять перехваты запросов (cy.intercept()).
  • Затем выполнять действия пользователя, которые запускают эти запросы.
  • После этого использовать cy.wait() для каждого запроса с последующей проверкой ответа.
  • После проверки запросов — проверять состояние интерфейса.

Расширенные возможности

  • Можно ожидать частично совпадающие URL:
cy.intercept('GET', '**/users*').as('getUsers');
cy.wait('@getUsers');
  • Поддержка регулярных выражений для динамических URL.
  • Совместное использование с retry-логикой Cypress, когда элемент или состояние может появляться асинхронно.

Эта команда является краеугольным камнем синхронизации в Cypress, позволяя создавать стабильные, предсказуемые и масштабируемые тесты при работе с динамическими веб-приложениями. Правильное сочетание cy.wait() с cy.intercept() и цепочкой команд Cypress обеспечивает надежность тестов без лишних искусственных задержек.