Разбираемся с DevTools в Selenium 4

Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті.

Один из самых популярных инструментов UI автоматизации — Selenium, готовит к релизу мажорное обновление. На момент написания статьи выпущена вторая бета.

В состав релиза входит API для работы с DevTools через CDP (Chrome DevTools Protocol), который выводит взаимодействие с браузером на новый уровень.

Инструментарий DevTools разделен на блоки (DOM, Debugger, Network etc.), каждый из которых определяет список поддерживаемых команд и генерируемых ивентов.

Selenium позволяет напрямую работать с каждым, что дает возможность:

  • работать с кэшем браузера
  • перехватывать и модифицировать запросы
  • эмулировать состояние сети
  • устанавливать геолокацию
  • обходить security ограничения
  • считывать браузерные метрики

Драйвер, который поддерживает работу с инструментами разработчика, реализует getDevTools() метод, а выполнять CDP команды можно непосредственно работая с объектом DevTools.

Для каждого блока команд предусмотрены классы обертки. Чтобы отправить команду достаточно создать сессию и вызвать devTools.send(Command<X> command).

DevTools devTools = driver.getDevTools();
devTools.createSession();
List<Cookie> cookies = devTools.send(Network.getAllCookies());

Еще один способ — вызвать метод executeCdpCommand(), который реализован у наследников ChromiumDriver и работает не с обертками, а raw командами. Аргументы метода — название операции и перечень параметров.

Map<String, Object> data = driver.executeCdpCommand("Network.getAllCookies", new HashMap<>());
List<Cookie> cookies = (List<Cookie>) data.get("cookies");

Используем новые возможности на практике

Переопределение UserAgent

До Selenium 4 UserAgent устанавливался только через capabilities, до создания объекта драйвера.
Network.setUserAgentOverride задает новое значение UserAgent на лету.

devTools.send(Network.setUserAgentOverride("aqa-agent", Optional.empty(), Optional.empty(), Optional.empty()));

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

Для некоторых операций, браузер запрашивает разрешение пользователя, например, для доступа к буферу обмена или микрофону. Предоставить права можно при помощи Browser.grantPermissions передавая перечень необходимых PermissionType.

Для примера разрешим браузеру захват звука.

driver.executeCdpCommand("Browser.grantPermissions", Map.of("permissions", asList("audioCapture")));

Добавление заголовков в запросы

Network.setExtraHTTPHeaders позволяет добавить кастомные заголовки к запросам.

devTools.send(Network.enable(empty(),empty(),empty()));
devTools.send(Network.setExtraHTTPHeaders(new Headers(Map.of("aqa-header", "John Wick"))));

Перехват и модификация запросов

Fetch.enable включает перехват, каждый запрос будет остановлен пока клиент не вызовет failRequest, fulfillRequest или continueRequest.
Перехватывать можно все запросы и модифицировать по условию, либо работать только с целевыми, указав для этого RequestPattern, ниже приведены оба варианта.

Модифицируем URL, например перенаправим запросы /v1/users на новую версию бэкенда /v2/users.

devTools.send(Fetch.enable(empty(), empty()));
devTools.addListener(Fetch.requestPaused(), request -> {
   
   String url = request.getRequest().getUrl().contains("/v1/users")
          ? request.getRequest().getUrl().replace("/v1/users", "/v2/users")
          : request.getRequest().getUrl();

   devTools.send(Fetch.continueRequest(
                               request.getRequestId(),
                               Optional.of(url),
                               Optional.of(request.getRequest().getMethod()),
                               request.getRequest().getPostData(),
                               request.getResponseHeaders()));
});

Аналогичным способом эмулируется неудачный запрос. Например для тестирования работы приложения с отвалившейся интеграцией.

Optional<List<RequestPattern>> patterns = Optional.of(asList(new RequestPattern(of("*.dropbox.*"), empty(), empty())));
devTools.send(Fetch.enable(patterns, empty()));
devTools.addListener(Fetch.requestPaused(), r -> devTools.send(Fetch.failRequest(r.getRequestId(), FAILED)));

Эмуляция интернет соединения

Network.emulateNetworkConditions позволяет задавать параметры соединения, например для тестирования поведения при слабом 3G или отсутствии сети.

devTools.send(Network.enable(empty(), empty(), empty()));
devTools.send(Network.emulateNetworkConditions(false, 100, 1000, 1000, of(ConnectionType.CELLULAR3G)));

Очистка кэша

Network.clearBrowserCache очистит кэш браузера.

devTools.send(Network.clearBrowserCache());

Блокировка загрузки ресурсов

Через Network.setBlockedURLs можно ограничишь загрузку ресурсов по паттерну. Например, заблокируем скачивание .svg

devTools.send(Network.enable(empty(), empty(), empty()));
devTools.send(Network.setBlockedURLs(List.of("*.svg")));

Установка TimeZone и Geolocation Position

Emulation.setTimezoneOverride переопределяет TimeZone браузера, а Emulation.setGeolocationOverride геопозицию.

devTools.send(Emulation.setTimezoneOverride("America/New_York"));
devTools.send(Emulation.setGeolocationOverride(Optional.of(40.730610), Optional.of(-73.935242), Optional.of(1)));

Обход ограничений безопасности

Security.setIgnoreCertificateErrors позволит обойти проблемы с SSL сертификатом. Отмечу, что не призываю к таким действиям, а показываю наличие возможности.

devTools.send(Security.enable());
devTools.send(Security.setIgnoreCertificateErrors(true));

Метрики

Performance.enable включает сбор метрик (Resources, Documents, JSHeapUsedSize etc.), а Performance.getMetrics возвращает текущие значения.

devTools.send(Performance.enable(empty()));
List<Metric> send = devTools.send(Performance.getMetrics());

Итоги

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

API для работы с инструментами разработчика делает Selenium еще мощнее, открывая возможности настроек, кастомизации, эмуляции, перехвата трафика, отслеживания ивентов и метрик.

Функционал DevTools добавит в тесты гибкости, сделает прекондишены проще, а репортинг и причины падений информативнее.

Ожидаем выхода официального релиза.

👍НравитсяПонравилось12
В избранноеВ избранном10
LinkedIn
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Додавання хедерів то прям супер
Дякую за статтю!

Это прекрасно, так и необходимость в puppeteer отпадает сама собой

Приведены реально востребованные примеры, спасибо за статью.

Подписаться на комментарии