如何在 chromedriver 中关闭 w3c 以解决错误未知命令:Cannot call non W3C standard command while in W3C [英] How to turn off w3c in chromedriver to address the error unknown command: Cannot call non W3C standard command while in W3C

查看:43
本文介绍了如何在 chromedriver 中关闭 w3c 以解决错误未知命令:Cannot call non W3C standard command while in W3C的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在刚刚发布的 75 版 Chrome 中,我们的测试不再正常运行.他们给出了粘贴在下面的堆栈跟踪.我们正在使用带有 rspec、selenium-webdriver 3.8.0 的 ruby​​ on rails v. 5.1.6.2.

堆栈跟踪:

Selenium::WebDriver::Error::UnknownCommandError:未知命令:在 W3C 模式下无法调用非 W3C 标准命令# 0 铬驱动程序 0x000000010c46e8e9 铬驱动程序 + 3594473# 1 chromedriver 0x000000010c3fe543 chromedriver + 3134787# 2 chromedriver 0x000000010c1aa29f chromedriver + 692895# 3 铬驱动程序 0x000000010c11a691 铬驱动程序 + 104081# 4 铬驱动程序 0x000000010c11b7d5 铬驱动程序 + 108501# 5 铬驱动程序 0x000000010c42d555 铬驱动程序 + 3327317# 6 铬驱动程序 0x000000010c438e60 铬驱动程序 + 3374688# 7 铬驱动程序 0x000000010c438bf8 铬驱动程序 + 3374072# 8 铬驱动程序 0x000000010c40cd39 铬驱动程序 + 3194169# 9 铬驱动程序 0x000000010c4396d8 铬驱动程序 + 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 `同步'#/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 = :debugSelenium::WebDriver.logger.output = LOG_FILE_PATHCapybara.register_driver :selenium do |app|# 来自 https://github.com/SeleniumHQ/selenium/issues/3738能力 = Selenium::WebDriver::Remote::Capabilities.chrome(loggingPrefs: {browser: 'ALL'})选项 = Selenium::WebDriver::Chrome::Options.newoptions.add_argument '--disable-infobars' # 隐藏关于 chrome 自动化测试的信息栏# 如果我们不使用这个标志,每个 selenium 测试都会报错:# 未知错误:Chrome 无法启动:异常退出"options.add_argument '--no-sandbox'options.add_argument '--headless' 如果 ENV.fetch("HEADLESS", nil).present?options.add_argument '--window-size=1600,2400'options.add_argument '--allow-file-access-from-files' # TODO Julie - 对文件规范有帮助吗?options.add_preference('homepage', 'about:blank') # TODO 这行得通吗?options.add_preference('profile.default_content_settings.popups', 0)options.add_preference('download.default_directory', DownloadHelpers::PATH.to_s)Capybara::Selenium::Driver.new(应用程序,clear_local_storage:真,clear_session_storage:真,浏览器::铬,选项:选项,desired_capabilities:能力,)结尾

更新:

我能够使用 capabilities = { "chromeOptions" => 让我们的测试临时工作.{'w3c' =>错误} }.

更新 chromedriver 后,我们开始收到错误未知错误:DevToolsActivePort 文件不存在".为了解决这个问题,我们将 selenium-webdriver gem 升级到了 3.142.3,这解决了这个问题,允许我们在没有任何额外参数的情况下使用 w3c.

解决方案

先解决方案

