Capybara: Running tests with headless Chrome

Updated . Posted . Visible to the public. Repeats.

Headless Chrome Show archive.org snapshot is a way to run the Chrome browser without a visible window.

Configuring Capybara

Configure the Capybara driver like this:

Capybara.register_driver :selenium do |app|
  options = Selenium::WebDriver::Chrome::Options.new
  options.add_argument('--disable-infobars')
  options.add_emulation(device_metrics: { width: 1280, height: 960, touch: false })
  
  unless ENV.key?('NO_HEADLESS')
    options.add_argument('--headless')
    options.add_argument('--disable-gpu')
  end
  
  if ENV.key?('CI') # Also when in Docker
    options.add_argument('--no-sandbox')
    options.add_argument('--disable-dev-shm-usage')
  end
  
  if ENV.key?('REMOTE_DEBUGGING')
    options.add_argument('--remote-debugging-port=9223')  
  end
  
  Capybara::Selenium::Driver.new(app, browser: :chrome, options: options)
end

Selenium::WebDriver.logger.level = :error

Headless Chrome in legacy Capybara 1 projects

If you're working on a legacy project with Capybara version 1.x, the code below should do:

Capybara.register_driver :selenium do |app|
  args = []
  args << '--headless' unless ENV.key?('NO_HEADLESS')
  args << '--disable-infobars'
  args << '--window-size=1280,960'
  Capybara::Selenium::Driver.new(app, browser: :chrome, args: args)
end

Looking at the hidden browser

Option 1: Run without headless

You can call your tests with NO_HEADLESS=1 bundle exec cucumber to see the Chrome window for this test run. (This will not work when your Chrome is running inside Docker – in that case see option 2.)

You might want to define a bash alias alias nh='NO_HEADLESS=1' to shorten this command to nh bundle exec cucumber.

Option 2: Remote debugging

With remote debugging, you can access a Docker Chrome from the host system.

Here is an example for a Docker container started with docker-compose:

  1. Start the Docker container: docker-compose run --publish 9222:9222 $service bash (mapping the local port 9222 into that container, and starting a shell)
  2. Capybara will instruct its instance of Chrome to open the remote debugging port. Unfortunately, Chrome will only listen on localhost. You need to make the debugging port available to the (Docker) network: socat TCP4-LISTEN:9222,fork TCP4:127.0.0.1:9223 (if missing, install with sudo apt install socat)
  3. Start you integration test e.g. REMOTE_DEBUGGING=1 bundle exec rspec spec/system/some_spec.rb with a debugger set
  4. Open chrome://inspect/. It should list the test Chrome under "Remote target". (Ensure "Discover network targets" is enabled and "localhost:9222" is registered behind the "Configure…" button.)

Note

Remote debugging does not work well if you change your selenium driver between features (e.g. from a mobile device emulation back to a desktop browser). Therefore it makes more sense to run only single features / specs with REMOTE_DEBUGGING enabled.

Image

Henning Koch
Last edit
Dominik Schöler
Attachments
License
Source code in this card is licensed under the MIT License.
Posted by Henning Koch to makandra dev (2020-12-17 11:39)