Selenium Java RemoteWebDriver文件上传报UnsupportedCommandException求助
问题描述
使用Selenium 4.12.1、Chrome 112、ChromeDriver 112及RemoteWebDriver,通过sendKeys方法给//input[@type='file']元素传入文件路径时,触发UnsupportedCommandException,错误信息为unknown command: session/9845d50a442f6c23dc498210a0d253d7/se/file。
环境规格
- Selenium版本:4.12.1
- 驱动:RemoteWebDriver
- 操作系统:Linux
代码示例
WebElement fileInput = driver.findElement(By.xpath("//input[@type='file']")); String filePath = "/path/to/file.txt"; fileInput.sendKeys(filePath);
错误堆栈
org.openqa.selenium.UnsupportedCommandException: unknown command: unknown command: session / 9845 d50a442f6c23dc498210a0d253d7 / se / file Build info: version: '4.12.1', revision: '8e34639b11' System info: os.name: 'Linux', os.arch: 'amd64', os.version: '5.10.215-181.850.amzn2int.x86_64', java.version: '17.0.11' Driver info: org.openqa.selenium.remote.RemoteWebDriver Command: [9845 d50a442f6c23dc498210a0d253d7, uploadFile { file = UEsDBBQACAgIADtor1gAAAAAAAAAAAAAAAARAAAAYnVsa1NoaXBUZXN0Lnhsc3icuwNwZdHXJZ502LFtq2PbTse2bTvp2LZt27Zt2x07mUr6+9d8M/+aX03Nq1dPdc/aZ6219z2n9rtXRgIIGAkAHBwcgNWkSgXgvz0QAQAA1AWsrRwMrRy0FVxtDO01qV0sLSYSxn730cIJeRPfoDBRw}] Capabilities { acceptInsecureCerts: true, browserName: chrome, browserVersion: 112.0 .5615 .49, chrome: { chromedriverVersion: 112.0 .5615 .49(bd2a7bcb881c..., userDataDir: /tmp/.org.chromium.Chromium... }, goog: chromeOptions: { debuggerAddress: localhost: 46485 }, networkConnectionEnabled: false, pageLoadStrategy: normal, platformName: linux, proxy: Proxy(), setWindowRect: true, strictFileInteractability: false, timeouts: { implicit: 0, pageLoad: 300000, script: 30000 }, unhandledPromptBehavior: dismiss and notify, webauthn: extension: credBlob: true, webauthn: extension: largeBlob: true, webauthn: extension: minPinLength: true, webauthn: extension: prf: true, webauthn: virtualAuthenticators: true } Element: [ [RemoteWebDriver: chrome on linux(9845 d50a442f6c23dc498210a0d253d7)] - > xpath: //div[@role='dialog']//input[@accept='.xlsx']] Session ID: 9845 d50a442f6c23dc498210a0d253d at java.base / jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at java.base / jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java: 77) at java.base / jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java: 45) at java.base / java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java: 499) at java.base / java.lang.reflect.Constructor.newInstance(Constructor.java: 480) at org.openqa.selenium.remote.codec.w3c.W3CHttpResponseCodec.createException(Unknown Source) at org.openqa.selenium.remote.codec.w3c.W3CHttpResponseCodec.decode(Unknown Source) at org.openqa.selenium.remote.codec.w3c.W3CHttpResponseCodec.decode(Unknown Source) at org.openqa.selenium.remote.HttpCommandExecutor.execute(Unknown Source) at org.openqa.selenium.remote.RemoteWebDriver.execute(Unknown Source) at org.openqa.selenium.remote.RemoteWebElement.execute(Unknown Source) at org.openqa.selenium.remote.RemoteWebElement.upload(Unknown Source) at java.base / java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java: 197) at java.base / java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java: 1625) at java.base / java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java: 509) at java.base / java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java: 499) at java.base / java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java: 921) at java.base / java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java: 234) at java.base / java.util.stream.ReferencePipeline.collect(ReferencePipeline.java: 682) at org.openqa.selenium.remote.RemoteWebElement.sendKeys(Unknown Source)
已尝试方案
- 使用JavaScriptExecutor设置元素可见,无效,问题根源在文件上传请求的端点
- 尝试重写UPLOAD_FILE命令,未解决
原因分析
这个错误源于Selenium 4.x版本的RemoteWebDriver使用了W3C协议的新文件上传端点/session/{sessionId}/se/file,但ChromeDriver 112不支持该端点——旧版本ChromeDriver未完全适配Selenium 4的W3C文件上传命令,导致请求被识别为未知命令。
另外,若文件不在Remote节点本地,sendKeys会触发Selenium的跨节点文件上传逻辑,而旧版ChromeDriver无法处理该逻辑,也会引发此错误。
解决方案
方案1:JavaScript直接设置元素值(文件在Remote节点本地)
绕过Selenium的上传命令,直接通过JS设置input元素的value属性:
WebElement fileInput = driver.findElement(By.xpath("//input[@type='file']")); JavascriptExecutor js = (JavascriptExecutor) driver; js.executeScript("arguments[0].value = arguments[1];", fileInput, "/path/to/file.txt");
方案2:升级ChromeDriver版本
ChromeDriver 112适配性不足,建议升级到与Selenium 4.12.1兼容的版本(Selenium 4.12.1推荐Chrome/ChromeDriver版本114-116),新版本完全支持W3C文件上传命令,可解决端点不识别问题。
方案3:配置FileDetector上传本地文件到Remote节点
如果文件在本地机器,需要上传到Remote节点,设置LocalFileDetector让RemoteWebDriver自动处理文件传输:
driver.setFileDetector(new LocalFileDetector()); WebElement fileInput = driver.findElement(By.xpath("//input[@type='file']")); fileInput.sendKeys(new File("/local/path/to/file.txt").getAbsolutePath());
注:使用Selenium Grid时,需确保Grid节点支持文件上传功能且配置正确。
内容的提问来源于stack exchange,提问作者Automation Coding

