How To Download and Upload Files Using Selenium With Java
This tutorial demonstrates how to upload and download files using Selenium Webdriver across multiple operating systems and web browsers.
Join the DZone community and get the full member experience.
Join For FreeWhile Selenium testing, you may have come across a requirement where you need to either download or upload a file in Selenium. Almost every web application over the internet may have a feature for allowing users to either download or upload a file. Be it a rich-media platform such as YouTube which lets you upload video files, an online photo collage maker, or an e-commerce web application which allows you to upload images. Even writing assistants like Grammarly and Plagiarism checker like Quetext offer an uploading file functionality.
Similarly, these websites offer downloading functionality, too. YouTube allows offline downloading, and e-commerce platforms such as Amazon will let you download the invoices of your orders. My point is that if you are an automation tester who has a routine set around Selenium testing, there is a good chance for you to run into a requirement where you may have to test a feature around downloading or uploading files in Selenium WebDriver.
In Selenium testing, it is very important to know how to upload files in Selenium WebDriver or download files in Selenium WebDriver through automation testing with Selenium. In this Selenium Java tutorial, I am going to highlight different ways through which you can download or upload files in Selenium WebDriver.
What Is A Remote WebDriver?
Remote WebDriver implements each command of the JSONWireProtocol and users can perform locally and remotely on a remote server. All browser drivers are child classes of the RemoteWebDriver and RemoteWebDriver is a class type and implements all WebDriver interface. So, RemoteWebDriver has the capability of Selenium testing on either local infrastructure or on a cloud-based Selenium Grid such as LambdaTest.
Let’s understand the real use case of uploading files in Selenium WebDriver. Suppose you are developing automation scripts for testing with Selenium and Java over an online clinical web platform where patients can book a video consultation with a doctor. On that website, there is an option to upload a Test Report where a doctor can review and discuss test reports. In such a case, you need to use upload file concepts to upload reports to their clinical web application.
Note: If you have already implemented file uploading script in your local script and want to upgrade to a remote cloud-based environment then you need to just change WebDriver to RemoteWebDriver and use the driver.setFileDetector(new LocalFileDetector());
method.
Upload Files in Selenium With Java
If you are familiar with Selenium 1, accessible web server and attachFile
command were using upload files. And in Selenium 2 and going forward, it is like just a sendkeys()
command and you're done uploading a file. When you want to upload files locally then you can directly use SendKey()
and give a path in code. However, the same thing will not work remotely as did on locally. For uploading files in Selenium Remote WebDriver, you need to leverage the method called the setFileDetector
method. That way, Remote WebDriver acknowledges when you are uploading files for Selenium testing over either a local machine or a remote machine. With this excellent feature of Selenium 2, you do not have to write separate code to perform Selenium testing for uploading files over locally or remotely hosted web-application. We have following options to upload files in a Remote Selenium WebDriver:
- SendKeys
- Robot Class
- AutoIT tool
- Jacob API
Upload Files In Selenium WebDriver Using Sendkeys()
It is always preferred to first use the built-in features provided by Selenium Java to upload a file in Remote Selenium WebDriver. That is the SendKeys
method. It directly applies to input tags which have an attribute as type=’file’
.
Here is an example of how to upload files in Selenium and Java using the Sendkeys()
:
WebElement addFile = driver.findElement(By.xpath(".//input[@type='file']"));
addFile.sendKeys("/Users/neeraj.kumar/Desktop/c1.jpeg");
Upload Files In Selenium WebDriver Using Robot Class
The Robot class is an AWT class package in Java. This is also a very good option to choose for the Upload file in selenium. This will help to automate a Windows-based alert or pop up, print pop up or native Windows screen. This is independent of the Operating System.
Here is the example of a file uploading using Robot class:
xxxxxxxxxx
public void fileUpload (String path) {
StringSelection strSelection = new StringSelection(path);
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(strSelection, null);
Robot robot = new Robot();
robot.delay(300);
robot.keyPress(KeyEvent.VK_ENTER);
robot.keyRelease(KeyEvent.VK_ENTER);
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_ENTER);
robot.delay(200);
robot.keyRelease(KeyEvent.VK_ENTER);
}
Upload File In Selenium WebDriver Using AutoIT
AutoIT is an external automation tool and not provided by the Selenium community. Initially, AutoIT was used to automate native Windows related pop-ups, however, a drawback of using AutoIT is that it creates .exe file and runs only on Windows. It is not advisable to use AutoIT for file uploads. However, if you still wish to perform a file upload in Selenium WebDriver using AutoIT then here is an example for you:
xxxxxxxxxx
WinWaitActive("File Upload");
Send("/Users/neeraj.kumar/Desktop/c1.jpeg");
Send("{ENTER}")
Upload File using Jacob API
Jacob provides the API technique to upload files using Selenium. Again, to perform a file upload in Selenium WebDriver using Jacob API you would need a .dll file. That means it won’t work for a Mac or Linux operating system. If you only want to target Windows operating systems then here is an example of upload File using Jabob API.
xxxxxxxxxx
public void UploadFile() throws InterruptedException {
String userDir = System.getProperty("user.dir");
FinalString jacobArchitect =
System.getProperty("sun.arch.data.model").contains("32") ? "jacob-1.18-x86.dll" : "jacob-1.18-x64.dll";
String jacobArchitectPath = userDir + "\" + jacobArchitect;
File filejacob = new File(jacobArchitect);
System.setProperty(LibraryLoader.JACOB_DLL_PATH,
filejacob.getAbsolutePath());
AutoItX uploadWin = new AutoItX();
driver = new FirefoxDriver();
driver.get(“https://blueimp.github.io/jQuery-File-Upload/
”);
Thread.sleep(1000);
WebElement addFile = driver.findElement(By.xpath(".//input[@type='file']"));
.click();
Thread.sleep(1000);
if (uploadWin.winWaitActive("File Upload", "", 5)) {
if (uploadWin.winExists("File Upload")) {
uploadWin.sleep(100);
uploadWin.send("/Users/neeraj.kumar/Desktop/c1.jpeg");
uploadWin.controlClick("File Upload", "", "&Open");
}
}
}
File Upload In Selenium WebDriver Locally and in the Cloud
Now, let me demonstrate how to upload files in a Remote Selenium WebDriver over both, on your local infrastructure as well as over the cloud-based Selenium Grid such as LambdaTest. As a part of this Selenium Java tutorial, I would be focusing on leveraging the SendKeys()
method to upload files in Selenium and Java.
The scenario would be
- Open https://blueimp.github.io/jQuery-File-Upload/ and
- Click on Add files... button
- Then Start Upload
- Assert it back.
First off, we will start with the demonstration to upload files using local infrastructure machines. Later we will have a demonstration of the same Selenium testing script over a cloud-based Selenium Grid.
Upload Files In Selenium WebDriver Over Local Infrastructure
Below is a Selenium Java testing script which demonstrates how to upload files in Selenium WebDriver over your local machine.
xxxxxxxxxx
package com.POMFramework.tests;
import static org.testng.Assert.assertTrue;
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.remote.RemoteWebDriver;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
public class LamdaTestUploadFile {
private RemoteWebDriver driver;
public void setUp() throws Exception {
System.setProperty("webdriver.chrome.driver", "/Users/neeraj.kumar/Desktop/chromedriver");
driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
}
public void lamdaTest() throws Exception {
driver.get("https://blueimp.github.io/jQuery-File-Upload/");
Thread.sleep(2000);
WebElement addFile = driver.findElement(By.xpath(".//input[@type='file']"));
addFile.sendKeys("/Users/neeraj.kumar/Desktop/c1.jpeg");
driver.findElement(By.xpath(".//span[text()='Start upload']")).click();
Thread.sleep(2000);
if(driver.findElement(By.xpath(".//a[text()='c1.jpeg']")).isDisplayed()) {
assertTrue(true, "Image Uploaded");
}else {
assertTrue(false, "Image not Uploaded");
}
}
public void tearDown() throws Exception {
driver.quit();
}
}
That is it.! However, it isn’t all you need to know. It is important to note that when we refer to practical and real-time scenarios the requirement to perform automated browser testing might involve hundreds of browsers + OS combinations to be tested. Not to forget, the desired capabilities are bound to go bigger as your web application would scale over time.
In such scenarios, maintaining an in-house Selenium infrastructure is both time-consuming and expensive. You will need to hire more machines and resources on-board. Unless you can afford a device lab provider such as Amazon AWS which can be costly for many businesses. So what can you do?
Upload Files In Selenium WebDriver Over An Online Selenium Grid
Now, the same scenario can be run on the online Selenium Grid. We will be running the same script over LambdaTest which is a cross browser testing tool offering an online Selenium Grid. You should observe here that we have changed only two points as shown below.
driver = new RemoteWebDriver(new URL("http://hub.lambdatest.com:80/wd/hub"), capabilities);
driver.setFileDetector(new LocalFileDetector());
And, you are done!!! Here is the full Selenium Java testing script to upload file in Selenium WebDriver over an online Selenium Grid.
xxxxxxxxxx
package com.POMFramework.tests;
import static org.testng.Assert.assertTrue;
import java.net.URL;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
public class LamdaTestUploadFileRemotely {
private RemoteWebDriver driver;
public void setUp() throws Exception {
ChromeOptions capabilities = new ChromeOptions();
capabilities.setCapability("user","<username>");
capabilities.setCapability("accessKey","<accesskey>");
capabilities.setCapability("build", "Build 2");
capabilities.setCapability("name", "Check Uploaded Image");
capabilities.setCapability("platformName", "Windows 10");
capabilities.setCapability("browserName", "Chrome");
capabilities.setCapability("browserVersion","79.0");
driver = new RemoteWebDriver(new URL("http://hub.lambdatest.com:80/wd/hub"), capabilities);
driver.setFileDetector(new LocalFileDetector());
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
}
public void lamdaTest() throws Exception {
driver.get("https://blueimp.github.io/jQuery-File-Upload/");
Thread.sleep(2000);
WebElement addFile = driver.findElement(By.xpath(".//input[@type='file']"));
addFile.sendKeys("/Users/neeraj.kumar/Desktop/c1.jpeg");
driver.findElement(By.xpath(".//span[text()='Start upload']")).click();
Thread.sleep(2000);
if(driver.findElement(By.xpath(".//a[text()='c1.jpeg']")).isDisplayed()) {
assertTrue(true, "Image Uploaded");
}else {
assertTrue(false, "Image not Uploaded");
}
}
public void tearDown() throws Exception {
driver.quit();
}
}
Download Files in Selenium WebDriver
Now, that you are familiar with file uploading in Selenium WebDriver, you might be thinking that downloading a file with Selenium WebDriver is going to be just as easy! Well, think again! You have a web application and you would want the download file functionality to work seamlessly across different browsers so that your customers aren’t bothered by a UI bug. However, every web browser offers a different UI when downloading a file. Let us look at different screenshots of different browsers running on a macOS.
Similarly, these screenshots would differ for different operating systems, and operating system versions too. So when you are downloading a file through Google Chrome on Windows 7 it might give the below screen.
As you may notice, here the file was directly downloaded when the timer got to 0 seconds, without any user confirmation.
So every browser will have a different download mechanism based on the operating system over which it is being utilized. Browser configuration using a profile, different browser, different operating systems play a vital role while Selenium testing with Java to download the file.
To automatically download file using Selenium with Java, we have the following options:
- AutoIT
- Robot Class
- Browser Profile
Download a File In Selenium WebDriver Using AutoIT
Already we have discussed the AutoIT tool. The same tool is used for downloading files in selenium. Again, download window changes as per Browsers. So users have to consider all scenarios to automate download pop up.
Here is an AutoIT script example:
xxxxxxxxxx
WinWait("[CLASS:#MozillaDialogClass]","",8)
Send("!s")
Sleep(10000)
Send("{ENTER}")
Save this code and generate .exe file and execute it in java code using Runtime.getRuntime().exec()
. Again, it is not advisable to use it as it supports only Windows operating system and its external tool.
Download File In Selenium WebDriver Using Robot Class
You can run the Selenium testing script to download files using Selenium with Java through the Robot class.
xxxxxxxxxx
public void fileDownload() {
Robot robot = new Robot();
robot.keyPress(KeyEvent.VK_TAB);
robot.keyRelease(KeyEvent.VK_TAB);
robot.keyPress(KeyEvent.VK_ENTER);
robot.keyRelease(KeyEvent.VK_ENTER);
}
Note: AutoIT and Robot class code could change based on the browser-specific profile set as well as where you want to save. Moreover, the most important is the cursor focus. If your download pop up is not in focus then mostly your code will not work.
Download a File In Selenium WebDriver Using The Browser Profile Setting
By leveraging the browser profile setting, you can download files in Selenium WebDriver without interacting with the download window pop-up. You need to trick the browser profile. Here I have given an example for Google Chrome browser and Mozilla Firefox browser.
Add this code into your Selenium Java testing suite.
Google Chrome
x
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);
RemoteWebDriver driver = new ChromeDriver(options);
Mozilla Firefox
xxxxxxxxxx
FirefoxProfile profile=new FirefoxProfile();
profile.setPreference("browser.helperApps.neverAsk.openFile", "application/octet-stream");
WebDriver driver=new FirefoxDriver(profile);
A File Download In Selenium WebDriver
As we did a practical implementation of uploading files in Selenium WebDriver, we will now practice downloading files in Selenium WebDriver on both local and cloud Selenium Grid. I will be demonstrating the file downloading using the Browser Profile Setting.
Download Files Using Selenium With Java With The Browser Profile Setting
xxxxxxxxxx
package com.POMFramework.tests;
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 LamdaTestDownloadFile {
private RemoteWebDriver driver;
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();
}
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);
}
public void tearDown() throws Exception {
driver.quit();
}
}
Note: Working on a local machine for downloading files is easy to handle but on a remote machine, it works based on the permission you have been provided to access the remote WebDrivers.
Download File Example For Online Selenium Grid With The Browser Profile Setting
Similar to uploading, the only thing we need to tweak in the Selenium Java testing script is going to be the file detector and the hub URL.
xxxxxxxxxx
package com.POMFramework.tests;
import java.awt.AWTException;
import java.net.URL;
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.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
public class LamdaTestDownloadFileRemotely {
private RemoteWebDriver driver;
public void setUp() throws Exception {
ChromeOptions capabilities = new ChromeOptions();
capabilities.setCapability("user","<userName>");
capabilities.setCapability("accessKey","<Access key>");
capabilities.setCapability("build", "Build 4");
capabilities.setCapability("name", "Downloading File");
capabilities.setCapability("platformName", "Windows 10");
capabilities.setCapability("browserName", "Chrome");
capabilities.setCapability("browserVersion","79.0");
Map<String, Object> prefs = new HashMap<String, Object>();
prefs.put("download.prompt_for_download", false);
capabilities.setExperimentalOption("prefs", prefs);
driver = new RemoteWebDriver(new URL("http://hub.lambdatest.com:80/wd/hub"), capabilities);
driver.setFileDetector(new LocalFileDetector());
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
}
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(10000);
}
public void tearDown() throws Exception {
driver.quit();
}
}
Below is a screenshot of automation logs which shows that the file is downloaded successfully.
Wrapping Up!
Working on the upload file feature of Selenium is very easy if you have understood the difference between Remote WebDriver and WebDriver Interface. Selenium alows you to work to upload file feature on both local machine and remote machine. With the help of WebDriver, you can directly upload a file locally and with little change in object creation, and your script will run on a remote server as well. Similarly, downloading a file using a third-party tool would end up having a flaky automation test. Given practical examples for both and detailed explanations will give you more insight into this article.
Published at DZone with permission of Harshit Paul, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments