Question

I'm trying to find the n-th element that has a special class in a document. The elements are not necessarily children of the same parent. So for example

<ul>
  <li><div class="foo">This</div></li>
  <li><div>Nothing</div>
    <ul>
      <li><div class="foo">This also</div></li>
    </ul>
  </li>
  <li><div class="foo">And this</div><li>
</ul>

I'd like to find the first, second or third element that has the class .foo.

I tried

page.find '.foo'

Which errors in Capybara::Ambiguous: Ambiguous match, found 3 elements matching css ".foo"

I then tried

page.all('.foo')[n]

Which works nice except that it doesn't seem to wait this little time like Capybaras find does, which I need because the HTML is actually generated from ajax data. So how to do this correctly with find?

Was it helpful?

Solution

Okay after a short chat in #RubyOnRails on freenode it became clear to me that this isn't as easy possible as it sounds first. The problem is that Capybara can't know if the .foos that are already inserted into the page are "all" of them. Thats why .all has no (or doesn't need) support for waiting like .find has.

The solution would be to manually wait for an appropriate amount of time and then just use .all.

OTHER TIPS

Nokogiri's CSS queries are effective for finding elements of certain classes. It is explained in the tutorial.

For example you can use the following Ruby one-liner to read from a given file and find the second element of class foo:

ruby -rnokogiri -e 'puts Nokogiri::HTML(readlines.join).css(".foo")[1]' sample.html

which returns

<div class="foo">This also</div>

Replace the number in [1] with the index of the element you want to find and replace sample.html with the html file you want to search in. If you want to pick out certain parts of the elements you can use methods of Nokogiri::XML::Element, e.g. content to get its contents.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top