Just like with uploading files we hit the same issue with downloading them. A dialog box just out of Selenium’s reach.
A Solution
With some additional configuration when setting up Selenium we can easily side-step the dialogue box. This is done by instructing the browser to download files to a specific location without triggering the dialogue box.
After the file is downloaded we can perform some simple checks to make sure the file is what we expect.
Sample code
Python
# filename: download.py
import os
import time
import shutil
import tempfile
import unittest
from selenium import webdriver
class Download(unittest.TestCase):
def setUp(self):
self.download_dir = tempfile.mkdtemp()
profile = webdriver.FirefoxProfile()
profile.set_preference("browser.download.dir", self.download_dir)
profile.set_preference("browser.download.folderList", 2)
profile.set_preference(
"browser.helperApps.neverAsk.saveToDisk",
"images/jpeg, application/pdf, application/octet-stream")
profile.set_preference("pdfjs.disabled", True)
self.driver = webdriver.Firefox(firefox_profile=profile)
def tearDown(self):
self.driver.quit()
shutil.rmtree(self.download_dir)
def test_example_1(self):
driver = self.driver
driver.get('http://the-internet.herokuapp.com/download')
download_link = driver.find_element_by_css_selector('.example a')
download_link.click()
time.sleep(1.0) # necessary for slow download speeds
files = os.listdir(self.download_dir)
files = [os.path.join(self.download_dir, f)
for f in files] # add directory to each filename
assert len(files) > 0, "no files were downloaded"
assert os.path.getsize(files[0]) > 0, "downloaded file was empty"
if __name__ == "__main__":
unittest.main()
Ruby
# filename: download_file.rb
require 'selenium-webdriver'
require 'rspec/expectations'
include RSpec::Matchers
require 'uuid'
require 'fileutils'
def setup
@download_dir = File.join(Dir.pwd, UUID.new.generate)
FileUtils.mkdir_p @download_dir
# Firefox
profile = Selenium::WebDriver::Firefox::Profile.new
profile['browser.download.dir'] = @download_dir
profile['browser.download.folderList'] = 2
profile['browser.helperApps.neverAsk.saveToDisk'] = 'images/jpeg, application/pdf, application/octet-stream'
profile['pdfjs.disabled'] = true
@driver = Selenium::WebDriver.for :firefox, profile: profile
end
def teardown
@driver.quit
FileUtils.rm_rf @download_dir
end
def run
setup
yield
teardown
end
run do
@driver.get 'http://the-internet.herokuapp.com/download'
download_link = @driver.find_element(css: '.example a')
download_link.click
files = Dir.glob("#{@download_dir}/*")
expect(files.empty?).to eql false
expect(File.size(files.first)).to be > 0
end
Java
//filename: DownloadFile.java
import java.awt.AWTException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
public class DownloadFile {
private RemoteWebDriver driver;
@BeforeClass
public void setUp() throws Exception {
System.setProperty("webdriver.chrome.driver", "/Users/neeraj.kumar/Desktop/chromedriver");
ChromeOptions options = new ChromeOptions();
Map<String, Object> prefs = new HashMap<String, Object>();
prefs.put("download.prompt_for_download", false);
options.setExperimentalOption("prefs", prefs);
driver = new ChromeDriver(options);
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
driver.manage().window().maximize();
}
@Test
public void fileDownload() throws AWTException, InterruptedException {
driver.get("https://chromedriver.storage.googleapis.com/index.html?path=79.0.3945.36/");
Thread.sleep(2000);
WebElement btnDownload = driver.findElement(By.xpath(".//a[text()='chromedriver_win32.zip']"));
btnDownload.click();
Thread.sleep(7000);
//add code related to validating downloaded files
}
@AfterClass
public void tearDown() throws Exception {
driver.quit();
}
}
When we save this file and run it, this is what will happen:
- Create a uniquely named temp directory in the present working directory
- Open the browser
- Visit the page
- Find and click the first download link on the page
- Automatically download the file to the temp directory without prompting
- Check that the temp directory is not empty
- Check that the downloaded file is not empty
- Close the browser
- Delete the temp directory