2014-03-28 188 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,以避免递归删除更多的告诫比预期的要好,当我们重新使用它时会自动安全地处理文件夹。