Best Practices & Tips: Selenium File Upload

Learn how to use the Selenium file upload feature with Sauce Labs’ guide.

In this tutorial, we’ll cover how to upload files using Webdriver’s native file upload feature.

As you may know, the way to address this in Selenium 1 is to place your files in an accessible web server and use the attachFile command that points to the correct URL. With Selenium 2, the Selenium Dev team has luckily made this a lot more straightforward.

For those of you doing this locally, all you need to do is use the sendKeys command to type the local path of the file in any file field. This works like a charm in all drivers. When moving this test to a remote server (such as, for example, our Selenium 2 Cloud), all you need 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. Almost magically, the file will be base64 encoded and sent transparently through the JSON Wire Protocol for you before writing the fixed remote path. This is an excellent solution, as it lets you switch your tests from a local to remote Driver without having to worry about changing your tests’ code.

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

Java

import junit.framework.Assert;
import junit.framework.TestCase;
import org.openqa.selenium.*;
import org.openqa.selenium.remote.*;
import java.net.URL;
import java.util.concurrent.TimeUnit;
    public class TestingUploadSe2Sauce extends TestCase {
    private RemoteWebDriver driver;
    public void setUp() throws Exception {
            DesiredCapabilities capabillities = DesiredCapabilities.firefox();
            capabillities.setCapability("version", "7");
            capabillities.setCapability("platform", Platform.XP);
            capabillities.setCapability("selenium-version", "2.18.0");
            capabillities.setCapability("name", "Remote File Upload using Selenium 2's FileDetectors");
        driver = new RemoteWebDriver(
            new URL("http://<username>:<api-key>@ondemand.saucelabs.com:80/wd/hub"),
        capabillities);
        driver.setFileDetector(new LocalFileDetector());
        driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
}

public void testSauce() throws Exception {
        driver.get("http://sso.dev.saucelabs.com/test/guinea-file-upload");
        WebElement upload = driver.findElement(By.id("myfile"));
        upload.sendKeys("/Users/sso/the/local/path/to/darkbulb.jpg");
        driver.findElement(By.id("submit")).click();
        driver.findElement(By.tagName("img"));
        Assert.assertEquals("darkbulb.jpg (image/jpeg)", driver.findElement(By.tagName("p")).getText());
}
public void tearDown() throws Exception {
      driver.quit();

}
}

view rawTestingUploadSe2Sauce.java hosted with ? by GitHub

Ruby

require 'rubygems'
require "test/unit"
require 'selenium-webdriver'
class ExampleTest < Test::Unit::TestCase
 def setup
    caps = Selenium::WebDriver::Remote::Capabilities.firefox
    caps.version = "5"
    caps.platform = :XP
    caps[:name] = "Remote File Upload using Selenium 2 with Ruby"
    caps['selenium-version'] = "2.18.0"
    @driver = Selenium::WebDriver.for(
      :remote,
      :url => "http://<username>:<api-key>@saucelabs.com:4444/wd/hub",
      :desired_capabilities => caps)
    @driver.file_detector = lambda do |args|
       # args => ["/path/to/file"]
       str = args.first.to_s    
       str if File.exist?(str)
    end
 end

 def test_sauce
    @driver.navigate.to "http://sso.dev.saucelabs.com/test/guinea-file-upload"
    element = @driver.find_element(:id, 'myfile')
    element.send_keys   "/Users/sso/SauceLabs/sauce/hostess/maitred/maitred/public/images/darkbulb.jpg"
    @driver.find_element(:id, "submit").click
    @driver.find_element(:tag_name, "img")
    assert "darkbulb.jpg (image/jpeg)" == @driver.find_element(:tag_name, "p").text
end

def teardown
    @driver.quit
end

end

view the raw test hosted with love by GitHub

And here’s what the test looks like after running in our cloud:

https://saucelabs.com/jobs/1a408cf60af0601f49052f66fa37812c

Pro tip: Write your own FileHandler that will use special codes to represent files before typing paths (locally) or uploading them (remotely). Example: “test-file:small-image”

Sauce Labs - Selenium Testing on the Cloud

This tutorial was brought to you by Sauce Labs, the leading cloud testing platform that enables you to run Selenium tests without the hassle of maintaining infrastructure. Co-founded by the original creator of Selenium, Sauce Labs helps developers scale their testing and speed up development. Sauce users run millions of Selenium tests a month in our cloud.