Capybara: Finding invisible elements and how to test that an element is not visible

When Capybara locates elements in the DOM, by default it allows only accessing visible elements -- when you are using a driver that supports it (e.g. Selenium, not the default Rack::Test driver).

Consider the following HTML:

<div class="test1">One<div>
<div class="test2">Two</div>

With some CSS:

.test1 { display: block }
.test2 { display: none }

We will be using Capybara's find below, but this applies to any Capybara finder methods.

Default: visible: :visible or visible: true

As described above, by default Capybara finds only visible elements.

  • find('.test1') finds the .test1 element
  • find('.test2') raises a Capybara::ElementNotFound error, as the .test2 element is not rendered.

Using find(...) means the same as find(..., visible: true) or find(..., visible: :visible).

Note that you could change the default behavior by setting the ignore_hidden_elements config option. However, ignoring invisible elements is a useful default.

Ignoring visibility with visible: :all or visible: false

If you want to access the hidden .test2 element, you can do so by supplying an option visible: :all.
Note that this only removes the visibility restriction, meaning:

  • find('.test1', visible: :all) finds the .test1 element
  • find('.test2', visible: :all) finds the .test2 element

Note that Capybara also supports visible: false as a synonym for visible: :all.
Since it is not always clear that visible: false means "both hidden and visible elements", I suggest you prefer :all over false.

Finding invisible elements with visible: :hidden

What if you want to test that .test1 is not visible? Use visible: :hidden

  • find('.test1', visible: :hidden) raises a Capybara::ElementNotFound error, as the .test1 element is not hidden.
  • find('.test2', visible: :hidden) finds the .test2 element

As an example, an RSpec test which tries to confirm an element exists but is currently not visible, would say:

expect(page).to have_css('.test2', visible: :hidden)
Arne Hartherz About 2 years ago