正如 John Chen [Owner - WebDriver for Google Chrome] 昨天所承诺的,ChromeDriver 75.0.3770.9076.0.3809.25 的新版本已发布,现在可在 John Chen(所有者 - Google Chrome 的 WebDriver)提到 Simon Stewart(创作者 - WebDriver)更新了:

  • w3c 会话的新会话响应应如下所示:

    <代码>{价值": {"sessionId": "一些 uuid",能力":{浏览器名称":铬",...}}}

  • 但是当在 w3c 选项设置为 true 的情况下启动新会话时,chromeOptions,返回的响应如下:

    <代码> {"sessionId": "af4656c27fb94485b7872e1fc616923a",状态":好的",价值": {浏览器名称":铬",...}}

这既不是 JSON Wire 协议的正确格式响应(其中状态"将是一个整数),也不是正确格式的 W3C 响应,如果没有正确格式的响应,则无法使用 w3c 兼容.

这个修订版和这个commit 解决了这个问题.

<小时>

这个用例

大概你正在使用 ChromeDriver v75.xChrome v75.x,如果你仍然看到错误,你需要传递 ExperimentalOption w3ctrue 明确如下:

  • Ruby 代码示例:

    capabilities = { "chromeOptions" =>{'w3c' =>真的} }

  • Java 代码示例:

    import org.openqa.selenium.chrome.ChromeDriver;导入 org.openqa.selenium.chrome.ChromeOptions;公共类 W3c {公共静态 void main(String[] args) 抛出异常 {ChromeOptions opt = new ChromeOptions();opt.setExperimentalOption("w3c", true);ChromeDriver 驱动程序 = 新的 ChromeDriver(opt);driver.get("https://www.google.co.in");}}

  • Python 代码示例:

    从 selenium 导入 webdriveropt = webdriver.ChromeOptions()opt.add_experimental_option('w3c', True)驱动程序 = webdriver.Chrome(chrome_options=opt)driver.get('https://www.google.co.in')

<小时>

更新

Till ChromeDriver v74.xChromeChromeDriver 组合默认在 w3c 模式下运行,但在 chromedriver/server/http_handler.cc.根据 goog:chromeOptions.w3c=false 中的详细信息不起作用对于空正文的 POST 请求:

<块引用>

方法 HttpHandler::HandleCommand 检查 kW3CDefault 常量的值,而不是会话 goog:chromeOptions.w3c 值.结果,JSON Wire 协议支持被破坏,允许使用空正文的 POST 请求.在 w3c 模式下恢复 displayed 端点之前,将需要 JSON Wire 协议.需要注意的是,W3C WebDriver 规范并没有禁止使用显示"端点,并且该功能在某些 API 中被积极使用.

As Is Element Displayed 命令不是 W3C 规范的一部分,但仍被某些 API 使用,其功能很难在这些 API 中复制.此更改列表 [修订版commit] 在 W3C 模式下重新启用此命令以轻松过渡到 W3C 模式.

@John 已经确认我们预计明天将更新 ChromeDriver v75.0 并进行修复.

With version 75 of Chrome just released, our tests no longer run properly. They give the stacktrace pasted below. We are using ruby on rails v. 5.1.6.2 with rspec, selenium-webdriver 3.8.0.

Stacktrace:

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'

Our driver configuration:

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

UPDATE:

I was able to get our tests to work temporarily using capabilities = { "chromeOptions" => {'w3c' => false} }.

After updating chromedriver, we began receiving the error "unknown error: DevToolsActivePort file doesn't exist". In order to fix this problem, we upgraded our selenium-webdriver gem to 3.142.3 and this fixed the issue, allowing us to use w3c without any additional parameters.

解决方案

First the solution

As promised by John Chen [Owner - WebDriver for Google Chrome] yesterday, new versions of ChromeDriver 75.0.3770.90 and 76.0.3809.25 have been released, and are now available at the ChromeDriver Downloads site. These versions include the following bug fixes over the previous releases of ChromeDriver 75 and 76:

  • Fixed a bug that incorrectly rejected POST requests with empty body in OSS mode
  • Added new endpoints for retrieving Chrome log

In addition, version 76.0.3809.25 also includes the following change:

  • Added endpoint for Is Displayed command in W3C mode

Email Snapshot


Details

It will be against the best practices to turn off w3c in chromedriver to address the error:

Selenium::WebDriver::Error::UnknownCommandError:
        unknown command: Cannot call non W3C standard command while in W3C mode

as the current implementation of ChromeDriver requests a W3C-compliant session to the client.


However, this error message implies that the ChromeDriver was unable to invoke a non W3C standard command while in W3C mode while initiating/spawning a new WebBrowser i.e. Chrome Browser session.

The main issue is, when ChromeDriver's client requests a W3C-compliant session, the response from ChromeDriver does not conform to the W3C spec, and causes errors in language APIs.

As per the discussion in ChromeDriver response in W3C mode is not standard compliant John Chen (Owner - WebDriver for Google Chrome) mentioned Simon Stewart (Creator - WebDriver) have updated that:

  • The new session response for a w3c session should look like:

    {
      "value": {
        "sessionId": "some-uuid",
        "capabilities": {
          "browserName": "chrome",
          ...
        }
      }
    }
    

  • But when starting a new session with the w3c option set to true in the chromeOptions, the returned response looked like:

        {
          "sessionId": "af4656c27fb94485b7872e1fc616923a",
          "status": "ok",
          "value": {
            "browserName": "chrome",
            ...
          }
        }
    

Which is neither a correctly formed response for the JSON Wire Protocol (where "status" would be an integer), nor a correctly formed W3C response and without a correctly formed response, the w3c compatible cannot be used.

This revision and this commit addressed this issue.


This usecase

Presumably you are using ChromeDriver v75.x with Chrome v75.x and in case you are still seeing the error, you need to pass the ExperimentalOption w3c as true explicitly as follows:

  • Ruby code sample:

    capabilities = { "chromeOptions" => {'w3c' => true} }
    

  • Java code sample:

    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 code sample:

    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')
    


Update

Till ChromeDriver v74.x, Chrome and ChromeDriver combo was running in w3c mode by default but there was bug with in the chromedriver/server/http_handler.cc. As per the details in goog:chromeOptions.w3c=false doesn't work for POST request with empty body:

Method HttpHandler::HandleCommand checks the value of the kW3CDefault constant instead of session goog:chromeOptions.w3c value. As a result, JSON Wire protocol support was broken, where POST requests with an empty body are allowed. JSON Wire protocol will be in demand until displayed endpoint is resumed in the w3c mode. It should be noted that W3C WebDriver specification doesn't forbid the use of 'displayed' endpoint and this feature is actively used in some APIs.

As Is Element Displayed command is not part of W3C spec, but is still used by some APIs, and its functionality can be difficult to replicate in those APIs. This Change List [revision and commit] re-enables this command in W3C mode to ease transition to W3C mode.

@John have already confirmed us to expect an update to ChromeDriver v75.0 tomorrow with the fix.

这篇关于如何在 chromedriver 中关闭 w3c 以解决错误未知命令:Cannot call non W3C standard command while in W3C的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