How to enable Chromedriver logging

When using Chrome for Selenium tests, the chromedriver binary will be used to control Chrome. To debug problems that stem from Selenium's Chrome and/or Chromedriver, you might want to enable logging for the chromedriver itself. Here is how.

Option 1: Use Selenium::WebDriver::Service

In your test setup, you may already have something like Capybara::Selenium::Driver.new(@app, browser: :chrome, options: ...), especially when passing options like device emulation.

Similar to options, simply add an extra key service and pass an instance of Selenium::WebDriver::Service like so:

service = ::Selenium::WebDriver::Chrome::Service.new(args: ['--verbose', '--log-path=/tmp/chromedriver.log'])
::Capybara::Selenium::Driver.new(@app, browser: :chrome, options: ..., service: service)

Note:

  • Version 3.x also supports passing the service arguments as driver_opts directly. However, this is deprecated and will be removed in version 4 of selenium-webdriver.
  • Version 5.x will drop support for passing the service options as hash. You might see a deprecation warning in version 4.x WARN Selenium [DEPRECATION] [:driver_opts] initializing Service class with :args using Hash is deprecated. Use :args parameter with an Array of String values instead..

Option 2: Connect tests to a manually started chromedriver

Warning

This does not work with selenium-webdriver > 4 anymore. You can pass in a specific port as attribute of the Selenium::WebDriver::Service, but the gem will use a different port if it is already in use.

If the above approach no longer works, or if you want to go bare metal, you can also start chromedriver yourself in a terminal on a custom port:

chromedriver --port=12345 --verbose --log-path=/tmp/chromedriver.log

Then configure Selenium to connect to that port. Like in option 1, you need to pass an extra key when creating your driver instance.

Capybara::Selenium::Driver.new(@app, browser: :chrome, options: ..., url: 'http://localhost:12345')

Note that you may omit the --log-path option to make chromedriver print to your terminal.

Example log output

    And I check "Some checkbox"                                                                                                            # spreewald-2.5.0/lib/spreewald/web_steps.rb:46
2020-01-02 00:00:03 INFO Selenium -> GET session/1230859ba100e7b2e5472cfb5bdf94c3/alert_text
2020-01-02 00:00:03 INFO Selenium <- {"sessionId":"1230859ba100e7b2e5472cfb5bdf94c3","status":27,"value":{"message":"no such alert\n  (Session info: chrome=84.0.4147.105)\n  (Driver info: chromedriver=84.0.4147.30 (48b3e868b4cc0aa7e8149519690b6f6949e110a8-refs/branch-heads/4147@{#310}),platform=Linux 5.4.0-42-generic x86_64)"}}
2020-01-02 00:00:03 WARN Selenium [DEPRECATION] Selenium::WebDriver::Error::NoAlertOpenError is deprecated. Use Selenium::WebDriver::Error::NoSuchAlertError (ensure the driver supports W3C WebDriver specification) instead.
2020-01-02 00:00:03 INFO Selenium -> POST session/1230859ba100e7b2e5472cfb5bdf94c3/se/log
2020-01-02 00:00:03 INFO Selenium    >>> http://127.0.0.1:9538/session/1230859ba100e7b2e5472cfb5bdf94c3/se/log | {"type":"browser"}
2020-01-02 00:00:03 DEBUG Selenium      > {"Accept"=>"application/json", "Content-Type"=>"application/json; charset=UTF-8", "User-Agent"=>"selenium/3.142.7 (ruby linux)", "Content-Length"=>"18"}
2020-01-02 00:00:03 INFO Selenium <- {"sessionId":"1230859ba100e7b2e5472cfb5bdf94c3","status":0,"value":[]}
2020-01-02 00:00:03 INFO Selenium -> POST session/1230859ba100e7b2e5472cfb5bdf94c3/elements
2020-01-02 00:00:03 INFO Selenium    >>> http://127.0.0.1:9538/session/1230859ba100e7b2e5472cfb5bdf94c3/elements | {"using":"xpath","value":".//input[((((./@type = 'submit') or (./@type = 'reset')) or (./@type = 'image')) or (./@type = 'button'))][((((./@id = 'Save') or (./@name = 'Save')) or (./@value = 'Save')) or (./@title = 'Save'))] | .//input[(./@type = 'image')][(./@alt = 'Save')] | .//button[((((((./@id = 'Save') or (./@name = 'Save')) or (./@value = 'Save')) or (./@title = 'Save')) or (normalize-space(string(.)) = 'Save')) or .//img[(./@alt = 'Save')])] | .//input[(./@type = 'image')][(./@alt = 'Save')]"}
2020-01-02 00:00:03 DEBUG Selenium      > {"Accept"=>"application/json", "Content-Type"=>"application/json; charset=UTF-8", "User-Agent"=>"selenium/3.142.7 (ruby linux)", "Content-Length"=>"506"}
2020-01-02 00:00:03 INFO Selenium <- {"sessionId":"1230859ba100e7b2e5472cfb5bdf94c3","status":0,"value":[{"ELEMENT":"0.2508372215483632-3"}]}
2020-01-02 00:00:03 INFO Selenium -> POST session/1230859ba100e7b2e5472cfb5bdf94c3/execute
2020-01-02 00:00:03 INFO Selenium    >>> http://127.0.0.1:9538/session/1230859ba100e7b2e5472cfb5bdf94c3/execute | {"script":"return arguments[0].matches(':disabled, select:disabled *')","args":[{"ELEMENT":"0.2508372215483632-3"}]}
2020-01-02 00:00:03 DEBUG Selenium      > {"Accept"=>"application/json", "Content-Type"=>"application/json; charset=UTF-8", "User-Agent"=>"selenium/3.142.7 (ruby linux)", "Content-Length"=>"116"}
2020-01-02 00:00:03 INFO Selenium <- {"sessionId":"1230859ba100e7b2e5472cfb5bdf94c3","status":0,"value":false}
2020-01-02 00:00:03 INFO Selenium -> POST session/1230859ba100e7b2e5472cfb5bdf94c3/element/0.2508372215483632-3/click
2020-01-02 00:00:03 INFO Selenium <- {"sessionId":"1230859ba100e7b2e5472cfb5bdf94c3","status":0,"value":null}
    And I press "Save"      

Further reading

Arne Hartherz Over 4 years ago