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 online protection

Rails professionals since 2007

Our laser focus on a single technology has made us a leader in this space. Need help?

  • We build a solid first version of your product
  • We train your development team
  • We rescue your project in trouble
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)