Cannot click html element with watir
Asked Answered
I

1

-1

I want to click the "button" below, but cannot click it.

enter image description here

The html is:

<table onclick="filtersJob_intrinsic_extender.addRow();return false;" class="FilterList_addLink">
<tbody>
<tr>
<td class="icon"><img src="/commander/lib/images/icn12px_add.gif" alt="Add Filter"></td>
<td class="text">Add Intrinsic Filter</td>
</tr>
</tbody>
</table>

I am basically doing this with watir and watir-webdriver:

browser.td(:text => 'Add Intrinsic Filter').click

I tried this method on another similar button in another website and it worked. I wonder why it does not work here.

It causes the exception:

Selenium::WebDriver::Error::ElementNotVisibleError in 'your rspec spec code'
Element is not currently visible and so may not be interacted with[remote server] file:///C:/Users/john/AppData/Local/Temp/webdriver-profile20150402-8208-15kr0zm/extensions/[email protected]/components/command_processor.js:7736:in `fxdriver.preconditions.visible'
[remote server] file:///C:/Users/john/AppData/Local/Temp/webdriver-profile20150402-8208-15kr0zm/extensions/[email protected]/components/command_processor.js:10437:in `DelayedCommand.prototype.checkPreconditions_'
[remote server] file:///C:/Users/john/AppData/Local/Temp/webdriver-profile20150402-8208-15kr0zm/extensions/[email protected]/components/command_processor.js:10456:in `DelayedCommand.prototype.executeInternal_/h'
[remote server] file:///C:/Users/john/AppData/Local/Temp/webdriver-profile20150402-8208-15kr0zm/extensions/[email protected]/components/command_processor.js:10461:in `DelayedCommand.prototype.executeInternal_'
[remote server] file:///C:/Users/john/AppData/Local/Temp/webdriver-profile20150402-8208-15kr0zm/extensions/[email protected]/components/command_processor.js:10401:in `DelayedCommand.prototype.execute/<'
C:/ruby/lib/ruby/gems/1.8/gems/selenium-webdriver-2.33.0/lib/selenium/webdriver/remote/response.rb:51:in `assert_ok'
C:/ruby/lib/ruby/gems/1.8/gems/selenium-webdriver-2.33.0/lib/selenium/webdriver/remote/response.rb:15:in `initialize'
C:/ruby/lib/ruby/gems/1.8/gems/selenium-webdriver-2.33.0/lib/selenium/webdriver/remote/http/common.rb:59:in `new'
C:/ruby/lib/ruby/gems/1.8/gems/selenium-webdriver-2.33.0/lib/selenium/webdriver/remote/http/common.rb:59:in `create_response'
C:/ruby/lib/ruby/gems/1.8/gems/selenium-webdriver-2.33.0/lib/selenium/webdriver/remote/http/default.rb:66:in `request'
C:/ruby/lib/ruby/gems/1.8/gems/selenium-webdriver-2.33.0/lib/selenium/webdriver/remote/http/common.rb:40:in `call'
C:/ruby/lib/ruby/gems/1.8/gems/selenium-webdriver-2.33.0/lib/selenium/webdriver/remote/bridge.rb:629:in `raw_execute'
C:/ruby/lib/ruby/gems/1.8/gems/selenium-webdriver-2.33.0/lib/selenium/webdriver/remote/bridge.rb:607:in `execute'
C:/ruby/lib/ruby/gems/1.8/gems/selenium-webdriver-2.33.0/lib/selenium/webdriver/remote/bridge.rb:364:in `clickElement'
C:/ruby/lib/ruby/gems/1.8/gems/selenium-webdriver-2.33.0/lib/selenium/webdriver/common/element.rb:54:in `click'
Intent answered 2/4, 2015 at 22:51 Comment(12)
Do you have the same issue in Chrome? There are a number of reasons why an element can be determined to be not visible by selenium. Usually it is because of the style 'display' is none, but sometimes the driver will determine another element is covering the element you want to click.Finfoot
@Titus - Chrome does not even reach that point. Say there are 10 steps in my code. IE can do 0, firefox does 7, chrome does 2. Best results are with ff.Intent
no solution huh? code.google.com/p/selenium/issues/detail?id=5557Intent
I suspect that if you are getting that different of results with the same code, you are likely hitting some race conditions with dynamic content. Try: browser.td(:text => 'Add Intrinsic Filter').when_present.clickFinfoot
@Titus - thanks. but, it did not work - Watir::Wait::TimeoutError....timed out after 30 seconds, waiting for {:tag_name=>"td", :text=>"Add Intrinsic Filter"} to become present.Intent
Do you have the full html for the page? Something is hiding the element. What does Chrome fail on before reaching this point?Finfoot
@Titus - I can paste the code here, but it would be too much. Can post later if needed. When I tried chrome with browser.td(:text => 'Add Intrinsic Filter').when_present.click , I got the same error Watir::Wait::TimeoutError....timed out after 30 seconds , waiting for {:tag_name=>"td", :text=>"Add Intrinsic Filter"} to become present.Intent
If you watch the browser, do you actually see the "Add Intrinsic Filter" cell? Assuming it is visible, have you validated that the DOM only contains one cell with such text? Watir picks the first matching element it finds. It is possible that there are multiple on the page and the first one, which is not the one you want, is not visible. What is the output if you do a browser.tds(:text => 'Add Intrinsic Filter').length?Cranial
@JustinKo - It says 51. Btw...I tried doing the same thing with selenium IDE. This is what it says when I click the Add intrinsic filter - //tr[@id='filtersJob_intrinsic_container']/td[2]/table[2]/tbody/tr/td[2]. thanks.Intent
I would guess you need a more specific locator. Just to validate that we will find a visible one, what do you get when you do browser.tds(:text => 'Add Intrinsic Filter').map(&:visible?).uniqCranial
@Justin Ko - u = browser.tds(:text => 'Add Intrinsic Filter').map(&:visible?).uniq; puts u Output is false, true. Btw, what does this do - .map(&:visible?).uniqIntent
map(&:visible?) says to collect the result of calling .visible? for each cell in the collection (into an array). .uniq takes the array and just outputs the unique values. Given that the result was [false, true], it means that some of the cells are visible and some are not.Cranial
C
1

