Andrey
Andrey

Reputation: 1818

How to use watir-webdriver to find element by class and text

I have the following HTML:

<td class="test1 test3">1</td>
<td class="test1 test2 test3">1</td>
<td class="test1 test2 test3">2</td>
<td class="test4 test3">2</td>
<td class="test1 test3">2</td>
<td class="test1 test3">3</td>
<td class="test1 test2 test3">3</td>

I am trying to find the following <td>:

<td class="test1">2</td>

Here is what I have tried so far:

b.td(:class => /(?!.*\btest2\b)/, :text => "2").click
b.td(:class => /^(?!.*\btest2\b)/, :text => "2").click
b.td(:class => /^(?!test2)/, :text => "2").click
b.td(:class => "test1", :class => /(?!test2)/, :text => "2").click

All of them return the wrong cell.

Edit: The number of elements could be different. The order could be different as well. Pretty much I need to find the element where class is test1 and class is not test2 and text is 2.

Edit2: I added more classes since it is not restricted to one or two classes. Could be more.

Edit3: Order of classes could be different:

<td class="test2 test1 test3">2</td>

Edit4: TD must have test1, must not have test2 and must have text 2

Upvotes: 1

Views: 4176

Answers (4)

boulder_ruby
boulder_ruby

Reputation: 39763

b.td(:class => "test1", :text => "2").click

should do the trick.

I tested this, but for some reason without the containing <table> tag, watir wasn't recognizing the html for the <td> elements. So after adding that, this worked.

Upvotes: 1

titusfortner
titusfortner

Reputation: 4194

I recommend avoiding regex when possible, the implementation of it is very slow. This is more readable and flexible, and probably makes fewer wire calls (i.e. faster):

elements = b.tds(class: 'test1', text: '2')
element = elements.find { |td| !td.attribute_value('class').include?('text2') }
element.click

Upvotes: 1

pjd
pjd

Reputation: 1173

I think this will work for you:

td_array=b.tds.to_a
td_array.each do |td|
  if td.class_name =~ /test1/ && td.class_name !~ /test2/ && td.text == '2'
    b.td(:index, td_array.index(td)).click
  end
end

This will click every td on the page with class containing test1 and not containing test2 and with text equal to 2. As you mentioned in a comment to Dane Andersen's answer, there should never be more than 1 such td to click.

Upvotes: 0

Alexis Andersen
Alexis Andersen

Reputation: 805

After the updates, if you're looking for the cell with test 2 and without class test2, you should use this regex on the class:

b.td(:class => /^((?!test2).)*$/, :text => "2").click

UPDATE:

To require matching test1 but omitting test2, I updated the regex:

b.td(:class => /^((?!test2).)*test1((?!test2).)*$/, :text => "2").click

Upvotes: 1

Related Questions