2014-03-28 9 views
6

Sobald Sie auf eine Download-Schaltfläche klicken, werden Dateien heruntergeladen. Bevor der nächste Code ausgeführt wird, muss er warten, bis der Download abgeschlossen ist. Mein Code sieht wie folgt aus:Warten Sie, bis der Download in selen webdriver beendet ist. 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(); 

Wie kann ich die WebDriver warten zu lassen, bis ein Download abgeschlossen ist?

+0

Haben Sie eine Frage? –

+0

Wie kann ich den Webdriver warten, bis ein Download abgeschlossen ist? – qaepk

+0

Dies geht über die Möglichkeiten von WebDriver hinaus, sobald ein Download startet, ist es kein Browser-Vorgang mehr, daher kann WebDriver es nicht als solches steuern. Schau dir diesen Blog-Beitrag an, der sehr informativ ist, wenn es um dieses Thema geht. http://ardesco.lazerycode.com/index.php/2012/07/how-to-download-files-with-selenium-and-why-you-souldnt/ –

Antwort

2

Nun, Ihre Datei ist irgendwo gespeichert, oder? Überprüfen Sie, ob es im Dateisystem vorhanden ist

File f = new File(filePathString); 

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

Einige Betriebssysteme (z. B. Mac OS X) legen den Dateinamen nicht fest, bis der Download abgeschlossen ist. Es scheint also ausreichend zu sein, eine wait- oder eine while-Schleife zu verwenden, um zu prüfen, ob die Datei existiert.

z.B.

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); 

wobei f eine Datei ist, Dateigröße ist lang

6

Ein wenig spät, aber diese Frage eine gute Anzahl von Ansichten hat, dachte ich, es ist die Zeit es für den Fall lohnen würde, Ihnen zu antworten sind nicht weitergezogen oder jemand anderes begegnet ihm.

Ich lief auch in das gleiche Problem und dachte, ich würde teilen. Ich entwickelte damals in Python, aber das gleiche Konzept gilt. Sie müssen den eigentlichen Download nicht mit Selen durchführen. Anstatt auf das Element zu klicken, um den Download zu starten, sollten Sie in Erwägung ziehen, den Link abzurufen und integrierte Funktionen zu verwenden, um von dort fortzufahren.

Das Element, auf das Sie normalerweise klicken würden, um den Download zu starten, sollte ein Attribut 'href' haben, das Sie mit Selen lesen können. Dies ist die URL, die auf die eigentliche Datei verweist. In Python sieht es ungefähr so ​​aus:

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

Von hier aus können Sie eine HTTP-Bibliothek verwenden, um die URL aufzurufen. Der wichtige Teil hier ist, dass Sie 'stream' auf 'true' setzen, damit Sie mit dem Schreiben der Bytes in eine Datei beginnen können. Stellen Sie sicher, dass der Dateipfad die richtige Dateierweiterung enthält und eine andere Sache, die meisten Betriebssysteme erlauben es Ihnen nicht, Dateien mit bestimmten Zeichen wie Backslashes oder Zitaten zu benennen.

Das Programm sollte nicht fortgesetzt werden, bis der Download abgeschlossen ist, so dass es nicht mehr notwendig ist, bis zum Abschluss abzurufen.

Ich entschuldige mich für die Beantwortung in einer anderen Sprache, in Java glaube ich, dass Sie die HttpURLConnection API verwenden können. Hoffe das hilft!

+0

Dies ist hervorragend für wenn es gilt. Ich beschäftige mich mit vielen Websites, die nicht so einfach sind, wie die Datei in 'href' zu schreiben, aber wenn sie das tun, ist das großartig. –

+0

Das ist nicht falsch, ich habe diese Methode auch schon mal benutzt. Und damit dies mit der Authentifizierung funktioniert, können Sie die Cookies von Selenis Treiber abrufen und an die http-Anfrage anhängen. Aber es ist ein Schmerz, wenn der Download-Link von js generiert wird. Und Sie können auch nicht testen, ob ein Klick auf den Download-Button die Datei tatsächlich herunterlädt. Ich bin wieder auf das normale Ding zurückgegangen, habe auf den Button geklickt und den 'file.exists()' Check in einer Schleife durchgeführt. Und für Selen in einer Hub-Knoten-Architektur verwende ich 'ssh', um' ls' oder 'dir' die Datei für das Vorhandensein. – rrw

2

Ich benutze Scala für meine Automatisierung, aber der Port zu Java sollte trivial sein, da ich dort sowieso Java Selenium Klassen verwende. So , müssen Sie zuerst das:

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 
     } 
    ) 
    } 

Da ist in meinem Test-Suite, wo ich xls-Datei zum Download ich dies nur haben:

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

Ich hoffe, dass Sie die Idee haben. FluentWait ist eine sehr nützliche Abstraktion und obwohl es ein Teil von Selenium ist, kann es überall dort verwendet werden, wo man mit dem Polling warten muss, bis eine Bedingung erfüllt ist.

0

Eine Java-Adaption von Alexander Arendar Idee:

(unter Verwendung von Java 8 & das Prädikat Version bis Methode 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; 
    } 

Beachten Sie die Verwendung von createTempDirectory die Einsprüche von rekursiv mehr Löschen zu vermeiden als beabsichtigt, sowie die automatische sichere Entsorgung des Ordners, wenn wir damit fertig sind.

Verwandte Themen