У меня на одной машине запускается java-код с selenium тестом. Но, браузер в котором выполняется тест - запускается в docker-контейнере, который запущен на другой машине. Организовано это при помощи RemoteWebDriver
.
Я нашел решение проблемы для File Uploads
. Чтобы получилось загружать файлы в браузере, который в контейнере, прямо с локальной машины где запущен java-код, нужна настройка driver.setFileDetector(new LocalFileDetector());
.
Вопрос, как организоваться File downloads
? Чтобы когда тест нажимал в браузере в контейнере на кнопку “Скачать” у файла. Он загрузился не в контейнере, а там где выполняется java-код. Хочу организовать всю работу с файлами локально, а не в контейнере. Контейнер нужен только для изоляции выполнения теста в браузере.
Или подскажите какие решения используете вы.
Сделай mount/volume папки в контейнере и папки с тестами
Я думаю что вы не правильно поняли вопрос. Я постарался более детально его описать.
Вы неверно поняли ответ Именно этот механиз и используется для работы с File downloads
. Прокиньте папку в которую сохраняются файлы (она или папка “по умолчанию” или прописана в конфигах) на свою машину где запускается код и работайте “локально”.
В Selenide реализованы три варианта скачивания файла, которые могут работать и в контейнере. Берите готовое решение и не изобретайте велосипед
Если используется Selenoid - то можно скачивать через специальное API:
Хочу использовать Selenide решение, но сталкиваюсь с ошибкой.
java.lang.IllegalStateException: config.proxyEnabled == true but proxy server is not created. You need to call `setWebDriver(webDriver, selenideProxy)` instead of `setWebDriver(webDriver)` if you need to use proxy.
Насколько я понял, такой ошибки не должно возникать и должно хватать объявлений
Configuration.proxyEnabled = true;
Configuration.fileDownload = PROXY;
Версию selenide использую последнюю. Что может быть не так?
Возможно, вы задаёте Configuration.proxyEnabled = true;
ПОСЛЕ того, как открыли браузер. А надо ДО.
Ну и вообще, тут важно, открываете ли вы браузер сами, или это делает селенид?
Пробовал сделать как вы подсказали тут Как правильно связать Selenide и Selenium Grid? - #11 от пользователя asolntsev , но получил ту же ошибку.
Мой код:
HashMap<String, Object> chromePrefs = new HashMap<>();
chromePrefs.put("profile.default_content_settings.popups", 0);
chromePrefs.put("download.prompt_for_download", false);
chromePrefs.put("download.default_directory", ConfigContainer.getInstance().getPathToTempFolderWithRandomName());
ChromeOptions options = new ChromeOptions();
options.addExtensions(new File(drivers + "CryptoCades.crx"));
options.setExperimentalOption("prefs", chromePrefs);
options.addArguments("--start-maximized");
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setBrowserName("chrome");
capabilities.setVersion("gost");
capabilities.setCapability("enableVNC", true);
capabilities.setCapability("enableVideo", false);
capabilities.setCapability(ChromeOptions.CAPABILITY, options);
Configuration.selectorMode = SelectorMode.Sizzle;
Configuration.pollingInterval = 50;
Configuration.proxyEnabled = true;
Configuration.fileDownload = PROXY;
RemoteWebDriver driver = new RemoteWebDriver(
URI.create("http://localhost:4444/wd/hub").toURL(),
capabilities
);
driver.setFileDetector(new LocalFileDetector());
WebDriverRunner.setWebDriver(driver);
timeout = 30000;
open("https://yandex.ru");
Браузер запускается при создании RemoteWebDriver
, конфигурация объявлена до этого.
При вызове open()
получаю ошибку.
java.lang.IllegalStateException: config.proxyEnabled == true but proxy server is not created. You need to call `setWebDriver(webDriver, selenideProxy)` instead of `setWebDriver(webDriver)` if you need to use proxy.
А, ну так конечно.
Мы же сами открываете браузер (new RemoteWebDriver
) и передаёте его селениду. И открываете его без прокси. В итоге ваш браузер ничего не знает про селенидовский прокси.
Идеальный вариант - не использовать метод WebDriverRunner.setWebDriver(driver);
.
Вроде получилось, но проблема что при запуске браузера нет интернета… Прокси же сам должен настроиться? Т.е. Selenide запускает собственный «встроенный» прокси-сервер на той же машине, где выполняются тесты. Может данный прокси из коробки не подходит в моём случае, где я подключаюсь к удаленному контейнеру через туннель(vpn).
И WebDriverRunner
не могу использовать для установки прокси - билд тогда падает.
Код
private void setRemoteDriver(){
Configuration.selectorMode = SelectorMode.Sizzle;
Configuration.pollingInterval = 50;
Configuration.proxyEnabled = true;
Configuration.fileDownload = PROXY;
Configuration.browser = MyWebDriverProvider.class.getName();
}
private static class MyWebDriverProvider implements WebDriverProvider {
@Override
public WebDriver createDriver(DesiredCapabilities capabilities) {
String drivers = ConfigContainer.getInstance().getConfigPropertyWithEncode("ExternalDriverPath");
HashMap<String, Object> chromePrefs = new HashMap<>();
chromePrefs.put("profile.default_content_settings.popups", 0);
chromePrefs.put("download.prompt_for_download", false);
ChromeOptions options = new ChromeOptions();
options.addExtensions(new File(drivers + "CryptoCades.crx"));
options.setExperimentalOption("prefs", chromePrefs);
options.addArguments("--start-maximized");
capabilities.setBrowserName("chrome");
capabilities.setVersion("gost");
capabilities.setCapability("enableVNC", true);
capabilities.setCapability("enableVideo", false);
capabilities.setCapability(ChromeOptions.CAPABILITY, options);
try {
return new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), capabilities);
}
catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}
}
Лог билда
2020-09-01 17:52:26 [INFO] - No webdriver is bound to current thread: 1 - let's create a new webdriver
2020-09-01 17:52:27 [INFO] - Starting proxy at address: 0.0.0.0/0.0.0.0:0
2020-09-01 17:52:27 [INFO] - Proxy listening with TCP transport
2020-09-01 17:52:28 [INFO] - Proxy started at address: /0:0:0:0:0:0:0:0:58983
2020-09-01 17:52:28 [INFO] - Creating folder: D:\PROJECTS\test_docker\build\downloads\1598971948014_11920_1
сен 01, 2020 5:52:37 PM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: W3C
2020-09-01 17:52:37 [INFO] - Set browser size to 1366x768
2020-09-01 17:52:37 [INFO] - BrowserName=chrome Version=81.0.4044.138 Platform=LINUX
2020-09-01 17:52:37 [INFO] - Selenide v. 5.14.2
2020-09-01 17:52:37 [INFO] - Selenium WebDriver v. 3.141.59 build time: 2018-11-14T08:17:03
2020-09-01 17:52:37 [INFO] - Create webdriver in current thread 1: RemoteWebDriver -> RemoteWebDriver: chrome on LINUX (a05e0a686fde5032373bb2e6b13192e4)
Конечно же, для работы прокси необходимо, чтобы машина с тестами (на которой запускается и прокси) была доступна с той машины/контейнера, где запускается браузер. Если нужно прокинуть порт или туннель - ну да, придётся прокинуть. Без этого прокси не взлетит (“не будет интернета”).
Не могу понять как сделать чтобы машина с тестами была доступна с контейнера. Понял что прокси-сервер запускается на машине рядом с запущенным тестом. Нашел как зафиксировать порт Configuration.proxyPort = 30001;
.
Пробовал добавлять этот порт при запуске контейнера -p 30001:30001
, но тогда тест падает при запуске прокси-сервера, т.к. порт уже занят(тот что первый).
Пробовал прописать его в Environment
в docker-compose
.
Пробовал chrome_options.addArgument("--proxy-server=localhost:30001")
.
Как именно открыть/прокинуть нужный доступ?
Дык, а я сам не знаю.
Никогда этого не делал. Может, коммьюнити поможет?
Вопрос решился) Создал экземпляр Proxy
, указал в нём хост и порт прокси-сервера, который создал Selenide, и передал его в capabilities
драйверу. экспериментировал развернув контейнер локально. Сложность была в том что я хост указывал localhost
, а из контейнера он указывается как host.docker.internal
. Надо будет ещё правильно задать его когда контейнер будет в другой сети под vpn.
Возникла сложность с методом download()
. Так как при нажатии на кнопку вызывался ряд запросов. Решением было создать и передать параметром FileFilter
В итоге использование решения с методом download()
и прокси-сервером не подошло.
- Через прокси идёт весь трафик, а это сильно замедляет тест. Как использовать иначе способа не нашел. Может вы подскажите… Я где-то на просторах читал ваше сообщение, где вы писали что прокси не замедляет тест. Может вы имели ввиду что потери минимальны. Но когда между тестом с прокси и контейнером с вебдрайвером расстояние тысяча километров, тогда потери скорости очень ощутились
- Прокси подменяет сертификат из-за чего пропадает возможность работать с гостовыми сайтами.
Использование прокси вызывает интерес, если возможно решить эти две проблемы. С сертом. И чтобы к примеру весь трафик шел напрямую, а вот именно скачивание файлов через прокси.
- Это правда: я говорил, что прокси не замедляет тесты. Но да, имелся в виду локальный запуск тестов. И конечно, имелось в виду, что замедление не равно нулю, а крайне мало. А при удалённом запуске наверняка замедление может быть и больше, да.
P.S. Но зачем запускать браузеры за тысячу километров, я вообще не понимаю, вне зависимости от прокси.
- Проблема с сертификатом наверняка решается так, что браузеру при открытии можно добавить сертификат прокси в список доверенных сертификатов. Но я сам это ещё не пробовал.