waitForResponse и waitForRequest

Puppeteer — это мощная библиотека для автоматизации браузера, которая предоставляет разработчикам и тестировщикам удобные инструменты для взаимодействия с веб-страницами. Одной из ключевых задач при тестировании и автоматизации является правильная работа с сетевыми запросами и их откликами. Puppeteer предоставляет несколько методов для контроля этого процесса, среди которых важную роль играют функции waitForResponse и waitForRequest.

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

Метод waitForResponse позволяет дождаться завершения определенного HTTP-запроса, отправленного страницей. Это может быть полезно в ситуациях, когда необходимо выполнить действия только после того, как определенные данные были успешно загружены. Например, можно дождаться ответа на запрос, чтобы затем проверить корректность работы интерфейса, или дождаться получения данных с сервера перед выполнением дальнейших действий.

Синтаксис:

page.waitForResponse(urlOrPredicate[, options])
  • urlOrPredicate — это либо строка с URL, либо функция-предикат, которая должна вернуть true или false в зависимости от ответа.
  • options — объект с дополнительными параметрами (например, таймаут или опции запроса).

Метод возвращает промис, который разрешается, когда сервер возвращает ответ на указанный запрос.

Пример использования waitForResponse:
const puppeteer = require(&

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  page.on('response', response => {
    console.log(`Received response: ${response.url()}`);
  });

  // Навигация к странице
  await page.goto('https://example.com');

  // Ожидание ответа на конкретный запрос
  await page.waitForResponse(response =>
    response.url().includes('data') && response.status() === 200
  );

  console.log('Response received, continuing...');
  await browser.close();
})();

В этом примере мы дожидаемся ответа на запрос, содержащий в URL подстроку data, и проверяем, что статус ответа равен 200 (успешный запрос).

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

Метод waitForRequest аналогичен методу waitForResponse, но используется для ожидания отправки HTTP-запроса. Этот метод полезен, когда нужно зафиксировать момент отправки запроса на сервер, например, для дальнейшего анализа или проверки.

Синтаксис:

page.waitForRequest(urlOrPredicate[, options])
  • urlOrPredicate — аналогично методу waitForResponse, это либо строка с URL, либо функция, которая возвращает true или false, если запрос удовлетворяет условиям.
  • options — объект с дополнительными параметрами, аналогичный параметрам waitForResponse.

Метод возвращает промис, который разрешается, когда запрос, удовлетворяющий условиям, был отправлен.

Пример использования waitForRequest:
const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  page.on('request', request => {
    console.log(`Request made to: ${request.url()}`);
  });

  // Навигация к странице
  await page.goto('https://example.com');

  // Ожидание отправки запроса
  await page.waitForRequest(request =>
    request.url().includes('submit') && request.method() === 'POST'
  );

  console.log('Request sent, continuing...');
  await browser.close();
})();

В данном примере тестируется момент отправки POST-запроса, содержащего подстроку submit в URL.

Использование waitForRequest и waitForResponse с условиями

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

Пример с использованием регулярных выражений:

await page.waitForResponse(response =>
  /api\/.*\/users/.test(response.url()) && response.status() === 200
);

В этом примере мы ждем ответа от запроса, URL которого соответствует регулярному выражению, и проверяем, что статус ответа равен 200.

Параллельное использование waitForRequest и waitForResponse

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

Пример:

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  page.on('request', request => {
    console.log(`Request made: ${request.url()}`);
  });

  page.on('response', response => {
    console.log(`Response received: ${response.url()}`);
  });

  // Навигация к странице
  await page.goto('https://example.com');

  // Ожидаем сначала отправку запроса
  await page.waitForRequest(request => request.url().includes('data') && request.method() === 'GET');

  // Затем ожидаем получения ответа на запрос
  await page.waitForResponse(response => response.url().includes('data') && response.status() === 200);

  console.log('Request and response completed');
  await browser.close();
})();

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

Тайм-ауты и обработка ошибок

Оба метода, waitForResponse и waitForRequest, поддерживают настройку тайм-аутов, что позволяет контролировать максимальное время ожидания. Если ответ или запрос не приходят в течение заданного времени, промис будет отклонен с ошибкой.

Пример с настройкой тайм-аута:

await page.waitForResponse(response => response.status() === 200, {
  timeout: 5000, // Ожидание не более 5 секунд
});

В этом примере мы ожидаем ответ со статусом 200, но если ответ не приходит в течение 5 секунд, будет выброшена ошибка.

Совмещение с другими методами Puppeteer

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

Пример комбинированного использования с waitForSelector:

await page.waitForResponse(response =>
  response.url().includes('api') && response.status() === 200
);
await page.waitForSelector('#data-loaded');

В этом примере сначала ожидается ответ на API-запрос, а затем проверяется наличие элемента на странице, который появляется только после загрузки данных.

Заключение

Методы waitForRequest и waitForResponse являются неотъемлемой частью эффективного тестирования с использованием Puppeteer. Они позволяют точно синхронизировать выполнение сценариев с отправкой запросов и получением ответов, обеспечивая возможность тестировать динамичные веб-приложения с асинхронными запросами. Возможность использования функций-предикатов, тайм-аутов и комбинирования с другими методами открывает широкие возможности для создания гибких и устойчивых тестов.