API Reference

All of the following methods can be called on a Capybara::TestHelper instance.

Many of these methods are coming from the Capybara API and can be used exactly the same, except they have been extended to support locator aliases.

Most methods that find or interact with an element can receive a :wait option, which determines how long the command will be retried before failing. For the ones that don't, it can still be configured with using_wait_time.

Test Helper Class

The following methods are available at the class scope in Capybara::TestHelper subclasses.

aliases

Defines locator aliases that can be used by actions, finders, matchers, and assertions.

A method with the alias name will be defined for each specified alias, as a shortcut for find.

Read the aliases guide for a quick overview.

  • Arguments:

    • locator_aliases {Hash}:
      • key {Symbol}: name of the alias
      • value {String | Array}: the locator
  • Example:

    class FormTestHelper < Capybara::TestHelper
      aliases(
        el: 'form',
        save_button: '.button[type=submit]',
        save_loading_indicator: [:save_button, ' .loading-indicator'],
      )
    
      def save
        within { save_button.click }
      end
    
      def be_saving
        have(:save_loading_indicator)
      end
    end
    

delegate_to_test_context

Makes the specified methods from the RSpec or Cucumber context available in the test helper instance.

This is useful when defining custom logic in support files.

For one-off usages, you may call test_context manually in the instance.

  • Arguments:

    • *method_names {Symbol}: the methods to delegate to the test context
  • Example:

    class BaseTestHelper < Capybara::TestHelper
      delegate_to_test_context(:support_file_path)
    
      def drop_file(filename)
        drop support_file_path(filename)
      end
    end
    

use_test_helpers

Makes other test helpers available in the instance as methods.

The defined methods can optionally receive an element to wrap.

Read the composition guide for a quick overview.

  • Arguments:

    • *helper_names {Symbol}: the names of the test helpers to inject
  • Example:

    class CitiesTestHelper < Capybara::TestHelper
      use_test_helpers(:form, :table)
    
      aliases(
        cities_table: '.cities',
      )
    
      def edit(name, with:)
        table(cities_table).row_for(name).click_link('Edit')
        form.within {
          fill_in('Name', with: with[:name])
          form.save
        }
      end
    end
    

Test Helper Instance

The following instance methods are available in Capybara::TestHelper instances.

not_to

The current assertion state of the test helper.

Intended to be used along with to_or to create positive and negative assertions at once.

Also available as or_should_not, for syntax sugar: should(or_should_not), but usually not needed because injected test helpers preserve the assertion state.

  • Example:

    def be_checked
      expect(checked?).to_or not_to, eq(true)
    end
    

    TIP

    Make sure to manually synchronize when writing custom expectations.

should

Returns a test helper with a positive assertion state, allowing any assertions to be chained after it.

Also available as should_still, should_now, and, and_instead, and_also, and_still.

  • Arguments:

    • negated {Boolean}: defaults to false, if truthy it will return a test helper with a negative assertion state.
  • Examples:

    users.should.have_content('Jane')
    
    Then(/^there should( not)? be an? "(.+?)" city$/) do |or_should_not, name|
      cities.should(or_should_not).have_city(name)
    end
    

should_not

Returns a test helper with a negative assertion state, allowing any assertions to be chained after it.

Also available as should_still_not, should_no_longer, nor, and_not.

  • Examples:
    users.should_not.have_content('Jane')
    

test_context

The test context in which the test helper was instantiated.

Set implicitly to the RSpec example or Cucumber world when using injected test helpers.

delegate_to_test_context allows you to expose methods in the test helper as needed.

  • Examples:
    # Internal: Quick way to grab the current user being used on the test.
    def user
      test_context.instance_variable_get('@user') || test_context.current_user
    end
    

to_capybara_node

  • Usage:

    Casts the current context as a Capybara::Node::Element.

    • If the test helper is wrapping an element, it will return it.
    • If the test helper is wrapping the page, it will find an element using the :el alias.

    Source

  • Example:

    def focus
      to_capybara_node.execute_script('this.focus()')
      self
    end
    

wrap_element

Wraps the given element with a new test helper instance.

When passing a test helper, it will wrap its current element.

  • Arguments:

    element {Capybara::Node::Element | Capybara::TestHelper}: the element to wrap

  • Returns:

    A new Capybara::TestHelper of the same class the method was invoked in.

  • Example:

    def find_user(name)
      wrap_element table.row_for(name)
    end
    

Actions

Check the guide for a quick tour.

