Ожидание завершения запросов

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

Перехват сетевых запросов

Для отслеживания запросов используется метод cy.intercept(). Он позволяет перехватывать HTTP-запросы и модифицировать их или проверять после выполнения. Основные параметры:

cy.intercept(method, url, response)
  • method — HTTP-метод запроса (GET, POST, PUT, DELETE и др.).
  • url — URL или паттерн запроса, который необходимо перехватить.
  • response — опциональный объект, позволяющий подменить ответ сервера.

Пример перехвата GET-запроса:

cy.intercept('GET', '/api/users').as('getUsers');

Использование as('getUsers') создает псевдоним запроса, что позволяет ссылаться на него в дальнейшем с помощью cy.wait().

Ожидание завершения запросов

Метод cy.wait() позволяет ожидать завершения запроса перед выполнением последующих действий:

cy.wait('@getUsers').then((interception) => {
  expect(interception.response.statusCode).to.eq(200);
  expect(interception.response.body).to.have.length.greaterThan(0);
});

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

  • cy.wait('@alias') приостанавливает выполнение теста до завершения перехваченного запроса.
  • Можно проверять свойства запроса и ответа через объект interception.
  • Поддерживается множественное ожидание: cy.wait(['@req1', '@req2']).

Проверка последовательности запросов

В сложных сценариях важно контролировать порядок выполнения запросов. Cypress позволяет использовать цепочку ожиданий:

cy.intercept('POST', '/api/login').as('login');
cy.intercept('GET', '/api/dashboard').as('dashboard');

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

cy.wait('@login').its('response.statusCode').should('eq', 200);
cy.wait('@dashboard').its('response.body').should('include', { user: 'admin' });

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

Тайм-ауты и повторные попытки

Cypress автоматически управляет тайм-аутами и повторными попытками ожидания. По умолчанию cy.wait() ждет до 30 секунд, если запрос не завершен, тест падает. Тайм-аут можно изменить:

cy.wait('@getUsers', { timeout: 10000 });

Также можно комбинировать ожидание с условными проверками через should:

cy.wait('@getUsers').its('response.statusCode').should('eq', 200);

Метод should будет повторяться, пока условие не выполнится или не истечет тайм-аут.

Модификация и контроль ответов

cy.intercept() позволяет не только ждать запросы, но и управлять ответами:

cy.intercept('GET', '/api/users', {
  statusCode: 200,
  body: [{ id: 1, name: 'Тестовый пользователь' }],
}).as('getUsers');

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

Практика асинхронного взаимодействия

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

  • Дождаться завершения запроса перед проверкой DOM.
  • Проверить статус ответа и корректность данных.
  • Синхронизировать несколько параллельных запросов.
  • Моделировать различные сценарии сервера через подмену ответов.

Пример проверки обновления таблицы после POST-запроса:

cy.intercept('POST', '/api/users').as('addUser');
cy.intercept('GET', '/api/users').as('getUsers');

cy.get('button.add-user').click();
cy.wait('@addUser').its('response.statusCode').should('eq', 201);
cy.wait('@getUsers').its('response.body').should('have.length', 1);
cy.get('table tbody tr').should('have.length', 1);

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

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

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