Как скачать файл с исходным именем, используя Selenide параметр (fileDownload = FOLDER)?

Всем привет!

На странице есть элемент (без href), при нажатии на который, на сервере генерируется файл и затем скачивается.
Мануально генерируется файл с человечески понятным именем, типа ‘20221003183144-pdf-export-Project-ATF-test-project1.pdf’.
Использование (fileDownload = FOLDER) приводит к скачиванию файла с именем, типа ‘Unconfirmed 459389.crdownload’. По непонятной мне причине на UI скачанный файл отображается, как ошибочный, хотя фактически он целый.
UI-evidence

Можно ли скачать файл с исходным именем?

Использование (fileDownload = HTTPGET) приводит к ошибке
java.lang.IllegalArgumentException: The element does not have href attribute: <i class="fa-light fa-print"></i>

Selenide: 6.6.4

“ *.crdownload” - временный файл, создаваемый браузером на короткий период, пока скачивается файл. Когда скачивание завершено, браузер сам переименовывает этот файл в что-то типа “‘20221003183144-pdf-export-Project-ATF-test-project1.pdf”.

В вашем случае, похоже, скачивание файла не удалось. Надпись “Failed - Download error” ясно говорит об этом. Эту надпись ведь показывает браузер - значит, браузер считает, что скачивание почему-то не удалось.

А селенид просто ждёт, пока в C:\Downloads исчезнут все файлы типа “*.crdownload”. И если так и не дождался в течение 4 секунд, выдаёт ошибку.

Возможно, вам надо просто увеличить таймаут?

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

Нет, стоп, метод “fileDownload = FOLDER” ровно это и делает: кликает на кнопку и ждёт, пока файл появится в скачанных файлах. Это и есть тот самый элегантный способ.
Можешь попробовать кликнуть сам, но ведь результат будет таким же.

Кстати, покажи код, как конкретно скачиваешь файл?

    @And("file is exported by clicking on PrintExport button")
    public void downloadFile() {
        File downloadedFile = null;
        try {
            downloadedFile = dashboardPage.getPrintExportButton().download(DownloadOptions.using(FileDownloadMode.FOLDER));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        assertThat(downloadedFile).withFailMessage("File is not downloaded").isNotNull();
        LoggerManager.makeScreenshot("file-is-exported");
    }

хмм, если я просто нажимаю на кнопку и жду, то скачивается все красиво

ок, покажи код, как именно ты нажимаешь на кнопку.
И кстати, как задаёшь таймаут.

настройка таймаута (15с)

@RunWith(Cucumber.class)
public class AbstractRunner {
    @BeforeClass
    public static void initializeBaseData() {
        Configuration.timeout = configuration().timeout() * 1000L;

в StepDefinition

public class CommonSteps {
    private final DashboardPage dashboardPage = new DashboardPage();
...
// в методе
dashboardPage.getPrintExportButton().click();
и ожидание через обычный Thread.sleep

где

@Getter
public class DashboardPage extends AbstractPage {
    private final SelenideElement printExportButton = $("i.fa-print");

возможно дело в запросах/ответах с сервером.
вот что происходит при нажатии на кнопку
запрос1


ответ1

запрос2


ответ2

запрос3


ответ3

и затем уже скачивается нужный файл запрос 4

я попробовал использовать фильтрацию

downloadedFile = dashboardPage.getPrintExportButton().download(withExtension("pdf"));

но так не скачивается вообще ничего.
стектрейс

java.io.FileNotFoundException: Failed to download file {i.fa-print} in 15000 ms. with extension "pdf"
	at com.codeborne.selenide.impl.Downloads.lambda$firstDownloadedFile$0(Downloads.java:76)
	at java.base/java.util.Optional.orElseThrow(Optional.java:403)
	at com.codeborne.selenide.impl.Downloads.firstDownloadedFile(Downloads.java:75)
	at com.codeborne.selenide.impl.DownloadFileToFolder.clickAndWaitForNewFilesInDownloadsFolder(DownloadFileToFolder.java:83)
	at com.codeborne.selenide.impl.DownloadFileToFolder.lambda$download$0(DownloadFileToFolder.java:57)
	at com.codeborne.selenide.impl.WindowsCloser.runAndCloseArisedWindows(WindowsCloser.java:25)
	at com.codeborne.selenide.impl.DownloadFileToFolder.download(DownloadFileToFolder.java:56)
	at com.codeborne.selenide.commands.DownloadFile.execute(DownloadFile.java:66)
	at com.codeborne.selenide.commands.DownloadFile.execute(DownloadFile.java:29)
	at com.codeborne.selenide.commands.Commands.execute(Commands.java:155)
	at com.codeborne.selenide.impl.SelenideElementProxy.dispatchAndRetry(SelenideElementProxy.java:129)
	at com.codeborne.selenide.impl.SelenideElementProxy.invoke(SelenideElementProxy.java:81)
	at jdk.proxy2/jdk.proxy2.$Proxy32.download(Unknown Source)
	at nl.emendis.stepdefs.CommonSteps.downloadFile(CommonSteps.java:201)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)

мне удалось решить проблему следующим образом

Configuration.fileDownload = FileDownloadMode.FOLDER;
downloadedFile = dashboardPage.getPrintExportButton().download(withNameMatching(fileName + "\\." + fileExtension));

но папка, в которую скачивается файл, имеет вид типа ‘dfdad1ce-5352-4c05-a60a-26ccc68945dc’ какой бы таймаут я не ставил общий и после скачивания.
это нормально?

  1. Да, это нормально. Селенид специально генерирует уникальные папки, чтобы файлы из разных тестов не конфликтовали друг с другом.
  2. Я не понимаю, что именно помогло решить проблему.
    Варианты download(withNameMatching(fileName + "\\." + fileExtension)) и .download(withExtension("pdf")) почти равнозначные. Не думаю, что именно эта замена повлияла.
1 лайк