簡體   English   中英

在 selenium webdriver JAVA 中等待下載完成

[英]Wait for Download to finish in 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 等待下載完成?

有點晚了,但這個問題有很多觀點,我認為如果你沒有繼續前進或其他人遇到它,我認為值得花時間回答它。

我也遇到了同樣的問題,並認為我會分享。 我當時正在用 python 開發,但同樣的概念也適用。 您不必使用 selenium 進行實際下載。 與其單擊元素開始下載,不如考慮檢索鏈接並使用內置函數從那里繼續。

您通常單擊開始下載的元素應該有一個“href”屬性,您應該能夠使用 selenium 讀取該屬性。 這是指向實際文件的 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 中我相信你可以使用 HttpURLConnection API。 希望這可以幫助!

do {

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

} while (filesize1 != filesize2); 

其中 f 是文件,文件大小很長

我使用 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 的一部分,但它可以用於任何需要等待輪詢直到滿足某些條件的地方。

好吧,您的文件存儲在某個地方,對嗎? 所以,檢查它是否存在於文件系統中

File f = new File(filePathString);

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

我喜歡等待

    Path filePath = Paths.get(".", "filename");
    await().atMost(1, MINUTES)
            .ignoreExceptions()
            .until(() -> filePath.toFile().exists());

更多信息: http : //www.testautomationguru.com/selenium-webdriver-how-to-wait-for-expected-conditions-using-awaitility/

Alexander Arendar 想法的 Java 改編版:

(使用 Java 8 和 FluentWait 的 until 方法的謂詞版本)

  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 避免遞歸刪除超出預期的警告,以及在我們完成文件夾時自動安全地處理文件夾。

下面的代碼對我來說工作正常。

也不會發出警告,因為我按照建議使用了泛型類型和Duration

File file = new File("C:\\chromedriver_win32.zip");
FluentWait<WebDriver> wait = new FluentWait<WebDriver>(driver).withTimeout(Duration.ofSeconds(25)).pollingEvery(Duration.ofMillis(100));
wait.until( x -> file.exists());

某些操作系統(例如 Mac OS X)在下載完成之前不會設置文件名。 因此,使用wait 或while 循環來檢查文件是否存在似乎就足夠了。

例如

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

如果您使用 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's 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
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()

這個對我有用:

    Path filePath = Paths.get("path/to/file/fileName.pdf");
    File file = filePath.toFile(); 

 void waitForFileDownloaded(File file, int timeoutSeconds) {
        WebDriver driver = getDriver();
        FluentWait<WebDriver> wait = new FluentWait<>(driver)
                .withTimeout(Duration.ofSeconds(timeoutSeconds))
                .pollingEvery(Duration.ofMillis(500))
                .ignoring(NoSuchElementException.class, StaleElementReferenceException.class);
        wait.until((webDriver) -> file.exists());
    }

這是一個只使用 WebDriverWait 的:

new WebDriverWait(driver, 60).until(d -> Paths.get(downloadDir, downloadFileName).toFile().exists());

此代碼將始終有效.. 試試吧伙計們!

public void waitForFileDownloaded(String fileName, int timeoutSeconds) {
    FluentWait<WebDriver> wait = new FluentWait<>(driver)
            .withTimeout(Duration.ofSeconds(timeoutSeconds))
            .pollingEvery(Duration.ofMillis(500))
            .ignoring(NoSuchElementException.class, StaleElementReferenceException.class);
    wait.until((x) -> {
        File[] files = new File(downloadfolderPath).listFiles();
        for (File file : files) {
            if (file.getName().contains(fileName)) {
                return true;
            }
        }
        return false;
    });
}

我是你在 Python + Firefox 中的波紋管代碼,但它可以適應 Java:

browser.get('about:downloads')  #Open the download page.
# WAit all icons change from "X" (cancel download)
WebDriverWait(browser, URL_LOAD_TIMEOUT * 40).until_not(
    EC.presence_of_element_located((By.CLASS_NAME, 'downloadIconCancel')))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM