Finders 🧭

Finder methods such as find and all allow you to obtain specific elements in the page. They return a test helper wrapping the element found by Capybara.

You can check the API Reference for more information, or learn about selectors.

users.find('table.users').find(:table_row)
form.find_field('First Name')
table.all(:table_row)

Scoping 🎯

You can use within to restrict certain actions to a specific area of the page.

Any operation inside the block will only target elements that are within the specified selector or element.

class UsersTestHelper < BaseTestHelper
  def add_user(first_name:)
    click_link('Add User')

    within('.new-user-modal') {
      fill_in 'First Name', with: first_name
      click_button 'Save'
    }
  end
end

In the example above, the Add User link could be anywhere on the page, while using within ensures that the First Name field and the Save button are inside the .new-user-modal element.

This is very helpful to make the test more explicit, and prevent interacting with similar fields in a different section of the page, which could cause ambiguity problems and race conditions.

users.add_user(first_name: 'Alice')

Note that a lot of uses of within can be replaced more succinctly with chaining.

Chaining 🔗

All finders wrap the result with a test helper so you can chain methods to work with the returned element, or find other elements within it.

class UsersTestHelper < BaseTestHelper
  def find_user(*name)
    find('table.users').find(:table_row, name)
  end

  def click_to_edit
    click_link('Edit')
  end
end
users.find_user('Bob').click_to_edit
# same as
find('table.users').find(:table_row, ['Bob']).click_link('Edit')

A way to make chaining even more terse is to use aliases shortcuts.