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 specificport
as attribute of theSelenium::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"