Скачивание файла в определенную директорию. Selenide

Добрый день,

Столкнулась с проблемой скачивания и сохранения файла.
Использую Selenide+Java, тесты запускаются через Jenkins в Docker, там Selenoid. Пока пытаюсь это воспроизвести на своей машине.

Скачивание файла производится в трёх шагах:

  1. Нажимаем название файла-link, где href=“javascript:void(0);”
<a role="textbox" href="javascript:void(0);" class="drilldown" name="Report Name" tabindex="-1">REPORT</a>
  1. В появившемся pop-up нажимаем Save.
<button type="button" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only siebui-ctrl-btn appletButton" role="button"><span class="ui-button-text">Save</span></button>
  1. Открывается новое окно с default url. и pdf автомотически сохраняется в Downloads.

Применила к линку . download (), выходит ошибка, файл не сохранился.
Применила к кнопке Save, та же ошибка, файл не сохранился.
java.lang.IllegalArgumentException: The element does not have href attribute

Нашла подобные проблемы на сайте, такие как:

Были добавлены:

Configuration.fileDownload = PROXY;
Configuration.proxyEnabled = true; 

На моей машине ip адрес автоматический.
Снова применила к линку . download (), выходит ошибка, файл не сохранился.
Применила к кнопке Save, та же ошибка, но файл СОХРАНИЛСЯ В Downloads.

java.io.FileNotFoundException: Failed to download file {By.xpath: ....} in 4000 ms.Intercepted 0 responses 
	at com.codeborne.selenide.impl.DownloadFileWithProxyServer.firstDownloadedFile(DownloadFileWithProxyServer.java:94)
	at com.codeborne.selenide.impl.DownloadFileWithProxyServer.clickAndInterceptFileByProxyServer(DownloadFileWithProxyServer.java:49)
	at com.codeborne.selenide.impl.DownloadFileWithProxyServer.download(DownloadFileWithProxyServer.java:33)
	at com.codeborne.selenide.commands.DownloadFile.execute(DownloadFile.java:51)
	at com.codeborne.selenide.commands.DownloadFile.execute(DownloadFile.java:18)
	at com.codeborne.selenide.commands.Commands.execute(Commands.java:144)
	at com.codeborne.selenide.impl.SelenideElementProxy.dispatchAndRetry(SelenideElementProxy.java:99)
	at com.codeborne.selenide.impl.SelenideElementProxy.invoke(SelenideElementProxy.java:65).

Сохранение в папку Downloads не устраивает, т.к. в конце теста хочу иметь все файлы в build/reports/tests, чтобы все вытащить в Jenkins.

Если кто сталкивался с данной проблемой и решил ее, подскажите пожалуйста.

Еще другое волщебство в том, что на хроме отключено автоматическое сохранение в Downloads, надо вручную указывать папку, но при запуске тестов, файл автоматически скачивается туда(Downloads folder) без окна подтверждения сохранения.

Спасибо.

1 лайк

Привет!

  1. Какая версия селенида и браузера?
  2. Приложение бегает на localhost?

В текущей версии селенида и последними версиями Chrome и Firefox прокси не видит localhost. В Selenide 5.2.4 мы это исправили, скоро он появится в maven central: Maven Central Repository Search

Привет,

Версия Selenide - 5.2.2
Хотела вчера обновить на 5.2.3, но сразу же возникли проблемы с allure (@Override onEvent() method), поэтому, чтоб пока избежать разбора и этой проблеме я вернулась на 5.2.2
Версия Chrome - 71.0.3578.98 (64-bit), обновления производятся автоматически от админов нашей организации.

Нет, приложение бегает на test environments, на дефолтних url. На своей машине, я подразумевала, что запускаю на intellij idea, когда это благополучно пробегает у меня, я создаю на тест джоб в Jenkins и все бежит на удаленных серверах, и пока там установлены другие версии chroma, старенькие, стабильные, одна из - 68.0

  • обновила версию Selenide на 5.2.4;
  • обновила allure, ошибку теперь не выдает в AllureSelenide().

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

