java - jemmy - windows screen automation




Warten Sie, bis der Download in selen webdriver JAVA abgeschlossen ist (4)

Ein wenig spät, aber diese Frage hat eine gute Anzahl von Ansichten, ich dachte, es wäre die Zeit wert, um es zu beantworten, falls Sie nicht weitergezogen sind oder jemand anderes darauf stößt.

Ich lief auch auf 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.

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)

Das Programm sollte nicht fortgesetzt werden, bis der Download abgeschlossen ist, so dass es nicht länger notwendig ist, bis zum Abschluss des Downloads zu pollen.

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

Nach dem Klicken auf eine Download-Schaltfläche werden Dateien heruntergeladen. Bevor der nächste Code ausgeführt wird, muss er warten, bis der Download abgeschlossen ist. Mein Code sieht so aus:

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 den Webdriver warten lassen, bis ein Download abgeschlossen ist?


Eine Java-Adaption von Alexander Arendars Idee:

(mit Java 8 und der Prädikatversion von bis FluentWait Methode)

  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, um die Vorbehalte zu vermeiden, dass rekursiv mehr als beabsichtigt gelöscht wird und der Ordner automatisch wieder sicher entfernt wird, wenn wir damit fertig sind.


Ich benutze Scala für meine Automatisierung, aber der Port zu Java sollte trivial sein, da ich dort sowieso Java-Selenium-Klassen verwende. Also, zuerst brauchst du 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
      }
    )
  }

Dann in meiner Testsuite, wo ich XLS-Datei herunterladen muss ich nur das:

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

Ich hoffe du hast die Idee. 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.


Nun, deine 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)




selenium-webdriver