我使用selenoid在ruby中进行远程浏览器测试。在这方面,我使用"selenium webdriver"、"capybara"one_answers"rspec"进行自动化。我正在使用attach_file方法将文件上传到浏览器我想在Firefox和Chrome浏览器上上传文件,但这两种浏览器都会出错;
铬
Selenium::WebDriver::Error::UnknownCommandError:未知命令:未知命令:session/***8d32e045e3***/se/file
在firefox 中
在"不允许HTTP方法"处出现意外令牌
所以在搜索后,我找到了chrome的解决方案,即将w3c选项设置为大写false['gog:chromeOptions']>caps['gog:chromeOptions']={w3c:false}所以现在chrome正在使用OSS桥接进行握手,但我不知道如何在Firefox中做到这一点。类似的解决方案不适用于Firefox。我的浏览器功能如下:
if ENV['BROWSER'] == 'firefox'
caps = Selenium::WebDriver::Remote::Capabilities.new
caps['browserName'] = 'firefox'
# caps['moz:firefoxOptions'] = {w3c: false} ## It is not working
else
caps = Selenium::WebDriver::Remote::Capabilities.new
caps["browserName"] = "chrome"
caps["version"] = "81.0"
caps['goog:chromeOptions'] = {w3c: false}
end
caps["enableVNC"] = true
caps["screenResolution"] = "1280x800"
caps['sessionTimeout'] = '15m'
Capybara.register_driver :selenium do |app|
Capybara::Selenium::Driver.new(app, browser: :remote,
:desired_capabilities => caps,
:url => ENV["REMOTE_URL"] || "http://*.*.*.*:4444/wd/hub"
)
end
Capybara.configure do |config|
config.default_driver = :selenium
end
我发现了问题。在java上运行的selenium服务器中有一个错误,所以我不得不更改selenium webdriver gem 3.142.7版本和monkey补丁。您可以在此处找到有关错误和解决方案的更多信息。
现在,我必须更改我的gem-and-monkey补丁selenium-webdriver-3142.7\lib\selenium\webdriver\remote\w3c\commands.rb文件。检查150号线上的底线。
上传文件:[:post,'session/:session_id/se/file']
并将其更新为
upload_file: [:post, 'session/:session_id/file']
我在rails 7上遇到了类似的问题。这个问题与w3c标准有关。核心问题是chrome的webdriver使用非w3c标准url来处理文件上传。上传文件时,网络驱动程序使用/se/file
url路径进行上传。只有selenium服务器才支持此路径。随后,selenium提供的docker图像工作良好。然而,如果我们使用chromedriver
,则上传失败。更多信息。
我们可以通过重写Selenium::WebDriver::Remote::Bridge::COMMANDS
中的:upload_file
密钥来强制web驱动程序使用符合标准的url来解决这个问题。由于在加载模块时不会初始化COMMAND常量,因此我们可以重写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
在Firefox镜像中,我们通过添加模仿此API的Selenoid二进制文件而不是Geckodriver(不实现它(来支持/session/<id>/file
API。