Čer 21, 2019 11:42:21 DOP. com.codeborne.selenide.drivercommands.LazyDriver getAndCheckWebDriver
INFO: No webdriver is bound to current thread: 1 - let's create a new webdriver
[main] INFO org.littleshoot.proxy.impl.DefaultHttpProxyServer - Starting proxy at address: 0.0.0.0/0.0.0.0:0
[main] INFO org.littleshoot.proxy.impl.DefaultHttpProxyServer - Proxy listening with TCP transport
[main] INFO org.littleshoot.proxy.impl.DefaultHttpProxyServer - Proxy started at address: /0:0:0:0:0:0:0:0:51294
[main] INFO io.github.bonigarcia.wdm.WebDriverManager - Using chromedriver 71.0.3578.137 (since Google Chrome 71 is installed in your machine)
[main] INFO io.github.bonigarcia.wdm.WebDriverManager - Exporting webdriver.chrome.driver as C:\Users\astakhovao\.m2\repository\webdriver\chromedriver\win32\71.0.3578.137\chromedriver.exe
Starting ChromeDriver 71.0.3578.137 (86ee722808adfe9e3c92e6e8ea746ade08423c7e) on port 18260
Only local connections are allowed.
Please protect ports used by ChromeDriver and related test frameworks to prevent access by malicious code.
Čer 21, 2019 11:42:36 DOP. org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: OSS
Čer 21, 2019 11:42:36 DOP. com.codeborne.selenide.webdriver.BrowserResizer adjustBrowserSize
INFO: Set browser size to 1366x768
Čer 21, 2019 11:42:37 DOP. com.codeborne.selenide.webdriver.WebDriverFactory logBrowserVersion
INFO: BrowserName=chrome Version=71.0.3578.98 Platform=XP
Čer 21, 2019 11:42:37 DOP. com.codeborne.selenide.webdriver.WebDriverFactory createWebDriver
INFO: Selenide v. 5.2.4
Čer 21, 2019 11:42:37 DOP. com.codeborne.selenide.webdriver.WebDriverFactory logSeleniumInfo
INFO: Selenium WebDriver v. 3.141.59 build time: 2018-11-14T08:17:03
Čer 21, 2019 11:42:37 DOP. com.codeborne.selenide.drivercommands.CreateDriverCommand createDriver
INFO: Create webdriver in current thread 1: ChromeDriver -> ChromeDriver: chrome on XP (1b6f69719b7998be4c674d2960a6a971)
Čer 21, 2019 11:42:37 DOP. com.codeborne.selenide.drivercommands.CreateDriverCommand addListeners
INFO: Add listener to webdriver: ...SyncEventListener@5aceec94
+++++++++ Test +++++++++
java.io.FileNotFoundException: Failed to download file {By.xpath: .....} in 4000 ms.Intercepted 0 responses.
at com.codeborne.selenide.impl.DownloadFileWithProxyServer.firstDownloadedFile(DownloadFileWithProxyServer.java:94)
	at com.codeborne.selenide.impl.DownloadFileWithProxyServer.clickAndInterceptFileByProxyServer(DownloadFileWithProxyServer.java:49)
	at com.codeborne.selenide.impl.DownloadFileWithProxyServer.download(DownloadFileWithProxyServer.java:33)
	at com.codeborne.selenide.commands.DownloadFile.execute(DownloadFile.java:51)
	at com.codeborne.selenide.commands.DownloadFile.execute(DownloadFile.java:18)
	at com.codeborne.selenide.commands.Commands.execute(Commands.java:144)
	at com.codeborne.selenide.impl.SelenideElementProxy.dispatchAndRetry(SelenideElementProxy.java:99)
	at com.codeborne.selenide.impl.SelenideElementProxy.invoke(SelenideElementProxy.java:65)
	at com.sun.proxy.$Proxy13.download(Unknown Source)
.
.
.

К сожалению, проблема с директорией скачивания файла через Selenide, так и не была решена. Не помогло ни
Configuration.reportsFolder = "build/reports/tests

ни

Configuration.browserCapabilities.setCapability("download.default_directory", "build/reports/tests");
    Configuration.browserCapabilities.setCapability("profile.default_content_settings.popups", "0");
    Configuration.browserCapabilities.setCapability("plugins.always_open_pdf_externally", true);
    Configuration.browserCapabilities.setCapability("download.prompt_for_download", false);

ни

Configuration.reportsFolder =pro.getProperty("reportsFolder");

Оставила стандартное решение для файла:

Files.move(
//TODO set default download directory from remote browser
                Paths.get("ZZZZ/Downloads/"+CONTRACT+".PDF"),
                Paths.get(reportsFolder +"/" + CONTRACT+".PDF"),
                StandardCopyOption.REPLACE_EXISTING);

Поделюсь решением данной проблемы.
Было рассмотрено 2 случая, если тест бежит на локалу, либо удалённо:

if (StringUtils.isEmpty(Configuration.remote)) {
      copyFromLocalBrowser(downloadFilename, downloadTimeoutSecs, targetPath);
    } else {
      copyFromRemoteBrowser(selenoidUser, downloadFilename, downloadTimeoutSecs, targetPath);
    }

Один минус, мы должны знать название скачиваемого файла.

Например для локального запуска:

private static void copyFromLocalBrowser(
      String downloadFilename, int downloadTimeoutSecs, Path targetPath) {
    Path downloadPath = Paths.get(System.getProperty("user.home"), "Downloads", downloadFilename);
    // wait for download finished
    try {
      await()
          .pollDelay(Duration.ONE_HUNDRED_MILLISECONDS)
          .pollInterval(Duration.ONE_HUNDRED_MILLISECONDS)
          .atMost(downloadTimeoutSecs, TimeUnit.SECONDS)
          .until(() -> Files.exists(downloadPath));
    }
    // throw some userfriendly exception
.
.
.
    Files.move(downloadPath, targetPath, StandardCopyOption.REPLACE_EXISTING);
  }
1 лайк

Необязательно знать название скачиваемого файла.
Можно до начала скачивания смотреть в папку, запомнить все имена уже существующих там файлов, начать скачивание - и найти новый добавленный файл.
Во всяком случае, если мне не изменяет память, когда качается файл, у него всегда расширение либо .crdownload, либо .tmp (применимо к Chrome, как минимум).
Тем самым можно всегда понять, когда файл будет скачан и какое у него название будет после скачивания.

1 лайк