Skip to content

Instantly share code, notes, and snippets.

@santiycr
Created December 22, 2011 04:44
Show Gist options
  • Star 13 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save santiycr/1508946 to your computer and use it in GitHub Desktop.
Save santiycr/1508946 to your computer and use it in GitHub Desktop.
Remote File Upload using Selenium 2's FileDetectors
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
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();
}
}
@santiycr
Copy link
Author

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

@bevischin
Copy link

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!

@santiycr
Copy link
Author

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.

@bevischin
Copy link

Thanks for your help!

@bevischin
Copy link

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)

@yurodivuie
Copy link

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.

@bevischin
Copy link

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

@senthilkaconnect
Copy link

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

Thanks

@daluu
Copy link

daluu commented Jul 9, 2012

/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.

@rivlinp
Copy link

rivlinp commented Apr 18, 2013

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?

@QuantumGeordie
Copy link

i'm wondering if this technique has issues with test run on iOS browsers? works great in 'regular' browsers, but i think i am seeing that it is not working as expected when testing against ipad and iphone browsers.

@yogeshkachare
Copy link

Hello Santi,

I am facing issue with uploading the file on remote machine Sauce lab using Selenium and C#.
so Can you provide the code for how to detect the Local file path.

         IAllowsFileDetection allowsDetection = (IAllowsFileDetection)wd;
        allowsDetection.FileDetector = new LocalFileDetector();
        string FilePath = "C:\\Users\\ABC\\Downloads\\Presentation1.ppt";
        wd.FindElement(By.CssSelector(".edit")).SendKeys(FilePath);

Execption:
System.InvalidOperationException was unhandled
HResult=-2146233079
Message=invalid entry size (expected 786432 but got 393216 bytes)
Source=WebDriver
StackTrace:
at OpenQA.Selenium.Remote.RemoteWebDriver.UnpackAndThrowOnError(Response errorResponse)

Thanks

@psobieski
Copy link

@yogeshkachare
This is because you select edit in your selector. You should select your input element and then use SendKeys for this element.

@Abel0916
Copy link

Abel0916 commented Jun 3, 2015

Hi @santiycr,

I am new on Selenium-SauceLabs. And I met one issue when try your code(in ruby) to test upload file: ETIMEDOUT: Operation timed out - connect(2) for "saucelabs.com" port 4445

Could you help on this, Thanks.

Below are the code:
require 'rubygems'
require "test/unit"
require 'selenium-webdriver'

class FileDector < Test::Unit::TestCase
def setup
caps = Selenium::WebDriver::Remote::Capabilities.firefox
caps.version = "33"
caps.platform = :Windows
caps[:name] = "Remote File Upload using Selenium 2 with Ruby"
caps['selenium-version'] = "2.42.0"
@driver = Selenium::WebDriver.for(
:remote,
:url => "http://{username}:{key}@saucelabs.com:4445/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/zhangfei/desktop/Logo/accurate-pest.png"
@driver.find_element(:id, "submit").click
@driver.find_element(:tag_name, "img")
assert "accurate-pest.png (image/png)" == @driver.find_element(:tag_name, "p").text
end

def teardown
@driver.quit
end

def Test
a = FileDector.new(@driver)
a.setup
a.test_sauce
end
end

@roughpandaz
Copy link

Does anyone how you could solve uploading a file to a remote server on js?

@adeepika
Copy link

Hi Santi,
I am using selenium with java and want to upload file.My application does not supports sendkeys because after clicking select file windows popup gets open up. So,I am using AutoIt in this case to handle waindowspop but want to run on remote machine(Suacebrowser)
Please help!

@VaibhavPitaliya
Copy link

Hi Santi,

I am using this implementation in JAVA, with latest version of Selenium and Firefox. It works fine in Chrome, but
I am getting the below error in firefox -

org.openqa.selenium.UnsupportedCommandException: Unrecognized command: POST /session/fd481a91-f664-114b-8363-f4a64ee30518/file
Command duration or timeout: 18 milliseconds
Build info: version: '2.53.0', revision: '35ae25b1534ae328c771e0856c93e187490ca824', time: '2016-03-15 10:43:46'
System info: host: 'Vaibhav.local', ip: '172.20.57.75', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.10.5', java.version: '1.8.0_66'
Driver info: org.openqa.selenium.firefox.FirefoxDriver
Capabilities [{applicationCacheEnabled=true, rotatable=false, handlesAlerts=true, databaseEnabled=true, version=46.0.1, platform=MAC, nativeEvents=false, acceptSslCerts=true, webStorageEnabled=true, locationContextEnabled=false, browserName=firefox, takesScreenshot=true, javascriptEnabled=true, cssSelectorsEnabled=true}]
Session ID: fd481a91-f664-114b-8363-f4a64ee30518

Can you help me out?

@VivaLosDoyers
Copy link

This procedure fails for me when the file in question is large. In my case, it's ~1.6GB. When I do this to a remote Selenium grid I have, it get an error that Java is out of heap space. Not sure how to fix that since I've already given both the hubs and the nodes a 16G max heap.

@psubrownie
Copy link

file_detector needs updated to str if File.exist?(str) and File.file?(str) to follow a bug with string "." being treated as a folder
SeleniumHQ/selenium@3dadcdc

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment