public
Last active

Remote File Upload using Selenium 2's FileDetectors

  • Download Gist
TestingUploadSe2Sauce.java
Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
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://sl-test.herokuapp.com/guinea_pig/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();
}
}
testing_upload_se2_sauce.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
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://sl-test.herokuapp.com/guinea_pig/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

The relevant lines in this gist for the upload are #21 (where the LocalFileDetector is set) and #28 (where the file input is typed into).
Here's the result job in Sauce Labs: https://saucelabs.com/jobs/1a408cf60af0601f49052f66fa37812c

This is great. Thanks for this Santi. I have some questions regarding the actual path here, upload.sendKeys("/Users/sso/the/local/path/to/darkbulb.jpg");

If I'm using Jenkins and GitHub as my repo, would the file path be relative to the Jenkins box? Also, is there a way to reference the file to upload from the GitHub repo? Any help would be greatly appreciated, thanks!

Happy to hear it's useful. Reading Java's implementation, seems like relative paths can also be used:
https://github.com/Selenium2/Selenium2/blob/master/java/client/src/org/openqa/selenium/remote/LocalFileDetector.java

The file path probably needs to be relative to the test case file, so something like the following would get you to the root of your repo: "../../../whereever/the/file/is/located"

Hope that helps.

Thanks for your help!

Hi Santi,

I'm getting the following error when I attempt to upload a .jpg to onDemand. I'm doing the same thing as the above in respect to line 21, 28.
Is there an issue on your end? Any help would be greatly appreciated. Thanks!!

Exception in thread "main" org.openqa.selenium.UnsupportedCommandException:
Command duration or timeout: 567 milliseconds
Build info: version: '2.15.0', revision: '15105', time: '2011-12-08 09:57:28'
System info: os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.7.2', java.version: '1.6.0_29'
Driver info: driver.version: RemoteWebDriver
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:147)
at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:113)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:424)
at org.openqa.selenium.remote.RemoteWebElement.execute(RemoteWebElement.java:231)
at org.openqa.selenium.remote.RemoteWebElement.upload(RemoteWebElement.java:98)
at org.openqa.selenium.remote.RemoteWebElement.sendKeys(RemoteWebElement.java:86)
at core.AssetsPage.uploadImageAsset(AssetsPage.java:28)
at tests.ImageAssetUploadTest.(ImageAssetUploadTest.java:16)
at core.TestSuite.executeRegressionTestSuite(TestSuite.java:71)
at core.JenkinsMain.runTestSuite(JenkinsMain.java:171)
at core.JenkinsMain.main(JenkinsMain.java:23)

This requires some of the later versions of selenium. As near as I can tell, you'll need an updated client and server. I've tested using v2.19.0 of both client and server, and it worked for me; your mileage may vary.

If you're testing through sauce, you'll need to set the desired capabilities for your driver to use the latest version, as so: https://saucelabs.com/docs/ondemand/additional-config#selenium-version.

Thanks yurodivule. Santi got back to me and said the same thing and it worked. Thanks again.

Santi. can you provide a sample code for python web driver implementation?

Thanks

/would also be nice to figure out how to do this with JSONWireProtocol, so that can use this with PHP and other 3rd party bindings.

Hey Santi,

I have a question. Say you are running the same test on windows and linux machine in that case the path to the images will change right? For eg the path to image on a windows will be different from path to image on linux. So if I have some image paths in my tests and when i am running them on saucelabs how will the test pick up my images from the sauce VM which is running my test?

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.