如何在 chromedriver 中关闭 w3c 来解决未知命令错误:Cannot call non W3C standard command while in W3C

2023-12-13

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

堆栈跟踪:

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

UPDATE:

我能够让我们的测试暂时工作capabilities = { "chromeOptions" => {'w3c' => false} }.

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


首先是解决方案

正如 John Chen [Owner - WebDriver for Google Chrome] 昨天所承诺的那样,新版本的Chrome驱动程序 75.0.3770.90 and 76.0.3809.25已经发布,现在可以在Chrome驱动程序下载地点。这些版本包括与之前版本相比的以下错误修复Chrome驱动程序 75 and 76:

  • 修复了 OSS 模式下错误拒绝 body 为空的 POST 请求的错误
  • 添加了用于检索 Chrome 日志的新端点

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

  • 在 W3C 模式下添加了 Is Displayed 命令的端点

电子邮件快照

75_76


Details

这将违背最佳实践w3c在 Chromedriver 中解决该错误:

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

作为目前的实施Chrome驱动程序向客户端请求符合 W3C 的会话。


但是,此错误消息意味着Chrome驱动程序无法调用非W3C标准命令而在W3C mode在启动/产生新的网页浏览器 i.e. Chrome浏览器会议。

主要问题是,当Chrome驱动程序的客户请求符合 W3C 的会话,响应来自Chrome驱动程序不符合W3C规范,并导致语言API错误。

根据讨论W3C 模式下的 ChromeDriver 响应不符合标准John Chen(所有者 - Google Chrome 的 WebDriver)提及Simon Stewart(WebDriver 创建者)已更新:

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

    {
      "value": {
        "sessionId": "some-uuid",
        "capabilities": {
          "browserName": "chrome",
          ...
        }
      }
    }
    
  • 但是当开始一个新的会话时w3c选项设置为true in the chrome选项,返回的响应如下所示:

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

这既不是 JSON Wire Protocol 的正确形成的响应(其中“状态”将为整数),也不是正确形成的 W3C 响应,如果没有正确形成的响应,则无法使用 w3c 兼容。

This revision和这个commit解决了这个问题。


这个用例

想必您正在使用Chrome 驱动程序 v75.x with Chrome v75.x如果您仍然看到错误,您需要通过实验选项 w3c as 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')
    

Update

Till Chrome 驱动程序 v74.x, Chrome and Chrome驱动程序组合默认在 w3c 模式下运行,但在chromedriver/server/http_handler.cc。根据详细信息goog:chromeOptions.w3c=false 不适用于正文为空的 POST 请求:

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

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

@John 已经确认我们期待更新Chrome驱动程序v75.0明天修复。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 chromedriver 中关闭 w3c 来解决未知命令错误:Cannot call non W3C standard command while in W3C 的相关文章

随机推荐