Working with file upload using Java Selenium WebDriver

The Blog To Learn Selenium and Test Automation

Working with file upload using Java Selenium WebDriver

We have seen how to download file in selenium in this article. Like file download scenario, file upload is also frequently used use case in automation testing.

In this article, lets learn how to upload a file using Java Selenium Webdriver. For python example, visit our article.

Sample HTML:

<!DOCTYPE html>
<html>
   <body>
      <form action="**">
         <input type="file" name="uploadfile" id="uploadfile"/>
         <input type="button" name="submit" id="submit"/>
      </form>
   </body>
</html>

As far as Selenium 1 is considered, the way to address this is to place the files in an accessible server and use the attachFile command that points to the correct URL to file location in server.

Things changed in Selenium Webdriver and it comes with native file upload feature. Uploading files in WebDriver is done by simply using the sendKeys() method on the ‘file select’ input field i.e. just enter the path to the file to be uploaded.

There is no setup required for running tests with file upload scenarios locally, all we need to do is use the sendKeys command to type the local path of the file in the file field. This is sufficient and works very well in all drivers.

WebDriver driver = new FirefoxDriver();
driver.get(“http://example.com/file-upload-page”);
WebElement upload = driver.findElement(By.id(“myfile”));
upload.sendKeys(“/path-to-file/users.csv”);
driver.findElement(By.id(“submit”)).click();

The problem occurs when moving the same test to run in a remote server (for example, Selenium Grid running in some other server). Selenium webdriver has a built-in feature for this scenario as well, all we have to do is use the setFileDetector method to let WebDriver know that you’re uploading files from your local computer to a remote server instead of just typing a path.

Two things happens,
1. The file is base64 encoded
2. And sent transparently through the JSON Wire Protocol to the remote server where test is running

This is before writing the fixed remote path. This is an straight forward solution which lets users to switch their tests from a local to remote Driver without having to worry about code change(However you need to have strategy to create local as well as remote webdriver based on some conditions and this condition could be from anywhere such as property file, command line, etc…).

This feature is available in all the official Selenium 2 bindings from Selenium 2.8.0 or newer as this feature has been released then. Here are some examples tests:

At any case, Do not click on browse button to upload file. This will open up OS native file explorer and halt the tests since selenium cannot handle those kind of stuffs.

Below is java example code:

import java.net.URL;
import java.util.concurrent.TimeUnit;

import org.openqa.selenium.By;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;

public class UploadFileTest {

private RemoteWebDriver driver;

public void setUp() throws Exception {
   DesiredCapabilities capabilities = DesiredCapabilities.firefox();
   capabilities.setCapability("platform", Platform.LINUX);

   driver = new RemoteWebDriver(new URL("http://127.0.0.1:4444/wd/hub"), capabilities);
   driver.setFileDetector(new LocalFileDetector());
   driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
}

public void testSauce() throws Exception {
   driver.get("http://example.com/file-upload-page");
   WebElement upload = driver.findElement(By.id("uploadfile"));
   upload.sendKeys("/path-to-file/users.csv");
   driver.findElement(By.id("submit")).click();
}

public void tearDown() throws Exception {
   driver.quit();
}
}

Note the game changing line ‘driver.setFileDetector(new LocalFileDetector());’ in above sample script. Also please note that this does not affect local test execution and comes into play only when tests are running in remote server.

This sample is to run tests in remote machine and refer files from local i.e. from where execution is controlled. If you want to send files to one machine/local to remote, you must use other file transfer options available outside of selenium.

There are other options like AutoIt and java in built Robot class available to handle this kind of scenario. However it is good to use built-in feature because, there are no dependency on external executables(AutoIt) and tests are not flaky(in case of Robot class).

Hope this helps you efficiently in your Selenium projects. If there are any different approach to work with the file uploads that you know, please use the comment box to share it which will help all.

 

Leave a Reply

Your email address will not be published. Required fields are marked *