Запускаем Selenium Grid с BrowserMob-Proxy в автоматизированных тестах на Java

BrowserMob-Proxy - достаточно популярный инструмент, решающий задачи захвата и/или управления траффиком в автоматизированных тестах на Selenium. В этой своей статье я показываю пример применения такого инструмента в случае, когда все компоненты решения размещаются на одном хосте.

Однако в некоторых случаях требуется использовать BrowserMob-Proxy в распределенной топологии Selenium Grid. В этой статье я расскажу о способе интеграции прокси в такого рода среды.

Как работает решение "всё в одном"

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

Selenium with BrowserMob Proxy

Вы запускаете свой автоматизированный тест, который, в свою очередь, запускает экземпляр прокси-сервера и конфигурирует веб браузер для использования запущенного прокси-сервера. Всё работает гладко, т.к. в данном случае отсутствует фактическое сетевое взаимодействие - все компоненты обращаются к localhost.

В схеме также может присутствовать опциональный компонент - например, вам может быть разрешен доступ во внешнюю сеть только через дополнительный корпоративный прокси. В таком случае вы "сцепляете" ваш экземпляр BrowserMob-Proxy с верхнеуровневым прокси при помощи специального метода.

Чем отличается распределённое решение

Когда вы запускаете автоматизированные тесты в Selenium Grid разные компоненты решения, как правило, запускаются на разных хостах. В том числе, код автоматизированного теста и браузер, в котором этот тест исполняется также разнесены. Схематично всё выглядит так:

Selenium Grid with BrowserMob Proxy

Вы запускаете свой автоматизированный тест на машине Host A. Ваш код стартует экземпляр прокси-сервера на той же самой машине. Ваш код посылает команды в hub-компонент, который запущен на отдельном хосте - Host GH, который в свою очередь диспатчит сообщения подходящему узлу. Например, для некоторого запуска такой узел может располагаться на хосте Host GN_1.

Каждый узел имеет собственный WebDriver (а иногда и несколько разных драйверов) и собственный браузер, который запускается на хосте узла. Вы не можете запустить прокси на Host GN_1 из тестового кода на Host A. Поэтому решением будет сконфигурировать браузер на узле таким образом, чтобы он использовал прокси, запущенный на Host A.

BrowserMob-Proxy предоставляет REST API, позволяющий конфигурировать прокси удаленно. Так, альтернативным решением может стать конфигурирование хостов узлов таким образом, чтобы каждый узел имел бы постоянно запущенный собственный экземпляр прокси-сервера, который бы настраивался из тестового кода через REST API. Однако, такое решение требует довольно больших усилий по настройке и поддержке, поэтому здесь мы его рассматривать не будем.

Конфигурируем прокси из тестового кода

Для того чтобы реализовать предложенное решение, при настройке BrowserMob-Proxy в вашем автоматизированном тесте, необходимо обратить внимание на ряд деталей. Посмотрите на пример ниже:

public void setUp() {
    BrowserMobProxy proxy = new BrowserMobProxyServer();
    proxy.start(12345);
    ChromeOptions options = new ChromeOptions();
    options.setProxy(ClientUtil.createSeleniumProxy(new InetSocketAddress("192.168.1.2", 12345)));
    try {
        driver = new RemoteWebDriver(new URL("http://your-hub-host:4444/wd/hub"), options);
    } catch (MalformedURLException e) {
        e.printStackTrace();
    }
}

В примере мы используем new InetSocketAddress("192.168.1.2", 12345) в качестве параметра, передаваемого в метод ClientUtil.createSeleniumProxy(..), где вместо 192.168.1.2 вы должны указать IP-адрес того сетевого интерфейса, который используется для взаимодействия с остальными компонентами грида. Также поменяйте 12345 на порт, который планируете использовать для запуска прокси-сервера, а your-hub-host замените на действительный адрес, где хостится hub-компонент грида.

Почему мы используем статичный порт вместо того чтобы разрешить BrowserMob-Proxy выбрать порт случайно при запуске? Мы коснемся этого момента в следующей секции.

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

Что еще надо иметь в виду

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

  1. Хост, где запускается ваш тестовый код, должен быть виден для узлов грида (IP-адрес должен пинговаться)

  2. Порт, используемый экземпляром прокси-сервера, должен быть доступен во время запуска прокси-сервера.

  3. Порт, используемый экземпляром прокси-сервера, должен быть доступен извне (не должен быть скрыт файрволом). Вот почему в своем примере я использую статичный порт - так проще управлять правилами файрвола.

  4. Локальный порт, используемый для соединения браузера и прокси, не должен блокироваться файрволом на узле грида, а также должен быть доступен для исходящих пакетов на хосте, где запускается код.

Вот вроде бы и всё. Если у вас остались вопросы, задавайте их тут. Я постараюсь дополнить статью опираясь на ваши замечания.