Есть отличная удаленная работа для php+codeception+jenkins+allure+docker спецов. 100% remote! Присоединиться к проекту

Как дождаться загрузки файла?

download
ruby
selenium
webdriver
chrome
Теги: #<Tag:0x00007f7b6452cb00> #<Tag:0x00007f7b6452c9c0> #<Tag:0x00007f7b6452c880> #<Tag:0x00007f7b6452c6f0> #<Tag:0x00007f7b6452c4e8>

(Сергей Блохин) #1

Пишу скирпт, который авторизуется на сайте и после этого загружает с него (скачивает) файл.
Загрузка файла с сервера на мой компьютер — клик по кнопке на странице.
Всё работает, но после полной загрузки файла мне нужно закрыть driver (закрыть браузер).
Как определить, что файл уже загружен?


(Alexey Panashchenko) #2

Привет,

Как вариант, смотреть на скачиваемый файл и ждать пока его размер не будет изменяться)


(Александр Таранков) #3

При скачивании браузер создает временный файл. Вот по нему и можно трекать


(Eugene Tkachenko) #4

Юзал в свое время этот воркераунд для Watir: Ruby / Watir-Webdriver download file


(Александр Таранков) #5

У нас сейчас сделано так:

  1. перед нажатием кнопки “скачать” в Download-дире берется список файлов
  2. после нажатия кнопки “скачать” сначала ожидается появление файла, которого до этого не было
  3. после этого ожидается скачивание файла
    1. если появившийся файл временный, то ожидается, когда он исчезнет и появится постоянный -> скачивание завершено
    2. если появившийся файл сразу не временный, то считается что скачивание завершено

В общих чертах так


(Сергей Блохин) #6

Всем большое спасибо. Мысли по поводу костыльной проверки наличия и размера файла были. Я надеялся, что ожидание можно реализовать силами самого Selenium. Увы. На самом деле мне подошло банальное ожидание в 5 секунд после клика на ссылку (файл в реальности грузится менее секунды). Хотел на будущее иметь правильное решение.


(Stan) #7

Вместо размера лучше проверять его хэш сумму (sha-1 как best practice), чтобы быть на 100% уверенными, что файл скачался и не битый.


(Сергей Блохин) #8

Это если мы знаем конечный размер файла.
У меня это была выгрузка CSV из Яндекс.Метрики. Каждый раз размер разный.


(barancev) #9

Используйте прокси.

http://selenium2.ru/news/106-selenium-i-browsermobproxy-vmeste-veselee.html


(Tester Testerman) #10

Не подскажете как в авто тесте на Java поставить ожидание 5 секунд чтобы успевал загрузится файл.

@After
//stop(5сек)
driver.quit();
}

PS. Заранее спасибо за помощь


(Alexandr D ) #11
TimeUnit.SECONDS.sleep(5);

Но… это дикий антипаттерн. Хардкоду - бой.


(Tester Testerman) #12

Спасибо огромное всё работает :blush:


(Tester Testerman) #13

Согласен но не знаю как сделать лучше, нужно дождаться пока фаил загрузится а потом закрыть браузер. Из данной темы я понял что команды ожидать окончания загрузки нет.


(Alexandr D ) #14

Лично я эту проблему решил следующим образом.
Пример, конечно же, с C#, а не Java, но в принципе из основных отличий - что это просто в джаве будет не метод расширения.

Создал такой метод:

public static FileInfo DownloadFile(this IWebDriver driver, Action action, TimeSpan timespan)
        {
            FileInfo newFile = null;
            lock (Locker)
            {
                var directoryFiles = DriverManager.DowndloadFolder.EnumerateFiles().ToList();
                action.Invoke();

                driver.Wait(timespan)
                    .Until(() => DriverManager.DowndloadFolder.EnumerateFiles().Count() != directoryFiles.Count);
                do
                {
                    foreach (var enumerateFile in DriverManager.DowndloadFolder.EnumerateFiles())
                        if (directoryFiles.All(_ => _.Name != enumerateFile.Name))
                            newFile = enumerateFile;
                } while (newFile != null && (newFile.Name.Contains(".tmp") || newFile.Name.Contains("crdownload")));
            }

            if (newFile == null)
                throw new AutoTestErrorException(
                    "Не нашли новый файл в папке загрузок.");
            return newFile;
        }

И использую его с любым действием.
Например - если файл качается по кнопке, то передаём что-то типа этого:

var downloadedFile = DriverManager.Driver.DownloadFile(() => downloadBtn.Click, TimeSpan.FromSeconds(3))

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


(Anton ) #15

Сама по себе автоматизация скачивания файла весьма спорное решение


(asolntsev) #16

@TesterTesterman

Используйте Selenide. Там есть готовый метод для скачивания файла:

File report = $("a#report").download();

Более того, вам даже driver.quit() не придётся вызывать.