Home

Awesome

Cuprite - Headless Chrome driver for Capybara

Cuprite is a pure Ruby driver (read as no Selenium/WebDriver/ChromeDriver dependency) for Capybara. It allows you to run Capybara tests on a headless Chrome or Chromium. Under the hood it uses Ferrum which is high-level API to the browser by CDP protocol.

Install

Add this to your Gemfile and run bundle install.

group :test do
  gem "cuprite"
end

In your test setup add:

require "capybara/cuprite"
Capybara.javascript_driver = :cuprite
Capybara.register_driver(:cuprite) do |app|
  Capybara::Cuprite::Driver.new(app, window_size: [1200, 800])
end

if you use Docker don't forget to pass no-sandbox option:

Capybara::Cuprite::Driver.new(app, browser_options: { 'no-sandbox': nil })

Since Cuprite uses Ferrum there are many useful methods you can call even using this driver:

browser = page.driver.browser
browser.mouse.move(x: 123, y: 456).down.up

For Selenium you better check your code for manage calls because it works differently in Cuprite, see the documentation below.

Customization

See the full list of options for Ferrum.

You can pass options with the following code in your test setup:

Capybara.register_driver(:cuprite) do |app|
  Capybara::Cuprite::Driver.new(app, options)
end

Cuprite-specific options are:

Debugging

If you pass inspector option, remote debugging will be enabled if you run tests with INSPECTOR=true. Then you can put page.driver.debug or page.driver.debug(binding) in your test to pause it. This will launch the browser where you can inspect the content.

Capybara.register_driver :cuprite do |app|
  Capybara::Cuprite::Driver.new(app, inspector: ENV['INSPECTOR'])
end

then somewhere in the test:

it "does something useful" do
  visit root_path

  fill_in "field", with: "value"
  page.driver.debug(binding)

  expect(page).to have_content("value")
end

In the middle of the execution Chrome will open a new tab where you can inspect the content and also if you passed binding an irb or pry console will be opened where you can further experiment with the test.

Clicking/Scrolling

Request headers

Manipulate HTTP request headers like a boss:

page.driver.headers # => {}
page.driver.headers = { "User-Agent" => "Cuprite" }
page.driver.add_headers("Referer" => "https://example.com")
page.driver.headers # => { "User-Agent" => "Cuprite", "Referer" => "https://example.com" }

Notice that headers= will overwrite already set headers. You should use add_headers if you want to add a few more. These headers will apply to all subsequent HTTP requests (including requests for assets, AJAX, etc). They will be automatically cleared at the end of the test.

Network traffic

# Retrieve all network exchanges
network_traffic = page.driver.network_traffic

# Access the first exchange
first_exchange = network_traffic.first

# Inspect the response of the first request
response = first_exchange.response
page.driver.wait_for_network_idle
page.driver.refresh

Please note that network traffic is not cleared when you visit new page. You can manually clear the network traffic by calling page.driver.clear_network_traffic or page.driver.reset

Manipulating cookies

The following methods are used to inspect and manipulate cookies:

Screenshot

Besides capybara screenshot method you can get image as Base64:

Authorization

Proxy

URL Blacklisting & Whitelisting

Cuprite supports URL blacklisting, which allows you to prevent scripts from running on designated domains:

page.driver.browser.url_blacklist = %r{http://www.example.com}

and also URL whitelisting, which allows scripts to only run on designated domains:

page.driver.browser.url_whitelist = %r{http://www.example.com}

If you are experiencing slower run times, consider creating a URL whitelist of domains that are essential or a blacklist of domains that are not essential, such as ad networks or analytics, to your testing environment.

License

The gem is available as open source under the terms of the MIT License.