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

查看:1675
本文介绍了如何在chromedriver中关闭w3c来解决错误未知命令:在W3C中无法调用非W3C标准命令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

随着75版本的Chrome刚刚发布,我们的测试无法正常运行.他们给出了粘贴在下面的堆栈跟踪.我们在带有rspec,selenium-webdriver 3.8.0的Rails v.5.1.6.2上使用ruby.

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:

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'

我们的驱动程序配置:

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} }使我们的测试暂时起作用.

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

更新chromedriver后,我们开始收到错误未知错误:DevToolsActivePort文件不存在".为了解决此问题,我们将selenium-webdriver gem升级到3.142.3,并解决了此问题,使我们可以使用w3c而无需任何其他参数.

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.

推荐答案

首先解决

正如John Chen [Google Chrome浏览器的WebDriver所有者]昨天所承诺的, ChromeDriver 75.0.3770.90 76.0.3809.25 的新版本已发布,现在可以在 ChromeDriver下载网站上找到.这些版本在 ChromeDriver 75 76 的先前版本中包含以下错误修复:

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:

  • 修复了一个错误,该错误在OSS模式下错误地拒绝了带有空主体的POST请求
  • 添加了用于检索Chrome日志的新端点

此外,版本 76.0.3809.25 还包括以下更改:

In addition, version 76.0.3809.25 also includes the following change:

  • 在W3C模式下为显示的命令"添加了端点

在chromedriver中关闭w3c 来解决该错误是违反最佳实践的:

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

ChromeDriver 的当前实现向客户端请求W3C兼容会话.

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

但是,此错误消息表示在启动/生成时, ChromeDriver W3C模式下无法调用非W3C标准命令一个新的 WebBrowser ,即 Chrome浏览器会话.

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.

主要问题是,当 ChromeDriver 的客户端请求一个 W3C兼容会话时, ChromeDriver 的响应不符合W3C规范,并导致语言API错误.

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.

根据 W3C模式下的ChromeDriver响应不是标准的符合的John Chen(所有者-Google Chrome浏览器的WebDriver)提到的西蒙·斯图尔特(Simon Stewart,创作者-WebDriver)更新了以下内容:

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:

  • w3c会话的新会话响应应类似于:

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

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

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

  • 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",
            ...
          }
        }
    

  • 既不是针对JSON Wire Protocol的正确格式的响应(状态"为整数),也不是正确格式的W3C响应,并且如果没有正确格式的响应,则无法使用w3c兼容.

    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.

    修订和此大概您将 ChromeDriver v75.x Chrome v75.x 一起使用,并且如果仍然看到错误,则需要传递 ExperimentalOption w3c 作为 true 如下:

    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 代码示例:

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

  • Java 代码示例:

  • 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 代码示例:

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

  • 直到 ChromeDriver v74.x Chrome ChromeDriver 组合默认在w3c模式下运行,但 chromedriver/server/http_handler.cc .根据 goog:chromeOptions.w3c = false的详细信息不起作用正文为空的POST请求:

    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:

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

    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.

    由于Is Element Displayed命令不是W3C规范的一部分,但仍被某些API使用,并且其功能可能很难在那些API中复制.此更改列表 [修订 commit ]在W3C模式下重新启用此命令以简化向W3C模式的转换.

    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已经确认,我们期望明天通过修复程序对 ChromeDriver v75.0 进行更新.

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

    这篇关于如何在chromedriver中关闭w3c来解决错误未知命令:在W3C中无法调用非W3C标准命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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