6

File Upload with a Selenium Grid:

Code

import java.net.MalformedURLException; import java.net.URL; import java.util.concurrent.TimeUnit; import org.openqa.selenium.By; 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 Main { public static void main(String[] args) throws MalformedURLException { DesiredCapabilities capabilities = DesiredCapabilities.internetExplorer(); capabilities.setBrowserName("internet explorer"); RemoteWebDriver driver = new RemoteWebDriver(new URL("http://URL:4444/wd/hub"), capabilities); driver.setFileDetector(new LocalFileDetector()); driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS); driver.get("https://url.de/index.xhtml"); driver.findElement(By.xpath("//*[@id='form:sdsupload']/span")).click(); WebElement addFile = driver.findElement(By.xpath("//input[@type='file']")); ((RemoteWebElement) addFile ).setFileDetector(new LocalFileDetector()); addFile.sendKeys("C:\\daten\\test\\test2.xml"); } } 

Exception

Jun 26, 2020 3:47:43 PM org.openqa.selenium.remote.ProtocolHandshake createSession INFORMATION: Detected dialect: W3C Exception in thread "main" org.openqa.selenium.InvalidArgumentException: Attempting to upload file 'C:\daten\test\test2.xml' which does not exist. Build info: version: '3.141.59', revision: 'e82be7d358', time: '2018-11-14T08:17:03' System info: host: 'xxx', ip: 'xxx', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '1.8.0_171' Driver info: org.openqa.selenium.remote.RemoteWebDriver Capabilities {acceptInsecureCerts: false, browserName: internet explorer, browserVersion: 11, javascriptEnabled: true, pageLoadStrategy: normal, platform: WINDOWS, platformName: WINDOWS, proxy: Proxy(), se:ieOptions: {browserAttachTimeout: 0, elementScrollBehavior: 0, enablePersistentHover: true, ie.browserCommandLineSwitches: , ie.ensureCleanSession: false, ie.fileUploadDialogTimeout: 3000, ie.forceCreateProcessApi: false, ignoreProtectedModeSettings: false, ignoreZoomSetting: false, initialBrowserUrl: http://localhost:5494/, nativeEvents: true, requireWindowFocus: false}, setWindowRect: true, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}, webdriver.remote.sessionid: ae053a22-c088-402e-8de1-f25...} Session ID: ae053a22-c088-402e-8de1-f25c4398ccbf at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at org.openqa.selenium.remote.http.W3CHttpResponseCodec.createException(W3CHttpResponseCodec.java:187) at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:122) at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:49) at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:158) at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:552) at org.openqa.selenium.remote.RemoteWebElement.execute(RemoteWebElement.java:285) at org.openqa.selenium.remote.RemoteWebElement.sendKeys(RemoteWebElement.java:106) at de.xxx.xxx.keywords.Main.main(Main.java:41) 

The file exists on the local node, but not on the remote node. If the file is on the remote node, it works great. The File exists on local node, but not on remote node: https://i.sstatic.net/f31Wb.png

I read this:

How can I pass a file to the remote node?

Edit

The same Error with Firefox, IE and Edge Chromium

Firefox:

Exception in thread "main" org.openqa.selenium.InvalidArgumentException: File not found: C:\daten\test\test3.xml Build info: version: '3.141.59', revision: 'e82be7d358', time: '2018-11-14T08:17:03' System info: host: 'xxx', ip: 'xxx', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '1.8.0_171' Driver info: org.openqa.selenium.remote.RemoteWebDriver Capabilities {acceptInsecureCerts: true, browserName: firefox, browserVersion: 60.5.0, javascriptEnabled: true, moz:accessibilityChecks: false, moz:geckodriverVersion: 0.25.0, moz:headless: false, moz:processID: 624, moz:profile: C:\Users\username\Ap..., moz:useNonSpecCompliantPointerOrigin: false, moz:webdriverClick: true, pageLoadStrategy: normal, platform: XP, platformName: XP, platformVersion: 10.0, rotatable: false, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}, webdriver.remote.sessionid: 8801c61e-6d61-488b-8f86-c0a...} Session ID: 8801c61e-6d61-488b-8f86-c0a1fb2f2df8 at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at org.openqa.selenium.remote.http.W3CHttpResponseCodec.createException(W3CHttpResponseCodec.java:187) at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:122) at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:49) at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:158) at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:552) at org.openqa.selenium.remote.RemoteWebElement.execute(RemoteWebElement.java:285) at org.openqa.selenium.remote.RemoteWebElement.sendKeys(RemoteWebElement.java:106) at de.xxx.xxx.keywords.Main.main(Main.java:52) 

