2014-03-28 187 views
6

一旦點擊下載按鈕,文件將被下載。在執行下一個代碼之前,它需要等到下載完成。 我的代碼如下所示:等待下載完成在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的等待,直至下載完成?

+0

你有問題嗎? –

+0

如何讓webdriver等待下載完成 – qaepk

+0

這超出了WebDriver的功能,一旦下載開始,它就不再是瀏覽器操作,因此WebDriver無法如此控制它。看看這個博客文章,這是非常豐富的,當談到這個話題。 http://ardesco.lazerycode.com/index.php/2012/07/how-to-download-files-with-selenium-and-why-you-shouldnt/ –

回答

2

那麼,你的文件存儲在某個地方,對吧?因此,檢查它是否在文件系統

File f = new File(filePathString); 

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

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

例如

File file = new File(fullPathToFile); 
while (!file.exists()) { 
    Thread.sleep(1000); 
} 
2
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是一個文件,文件大小是長

6

晚了一點,但這個問題有意見了好多個,我認爲這將是值得花時間來回答如果你還沒有移動或有人遇到它。

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

您通常會點擊開始下載的元素應該有一個'href'屬性,您應該可以使用硒進行讀取。這是指向實際文件的網址。在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。希望這可以幫助!

+0

這非常適合應用。我處理大量不使用諸如將文件放在'href'中那樣簡單的網站,但如果它們這樣做,那就太棒了。 –

+0

這沒有錯,我之前也用過這個方法。爲了使這個工作通過身份驗證,您可以從selenium的驅動程序獲取cookie並追加到http請求中。但是,當下載鏈接由js生成時,它會很痛苦。而且你不能測試點擊下載按鈕是否實際下載文件。我切換回正常的狀態,點擊按鈕並執行'file.exists()'循環檢查。對於集線器節點體系結構中的硒,我使用'ssh'來存放'ls'或'dir'文件。 – rrw

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

0

亞歷山大Arendar的想法的一個java適應:

(使用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,以避免遞歸刪除更多的告誡比預期的要好,當我們重新使用它時會自動安全地處理文件夾。