随着75版本的Chrome刚刚发布,我们的测试无法正常运行。他们给出了粘贴在下面的堆栈跟踪。我们正在使用带有rspec,selenium-webdriver 3.8.0的Rails v。5.1.6.2上的ruby。
堆栈跟踪:
Selenium::WebDriver::Error::UnknownCommandError:
unknown command: Cannot call non W3C standard command while in W3C mode
# 0 chromedriver 0x000000010c46e8e9 chromedriver + 3594473
# 1 chromedriver 0x000000010c3fe543 chromedriver + 3134787
# 2 chromedriver 0x000000010c1aa29f chromedriver + 692895
# 3 chromedriver 0x000000010c11a691 chromedriver + 104081
# 4 chromedriver 0x000000010c11b7d5 chromedriver + 108501
# 5 chromedriver 0x000000010c42d555 chromedriver + 3327317
# 6 chromedriver 0x000000010c438e60 chromedriver + 3374688
# 7 chromedriver 0x000000010c438bf8 chromedriver + 3374072
# 8 chromedriver 0x000000010c40cd39 chromedriver + 3194169
# 9 chromedriver 0x000000010c4396d8 chromedriver + 3376856
# 10 chromedriver 0x000000010c420f27 chromedriver + 3276583
# 11 chromedriver 0x000000010c456064 chromedriver + 3493988
# 12 chromedriver 0x000000010c474617 chromedriver + 3618327
# 13 libsystem_pthread.dylib 0x00007fff7744c2eb _pthread_body + 126
# 14 libsystem_pthread.dylib 0x00007fff7744f249 _pthread_start + 66
# 15 libsystem_pthread.dylib 0x00007fff7744b40d thread_start + 13
# /Users/julie/.rvm/gems/ruby-2.5.1/gems/selenium-webdriver-3.8.0/lib/selenium/webdriver/remote/response.rb:69:in `assert_ok'
# /Users/julie/.rvm/gems/ruby-2.5.1/gems/selenium-webdriver-3.8.0/lib/selenium/webdriver/remote/response.rb:32:in `initialize'
# /Users/julie/.rvm/gems/ruby-2.5.1/gems/selenium-webdriver-3.8.0/lib/selenium/webdriver/remote/http/common.rb:81:in `new'
# /Users/julie/.rvm/gems/ruby-2.5.1/gems/selenium-webdriver-3.8.0/lib/selenium/webdriver/remote/http/common.rb:81:in `create_response'
# /Users/julie/.rvm/gems/ruby-2.5.1/gems/selenium-webdriver-3.8.0/lib/selenium/webdriver/remote/http/default.rb:104:in `request'
# /Users/julie/.rvm/gems/ruby-2.5.1/gems/selenium-webdriver-3.8.0/lib/selenium/webdriver/remote/http/common.rb:59:in `call'
# /Users/julie/.rvm/gems/ruby-2.5.1/gems/selenium-webdriver-3.8.0/lib/selenium/webdriver/remote/bridge.rb:166:in `execute'
# /Users/julie/.rvm/gems/ruby-2.5.1/gems/selenium-webdriver-3.8.0/lib/selenium/webdriver/remote/oss/bridge.rb:579:in `execute'
# /Users/julie/.rvm/gems/ruby-2.5.1/gems/selenium-webdriver-3.8.0/lib/selenium/webdriver/remote/oss/bridge.rb:526:in `element_displayed?'
# /Users/julie/.rvm/gems/ruby-2.5.1/gems/selenium-webdriver-3.8.0/lib/selenium/webdriver/common/element.rb:199:in `displayed?'
# /Users/julie/.rvm/gems/ruby-2.5.1/gems/capybara-2.17.0/lib/capybara/selenium/node.rb:148:in `visible?'
# /Users/julie/.rvm/gems/ruby-2.5.1/gems/capybara-2.17.0/lib/capybara/node/element.rb:269:in `block in visible?'
# /Users/julie/.rvm/gems/ruby-2.5.1/gems/capybara-2.17.0/lib/capybara/node/base.rb:81:in `synchronize'
# /Users/julie/.rvm/gems/ruby-2.5.1/gems/capybara-2.17.0/lib/capybara/node/element.rb:269:in `visible?'
# /Users/julie/.rvm/gems/ruby-2.5.1/gems/capybara-2.17.0/lib/capybara/queries/selector_query.rb:84:in `matches_filters?'
# /Users/julie/.rvm/gems/ruby-2.5.1/gems/capybara-2.17.0/lib/capybara/result.rb:29:in `block in initialize'
我们的驱动程序配置:
File.write(LOG_FILE_PATH, '')
Selenium::WebDriver.logger.level = :debug
Selenium::WebDriver.logger.output = LOG_FILE_PATH
Capybara.register_driver :selenium do |app|
# from https://github.com/SeleniumHQ/selenium/issues/3738
capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(loggingPrefs: {browser: 'ALL'})
options = Selenium::WebDriver::Chrome::Options.new
options.add_argument '--disable-infobars' # hide info bar about chrome automating test
# if we don't use this flag, every selenium test will die with the error:
# "unknown error: Chrome failed to start: exited abnormally"
options.add_argument '--no-sandbox'
options.add_argument '--headless' if ENV.fetch("HEADLESS", nil).present?
options.add_argument '--window-size=1600,2400'
options.add_argument '-–allow-file-access-from-files' # TODO Julie - may help with file specs?
options.add_preference('homepage', 'about:blank') # TODO is this working?
options.add_preference('profile.default_content_settings.popups', 0)
options.add_preference('download.default_directory', DownloadHelpers::PATH.to_s)
Capybara::Selenium::Driver.new(
app,
clear_local_storage: true,
clear_session_storage: true,
browser: :chrome,
options: options,
desired_capabilities: capabilities,
)
end
更新:
我能够使用
capabilities = { "chromeOptions" => {'w3c' => false} }
使我们的测试暂时起作用。更新chromedriver后,我们开始收到错误“未知错误:DevToolsActivePort文件不存在”。为了解决此问题,我们将selenium-webdriver gem升级到3.142.3,并解决了此问题,使我们可以使用w3c而无需任何其他参数。
最佳答案
首先解决
正如John Chen [所有者-Google Chrome的WebDriver]昨天所承诺的那样,ChromeDriver 75.0.3770.90和76.0.3809.25的新版本已经发布,并且现在可以在ChromeDriver Downloads站点上使用。这些版本包含以下针对先前版本的ChromeDriver 75和76的错误修复:
修复了在OSS模式下错误地拒绝主体为空的POST请求的错误
添加了用于检索Chrome日志的新端点
此外,版本76.0.3809.25还包括以下更改:
在W3C模式下为显示命令添加了端点
电子邮件快照
细节
在chromedriver中关闭w3c
来解决错误是违反最佳实践的:
Selenium::WebDriver::Error::UnknownCommandError:
unknown command: Cannot call non W3C standard command while in W3C mode
因为ChromeDriver的当前实现要求向客户端发送W3C兼容会话。
但是,此错误消息表示在启动/生成新的WebBrowser(即Chrome浏览器会话)时,ChromeDriver在W3C模式下无法调用非W3C标准命令。
主要问题是,当ChromeDriver的客户端请求符合W3C的会话时,ChromeDriver的响应不符合W3C规范,并导致语言API出错。
根据ChromeDriver response in W3C mode is not standard compliant John Chen(Google Chrome浏览器WebDriver的所有者)中的讨论,mentioned Simon Stewart(Creator-WebDriver)的更新为:
w3c会话的新会话响应应类似于:
{
"value": {
"sessionId": "some-uuid",
"capabilities": {
"browserName": "chrome",
...
}
}
}
但是,当在chromeOptions中将
w3c
选项设置为true
的情况下启动新会话时,返回的响应如下所示: {
"sessionId": "af4656c27fb94485b7872e1fc616923a",
"status": "ok",
"value": {
"browserName": "chrome",
...
}
}
这既不是针对JSON Wire Protocol的正确格式的响应(“状态”为整数),也不是正确格式的W3C响应,并且如果没有正确格式的响应,则不能使用w3c兼容。
此revision和此commit解决了此问题。
这个用例
假设您正在将ChromeDriver v75.x与Chrome v75.x一起使用,并且如果仍然看到错误,则需要按以下方式明确地将ExperimentOption
w3c
作为true
传递给:Ruby代码示例:
capabilities = { "chromeOptions" => {'w3c' => true} }
Java代码示例:
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
public class W3c {
public static void main(String[] args) throws Exception {
ChromeOptions opt = new ChromeOptions();
opt.setExperimentalOption("w3c", true);
ChromeDriver driver = new ChromeDriver(opt);
driver.get("https://www.google.co.in");
}
}
Python代码示例:
from selenium import webdriver
opt = webdriver.ChromeOptions()
opt.add_experimental_option('w3c', True)
driver = webdriver.Chrome(chrome_options=opt)
driver.get('https://www.google.co.in')
更新资料
直到ChromeDriver v74.x,Chrome和ChromeDriver组合默认在w3c模式下运行,但chromedriver/server/http_handler.cc中存在错误。根据goog:chromeOptions.w3c=false doesn't work for POST request with empty body中的详细信息:
方法
HttpHandler::HandleCommand
检查kW3CDefault
常量的值,而不是会话goog:chromeOptions.w3c
值。结果,JSON Wire协议支持被破坏,允许带有空主体的POST请求。在w3c模式下恢复
displayed
端点之前,将需要JSON Wire协议。应当注意,W3C WebDriver规范不禁止使用“显示”端点,并且某些API中积极使用了此功能。由于
Is Element Displayed
命令不是W3C规范的一部分,而是某些API仍在使用,因此其功能可能很难在这些API中复制。此更改列表[revision和commit]在W3C模式下重新启用此命令,以简化向W3C模式的转换。@John已确认我们希望明天通过修复程序对ChromeDriver v75.0进行更新。
关于selenium - 如何在chromedriver中关闭w3c来解决错误未知命令:在W3C中无法调用非W3C标准命令,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57070093/