When I copy the file to the remote client it works great again :(

Debug: Debug with Firefox

2 Answers 2

11

This error message...

Exception in thread "main" org.openqa.selenium.InvalidArgumentException: Attempting to upload file 'C:\daten\test2.xml' which does not exist. 

...implies that the desired file doesn't exist on the client machine.


Local file detector

The Local File Detector allows the transfer of files from the client machine to the remote server. In case a test needs to upload a file to a web application, a remote WebDriver can automatically transfer the file from the local machine to the remote web server during runtime. This allows the file to be uploaded from the remote machine running the test. It is not enabled by default and can be enabled as follows:

  • Java:

    driver.setFileDetector(new LocalFileDetector()); 
  • Python:

    from selenium.webdriver.remote.file_detector import LocalFileDetector driver.file_detector = LocalFileDetector() 
  • C#:

    var allowsDetection = this.driver as IAllowsFileDetection; if (allowsDetection != null) { allowsDetection.FileDetector = new LocalFileDetector(); } 
  • Ruby:

    @driver.file_detector = lambda do |args| # args => ["/path/to/file"] str = args.first.to_s str if File.exist?(str) end 
  • JavaScript:

    var remote = require('selenium-webdriver/remote'); driver.setFileDetector(new remote.FileDetector); 
  • Kotlin:

    driver.fileDetector = LocalFileDetector() 

This usecase

If you are running your tests on Selenium Grid then you need to let your remote driver know that the file that needs to be uploaded is residing on the local machine and not on remote machine. In those cases, to upload a file from the client machine to the remote server, WebDriver can automatically transfer the file from the local machine to the remote web server during runtime you can use the following code block:

WebElement addFile = driver.findElement(By.xpath("//input[@type='file']")); ((RemoteWebElement)addFile).setFileDetector(new LocalFileDetector()); addFile.sendKeys("C:\\daten\\test2.xml"); 

Outro

Selecting and uploading files while running your tests on Selenium Grid

Sign up to request clarification or add additional context in comments.

5 Comments

i post the new code with the same error message and a Screenshot that the file exists
@Andreas Can you try once with Chrome or Firefox please. There seems to besome issue with IE.
It WORKS :) THANKS! I don't know what's the Problem. It doesn't work with Firefox, Edge Chromium and IE. When I rewritten the sendKeys command, it worked. I don't know why.
hank you very much! I think the problem was a broken xml file.
I am getting failure intermittently though localFileDetector is set. stackoverflow.com/questions/68007769/…
0

Thank you @DebanjanB for helping me finding the solution - I've upvoted your response, and this is another answer to state it indeed works.

My problem:

Locally, I was running Selenium tests against a locally running Selenium server (running selenium-server-4.0.0-beta-4.jar file), and I was using chromedriver.exe file too.

My tests (written in TypeScript) that uploaded files using:

await ( await driver.findElement(By.xpath("//form//input[@id='upload-input']")) ).sendKeys(join(__dirname, "testfile.txt")); 

Ran without problems locally. But in our DevOps pipeline, running Docker using the selenium/standalone-chrome image, it was like the driver couldn't find the file:

InvalidArgumentError: invalid argument: File not found: /home/vsts/work/1/s/selenium/tests/flows/testfile.txt 

Even though we had confirmed that the file was indeed found in the correct folder by running:

> pwd /home/vsts/work/1/s > find . -name testfile.txt ./selenium/tests/flows/testfile.txt 

Meaning the file was indeed located at /home/vsts/work/1/s/selenium/tests/flows/testfile.txt.

My team and I Googled and searched why this was and found @DebanjanB's answer.

What we didn't realize was that the selenium/standalone-chrome Docker image is running a Selenium Grid server, which is "remote" rather than "local". And so the driver can't find the file when running "remote".

The solution

We added

driver.setFileDetector(new FileDetector()); 

Before

await ( await driver.findElement(By.xpath("//form//input[@id='upload-input']")) ).sendKeys(join(__dirname, "testfile.txt")); 

And now our tests pass when running against the docker container in our pipeline too!

From Selenium's documentation:

The Local File Detector allows the transfer of files from the client machine to the remote server. For example, if a test needs to upload a file to a web application, a remote WebDriver can automatically transfer the file from the local machine to the remote web server during runtime. This allows the file to be uploaded from the remote machine running the test.

Source: https://www.selenium.dev/documentation/webdriver/remote_webdriver/#local-file-detector

I hope this will help someone struggling with the same problem :-)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.