Roma_Roman
(Yaroslav Lazakovich)
24.Январь.2022 14:36:03
#1
Обнаружил проблему следующего характера:
Если запускать браузер в HEADLESS режиме, то возникает проблема следующая
Пример следующий:
Я делаю загрузку файла и жду окончания его загрузки
через джаваскрипт я жду state.equals(“COMPLETE”)
((JavascriptExecutor) WebDriverRunner.getWebDriver()).executeScript("return document.querySelector('downloads-manager').shadowRoot.getElementById('downloadsList').items[0].state")
Если отключать HEADLESS режим, то все прекрасно отрабатывает.
Кто-то может уже сталкивался с такого рода сложностью и отыскал выход из ситуации?
Буду благодарен, если поможете отыскать ответ на данный вопрос
sergueik
(Сергей Кузьмин)
24.Январь.2022 16:06:30
#2
вам именно с download хочется или глобально ?
Roma_Roman
(Yaroslav Lazakovich)
24.Январь.2022 18:27:52
#3
На данный момент, хочется решить на уровне download
На более глобальный уровень думаю, что это займет больше усилий
sergueik
(Сергей Кузьмин)
24.Январь.2022 19:12:05
#4
может попробуйте используйте браузер для этого вместо того чтобы подглядывать в шадодом ShadowDOM ?
Browser.setDownloadBehavior
Browser.downloadWillBegin
Browser.downloadProgress
и тд
а пример свой покажите интересно же всем как исчезает ShadowDOM в HEADLESS!
Roma_Roman
(Yaroslav Lazakovich)
24.Январь.2022 19:45:08
#5
Сценарий для воспроизведения очень простой
Я тестировал на Chrome используя Selenide
Можно скачать любой файлик (я для примера скачивал IDEA)
как раз можно подебажить, какие state возвращаются, пока скачивается файлик и когда он завершает скачивание
Открыть страничку chrome://downloads/
Настроить свою ожидалку через джаваскрипт, который я написал выше, где ты ждешь статус COMPLETE или IN_PROGRESS
Если браузер запускается в хедлесс, то джаваскрипт не исполнится, потому что нету shadowroot элементов и прокинится ошибка
you can’t get the shadowRoot
property of null
Предварительно я искал ответ на вопрос, и вот аналогичный вопрос был задан на stackoverflow:
sergueik
(Сергей Кузьмин)
24.Январь.2022 20:03:23
#6
вам нужен пример ?
катси
свой горе кейс бросьте гистом пжта
какая версия селениума у вас
если 3 то одно ws:
если 4 то есть 2 легальных способа (один крутой):
private static String command = "Browser.setDownloadBehavior";
@Before
public void beforeTest() throws Exception {
// Arrange
params = new HashMap<>();
params.put("behavior", "allow");
// NOTE: the "allowAndName" will randomly name the downloaded file
params.put("downloadPath", downloadPath);
params.put("eventsEnabled", true);
result = driver.executeCdpCommand(command, params);
assertThat(result, notNullValue());
new File(
Paths.get(downloadPath).resolve(filename).toAbsolutePath().toString())
.delete();
}
@After
public void clearPage() {
// Arrange
params = new HashMap<>();
params.put("behavior", "default");
result = driver.executeCdpCommand(command, params);
assertThat(result, notNullValue());
driver.get("about:blank");
}
@Test
public void test1() {
try {
// Act
driver.get(url);
Utils.sleep(3000);
assertThat(new File(
Paths.get(downloadPath).resolve(filename).toAbsolutePath().toString())
.exists(),
is(true));
} catch (WebDriverException e) {
System.err.println("Web Driver exception in " + command + " (ignored): "
+ Utils.processExceptionMessage(e.getMessage()));
} catch (Exception e) {
System.err.println("Exception in " + command + " " + e.toString());
throw (new RuntimeException(e));
}
}
сейчас напишу еще -
@Test
public void test2() {
List<DownloadProgress.State> states = new ArrayList<>();
// Arrange
chromeDevTools.send(
Browser.setDownloadBehavior(Browser.SetDownloadBehaviorBehavior.ALLOW,
Optional.empty(), Optional.of(downloadPath), Optional.of(true)));
// Act
try {
chromeDevTools.addListener(Browser.downloadWillBegin(), o -> {
System.err.println("in Browser.downloadWillBegin listener. url: "
+ o.getUrl() + "\tfilename: " + o.getSuggestedFilename());
});
chromeDevTools.addListener(Browser.downloadProgress(), o -> {
DownloadProgress.State state = o.getState();
System.err.println(
"in Browser.downloadProgress listener. state: " + state.toString());
states.add(state);
});
driver.get(url);
Utils.sleep(3000);
assertThat(states.indexOf(DownloadProgress.State.COMPLETED),
greaterThan(-1));
} catch (WebDriverException e) {
System.err.println("Web Driver exception (ignored): "
+ Utils.processExceptionMessage(e.getMessage()));
} catch (Exception e) {
System.err.println("Exception: " + e.toString());
throw (new RuntimeException(e));
}
}
свой горе кейс бросьте гистом пжта
мои примеры лежат на
и на
(3.x / ws:// ) - пример с download положу туда через 3 часа
asolntsev
(asolntsev)
25.Январь.2022 05:04:15
#7
Господь с вами, вовсе не нужно открывать вкладку “downloads” и отслеживать статусы. Всё гораздо проще.
В селениде это уже давно сделано за вас:
File idea = $("#download").download(with extension("exe"));
И селенид сам дождется окончания загрузки и вернёт вам готовый скачанный файл.
Roma_Roman
(Yaroslav Lazakovich)
25.Январь.2022 05:37:48
#8
Проблема в том, что, к сожалению, на проекте кнопка не имеет @href и селенидовский метод download не отрабатывает, проксирование тоже ломает проект
Поэтому и было придумано именно такое решение
asolntsev
(asolntsev)
25.Январь.2022 05:50:50
#9
Так кроме href и прокси, в селениде есть третий метод FOLDER. Как раз то, что вам надо.
1 лайк
88Post1
(Arthur Khasanov)
25.Январь.2022 07:27:30
#10
Это неверное решение. Костыльное.
Для таких вещей есть Proxy. Юзайте его.
“проксирование тоже ломает проект”
что именно ломает ?
1 лайк
sergueik
(Сергей Кузьмин)
28.Январь.2022 03:22:30
#11
Roma_Roman Yaroslav Lazakovich вам все еще актуально ?
почему я спрашиваю ?
в примере на стаке похоже есть ошибка
… с другой стороны где их нет