Capybara Cheatsheet
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
This snippet does 2 things:
- Delete the HTML file and only keep the screenshot.
- Rename the screenshot if
filename
argument is present.
module ScreenshotHelper
# override Capybara#screenshot_and_save_page
def screenshot_and_save_page(filename = nil)
# {:html => saver.html_path, :image => saver.screenshot_path}
result = super()
File.delete(result[:html])
if filename
folder_path, _, _ = result[:image].rpartition('/')
new_file = folder_path + '/' + filename + '.png'
File.rename(result[:image], new_file)
end
end
end