_java
TL;DR - Show Me The Code
package com.elemental.selenium;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.By;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.io.File;
import java.util.UUID;
import java.time.Duration;
public class DownloadTest {
WebDriver driver;
File folder;
@BeforeEach
public void beforeEach() {
folder = new File(UUID.randomUUID().toString());
folder.mkdir();
FirefoxOptions options = new FirefoxOptions();
options.addPreference("browser.download.dir", folder.getAbsolutePath());
options.addPreference("browser.download.folderList", 2);
options.addPreference("browser.helperApps.neverAsk.saveToDisk",
"image/jpeg, application/pdf, application/octet-stream");
options.addPreference("pdfjs.disabled", true);
driver = new FirefoxDriver(options);
}
@AfterEach
public void afterEach() {
if (driver != null) {
driver.quit();
}
for (File file: folder.listFiles()) {
file.delete();
}
folder.delete();
}
@Test
public void downloadFile() throws Exception {
driver.get("https://the-internet.herokuapp.com/download");
driver.findElement(By.cssSelector(".example a")).click();
// Wait for the file to be downloaded up to 5 seconds
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));
wait.until((WebDriver d) -> folder.listFiles().length > 0 && folder.listFiles()[0].length() > 0);
File[] listOfFiles = folder.listFiles();
// Make sure the directory is not empty
Assertions.assertTrue(listOfFiles.length > 0);
for (File file : listOfFiles) {
// Make sure the downloaded file(s) is(are) not empty
Assertions.assertTrue(file.length() > 0);
}
}
}
Code Walkthrough
Importing Libraries
Lines 3 to 14 are pulling in our requisite classes for annotations (e.g., org.junit.jupiter.api.BeforeEach
, etc.),
driving the browser with Selenium (e.g., org.openqa.selenium.WebDriver
, etc.), matchers for assertions
(e.g., org.junit.jupiter.api.Assertions;
, etc. ), something to handle local files (e.g., java.io.File
), and a means
to create a uniquely named folder to place downloaded files in (e.g., java.util.UUID
)
Setup and Teardown
Lines 21 to 42 are setting up and tearing down the browser instance. The beforeEach
method, will execute before
each test. In it we're creating a uniquely named temp directory (e.g., UUID.randomUUID().toString();
), configuring a
browser options object (for Firefox in this case), and plying it with the necessary configuration parameters to make
it automatically download the file where we want (e.g., in the newly created temp directory).
Here's a breakdown of each of the browser preferences being set:
browser.download.dir
accepts a string. This is how we set the custom download path. It needs to be an absolute path.browser.download.folderList
takes a number. It tells Firefox which download directory to use.2
tells it to use a custom download path, wheras1
would use the browser's default path, and0
would place them on the Desktop.browser.helperApps.neverAsk.saveToDisk
tells Firefox when not to prompt for a file download. It accepts a string of the file's MIME type. If you want to specify more than one, you do it with a comma-separated string.pdfjs.disabled
is for when downloading PDFs. This overrides the sensible default in Firefox that previews PDFs in the browser. It accepts a boolean.
This options object is then passed into our instance of Selenium (e.g., driver = new FirefoxDriver(options);
).
After our test executes the second method, afterEach
, will execute. In it, we close the browser instance and then
clean up the temp directory by deleting the files in the temp folder and then the temp folder.
The Test
Lines 45 to 60 are the test itself.
After visiting the page we find the first download link and click it. The click triggers an automatic download to the
temp directory created in setUp()
. We need to wait for the download to finish, so we use Selenium's WebDriverWait
to
wait up to 5 seconds. After the file downloads, we perform some rudimentary checks to make sure the temp directory
isn't empty and then check the file (or files) that they aren't empty either.
Executing the Test
Before executing the test, we need to make sure the required dependencies are declared on the pom.xml
file.
Toggle to see the pom.xml
file.
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.elemental.selenium</groupId>
<artifactId>tips</artifactId>
<version>1.0.0</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.26.0</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.11.3</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Finally, we can run the test by executing mvn test
from the command-line.