Published 08/092020
Last Updated 17/11/2024

Predicates

Different way to write predicates:

expect(page).to have_selector 'selector' # prefered method
page.should have_selector 'selector'
page.has_selector? 'selector'
page.assert_selector 'selector', count: 3
find('selector').text.should == 'something'

List of predicates

# User has_*? and has_no_*? if you use page.has_*?(selector) syntax
have_selector      | have_no_selector
have_css           | have_no_css
has_xpath          | has_no_xpath?
has_link?          | has_no_link?
has_button?        | has_no_button?
has_field?         | has_no_field?
has_checked_field? | has_unchecked_field?
has_table?         | has_no_table?
has_select?        | has_no_select?

Note: Avoid using should_not have_* or expect(page).not_to have_* in RSpec because they don't wait for timeout in from the driver.

Mouse emulator

Move mouse around. This seems only work with driver using CDP protocol such as cuprite

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

Click/Scroll

page.driver.click(x, y) Click a very specific area of the screen.
page.driver.scroll_to(left, top) Scroll to a given position.
element.send_keys(*keys) Send keys to a given node.

Register a driver

The example below uses cuprite driver.

Capybara.register_driver(:cuprite) do |app|
  Capybara::Cuprite::Driver.new(
    app,
    window_size: [1200, 800],
    browser_options: { "no-sandbox" => nil },
    # Increase Chrome startup wait time (required for stable CI builds)
    process_timeout: 10,
    # Enable debugging capabilities
    inspector: true,
    # Allow running Chrome in a headful mode by setting HEADLESS env
    # var to a falsey value
    headless: ENV.fetch('HEADLESS', 'true') == 'true'
  )
end

# Configure Capybara to use :cuprite driver by default
Capybara.default_driver = Capybara.javascript_driver = :cuprite

URL whitelist and blacklist

Blacklist/Whitelist config tell Capybara to ignore unneccesary resources, reduce loading time for the site and thus improve testing speed as well as avoid timeout errors.

config.before :each, :js do
  page.driver.browser.url_blacklist = [
    'fonts.googleapis.com',
    'www.googletagmanager.com'
  ].flat_map { |domain| [ "http://#{domain}", "https://#{domain}" ] }
end
page.driver.browser.url_whitelist = ['<http://www.example.com>']

Override Capybase screenshot_and_save_page