Capybara: Find the innermost DOM element that contains a given string

Updated . Posted . Visible to the public.

Let's say you want to find the element with the text hello in the following DOM tree:

<html>
  <body>
    <article>
      <strong>hello</strong>
      <strong>world</strong>
    </article>
  </body>
</html>

You might think of XPath's contain() function:

page.find(:xpath, ".//*[contains(text(), 'hello')")

Unfortunately that returns a lot more elements than you expect:

[ <html>...<html>,
  <body>...</body>,
  <article>...</article>,
  <strong>hello</strong> ]

What you need to do instead is to find all elements containing "hello" which don't have a descendant containing "hello":

page.find(:xpath, ".//*[contains(text(), 'hello') and not (./*[contains(text(), 'hello')])]")

With jQuery

jQuery has a custom selector :contains() that you can use in the same fashion:

$(":contains('hello'):not(:has(:contains('hello')))")
Henning Koch
Last edit
Henning Koch
License
Source code in this card is licensed under the MIT License.
Posted by Henning Koch to makandra dev (2016-03-02 10:22)