Posted 10 days ago. Visible to the public. Repeats. Linked content.

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:

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

With some CSS:

Copy
.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:

Copy
expect(page).to have_css('.test2', visible: :hidden)

Once an application no longer requires constant development, it needs periodic maintenance for stable and secure operation. makandra offers monthly maintenance contracts that let you focus on your business while we make sure the lights stay on.

Owner of this card:

Avatar
Arne Hartherz
Last edit:
4 days ago
by Arne Hartherz
About this deck:
We are makandra and do test-driven, agile Ruby on Rails software development.
License for source code
Posted by Arne Hartherz to makandra dev
This website uses short-lived cookies to improve usability.
Accept or learn more