Подождите, пока загрузка закончится в selenium webdriver JAVA

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

Thread.sleep(2000);
driver.findElement(By.xpath("//*[@id='perform']")).click();//click for download

Thread.sleep(20000);
//code to be executed after download completes
Readfile fileobj=new Readfile();
String checkfile=fileobj.checkfilename();

Как заставить webdriver ждать завершения загрузки?

Ответ 1

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

Я тоже столкнулся с той же проблемой и думал, что поделюсь ею. В то время я развивался в python, но эта же концепция применяется. Вам не нужно делать фактическую загрузку с использованием селена. Вместо того, чтобы нажимать на элемент, чтобы начать загрузку, вы должны рассмотреть возможность получения ссылки и использования встроенных функций для перехода оттуда.

Элемент, который вы обычно нажимаете для начала загрузки, должен иметь атрибут "href", который вы должны читать с помощью селена. Это URL, указывающий на фактический файл. В python это выглядит примерно так:

    element = driver.find_element_by_id('dl_link')
    url = element.get_attribute('href')

Отсюда вы можете использовать http-библиотеку для вызова URL-адреса. Важная часть здесь заключается в том, что вы установили 'stream' в true, чтобы начать писать байты в файл. Убедитесь, что путь к файлу содержит правильное расширение файла, а другое - большинство операционных систем не позволяют вам указывать файлы с определенными символами, такими как обратные косые черты или котировки, так что хэдз-ап на это.

def download_file(url, file_path):
    from requests import get
    reply = get(url, stream=True)
    with open(file_path, 'wb') as file:
        for chunk in reply.iter_content(chunk_size=1024): 
            if chunk:
                file.write(chunk)

Программа не должна продолжаться до тех пор, пока загрузка не будет завершена, так как она больше не нужна для опроса, пока она не будет завершена.

Я извиняюсь за ответ на другом языке, в Java, я считаю, что вы можете использовать API HttpURLConnection. Надеюсь это поможет!

Ответ 2

Я использую Scala для моей автоматизации, но порт для Java должен быть тривиальным, так как в любом случае я использую классы Java Selenium. Итак, сначала вам это нужно:

import com.google.common.base.Function
import java.nio.file.{Files, Paths, Path}

def waitUntilFileDownloaded(timeOutInMillis:Int)={
    val wait:FluentWait[Path] = new FluentWait(Paths.get(downloadsDir)).withTimeout(timeOutInMillis, TimeUnit.MILLISECONDS).pollingEvery(200, TimeUnit.MILLISECONDS)
    wait.until(
      new Function[Path, Boolean] {
        override def apply(p:Path):Boolean = Files.list(p).iterator.asScala.size > 0
      }
    )
  }

Затем в моем тестовом наборе, где мне нужно загрузить файл xls, я просто это:

def exportToExcel(implicit driver: WebDriver) = {
    click on xpath("//div[contains(@class, 'export_csv')]")
    waitUntilFileDownloaded(2000)
  }

Надеюсь, у вас есть идея. FluentWait - очень полезная абстракция, и хотя она является частью Selenium, ее можно использовать везде, где вам нужно подождать с опросом до тех пор, пока не будет выполнено какое-либо условие.

Ответ 3

do {

   filesize1 = f.length();  // check file size
   Thread.sleep(5000);      // wait for 5 seconds
   filesize2 = f.length();  // check file size again

} while (length2 != length1); 

где f - файл, размер файла длинный

Ответ 4

Ну, ваш файл где-то хранится, верно? Итак, проверьте, существует ли она в файловой системе

File f = new File(filePathString);

do {
  Thread.sleep(3000);
} while (f.exists() && f.length() == expectedSizeInBytes)

Ответ 5

Явная адаптация идеи Александра Арендра:

(с использованием Java 8 и предикатной версии до метода FluentWait)

  private void waitForFileDownload(int totalTimeoutInMillis, String expectedFileName) throws IOException {  
            FluentWait<WebDriver> wait = new FluentWait(this.funcDriver.driver)
                                   .withTimeout(totalTimeoutInMillis, TimeUnit.MILLISECONDS)
                                   .pollingEvery(200, TimeUnit.MILLISECONDS);
            File fileToCheck = getDownloadsDirectory()
                               .resolve(expectedFileName)
                               .toFile();

            wait.until((WebDriver wd) -> fileToCheck.exists());

        }


public synchronized Path getDownloadsDirectory(){
        if(downloadsDirectory == null){

            try {
                downloadsDirectory = Files.createTempDirectory("selleniumdownloads_");
            } catch (IOException ex) {
                throw new RuntimeException("Failed to create temporary downloads directory");
            }
        }
        return downloadsDirectory;
    }

Обратите внимание на использование createTempDirectory, чтобы избежать предостережений рекурсивно удалять больше, чем предполагалось, а также автоматически безопасно удалять папку, когда мы это делаем.

Ответ 6

Некоторые операционные системы (например, Mac OS X) не устанавливают имя файла до завершения загрузки. Поэтому для проверки существования файла достаточно использовать цикл ожидания или времени.

например

File file = new File(fullPathToFile);
while (!file.exists()) {
    Thread.sleep(1000);
}

Ответ 8

Приведенный ниже код работает нормально для меня.

Также никаких предупреждений не будет, так как я использовал общий тип и продолжительность, как рекомендовано.

Файл файл = новый файл ("C:\chromedriver_win32.zip"); FluentWait wait = новый FluentWait (драйвер).withTimeout(Duration.ofSeconds(25)). PollingEvery (Duration.ofMillis(100)); wait.until(x → file.exists());

Ответ 9

Если вы используете Chrome для загрузки, вы можете использовать приведенный ниже метод, чтобы убедиться, что скрипт будет ждать завершения загрузки.

Реализация Python:

def waitUntilDownloadCompleted(maxTime=600):
    driver.execute_script("window.open()")
    # switch to new tab
    driver.switch_to.window(driver.window_handles[-1])
    # navigate to chrome downloads
    driver.get('chrome://downloads')
    # define the endTime
    endTime = time.time() + maxTime
    while True:
        try:
            # get the download percentage
            downloadPercentage = driver.execute_script(
                "return document.querySelector('downloads-manager').shadowRoot.querySelector('#downloadsList downloads-item').shadowRoot.querySelector('#progress').value")
            # check if downloadPercentage is 100 (otherwise the script will keep waiting)
            if downloadPercentage == 100:
                # exit the method once it completed
                return downloadPercentage
        except:
            pass
        # wait for 1 second before checking the percentage next time
        time.sleep(1)
        # exit method if the download not completed with in MaxTime.
        if time.time() > endTime:
            break

Просто вызывайте метод, когда нажимаете на ссылку/кнопку загрузки.

# click on download button
driver.find_element_by_xpath("//*[@id='perform']").click()
#wait until the download completed
waitUntilDownloadCompleted(120) #2 minutes

Ответ 10

import time
from os import walk

download_dir = 'path\\to\\download\\folder'


def check_if_download_folder_has_unfinished_files():
    for (dirpath, dirnames, filenames) in walk(download_dir):
        return str(filenames)


def wait_for_files_to_download():
    time.sleep(5)  # let the driver start downloading
    file_list = check_if_download_folder_has_unfinished_files()
    while 'Unconfirmed' in file_list or 'crdownload' in file_list:
        file_list = check_if_download_folder_has_unfinished_files()
        time.sleep(1)


if __name__ == '__main__':
    wait_for_files_to_download()