19

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

堆栈跟踪:

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。

4

8 回答 8

23

首先解决方案

正如 John Chen [所有者 - Google Chrome 的 WebDriver] 昨天所承诺的,ChromeDriver 75.0.3770.9076.0.3809.25的新版本已经发布,现在可以在ChromeDriver 下载站点上获得。这些版本包括对ChromeDriver 7576以前版本的以下错误修复:

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

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

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

电子邮件快照

75_76


细节

在 chromedriver中关闭w3c以解决错误将违反最佳实践:

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

由于ChromeDriver的当前实现向客户端请求符合 W3C 的会话。


但是,此错误消息意味着ChromeDriver无法在W3C 模式下调用非 W3C 标准命令,同时启动/生成新的WebBrowserChrome 浏览器会话。

主要问题是,当ChromeDriver的客户端请求符合 W3C 的会话时,来自ChromeDriver的响应不符合 W3C 规范,并导致语言 API 出现错误。

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

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

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

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

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

修订版和此提交解决了此问题。


这个用例

假设您正在使用ChromeDriver v75.xChrome v75.x,如果您仍然看到错误,您需要明确传递ExperimentalOption 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 之前ChromeChromeDriver组合默认在 w3c 模式下运行,但chromedriver/server/http_handler.cc中存在错误。根据goog:chromeOptions.w3c=false 中的详细信息不适用于空正文的 POST 请求

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

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

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

于 2019-06-05T09:28:40.923 回答
8

对于 Javascript 人员(我专门使用 WebdriverIO),请确保使用“goog:chromeOptions”

  capabilities: {
    browserName: 'chrome',
    'goog:chromeOptions': {
        'w3c': false
    }
  }

否则你会得到

unknown error: Illegal key values seen in w3c capabilities: [chromeOptions]
于 2019-07-18T17:59:47.530 回答
7

做后options = Selenium::WebDriver::Chrome::Options.new 你可以做options.add_option('w3c', false)

于 2019-06-07T20:03:37.950 回答
4

我面临同样的问题。

我试图禁用使用capabilities = Selenium::WebDriver::Remote::Capabilities.chrome({ "chromeOptions" => {'w3c' => false} }),但它没有工作。

然后我改为capabilities = { "chromeOptions" => {'w3c' => false} }现在它可以工作了。

也许它可以帮助你。

于 2019-06-05T01:40:51.383 回答
1

这就是在 Behat 中使用 Mink 的方法: #behat #mink

  Behat\MinkExtension:
    base_url: "your_site_url"
    browser_name: 'chrome'
    goutte: ~
    javascript_session: selenium2
    selenium2:
      wd_host: http://127.0.0.1:4444/wd/hub
      capabilities:
        browser: chrome
        extra_capabilities:
          chromeOptions:
            args: ['--headless', '--disable-gpu']
            w3c: false
于 2019-08-09T13:41:00.357 回答
0

PHP Behat-Mink-Selenium 用户查看此帖子以获取信息: https ://medium.com/@alex.designworks/chromedriver-75-enforces-w3c-standard-break-behat-tests-460cad435545 和 GitHub 问题https:// github.com/minkphp/MinkSelenium2Driver/issues/293

在这篇文章中,“解决方法”是让那些使用 Behat-Mink-Selenium 的人回退到 Chrome 74。

于 2019-06-07T08:42:16.927 回答
0
{ 
  'platformName':'Android', 
  'platformVersion':'8.0.0',
  'deviceName':'Samsung Galaxy S9',
  'deviceType':'Phone', 
  'nativeWebTap': 'True',
  'browser' : 'Chrome',
  "goog:chromeOptions": {'w3c': False}
}

使用 goog:chromeOptions 选项设置 w3c True 或 False。在控制台上你会看到同样的通过。

于 2020-08-04T14:24:19.120 回答
-1

我最近将 appium 升级到 1.18 ,使用 chromeDriver 版本 84,我的 chrome 浏览器版本也是 84。我使用 appium python 库启动浏览器。我的功能如下所示,但出现错误-“WebDriverException:消息:'chromeOptions'必须是对象类型”。请让我知道我的能力出了什么问题。

{ 
  'platformName':'Android', 
  'platformVersion':'8.0.0',
  'deviceName':'Samsung Galaxy S9',
  'deviceType':'Phone', 
  'nativeWebTap': 'True',
  'browser' : 'Chrome',
  'chromeOptions' : '{args: [ 'w3c : false']}' 
}
于 2020-07-27T15:21:41.957 回答