Some of the following methods will be performed on the current element, while other methods will use the current context (which by default is the current page).

attach_file

Finds a file field in the current context, and attaches a file to it.

  • Arguments:

    • locator (optional): uses the :file_field selector
    • paths {String | Array<String>}: the path(s) of the file(s) to attach
  • Returns: the file field

  • Example:

      form.csv_file_input.attach_file('/path/to/example.csv')
      # same as
      form.attach_file('CSV File', '/path/to/example.csv')
    
      # attach file to any file input triggered by the block
      form.attach_file('/path/to/file.png') { form.click_link('Upload Image') }
    

blur

Removes focus from the current element using JS.

  • Returns: self

  • Example:

    form.search_input.blur
    

check

Finds a check box in the current context, and marks it as checked.

  • Arguments: locator (optional): uses the :checkbox selector

  • Returns: the element checked or the label clicked

  • Example:

    form.terms_and_conditions.check
    form.language.check('German')
    

choose

Finds a radio button in the current context, and checks it.

  • Arguments: locator (optional): uses the :radio_button selector

  • Returns: the element chosen or the label clicked

  • Example:

    form.preferred_menu.check('Vegetarian')
    form.check('menu', option: 'Vegetarian')
    

click

Clicks the current element.

  • Arguments:

    • *modifier_keys {Symbol}: modifier keys that should be held during click

    Options:

    By default it will attempt to click the center of the element.

    • :x {Numeric}: the X coordinate to offset the click location
    • :y {Numeric}: the Y coordinate to offset the click location
  • Returns: self

  • Examples:

    def toggle_menu
      find('#menu').click
    end
    
    def open_in_new_tab
      click(:control, x: 5, y: 5)
    end
    

click_button

Finds a button in the current context and clicks it.

  • Arguments: same as find_button

  • Returns: the clicked button

  • Example:

    form.click_button('Save')
    

Finds a link in the current context and clicks it.

  • Arguments: same as find_link

  • Returns: the clicked link

  • Example:

    current_page.click_link('Back to Home')
    

click_on

Finds a link or button in the current context and clicks it.

  • Arguments: same as find_button and find_link

  • Returns: the clicked link or button

  • Example:

    purchase_page.click_on('Checkout')
    

double_click

Double clicks the current element.

  • Arguments: Same as click.

  • Returns: self

drag_to

Drags the current element to the given other element.

  • Arguments:

    • node {Capybara::Node::Element | Capybara::TestHelper}: the destination to drag to

    Options:

    Driver-specific, might not be supported by all drivers.

    • :delay {Numeric}: the amount of seconds between each stage, defaults to 0.05
    • :html5 {Boolean}: force the use of HTML5, otherwise auto-detected by the driver
    • :drop_modifiers {Array<Symbol>}: Modifier keys which should be held while dragging
  • Returns: self

  • Example:

    todo = pending_list.item_for('Water plants')
    todo.drag_to(done_list)
    

drop