Problem

From the comments we see that there are actually 51 td elements that have the text "Add Intrinsic Filter":

browser.tds(:text => 'Add Intrinsic Filter').length
#=> 51

We also see that some of these cells are visible and some are not - ie when calling .visible? for each cell, some returned true while others returned false:

browser.tds(:text => 'Add Intrinsic Filter').map(&:visible?).uniq
#=> [false, true]

When locating a single element, Watir will pick the first element that matches. In this case, we can infer that the first cell with text "Add Intrinsic Filter" is not visible: * The Selenium::WebDriver::Error::ElementNotVisibleError exception does it was not visible. * Based on the ordering of the results of browser.tds(:text => 'Add Intrinsic Filter').map(&:visible?).uniq, the first element was not visible.

Without seeing the page, we can only assume that the first matching cell is not the one you actually want to click.

Solution

You need to determine which of the 51 cells is actually the one you want to click and then use a more specific locator.

Based on the result from Selenium IDE, you could do:

browser.td(:xpath => '//tr[@id="filtersJob_intrinsic_container"]/td[2]/table[2]/tbody/tr/td[2]').click

Specifying the whole path to the element can be brittle to changes, so you might want to try something a little less specific. Perhaps try locating the row that has a specific id and then the cell with the specific text:

browser.tr(:id => 'filtersJob_intrinsic_container').td(:class => 'text', :text => 'Add Intrinsic Filter').click

Note that the :class was added as a locator to try to get the inner td rather than the outer one.

Cranial answered 7/4, 2015 at 18:35 Comment(6)
Thanks a lot justin. I also tried this way, is it good ? collection = browser.tds(:text => 'Add Intrinsic Filter'); collection.each do |td| td_vis = td.visible? if td_vis == true puts "Adding intrinsic filter..." td.click end endIntent
In general, that approach can work but might not have good performance for large pages. However, there is a chance it will not be cross-browser compatible - at least Firefox and Chrome will interpret it differently.Cranial
I have a follow up question to this one. Can you please help me ? #29503869 I just can't find these elements. I wonder if I am lacking something critical in my watir skill set.Intent
Have you read my book on Watir? The book is quite far from being done, but it does cover many of the basics of locating an element.Cranial
thanks for the book!!! Great work. I am reading it now. Btw, is watir being replaced by something else ?Intent
Watir is still pretty active, so I do not expect it to go away soon. There are more competing libraries/tools than there used to be - eg Capybara. But they are just alternatives rather than replacements.Cranial

© 2022 - 2024 — McMap. All rights reserved.