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')))")
Profile picture of Henning Koch
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)