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.
visible: :visible
or visible: true
As described above, by default Capybara finds only visible elements.
find('.test1')
finds the .test1
elementfind('.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.
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
elementfind('.test2', visible: :all)
finds the .test2
elementNote 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
.
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
elementAs 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)