Drops items on the current element.

  • Arguments:

    • *path {String | #to_path | Hash}: location(s) of the file(s) to drop on the element
  • Returns: self

  • Example:

    file_input.drop('/some/path/file.csv')
    file_input.drop({ 'text/url' => 'https://www.google.com', 'text/plain' => 'Website' })
    

evaluate_async_script

Evaluates the given JavaScript in the current context of the element, and obtains the result from a callback function that is passed as the last argument to the script.

  • Arguments:

    • script {String}: a string of JavaScript to evaluate
    • *args {Object}: parameters for the JavaScript function
  • Returns: Object result of the callback function

  • Example:

    def delayed_value(delay: 0.1)
      # Since we are passing only one argument (delay), the second argument will
      # be the callback that will capture the value.
      evaluate_async_script(<<~JS, delay)
        const delay = arguments[0]
        const callback = arguments[1]
        setTimeout(() => callback(this.value), delay)
      JS
    end
    

evaluate_script

Evaluates the given JS in the current context, and returns the result.

If the test helper has a current element, then this in the script will refer to that HTML node.

  • Arguments:

    • script {String}: a string of JavaScript to evaluate
    • *args {Object}: parameters for the JavaScript function
  • Returns: Object result of evaluating the script

  • Example:

    def offset_height(padding: 5)
      evaluate_script('this.offsetHeight - arguments[0]', padding)
    end
    

    TIP

    Use execute_script instead when the script returns complex objects such as jQuery statements.

execute_script

Execute the given JS in the current context without returning a result.

If the test helper has a current element, then this in the script will refer to that HTML node.

  • Arguments:

    • script {String}: a string of JavaScript to evaluate
    • *args {Object}: parameters for the JavaScript function
  • Returns: self

  • Example:

    def move_caret_to_the_beginning
      execute_script('this.setSelectionRange(0, 0)')
    end
    

    TIP

    Should be used over evaluate_script whenever a result is not needed, specially for scripts that return complex objects, such as jQuery statements.

fill_in

Finds a text field or text area in the current context, and fills it in with the given text.

  • Arguments:

    Options:

    • :with {String}: the value to fill in
    • :currently_with {String}: the current value of the field to fill in
  • Returns: the element that was filled in

  • Example:

    def add_user(name:)
      fill_in('Name', with: name)
      click_on('Submit')
    end
    
    address_form.street_input.fill_in(with: 'Evergreen St.')
    

focus

Focuses the current element using JS.

  • Returns: self

  • Example:

    form.find_field('Name').focus.move_caret_to_the_beginning
    

hover

Hovers on the current element.

  • Returns: self

  • Example:

    def have_tooltip(title)
      hover.have('.tooltip', text: title)
    end
    

right_click

Right clicks the current element.

  • Arguments: Same as click.

  • Returns: self

scroll_to

Supports three different ways to perform scrolling.

  • Scroll the page or element to its top, bottom or middle.

    • position {:top | :bottom | :center | :current}
    current_page.scroll_to(:top, offset: [0, 20])
    
  • Scroll the page or element into view until the given element is aligned as specified.

    • element {Capybara::Node::Element | Capybara::TestHelper}: the element to be scrolled
    • :align {:top | :bottom | :center }: where to align the element being scrolled into view with relation to the current page/element if possible.
    def scroll_into_view
      scroll_to(self, align: :top)
    end
    
  • Scroll horizontally or vertically.

    • x {Integer}
    • y {Integer}
    current_page.scroll_to(100, 500)
    
  • Options:

    • [x, y] :offset
  • Returns: self

select

Finds an option inside the current context and selects it.

If the select box is a multiple select, it can be called multiple times to select more than one option.

  • Arguments:

  • Returns: the selected option element

  • Example:

      form.month_input.select('March')
      # same as
      form.select('March', from: 'Month')
    

select_option

Selects the current element if it is an option inside a select tag.

Used implicitly when calling select, which should be preferred.

  • Returns: self

  • Example:

    option.select_option
    

send_keys

Sends keystrokes to the current element.

You may use any of the supported symbol keys.

  • Arguments: *keys {String | Symbol} the keys to type

  • Returns: self

  • Example:

    input
      .send_keys('fod', :left, 'o')       # value: 'food'
      .send_keys([:control, 'a'], :space) # value: ' ' (assuming select all)
      .send_keys(:tab)
    

set

Sets the value of the current element to the specified value.

  • Arguments: value {Object} the new value

    Options:

    • :clear: The method used to clear the previous value
      • nil the default, clears the input using JS
      • :none appends the new value to the previous value
      • :backspace sends backspace keystrokes to clear the field
  • Returns: self

  • Example:

    input.set('fo').set('od', clear: :none).should.have_value('food')
    

style

Retrieves the specified CSS styles for the current element.

  • Arguments: *styles {String} the style properties to retrieve

  • Returns: Hash with the computed style properties

  • Example:

      heading.style(:color, 'font-size')
    

    TIP

    Use match_style instead when making assertions.

uncheck

Finds a check box in the current context, and unchecks it.

  • Arguments:

  • Returns: the element checked or the label clicked

  • Example:

    form.uncheck('Email Notifications')
    form.terms_and_conditions.uncheck
    

unselect

Finds an option inside the current context and unselects it.

If the select box is a multiple select, it can be called multiple times to unselect more than one option.

  • Arguments:

  • Returns: the unselected option element

  • Example:

      form.locale_select.unselect('English')
      # same as
      form.unselect('English', from: 'form_locale')
    

unselect_option

Unselects the current element if it is an option inside a multiple select tag.

Used implicitly when calling unselect, which should be preferred.

  • Returns: self

  • Example:

    option.unselect_option
    

Assertions

Check the guide for a quick tour.

To use an assertion, call should or should_not, and then chain the assertion.

Negated versions are available, such as have_no_selector and not_match_selector, but are omitted for brevity as they work exactly the same as using should_not with a positive assertion.

TIP

Injected test helpers will preserve the assertion state of the current helper.

have

Asserts that the current context contains an element with the given selector.

You may specify a locator alias or use any capybara selector.

  • Arguments: same as find_all

  • Returns: self

  • Examples:

    current_page
      .should.have(:title, text: 'Using Test Helpers')
      .should.have(:subtitle, count: 3)
      .should.have('h3', text: 'Global Test Helpers', visible: true)
    
    table.should.have(:table_row, { 'Name' => 'Allen' })
    

have_ancestor

Asserts that the current element has an ancestor with the given selector.

  • Arguments: same as ancestor

  • Returns: self

  • Example:

    list_item
      .should.have_ancestor('ul', text: 'Pending')
      .should_not.have_ancestor('ul', text: 'Done')
    

have_button

Asserts that the current context contains a button with the given selector.

  • Arguments: same as find_all, see the :button selector for usage

  • Returns: self

  • Example:

    form.should.have_button(type: 'submit', disabled: true)
    

have_checked_field

Asserts that the current context contains a radio button or checkbox with the given selector, that is currently checked.

  • Arguments: same as find_all, see the :field selector for usage

  • Returns: self

  • Example:

    form.should.have_checked_field('Terms and Conditions')
    

have_content

Alias for have_text.

  • Example:
    current_page.should.have_content('have', between: 130..150)
    

have_css

Asserts that the current context contains an element with the given CSS selector.

  • Arguments: same as find_all, see the :css selector for usage

  • Returns: self

  • Example:

    current_page.should.have_css('#main .container')
    

have_field

Asserts that the current context contains a form field with the given selector.

  • Arguments: same as find_all, see the :field selector for usage

  • Returns: self

  • Example:

    form.should.have_field('First Name').and_not.have_field('Last Name')
    

Asserts that the current context contains a link with the given selector.

  • Arguments: same as find_all, see the :link selector for usage

  • Returns: self

  • Example:

    current_page.should.have_link('Go to Checkout', href: '#checkout')
    

have_select

Asserts that the current context contains a select field with the given selector.

  • Arguments: same as find_all, see the :select selector for usage

  • Returns: self

  • Example:

    form.should.have_select('Language', selected: ['English', 'Spanish'])
    

have_selector

Alias for have.

  • Example:
    form.should.have_selector(:button, 'Save')
    

have_sibling

Asserts that the current element has a sibling with the given selector.

  • Arguments: same as sibling

  • Returns: self

  • Example:

    list_item.should.have_sibling('li', text: 'Pending')
    

have_table

Asserts that the current context contains a table field with the given selector.

  • Arguments: same as find_all, see the :table selector for usage

  • Returns: self

  • Example:

    users.should.have_table(caption: 'Users')
    

have_text

Asserts that the current element has the given text content, ignoring HTML tags.

  • Arguments:

    • type { :all | :visible } (optional): whether to check for only visible or all text
    • text {String | Regexp}: the expected text

    Options: same options as find_all, plus:

    • :exact {Boolean}: defaults to false, whether the provided string should be an exact match or just a substring
  • Returns: self

  • Example:

    lorem_ipsum
      .should.have_text('Lorem').and_also.have_text('ipsum')
      .should.have_text('Lorem ipsum dolor', exact: true)
    
    lorem_ipsum.should.have_text(:all, /dolor/, between: 2..6)
    

have_unchecked_field

Asserts that the current context contains a radio button or checkbox with the given selector, that is currently unchecked.

  • Arguments: same as find_all, see the :field selector for usage

  • Returns: self

  • Example:

    form.should.have_unchecked_field('Terms and Conditions')
    

have_value

Asserts that the value of the current element matches the provided value.

  • Arguments:

    • value { String | Array<String> }: the expected value
  • Returns: self

  • Example:

    form.find_field('Address').should.have_value('Oceanside Resort', wait: 5)
    form.find_field('Languages').should.have_value(['Spanish', 'English'])
    

have_xpath

Asserts that the current context contains an element with the given XPath selector.

  • Arguments: same as find_all, see the :xpath selector for usage

  • Returns: self

  • Example:

    current_page.should.have_xpath('.//table/tr')
    

match_css

Asserts that the current element matches a given CSS selector.

  • Arguments: same as find, see the :css selector for usage

  • Returns: self

  • Example:

    form.find_select('Languages').should.match_css(':disabled')
    

match_selector

Asserts that the current element matches a given selector.

You may specify a locator alias or use any capybara selector.

  • Arguments: same as find

  • Returns: self

  • Examples:

    form_page.submit_button.should.match_selector(:button, label: 'Submit')
    

match_style

Asserts that the current element matches the specified CSS styles.

  • Arguments:

    • styles {Hash}: the expected styles
  • Returns: self

  • Example:

    icon.should.match_style(color: 'white', 'font-size': => /px/)
    icon.hover.should.match_style({ color: 'red' }, wait: 2)
    

match_xpath

Asserts that the current element matches a given XPath expression.

  • Arguments: same as find, see the :xpath selector for usage

  • Returns: self

  • Example:

    form.find_select('Title').should.match_xpath('.//select[@id="form_title"]')
    

have_all_of_selectors

Asserts that all of the provided selectors are descendants of the current context.

If using aliases, you must explicitly provide a selector as the first argument.

Waits until all of the elements are found, or times out.

  • Returns: self

  • Example:

    form.should.have_all_of_selectors(:css, :name_input, :last_name_input)
    

have_any_of_selectors

Asserts that at least of the provided selectors are descendants of the current context.

If using aliases, you must explicitly provide a selector as the first argument.

Waits until one of the elements is found, or times out.

  • Returns: self

  • Example:

    form.should.have_any_of_selectors(:css, :name_input, :last_name_input, wait: 2)
    

have_none_of_selectors

Asserts that none of the provided selectors are descendants of the current context.

If using aliases, you must explicitly provide a selector as the first argument.

Waits until none of the elements are found, or times out.

  • Returns: self

  • Example:

    form.should.have_none_of_selectors(:css, '.error', '.warning')
    

Debugging

Check out the guide for additional information.

The following methods are useful when debugging test failures.

flash

Toggles the current element background color between white and black for a period of time.

inspect_node

Inspects the Capybara::Node::Element element the test helper is wrapping.

save_and_open_page

Saves a snapshot of the page and open it in a browser for inspection. Requires launchy.

  • Arguments: path {String} (optional): the path to where it should be saved

save_and_open_screenshot

Save a screenshot of the page and open it for inspection. Requires launchy.

  • Arguments: path {String} (optional): the path to where it should be saved

  • Returns: path {String}: the path to which the file was saved

  • Example:

    def have_city(name)
      # Take a screenshot before the assertion runs.
      save_and_open_screenshot('have_city.png')
      have_content(name)
    end
    

save_page

Saves a snapshot of the page.

  • Arguments: path {String} (optional): the path to where it should be saved

  • Returns: path {String}: the path to which the file was saved

save_screenshot

Saves a screenshot of the page.

  • Arguments: path {String} (optional): the path to where it should be saved

  • Returns: path {String}: the path to which the file was saved

Element

The following methods are always performed on the current element.

[]

Retrieves the given HTML attribute of the current element.

  • Arguments:

    • attribute {String | Symbol} the name of the HTML attribute
  • Returns: String value of the attribute

  • Examples:

    input[:value]
    
    # Public: Returns the HTML id of the element.
    def id
      self[:id]
    end
    

checked?

Whether or not the current element is checked.

disabled?

Whether or not the current element is disabled.

multiple?

Whether or not the current element supports multiple results.

native

The native element from the driver, this allows access to driver-specific methods.

  • Returns: Object

obscured?

Whether the current element is not currently in the viewport or it (or descendants) would not be considered clickable at the elements center point.

path

An XPath expression describing where on the page the element can be found.

  • Returns: String

readonly?

Whether the current element is read-only.

  • Returns: Boolean

  • Example:

    def optional_type_in(text)
      input.set(text) unless input.readonly?
    end
    

    TIP

    You can pass :readonly to assertions or finders.

rect

Returns size and position information for the current element.

  • Returns: Struct { x, y, height, width }

selected?

Whether or not the current element is selected.

tag_name

The tag name of the current element.

  • Returns: String

  • Example:

    users.click_link('Add User').tag_name == 'a'
    

text

Retrieves the text of the current element.

  • Arguments: type { :all | :visible }: defaults to :visible text

  • Returns: String

  • Example:

    find_link('Home').text == 'Home'
    find_link('Hidden', visible: false).text(:all) == 'Hidden'
    

    TIP

    Use have_text instead when making assertions, or pass :text or :exact_text to finders to restrict the results.

value

Retrieves the value of the current element.

  • Returns: { String | Array<String> }

  • Example:

    city_input.value == 'Montevideo'
    languages_input.value == ['English', 'Spanish']
    

    TIP

    Use have_value instead when making assertions, or pass :with to find_field.

visible?

Whether or not the current element is visible.

Finders

Check the guide for a quick tour.

You can locate elements with different strategies by specifying a selector.

Additionally, you can use locator aliases, and may provide an optional block to filter results.

TIP

All finders will automatically retry until the element is found, or the timeout ellapses.

all

Finds all elements in the current context that match the given selector and options.

Also available as find_all.

  • Arguments: same as find, plus:

    • :count {Integer}: of matching elements that should exist
    • :minimum {Integer}: of matching elements that should exist
    • :maximum {Integer}: of matching elements that should exist
    • :between {Range}: range of matching elements that should exist
  • Raises: Capybara::ExpectationNotMet if the number of elements doesn't match the conditions

  • Returns: a collection of found elements, which may be empty

    TIP

    If no elements are found, it will wait until timeout and return an empty collection.

    If you want it to fail, you can pass minimum: 1, or to avoid waiting wait: false.

  • Examples:

    table.find_all('tr', minimum: 1)
    form.all(:fillable_field, count: 3)
    
    def unselect_all_items
      all(:selected_option, wait: false).each(&:click)
    end
    
    def find_by_index(locator, index:, **options)
      find_all(locator, minimum: index + 1, **options)[index]
    end
    

ancestor

Finds an element that matches the given arguments and is an ancestor of the current context.

  • Arguments: same as find.

  • Returns: the ancestor element

  • Examples:

    list_item.ancestor('ul', text: 'Pending')
    
    def group_with_name(group)
      find(:group_name, text: group).ancestor(:group)
    end
    

find

Finds an element in the current context based on the given arguments.

  • Arguments: a locator alias, or a capybara selector.

    Options: any filters in the specified (or default) selector, plus:

    • :text {String | Regexp}: only elements which contain or match this text
    • :exact_text {String | Boolean}: only elements that exactly match this text
    • :visible {Boolean | Symbol}:
      • true or :visible: only find visible elements
      • false or :all: find invisible and visible elements
      • :hidden: only find invisible elements
    • :obscured {Boolean}:
      • true: only elements whose centerpoint is not in the viewport or is obscured
      • false: only elements whose centerpoint is in the viewport and is not obscured
    • :id {String | Regexp}: only elements with the specified id
    • :class {String | Array<String> | Regexp}: only elements with matching class(es)
      • Absence of a class can be checked by prefixing the class name with !
    • :style {String | Regexp | Hash}: only elements with matching style
    • :match {Symbol}: the matching strategy to use
  • Returns: the found element, wrapped in a test helper

  • Examples:

    table.find('tr', match: :first).find('td', text: 'Bond')
    
    form.find(:first_name_input, disabled: true, wait: 5)
    
    container.find(:xpath, '../..')
    
    def find_admin(name)
      find('tr.user', text: name) { |row| row.admin? }
    end
    

find_all

Alias for all.

find_button

Finds a button in the current context.

  • Arguments: same as find, see the :button selector for usage

  • Returns: the found button

  • Examples:

    find_button('Save')
    find_button(type: 'submit')
    

find_by_id

Finds a element in the current context, given its id.

  • Arguments: same as find, see the :id selector for usage

  • Returns: the found element

  • Examples:

    find_by_id('main', visible: true)
    

find_field

Finds a form field in the current context.

The field can be found by its name, id, or label text.

  • Arguments: same as find, see the :field selector for usage

  • Returns: the found field

  • Examples:

    find_field(type: 'checkbox', disabled: false)
    find_field('Description', type: 'textarea', with: /Lorem/)
    

Finds a link in the current context.

  • Arguments: same as find, see the :link selector for usage

  • Returns: the found link

  • Examples:

    find_link(href: '#introduction')
    find_link('Download Paper', download: true)
    

first

Finds the first element in the current context matching the given selector and options.

  • Arguments: same as all, uses minimum: 1 by default

  • Returns: the found element

    When passing count, minimum, or between, it may return nil if the conditions allow it.

  • Raises: Capybara::ExpectationNotMet if the number of elements doesn't match the conditions

  • Examples:

    first(:link, href: true)
    
    navbar.first(:menu, minimum: 0)
    

sibling

Finds an element based on the given arguments that is also a sibling of the current context.

  • Arguments: same as find.

  • Returns: the sibling element

  • Examples:

    list_item.sibling('li', text: 'Pending')
    
    def next_menu
      sibling(:menu, below: self)
    end
    

Modals

accept_alert

Executes the block, accepting an alert that is opened while it executes.

  • Arguments:
    • text {String | Regexp} (optional): text that the modal should contain

accept_confirm

Executes the block, accepting a confirmation dialog that is opened while it executes.

  • Arguments:

    • text {String | Regexp} (optional): text that the modal should contain
  • Example:

    def delete(city)
      accept_confirm { row_for(city).click_on('Destroy') }
    end
    

accept_prompt

Executes the block, accepting a prompt, and optionally responding to it.

  • Arguments:

    • text {String | Regexp} (optional): text that the prompt should contain

    Options: - :with {String} (optional): input for the prompt

dismiss_confirm

Like accept_confirm, but dismisses the confirmation dialog instead.

dismiss_prompt

Like accept_prompt, but dismisses the prompt instead.

go_back

Moves back a single entry in the browser's history.

go_forward

Moves forward a single entry in the browser's history.

refresh

Refreshes the current page.

visit

Navigates to the given URL, which can either be relative or absolute.

Path helpers can be easily made available to test helpers.

  • Arguments:

    • visit_uri: The URL to navigate to. The parameter will be cast to a String.
  • Example:

    def visit_page
      visit cities_path
    end
    

Page

have_current_path

Asserts that the page has the given path.

  • When passing a full url it will compare against the full url

  • When passing a path only the path and query portion will be compared

  • When passing a regexp, it will depend on the :url option

  • Arguments: path {String | Regexp}: the expected path

    Options:

    • :url {Boolean}: whether to compare to the current url or just the path
    • :ignore_query {Boolean}: whether to ignore the query portion, defaults to false
    • :wait {Numeric}: how much time to wait for the current url to match
  • Returns: self

  • Example:

    current_page.should.have_current_path('/cities', wait: 10)
    current_page.should_not.have_current_path('https://example.com', ignore_query: true)
    

have_title

Asserts if the page has the given title.

  • Arguments:

    • title {String | Regexp}: string or regex that the title should match

    Options:

    • :exact {Boolean}: defaults to false, whether the provided string should be an exact match or just a substring
  • Example:

    current_page.should.have_title('Capybara Test Helpers', exact: false)
    

has_title?

Checks if the page has the given title.

  • Arguments:

    • title {String | Regexp}: string or regex that the title should match

    Options:

    • :exact {Boolean}: defaults to false, whether the provided string should be an exact match or just a substring
  • Returns: Boolean

  • Example:

    current_page.has_title?('Capybara Test Helpers', wait: false)
    

page.html

  • Returns: String snapshot of the DOM of the current document

page.title

  • Returns: String title of the document

Querying

Check the guide for a quick tour.

Unlike assertions, matchers return a Boolean instead of failing.

Negated versions are available for all of them, such as has_no? and not_matches_selector?, but are omitted for brevity.

TIP

Have in mind that matchers have some caveats, so prefer assertions when possible.

has?

Predicate version of have.

  • Returns: Boolean

has_ancestor?

Predicate version of have_ancestor.

  • Returns: Boolean

has_button?

Predicate version of have_button.

  • Returns: Boolean

has_checked_field?

Predicate version of have_checked_field.

  • Returns: Boolean

has_content?

Predicate version of have_text.

  • Returns: Boolean

has_css?

Predicate version of have_css.

  • Returns: Boolean

has_field?

Predicate version of have_field.

  • Returns: Boolean

Predicate version of have_link.

  • Returns: Boolean

has_select?

Predicate version of have_select.

  • Returns: Boolean

has_selector?

Predicate version of have_selector.

  • Returns: Boolean

has_sibling?

Predicate version of have_sibling.

  • Returns: Boolean

has_table?

Predicate version of have_table.

  • Returns: Boolean

has_text?

Predicate version of have_text.

  • Returns: Boolean

has_unchecked_field?

Predicate version of have_unchecked_field.

  • Returns: Boolean

has_xpath?

Predicate version of have_xpath.

  • Returns: Boolean

matches_css?

Predicate version of match_css.

  • Returns: Boolean

matches_selector?

Predicate version of match_selector.

  • Returns: Boolean

matches_style?

Predicate version of match_style.

  • Returns: Boolean

matches_xpath?

Predicate version of match_xpath.

  • Returns: Boolean

Scoping

Check the guide for a quick tour.

within

Executes the given block within the context of the specified element.

For the duration of the block, any command to Capybara will be scoped to the given element.

TIP

When called without parameters the block will be scoped to the current element.

  • Arguments: Same as find, can also handle aliases.

  • Returns: Object: The return value of the block.

  • Examples:

    dropdown.within { click_link('Open') }
    
    users.find_user('Kim').within { click_link('Edit') }
    
    def add_user(first_name:)
      click_link('Add User')
    
      within('.new-user-modal') {
        fill_in 'First Name', with: first_name
        click_button 'Save'
      }
    end
    

within_document

Unscopes the inner block from any previous within calls.

For the duration of the block, any command to Capybara will be scoped to the entire page.

TIP

Use as a escape hatch to interact with content outside a previous within call, such as modals.

within_fieldset

Executes the given block within the specific fieldset.

  • Arguments:
    • locator {String}: id or legend of the fieldset

within_frame

Executes the given block within the given iframe.

  • Arguments:
    • frame {String}: frame, id, name, or index of the frame

within_table

Executes the given block within the a specific table.

  • Arguments:
    • locator {String}: id or caption of the table

within_window

Switches to the given window, executes the given block within that window, and then switches back to the original window.

  • Arguments:

    • window {Capybara::Window | Proc }: window to switch to

    When passing a proc, it will be invoked once per existing window, choosing the first window where the proc returns true.

  • Examples:

    checkout = window_opened_by { click_button('Checkout') }
    within_window(checkout) { click_on('Confirm Purchase') }
    
    within_window(->{ page.title == 'New User' }) do
      click_button 'Submit'
    end
    

Server

server_url

  • Returns: String url of the current server, including protocol and port

status_code

  • Returns: Integer for the current HTTP status code

response_headers

  • Returns: Hash<String, String> of response headers

Session

current_host

  • Returns: String host of the current page

current_path

  • Returns: String path of the current page, without any domain information

current_url

  • Returns: String fully qualified URL of the current page.

Synchronization

Check the guide for a quick tour.

synchronize

This method is Capybara's primary way to deal with asynchronicity.

Learn more about it in the documentation.

You should rarely need to use this directly, check synchronize_expectation instead.

  • Options:

    • :errors {Array}: exception classes that should be retried
    • :wait {Numeric}: amount of seconds to retry the block before it succeeds or times out
  • Example:

    def have_created_user(name)
      synchronize(wait: 3, errors: [ActiveRecord::RecordNotFound]) {
        User.find_by(name: name)
      }
    end
    

synchronize_expectation

Allows to automatically retry expectations until they succeed or the time out ellapses.

It will automatically reload the current context on each retry.

  • Options:

    • :retry_on_errors {Array}: additional exception classes that should be retried
    • :wait {Numeric}: amount of seconds to retry the block before it succeeds or times out
  • Example:

    def be_visible
      synchronize_expectation(wait: 2) {
        expect(visible?).to_or not_to, eq(true)
      }
    end
    

using_wait_time

Changes the default maximum wait time for all commands that are executed inside the block.

Useful for changing the timeout for commands that do not take a :wait keyword argument.

  • Arguments:

    • seconds {Numeric}: the default maximum wait time for retried commands
  • Example:

    # Hovers even if it takes 10 seconds for the element to become interactable.
    def wait_and_hover
      using_wait_time(10) { hover }
    end
    

Windows

become_closed

Waits for a window to become closed.

  • Example:

    expect(window).to become_closed(wait: 5)
    

current_window

  • Returns: Capybara::Window the current window

  • Example:

    def close_window
      current_window.close
    end
    

open_new_window

Opens a new window, without switching to it.

  • Arguments: kind {Symbol} defaults to :tab

  • Returns: Capybara::Window a new window or tab

  • Examples:

    def visit_in_new_tab(url)
      new_tab = open_new_window(:tab)
      within_window(new_tab) { visit(url) }
    end
    

switch_to_frame

Switches to the specified frame permanently. Prefer to use within_frame when possible.

switch_to_window

Switches to the given window permanently. Prefer to use within_window when possible.

window_opened_by

Captures a window that is opened while executing the given block.

More reliable than using windows.last, as it will wait for the window to be opened.

  • Options: :wait {Numeric}: seconds to wait a new window to be opened

  • Returns: Capybara::Window opened in the block

  • Examples:

    checkout_window = window_opened_by { click_button('Checkout') }
    

windows

All the windows that are currently open. The order depends on the driver, don't rely on it.

  • Returns: Array<Capybara::Window>