简体   繁体   中英

How to wait for download to finish using Webdriver

Is there any way to wait for a download to finish in WebDriver?

Basically, I want to verify that downloaded file getting stored correctly inside hard drive and to verify that, need to wait till download finishes. Please help if anyone aware of such a scenario earlier.

Not a direct answer to your question but I hope it will help.

Pool the file on your hard drive (compute a MD5 of it). Once it is correct, you can go further with your test. Fail your tets if the file is not correct after a timeout.

Poll the configured download directory for absence of partial file.

Example code for Chrome below:

    File destinationDir = new File("blah");

    Map<String, Object> prefs = new HashMap<>();
    prefs.put("download.default_directory", destinationDir.getAbsolutePath());

    DesiredCapabilities desiredCapabilities = DesiredCapabilities.chrome();

    ChromeOptions options = new ChromeOptions();
    options.setExperimentalOption("prefs", prefs);
    desiredCapabilities.setCapability(ChromeOptions.CAPABILITY, options);

    WebDriver webDriver = new ChromeDriver(desiredCapabilities);
    // Initiate download...

    do {
        Thread.sleep(5000L);
    } while(!org.apache.commons.io.FileUtils.listFiles(destinationDir, new String[]{"crdownload"}, false).isEmpty());

As answered on Wait for Download to finish in selenium webdriver JAVA

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

Then you can use a library like this to do the actual file handling to see the file is stored correctly (that could mean comparing file size, Md5 hashes or even checking the content of the file which Tika can actually do as well).

public void fileChecker(){
        waitForFileDownload(20000,"filename_here");

        File file = downloadsDirectory.resolve(expectedFileName).toFile();

        AutoDetectParser parser = new AutoDetectParser();
        parser.setParsers(new HashMap<MediaType, Parser>());

        Metadata metadata = new Metadata();
        metadata.add(TikaMetadataKeys.RESOURCE_NAME_KEY, file.getName());

        try (InputStream stream = new FileInputStream(file)) {
            parser.parse(stream, (ContentHandler) new DefaultHandler(), metadata, new ParseContext());
        }

        String actualHash = metadata.get(HttpHeaders.CONTENT_MD5); 
        assertTrue("There was a hash mismatch for file xyz:",actualHash.equals("expectedHash"));
    }

I am your the bellow code in Python + Firefox:

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

For small files, I currently either use an implied wait or wait for the JS callback that my file has downloaded before moving on. The code below was posted on SO by another individual, I can't find the post right away, so I won't take credit for it.

public static void WaitForPageToLoad(IWebDriver driver) { TimeSpan timeout = new TimeSpan(0, 0, 2400); WebDriverWait wait = new WebDriverWait(driver, timeout);

        IJavaScriptExecutor javascript = driver as IJavaScriptExecutor;
        if (javascript == null)
            throw new ArgumentException("driver", "Driver must support javascript execution");

        wait.Until((d) =>
        {
            try
            {
                string readyState = javascript.ExecuteScript("if (document.readyState) return document.readyState;").ToString();
                return readyState.ToLower() == "complete";
            }
            catch (InvalidOperationException e)
            {
                //Window is no longer available
                return e.Message.ToLower().Contains("unable to get browser");
            }
            catch (WebDriverException e)
            {
                //Browser is no longer available
                return e.Message.ToLower().Contains("unable to connect");
            }
            catch (Exception)
            {
                return false;
            }
        });
    }

It should wait for your file to finish if it is small. Unfortunately, I haven't tested this on larger files ( > 5MB )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM