How to upload a file by transfering the file from the local machine to the remote web server using Selenium Grid

时光毁灭记忆、已成空白 提交于 2021-02-05 08:16:08

问题


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.stack.imgur.com/f31Wb.png

I read this:

  • https://www.selenium.dev/documentation/en/remote_webdriver/remote_webdriver_client/
  • https://www.lambdatest.com/blog/how-to-download-upload-files-using-selenium-with-java/

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


回答1:


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



来源:https://stackoverflow.com/questions/62595459/how-to-upload-a-file-by-transfering-the-file-from-the-local-machine-to-the-remot

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!