BrowserMob-Proxy - достаточно популярный инструмент, решающий задачи захвата и/или управления траффиком в автоматизированных тестах на Selenium. В этой своей статье я показываю пример применения такого инструмента в случае, когда все компоненты решения размещаются на одном хосте.
Однако в некоторых случаях требуется использовать BrowserMob-Proxy в распределенной топологии Selenium Grid. В этой статье я расскажу о способе интеграции прокси в такого рода среды.
Как работает решение "всё в одном"
Ниже представлена схема топологии компонентов, когда всё необходимое для теста, запускается на одной машине.
Вы запускаете свой автоматизированный тест, который, в свою очередь, запускает экземпляр прокси-сервера и конфигурирует веб браузер для использования запущенного прокси-сервера. Всё работает гладко, т.к. в данном случае отсутствует фактическое сетевое взаимодействие - все компоненты обращаются к localhost.
В схеме также может присутствовать опциональный компонент - например, вам может быть разрешен доступ во внешнюю сеть только через дополнительный корпоративный прокси. В таком случае вы "сцепляете" ваш экземпляр BrowserMob-Proxy с верхнеуровневым прокси при помощи специального метода.
Чем отличается распределённое решение
Когда вы запускаете автоматизированные тесты в Selenium Grid разные компоненты решения, как правило, запускаются на разных хостах. В том числе, код автоматизированного теста и браузер, в котором этот тест исполняется также разнесены. Схематично всё выглядит так:
Вы запускаете свой автоматизированный тест на машине 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 выбрать порт случайно при запуске? Мы коснемся этого момента в следующей секции.
Таким образом, реализовав подобную конфигурацию, мы заставим браузеры на узлах грида использовать прокси-сервер, поднятый на машине, где запускается тестовый код.
Что еще надо иметь в виду
Есть несколько моментов, которые необходимо учитывать при реализации подобной схемы.
-
Хост, где запускается ваш тестовый код, должен быть виден для узлов грида (IP-адрес должен пинговаться)
-
Порт, используемый экземпляром прокси-сервера, должен быть доступен во время запуска прокси-сервера.
-
Порт, используемый экземпляром прокси-сервера, должен быть доступен извне (не должен быть скрыт файрволом). Вот почему в своем примере я использую статичный порт - так проще управлять правилами файрвола.
-
Локальный порт, используемый для соединения браузера и прокси, не должен блокироваться файрволом на узле грида, а также должен быть доступен для исходящих пакетов на хосте, где запускается код.
Вот вроде бы и всё. Если у вас остались вопросы, задавайте их тут. Я постараюсь дополнить статью опираясь на ваши замечания.