События CDP

Puppeteer предоставляет высокоуровневый API для автоматизации браузера, но его мощь во многом строится на взаимодействии с Chrome DevTools Protocol (CDP). CDP позволяет получать события, связанные с жизненным циклом страницы, сетью, DOM, производительностью и другими аспектами браузера. Понимание работы событий CDP расширяет возможности тестирования и мониторинга веб-приложений.


Подключение к CDP

Для работы с CDP Puppeteer предоставляет метод page.target().createCDPSession(). Он создаёт сессию, через которую можно отправлять команды и подписываться на события.

const puppeteer = require(&

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

  const client = await page.target().createCDPSession();
  
  await client.send('Network.enable'); // Включение отслеживания сети

  client.on('Network.requestWillBeSent', (event) => {
    console.log('Запрос отправлен:', event.request.url);
  });

  await page.goto('https://example.com');
})();

Ключевой момент: события CDP напрямую не привязаны к API Puppeteer, а приходят через сессию CDP. Это позволяет получать более низкоуровневую и детализированную информацию, недоступную через стандартные методы page.on().


Основные категории событий CDP

  1. События сети (Network) Позволяют отслеживать все HTTP/HTTPS запросы и ответы, включая редиректы, ошибки и метаданные запросов.

    • Network.requestWillBeSent – событие перед отправкой запроса.
    • Network.responseReceived – когда браузер получил ответ.
    • Network.loadingFinished – когда загрузка ресурса завершена.
    • Network.loadingFailed – при ошибке загрузки.

    Пример фильтрации конкретных запросов:

    client.on('Network.responseReceived', (event) => {
      if (event.response.url.includes('api')) {
        console.log('API ответ:', event.response.status);
      }
    });
  2. События страницы (Page) Позволяют отслеживать навигацию, ошибки JavaScript и изменения состояния страницы.

    • Page.frameNavigated – вызов при навигации фрейма.
    • Page.javascriptDialogOpening – событие открытия диалога alert, confirm, prompt.
    • Page.loadEventFired – событие полной загрузки страницы.

    Пример обработки алерта:

    client.on('Page.javascriptDialogOpening', async (event) => {
      console.log('Диалог открыт с сообщением:', event.message);
      await client.send('Page.handleJavaScriptDialog', { accept: true });
    });
  3. События DOM (DOM) Позволяют следить за изменениями структуры документа, добавлением элементов или удалением узлов.

    • DOM.documentUpdated – вызов при обновлении всего документа.
    • DOM.setChildNodes – уведомление о добавлении дочерних узлов.

    Это особенно полезно для тестирования динамических интерфейсов и SPA.

  4. События производительности (Performance) Позволяют собирать метрики рендеринга, загрузки ресурсов, задержек и FPS.

    • Performance.metrics – периодическая отправка метрик страницы.
    • Tracing.dataCollected – события при записи трейсинга производительности.

Обработка и фильтрация событий

Поскольку событий может быть очень много, важно уметь их фильтровать и обрабатывать асинхронно. Для этого используют функции обратного вызова с проверкой свойств события:

client.on('Network.requestWillBeSent', (event) => {
  if (event.request.url.endsWith('.js')) {
    console.log('JS файл загружается:', event.request.url);
  }
});

Для асинхронной обработки большого числа событий часто используют очереди или Promise.all(), чтобы не блокировать основной поток выполнения.


Практические сценарии использования событий CDP

  1. Тестирование производительности Подключение к CDP и отслеживание метрик загрузки позволяет измерять время ответа, рендеринг страницы и сетевые задержки.

  2. Мониторинг сетевых запросов Позволяет проверять, какие API вызываются, корректность ответов и статус кода. Это важно для интеграционных тестов.

  3. Автоматическая обработка JavaScript-диалогов Позволяет тестировать поведение страницы при появлении alert, confirm или prompt.

  4. Отслеживание изменений DOM Полезно при тестировании SPA или динамически загружаемого контента.


Советы по работе с событиями CDP

  • Всегда включать нужные домены через client.send(‘Domain.enable’), иначе события приходить не будут.
  • Сохранять ссылки на сессию CDP, чтобы иметь возможность отписаться от событий при необходимости.
  • Использовать фильтры на стороне обработчика, чтобы снизить нагрузку при большом потоке данных.
  • Совмещать события CDP с высокоуровневыми событиями Puppeteer (page.on) для комплексного тестирования.

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