Back to Resources

Blog

Posted March 9, 2012

Selenium Tips: Uploading Files in Remote WebDriver

quote

Since it's been a while since my last Selenium testing tips blog post, I thought it was time to share some Selenium love again. Today we're covering WebDriver's native solution to a very common issue when doing distributed cross browser testing: uploading files in remote servers. 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 JSONWireProtocol 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

1
import junit.framework.Assert;
2
import junit.framework.TestCase;
3
import org.openqa.selenium.*;
4
import org.openqa.selenium.remote.*;
5
import java.net.URL;
6
import java.util.concurrent.TimeUnit;
7
8
public class TestingUploadSe2Sauce extends TestCase {
9
private RemoteWebDriver driver;
10
11
public void setUp() throws Exception {
12
DesiredCapabilities capabillities = DesiredCapabilities.firefox();
13
capabillities.setCapability("version", "7");
14
capabillities.setCapability("platform", Platform.XP);
15
capabillities.setCapability("selenium-version", "2.18.0");
16
capabillities.setCapability("name", "Remote File Upload using Selenium 2's FileDetectors");
17
18
driver = new RemoteWebDriver(
19
new URL("http://<username>:<api-key>@ondemand.saucelabs.com:80/wd/hub"),
20
capabillities);
21
driver.setFileDetector(new LocalFileDetector());
22
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
23
}
24
25
public void testSauce() throws Exception {
26
driver.get("http://sl-test.herokuapp.com/guinea_pig/file_upload");
27
WebElement upload = driver.findElement(By.id("myfile"));
28
upload.sendKeys("/Users/sso/the/local/path/to/darkbulb.jpg");
29
driver.findElement(By.id("submit")).click();
30
driver.findElement(By.tagName("img"));
31
Assert.assertEquals("darkbulb.jpg (image/jpeg)", driver.findElement(By.tagName("p")).getText());
32
}
33
34
public void tearDown() throws Exception {
35
driver.quit();
36
}
37
}

Ruby

1
require 'rubygems'
2
require "test/unit"
3
require 'selenium-webdriver'
4
5
class ExampleTest < Test::Unit::TestCase
6
def setup
7
caps = Selenium::WebDriver::Remote::Capabilities.firefox
8
caps.version = "5"
9
caps.platform = :XP
10
caps[:name] = "Remote File Upload using Selenium 2 with Ruby"
11
caps['selenium-version'] = "2.18.0"
12
13
@driver = Selenium::WebDriver.for(
14
:remote,
15
:url => "http://<username>:<api-key>@saucelabs.com:4444/wd/hub",
16
:desired_capabilities => caps)
17
18
@driver.file_detector = lambda do |args|
19
# args => ["/path/to/file"]
20
str = args.first.to_s
21
str if File.exist?(str)
22
end
23
end
24
25
def test_sauce
26
@driver.navigate.to "http://sl-test.herokuapp.com/guinea_pig/file_upload"
27
element = @driver.find_element(:id, 'myfile')
28
element.send_keys "/Users/sso/SauceLabs/sauce/hostess/maitred/maitred/public/images/darkbulb.jpg"
29
30
@driver.find_element(:id, "submit").click
31
@driver.find_element(:tag_name, "img")
32
assert "darkbulb.jpg (image/jpeg)" == @driver.find_element(:tag_name, "p").text
33
end
34
35
def teardown
36
@driver.quit
37
end
38
end

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"

Published:
Mar 9, 2012
Share this post
Copy Share Link
© 2023 Sauce Labs Inc., all rights reserved. SAUCE and SAUCE LABS are registered trademarks owned by Sauce Labs Inc. in the United States, EU, and may be registered in other jurisdictions.