Daniel
Daniel

Reputation: 4321

Chromedriver `driver.manage.logs.get(:browser)` fails on chromedriver 75.0.3770.8

While accessing driver.manage.logs.get(:browser) on chromedriver 75.0.3770.8 I'm getting this error:

undefined method `log' for #<Selenium::WebDriver::Remote::W3C::Bridge:0x0000562dc661c250> (NoMethodError)

Works fine on 74.0.3729.6

from: https://github.com/SeleniumHQ/selenium/issues/7270

Upvotes: 17

Views: 4755

Answers (8)

snoblucha
snoblucha

Reputation: 129

For me none of suggested solution worked. What helped was

options = Selenium::WebDriver::Chrome::Options.new
options.logging_prefs = {browser: 'ALL'}

The options internally stores logging_prefs from the initialization in the instance variable, and when processing options it sets up browser-dependent config. Although when doing so in new(logging_prefs: {browser: 'ALL'}) it complains about w3c incompatible params. But hopefully the options do have the accessor for this.

Upvotes: 0

Erik Tribou
Erik Tribou

Reputation: 51

I've found that just upgrading the selenium-webdriver gem to 3.142.4+ fixes the issue even if you are using an outdated Capybara.

driver.browser.manage.logs.get(:browser) works just as before.

From the changelog:

3.142.4 (2019-09-02)
====================

Chrome:
  * Added support for new command for getting logs in ChromeDriver 76+
    with W3C mode on

Upvotes: 2

jaynetics
jaynetics

Reputation: 1313

in recent selenium-webdriver (4.4.0) with recent Chrome (105), manage.logs is gone but this works:

page.driver.browser.logs.get(:browser)

Upvotes: 13

Hussam Kurd
Hussam Kurd

Reputation: 9216

This works for me:

Capybara.register_driver :chrome do |app|

  Capybara::Selenium::Driver.new(app, :browser => :chrome,   desired_capabilities: {
      "chromeOptions" => {
        w3c: false
      },
      'goog:loggingPrefs' => {browser: 'ALL'}
    })  
end

and in the log place

puts ""
puts "*** Browser logs:"
puts ""

puts page.driver.browser.manage.logs.get("browser").map { |log_entry|
  "[#{Time.at(log_entry.timestamp.to_i)}] [#{log_entry.level}] #{log_entry.message}"
}.join("\n")

Upvotes: 1

Thomas Walpole
Thomas Walpole

Reputation: 49960

Capybara 3.24 now works around this issue when used with chromedriver >= 75.0.3770.90

Upvotes: 6

Justin Ko
Justin Ko

Reputation: 46846

As a short term fix, it seems you can monkey-patch the functionality back in (tested using Selenium-WebDriver v3.142.3):

You will need to add/patch the method to the Chrome::Bridge:

require 'selenium-webdriver'

module Selenium
  module WebDriver
    module Chrome
      module Bridge
        COMMANDS = remove_const(:COMMANDS).dup
        COMMANDS[:get_log] = [:post, 'session/:session_id/log']
        COMMANDS.freeze

        def log(type)
          data = execute :get_log, {}, {type: type.to_s}

          Array(data).map do |l|
            begin
              LogEntry.new l.fetch('level', 'UNKNOWN'), l.fetch('timestamp'), l.fetch('message')
            rescue KeyError
              next
            end
          end
        end
      end
    end
  end
end

In your capabilities, you will need to switch to using "goog:loggingPrefs" instead of just "loggingPrefs":

caps = Selenium::WebDriver::Remote::Capabilities.chrome('goog:loggingPrefs' => {browser: 'ALL'})
driver = Selenium::WebDriver.for(:chrome, desired_capabilities: caps)

driver.execute_script('console.log("test");')

puts driver.manage.logs.get(:browser)
#=> INFO 2019-06-13 21:48:03 -0400: console-api 362:34 "test"

Upvotes: 2

Alexey Subach
Alexey Subach

Reputation: 12312

As specified in the release notes for Chrome Driver 75, capability loggingPrefs has been renamed to goog:loggingPrefs, as required by W3C standard. Thus, the code setting the capabilities should be adjusted and there will be no necessity of falling back to non-w3c mode at least due to the log capturing reason.

Upvotes: 3

Daniel
Daniel

Reputation: 4321

Chrome 75 defaults to W3C mode, which doesn't specify a way to get log access.

The short term fix for this issue is to disable w3c via chromeOptions.

Capybara.register_driver :headless_chrome do |app|
  capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
    chromeOptions: { args: %w[headless window-size=1280,800], w3c: false },
  )

  Capybara::Selenium::Driver.new app,
                                 browser: :chrome,
                                 desired_capabilities: capabilities
end

Upvotes: 8

Related Questions