Переопределение папки Download в Selenide

Я нашел на форуме ветку Как можно изменить директорию, куда скачиваются файлы? - #5 от пользователя MyLuk
И в принципе такой код работает

 HashMap<String, Object> chromePrefs = new HashMap<String, Object>();
        chromePrefs.put("download.default_directory", downloadFolderPath);
        ChromeOptions options = new ChromeOptions();
        options.setExperimentalOption("prefs",chromePrefs);
        WebDriverRunner.setWebDriver(new ChromeDriver(options));

Но запускается новый инстанс хрома с другой папки, который не подхватывает мои настройки.

Моя текущая конфигурация ниже, ее я использую в каждом тесте в аннотации @BeforeClass

    public static void setUp(String chooseBrowser, String windowSize, boolean fastInputValue) {
        driverManagerEnabled = true;
        baseUrl = "";
        startMaximized = false;
        fastSetValue = fastInputValue;
        browser = chooseBrowser;
        browserSize = windowSize;

Как вместе связать эти 2 конфигурации, просто вторая мне нравится лаконичностью и что все настройки подхватываются из Configuration в Selenide, жаль там нельзя задать такие вещи как смена папки загрузки, выходит какой-то костыль.

А зачем вам менять папку загрузки? Selenide ведь сам скачивает файл и возвращает объект File. Какая разница, где он лежит - вам ведь не надо его искать?

Ну например я хочу проверять, что он скачался и удалять его после этого, очищая папку, чтобы не захламлять место.

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

Ну или слишком все усложняю =)
Андрей, а как тогда лучше это реализовать? Загрузка файла происходит автоматически по клику на айтем в меню, т.е. кроме $("some_element).click(); ничего не делаю, имя файла каждый раз генерируется системой, одинаковых нет.

Всё просто. Надо использовать метод $.download() вместо $.click():

File pdf = $("some_element).download();
// TODO check pdf content
pdf.delete();
1 лайк

Спасибо вам большое, попробую.

Попробовал.
Без добавления параметра конфигурации
fileDownload = PROXY; метод .download вообще ничего скачивать не будет, тест будет падать с UndeclaredThrowableException , поэтому немного погуглил и нашел что надо добавлять этот прокси, жаль с ним тест дольше работает.

Набросал вот так:

    public static void downloadExcel() throws FileNotFoundException {
        File excel = excel().download();
        System.out.println("FILE Path: " + excel.getPath());
        if (excel != null) {
            excel.delete(); 
        }
    }

Что интересно, в логе потом я вижу
Сперва ссылку загрузки, а следующей строкой
FILE Path: build\reports\tests<Something>.xlsx
Но файлы так же и в папке Downloads системы есть… Хотелось бы чтобы они просто удалялись после скачивания, их контент я проверять не буду (там очень много зависимостей), главно что скачались и чтобы удалились.

  1. Почему вы решили, что через PROXY дольше работает? Мои замеры этого не подтверждают.
  2. Вернёмся к вашему изначальному варианту. Без PROXY Selenide скачивает файл в папку “build/reports/tests”, и ваш билд-скрипт наверняка её очищает. Вам вообще не надо беспокоиться об удалении файлов. Ну или если уж очень невтерпёж, строка excel.delete(); удаляет файл. Больше ничего не нужно.
    P.S. Кстати, проверка на null не нужна - метод $.download() всегда возвращает ненулевой объект File.
  1. Мне так показалось, попробую еще ряд тестов запустить, точно буду знать, но вечером прямо чуть ли не на 50% медленнее было.
  2. Что-то я делаю наверно не так: стоит fileDownload = proxy; и убрал excel.delete(); чтобы увидеть где будут файлы.
    С fileDownload = proxy; После теста файлы загрузки лежат как в build/reports/tests так и в папке Downloads системы где я запускаю тест.

Без PROXY Selenide (убрал вообще fileDownload = proxy;) тест падает в момент
File excel = excelExport().download();
с сообщением

java.lang.reflect.UndeclaredThrowableException
	at com.sun.proxy.$Proxy7.download(Unknown Source)

Что я делаю не так?

Я вижу, что excel.delete(); удалит файл ТОЛЬКО из папки build/reports/tests.

Нужно больше информации про этот UndeclaredThrowableException.
Скиньте полный стэктрейс.

Залил на GD https://docs.google.com/document/d/1ZdAK34Wp3CkScvJX1i1canNH-_1Y5y8jNPzDTCo4OrY/edit?usp=sharing

Спасибо, теперь понятно.
Важная ошибка в середине стэктрейса:
URI does not specify a valid host name: javascript:void(0)

Значит, вы можете использовать только способ PROXY. И тогда ваш изначальный код с "download.default_directory" правильный.

1 лайк

Да я так и делеаю, например
File excel = excelExport().download();
И так же стоит в конфигурации браузера

fileDownload = FileDownloadMode.PROXY;

Но все равно я тогда не совсем понимаю почему после команды

excel.delete();

Удаляется файл только из build/reports/tests, все равно остается мой файл в системной папке загрузок. Т.е. он загружается в 2 папки (системную Downloads и build/reports/tests), а удаляет данной командой только из одного места.

И еще один вопрос насчет

fileDownload = FileDownloadMode.PROXY;

Локально это работает, а вот если удаленный запуск через Selenoid, то будет такая красота
qw
Ответа на форуме не нашел.

Всё верно, Селенид и должен создавать два файла. А операция .delete() должна стирать один файл.

Правда, скачанный файл должен оказаться не в ~/Downloads, а в той папке, которую вы указали в "download.default_directory".

Но вообще я теперь задумался: может, и правда, будет лучше, если селенид будет создавать не два файла, а один?

1 лайк

Это означает, что с той машины, где запущен браузер, нет доступа к той машине, где запущены тесты (и соответственно прокси-сервер). Тут вам надо как-то на своей стороне решить вопрос.

А вообще, чтобы со всем этим не заморачиваться, есть решение гораздо проще. Узнайте, по какому URL реально грузится файл, и просто дёргайте из теста этот URL напрямую.

1 лайк

Ну мне кажется, что это лишнее создавать 2 файла, так например один скачался, я удалил командой .delete() и забыл об этом. Ну в общем если реализуете, то будет здорово, может даже какой-то триггер для тех кому надо 2 или 1.
Я вот как раз download.default_directory не задавал по той причине, что я работаю на винде, кто-то запускает тесты на маке, а в CI они будут бегать на убунте, хотя наверно как вариант можно задать папку профиля хрома, которая по идее будет пересоздаваться при следующих запусках.

Про доступ от браузера к машине где запущены тесты понял, поиграюсь.
Спасибо!

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

Добрый день! как решили вопрос? такая же проблема)

Да никак, остановили покрытие этого функционала, по причине 7 пятниц на неделе у заказчика, ну и .download() не работает в моем случае, раз я использую Selenoid на удаленной машине.