Ruby-Selenium WebDriver 3.142.6:由于"Selenium::WebDriver::Error::UnknownCommandError:"无法上传文件



无法使用Ruby 中的 gem 上传文件selenium-webdriver (3.142.6)

技术堆栈:

硒网络驱动程序 (3.142.6(

铬版本 : 77

铬驱动程序:77

错误信息:

Selenium::WebDriver::Error::UnknownCommandError: unknown command: unknown command: session/xxxsession_idXXX/se/file
Backtrace:
Ordinal0 [0x00FDEB13+1501971]
Ordinal0 [0x00F5F6D1+980689]
Ordinal0 [0x00EE765F+489055]
Ordinal0 [0x00E9618E+156046]
Ordinal0 [0x00E95FF4+155636]
Ordinal0 [0x00E7220E+8718]
Ordinal0 [0x00E72626+9766]
Ordinal0 [0x00E72C10+11280]
Ordinal0 [0x00F78F37+1085239]
GetHandleVerifier [0x0107D7ED+503293]
GetHandleVerifier [0x0107D580+502672]
GetHandleVerifier [0x010846AC+531644]
GetHandleVerifier [0x0107DFFA+505354]
Ordinal0 [0x00F70606+1050118]
Ordinal0 [0x00F7047F+1049727]
Ordinal0 [0x00E7204B+8267]
Ordinal0 [0x00E71D7C+7548]
GetHandleVerifier [0x013CD83C+3976780]
BaseThreadInitThunk [0x755738F4+36]
RtlUnicodeStringToInteger [0x77375E13+595]
RtlUnicodeStringToInteger [0x77375DDE+542]

似乎是这个版本的 gem 的上传被破坏了。

用于上传文件的代码(watir with cheezy(

@browser.file_field(xpath: "//*[contains(text(), 'Upload')]/input[@type='file']").set(complete_path_to_file)

根本原因:w3c浏览器功能状态

说明:w3c:true硒网络驱动程序抛出此错误时。这可能是因为Selenium 3并不完全支持w3c实现。

解决方案1:如果您没有任何基于w3c功能的依赖项,则简单的解决方案将是w3c:false

解决方案2:如果解决方案1不起作用,则必须更新selenium-webdriver-3.142.6libseleniumwebdriverremotew3ccommands.rb文件。 检查以下行,然后更新它。

upload_file: [:p ost, 'session/:session_id/se/file']

将此行更新为

upload_file: [:p ost, 'session/:session_id/file']

结论:在硒 4 推出之前,首选解决方案 1。如果您使用解决方案 2,则当您尝试在不推送此更改的计算机上运行它们时,可能会测试失败/文件可能会用bundle install设置。

您可以使用方法直接使用解决方案,但我个人觉得这太多了。

将解决方案发布到SeleniumHQ,一旦得到确认,将向SeleniumHQ提交拉取请求。这样您就不会在更高版本的Selenium Ruby WebDriver中遇到此问题。

核心问题是 Chrome 的网络驱动程序使用非 W3C 标准网址来处理文件上传。 上传文件时,WebDriver 使用/se/fileURL 路径进行上传。 此路径(又名命令(受 Selenium 服务器支持。因此,Selenium 提供的 docker 镜像工作正常。 一旦我们直接使用chromedriver,上传就会失败。 在此 GitHub 问题和其中的链接问题中查找更多信息。

为了解决这个问题,我们可以通过覆盖:upload_file中的 键来强制 Web 驱动程序使用符合标准的Selenium::WebDriver::Remote::Bridge::COMMANDS键。 由于加载模块时不会初始化此COMMANDS常量,因此我们可以覆盖attach_file方法以确保正确设置常量。这里是黑客代码:

module Capybara::Node::Actions
alias_method :original_attach_file, :attach_file
def attach_file(*args, **kwargs)
implement_hacky_fix_for_file_uploads_with_chromedriver
original_attach_file(*args, **kwargs)
end
def implement_hacky_fix_for_file_uploads_with_chromedriver
return if @hacky_fix_implemented
original_verbose, $VERBOSE = $VERBOSE, nil # ignore warnings
cmds = Selenium::WebDriver::Remote::Bridge::COMMANDS.dup
cmds[:upload_file] = [:post, "session/:session_id/file"]
Selenium::WebDriver::Remote::Bridge.const_set(:COMMANDS, cmds)
$VERBOSE = original_verbose
@hacky_fix_implemented = true
end
end

顺便说一下,找到根本原因很困难,因为当错误发生时,水豚宝石会捕获错误并尝试再次引发错误。 但是,当重新引发时,它使用不存在的错误常量。我通过在gems/capybara-3.38.0/lib/capybara/selenium/nodes/chrome_node.rb +109中使用StandardError来解决它。只有这样,错误搜索才能继续。也许这本身就值得一个问题。

相关内容

最新更新