Read more

Do not use "find" on Capybara nodes from an array

Arne Hartherz
June 26, 2012Software engineer at makandra GmbH

In a nutshell: Capybara's find will not work properly on nodes from a list. Don't find on elements from a list.

Background

Illustration book lover

Growing Rails Applications in Practice

Check out our e-book. Learn to structure large Ruby on Rails codebases with the tools you already know and love.

  • Introduce design conventions for controllers and user-facing models
  • Create a system for growth
  • Build applications to last
Read more Show archive.org snapshot

Consider this HTML:

<div class="message">
  <h2>Hello World</h2>
  Lorem ipsum...
</div>
<div class="message">
  <h2>Hello Universe</h2>
  Lorem ipsum...
</div>

Now let's say you obtain a list of all such message containers as an array:

messages = page.all('.message')

And then you look at their titles like this:

messages[0].find('h2').text
=> "Hello World"
messages[1].find('h2').text
=> "Hello Universe"

So far, so good. Now we want to find titles by their content, as usual:

messages[0].find('h2', :text => 'Hello World').text
=> "Hello World"

Now we search inside the same container as above, which contains "Hello World" as its headline. \
So expecting it to contain some other text should break, right? Wrong:

messages[0].find('h2', :text => 'Hello Universe').text
=> "Hello Universe"

It seems as if Capybara concatenates the selector "route" it took to get the initial elements to search for content, instead of search finding on the actual element as requested -- which is not what anyone would want. This is just plain crazy.

Solution

I could not come up with a solution to this other than "don't do it".

Instead, I'm now using a "full" selector to avoid the broken behavior:

page.find('.message:nth-of-type(1)', :text => 'Hello World').text
=> "Hello World"
page.find('.message:nth-of-type(2)', :text => 'Hello World').text
# Fails as expected (the element can not be found)

Mind that lists start on 1 (not 0) for nth-of-type.

Posted by Arne Hartherz to makandra dev (2012-06-26 21:20)