How to get only direct child objects in Watir

When you come across methods in watir that return child objects for the first time (eg: the ‘lis‘ in @browser.ul(:id,’main’).lis ) you’d think they’d return only the direct child objects. Frustratingly, they don’t. They’ll also return nested objects of the same type. Here’s some example html:



<ul id='main'>
  <li></li>
  <li> </li>
  <li>
  <ul>
    <li></li>
  </ul>
  </li>
</ul>
  

If you call @browser.ul(:id, 'main').lis.length (to get the number of child li objects), you’d get the answer: 4. Intuitively, you’d expect to get the answer 3. Well, I would, and everyone else I’ve mentioned this to agrees [grumble grumble]. Now the example above is trivial – in the real world, nesting ul‘s in li‘s is common and can get quite complex. It gets even more complex when what you really want is to be able to type the following:


@browser.ul(:id,'main').lis[4].links[7]

…but instead you end up writing convoluted, complex, fragile and unmaintainable code to do what you’d think the above code should do – get the 7th link that is a direct child of the 4th li element that is a direct child of the ul.

But, there is a solution. Perversely, the solution is part of the watir/firewatir code. If you’re prepared to use xpath to identify your objects (my personal preference is to always use xpath), there’s a great method called elements_by_xpath which will do exactly what you want. Again, using the example above, you can get 3 as the answer (number of direct child li’s of the ul) with the following code:


@browser.elements_by_xpath("//ul[@id='main']/li").length

Even better, in doing the following:


my_lis = []
my_lis = @browser.elements_by_xpath("//ul[@id='main']/li")

…the my_lis variable will contain an array of elements; each element being of the right type – Li‘s in this instance. This works with links, table rows, table cells… everything! You can go back to writing clean, maintainable tests!

Note, this works in watir and firewatir. I haven’t checked safariwatir…

One thought on “How to get only direct child objects in Watir

  1. Great article. Do you know where there is documentation on XPATH using FireWatir? Googling brings up waffle but no documentation.

    I need to access some deeply nested values but no-one ever seems to talk about how XPATH really works in a nested way. i.e. people only ever access values at a single depth.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>