The Capybara API: Querying

Learn about capybara testing, capybara queries, HTML attributes in capybara queries, minitest assertions and capybara screenshots.

Capybara has a few methods designed to query the simulated browser page to check for various selector patterns in the page. This is one case where the syntax differs slightly between Minitest and RSpec.

Capybara testing

Here the method current_url is used, which returns as a complete string the current URL that the simulated user is viewing. That’s useful for testing whether the navigation links take us where they should.

The most common query method in Capybara is written as the matcher have_selector in RSpec, and as assert_selector in Minitest. The two are identical in functionality. By default, Capybara looks for a CSS selector matching the argument to the query method, using the common # shortcut for DOM ID and a dot (.) for DOM class. The assertion passes if the selector is found.

Capybara queries

The Capybara query methods, including have_selector, take options that limit whether a selector with the given HTML tag, DOM class, and/or ID matches. These are the most commonly used:

  • The count option: If we expect the selector to appear more than once, we can specify exactly how many times, as in count: 3. We can also use minimum and maximum as options, and use a range with between: (1 .. 3).

  • The text option: This takes a string or a regular expression and matches if the text of the selector either contains the text or matches the regular expression. (There’s also exact_text, which just takes a string and requires the string to match the text of the selector exactly).

  • The visible option: By default, Capybara only matches visible elements, but we can change that behavior with visible: :hidden, or visible: :all. (The latter finds all elements regardless of visible state).

HTML attributes in Capybara queries

We can augment have_selector in a number of ways. The selector argument to have_selector can be just an element, as in div, or an element plus a class or ID decoration, as in div.hidden. In the latter case, a matching element must have both the HTML tag and the DOM class or ID. As with other DOM selectors, a dot (.) indicates a DOM class and a hash mark (#) indicates a DOM ID. We can also use brackets to indicate arbitrary HTML attributes, as in input[name='email']. The Capybara docs have more details. In particular, see the description of the all method.

Minitest assertions

If we want to specify that a given selector does not exist on the page, in RSpec, we can use either not_to have_selector or to have_no_selector, which are equivalent. In Minitest, though, we must use assert_no_selector.

Our test first uses have_selector to validate that .name and .size elements exist and match any options given. Capybara has some other methods we might use that are less powerful or flexible than have_selector, such as have_text and has_link?.

Our test also uses the within method, which takes a selector argument and a block. Capybara expects the selector passed to within to match a single element on the page. Inside the block argument, any Capybara call is scoped to only find or assert against the contents of that element. So, part of the test looks like this:

Get hands-on with 1200+ tech skills courses.