How to find an element that doesn't match a specific text with Capybara?

301 Views Asked by At

With Capybara I am used to searching first('div', text: 'asdf'), but is there a way to search for elements that do not have the text?

I tried first('div', text: /^(?!asdf)/) and it still matches on div with 'asdf' text.

I checked to make sure my regex is right though: https://rubular.com/r/CN6MYKJNahiohD

Any ideas?

3

There are 3 best solutions below

3
Emma On BEST ANSWER

Not sure about Capybara, just guessing that you might be trying to design an expression that would exclude asdf with word boundaries in a string, maybe close to:

^(?!.*\basdf\b).*$

The expression is explained on the top right panel of regex101.com, if you wish to explore/simplify/modify it, and in this link, you can watch how it would match against some sample inputs, if you like.

Test

re = /^(?!.*\basdf\b).*$/s
str = 'some content before, then asdf as a word, some after
some content before, then noasdf as a word, some after'

str.scan(re) do |match|
    puts match.to_s
end
1
chasethesunnn On

My current workaround for this:

selected_element = 
   (all('div').select do |d|
      d.has_no_text?('asdf', wait: false)
   end).first

It will return nil if none are found.

4
Thomas Walpole On

Without knowing what the text content is of the actual element being returned it's tough to say what's wrong, but negative regexes get complicated (especially if the element has multiple lines of content) so it's pretty safe to assume the issue is your regex. In cases like this sometimes it's easier to just use a filter block

first('div') do |element|
  !element.text.include?('asdf')
end

Note: Capybara can't optimize this so it may not be as efficient, but for occasional use that's not always important.