Отладка тестов через DevTools

WebdriverIO предоставляет гибкие возможности для интеграции с Chrome DevTools Protocol (CDP), что позволяет детально отслеживать выполнение тестов, анализировать сетевые запросы, работать с консолью браузера и управлять производительностью страницы. Использование DevTools открывает дополнительные методы диагностики и упрощает выявление ошибок в автоматизированных тестах.


Подключение DevTools к WebdriverIO

Для работы с DevTools необходимо установить пакет @wdio/devtools-service и добавить его в конфигурацию WebdriverIO.

// wdio.conf.js
exports.config = {
    services: ['devtools'],
    capabilities: [{
        browserName: 'chrome',
        'goog:chromeOptions': {
            args: ['--headless=new', '--disable-gpu']
        }
    }],
};

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

  • services: ['devtools'] — подключает сервис DevTools к сессии WebdriverIO.
  • Опция headless=new позволяет запускать браузер без графического интерфейса, что важно для CI/CD.

После подключения DevTools становится доступен объект browser.cdp, через который выполняются команды CDP.


Работа с консолью и логами

CDP позволяет перехватывать сообщения консоли браузера и ошибки JavaScript. Это особенно полезно при тестировании фронтенд-логики.

await browser.cdp('Log', 'enable');

browser.on('Log.entryAdded', (entry) => {
    console.log('Console message:', entry.entry.text);
});

await browser.url('https://example.com');

Пояснение:

  • Log.enable активирует сбор логов браузера.
  • Событие Log.entryAdded срабатывает при каждом новом сообщении в консоли.
  • Таким образом можно отслеживать предупреждения, ошибки и кастомные логи, которые выбрасываются на странице.

Сетевые запросы и мониторинг трафика

CDP позволяет перехватывать все сетевые запросы и анализировать их статус, заголовки и тело ответа.

await browser.cdp('Network', 'enable');

browser.on('Network.requestWillBeSent', (params) => {
    console.log('Request URL:', params.request.url);
});

browser.on('Network.responseReceived', (params) => {
    console.log('Response status:', params.response.status, 'URL:', params.response.url);
});

await browser.url('https://example.com');

Особенности:

  • Network.enable включает отслеживание всех сетевых операций.
  • Событие requestWillBeSent фиксирует момент отправки запроса, а responseReceived — получения ответа.
  • Можно фильтровать запросы по URL, типу ресурса или статусу ответа для более точного анализа.

Снимки состояния DOM и производительности

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

const screenshot = await browser.takeScreenshot();
require('fs').writeFileSync('screenshot.png', screenshot, 'base64');

const metrics = await browser.cdp('Performance', 'getMetrics');
console.log(metrics.metrics);

Подробности:

  • takeScreenshot() позволяет создавать снимки экрана для визуальной проверки.
  • Performance.getMetrics возвращает ключевые показатели: время загрузки, скриптов, рендеринга.
  • Эти данные помогают выявлять узкие места в производительности и корректно синхронизировать тесты.

Точки остановки и пошаговое выполнение

Используя DevTools Protocol, можно включить дебаггер JavaScript и ставить точки останова прямо в коде страницы.

await browser.cdp('Debugger', 'enable');
await browser.cdp('Debugger', 'setPauseOnExceptions', { state: 'all' });

browser.on('Debugger.paused', async (params) => {
    console.log('Paused at:', params.callFrames[0].url, 'line:', params.callFrames[0].location.lineNumber);
    await browser.cdp('Debugger', 'resume');
});

await browser.url('https://example.com');

Важно:

  • setPauseOnExceptions позволяет приостановить выполнение при любой ошибке.
  • Debugger.paused даёт доступ к стеку вызовов и локальным переменным.
  • После анализа можно продолжить выполнение через Debugger.resume.

Инспекция элементов и манипуляция DOM

CDP обеспечивает прямой доступ к элементам страницы без использования стандартных WebDriver команд.

const { nodeId } = await browser.cdp('DOM', 'getDocument');
const element = await browser.cdp('DOM', 'querySelector', { nodeId, selector: '#login' });
await browser.cdp('DOM', 'setAttributeValue', { nodeId: element.nodeId, name: 'value', value: 'testuser' });

Пояснение:

  • DOM.getDocument возвращает корень DOM.
  • DOM.querySelector позволяет искать элементы по CSS-селекторам.
  • DOM.setAttributeValue даёт возможность изменять атрибуты элементов напрямую, что удобно для симуляции действий или исправления состояния страницы в тестах.

Логирование и хранение данных для последующего анализа

Реализация сложных тестов часто требует хранения сетевых и консольных данных для последующего анализа. Пример:

const logs = [];
browser.on('Log.entryAdded', (entry) => logs.push(entry.entry));
browser.on('Network.responseReceived', (params) => logs.push(params.response));

await browser.url('https://example.com');

// Сохранение в файл для анализа
require('fs').writeFileSync('test_logs.json', JSON.stringify(logs, null, 2));

Особенности:

  • Позволяет создавать комплексные отчёты по каждому тесту.
  • Объединяет логи разных источников: консоль, сеть, производительность.
  • Дает возможность проводить постфактум анализ проблем, которые сложно воспроизвести вручную.

Использование DevTools в WebdriverIO открывает глубинный контроль над браузером, расширяет стандартные возможности WebDriver и позволяет строить высоконадежные, легко отлаживаемые тесты. Детальное взаимодействие с логами, сетью, DOM и производительностью значительно ускоряет процесс выявления и исправления ошибок.