【问题标题】:Cannot click html element with watir无法单击带有 watir 的 html 元素
【发布时间】:2015-06-08 01:09:48
【问题描述】:

我想点击下方的“按钮”,但无法点击。

html 是:

<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>

我基本上是用 watir 和 watir-webdriver 来做这个的:

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

我在另一个网站的另一个类似按钮上尝试了这种方法,它成功了。我想知道为什么它在这里不起作用。

导致异常:

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/fxdriver@googlecode.com/components/command_processor.js:7736:in `fxdriver.preconditions.visible'
[remote server] file:///C:/Users/john/AppData/Local/Temp/webdriver-profile20150402-8208-15kr0zm/extensions/fxdriver@googlecode.com/components/command_processor.js:10437:in `DelayedCommand.prototype.checkPreconditions_'
[remote server] file:///C:/Users/john/AppData/Local/Temp/webdriver-profile20150402-8208-15kr0zm/extensions/fxdriver@googlecode.com/components/command_processor.js:10456:in `DelayedCommand.prototype.executeInternal_/h'
[remote server] file:///C:/Users/john/AppData/Local/Temp/webdriver-profile20150402-8208-15kr0zm/extensions/fxdriver@googlecode.com/components/command_processor.js:10461:in `DelayedCommand.prototype.executeInternal_'
[remote server] file:///C:/Users/john/AppData/Local/Temp/webdriver-profile20150402-8208-15kr0zm/extensions/fxdriver@googlecode.com/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'

【问题讨论】:

  • 您在 Chrome 中是否有同样的问题?硒可以确定元素不可见的原因有很多。通常是因为样式 'display' 是 none,但有时驱动程序会确定另一个元素正在覆盖您要单击的元素。
  • @Titus - Chrome 甚至没有达到这一点。假设我的代码中有 10 个步骤。 IE 可以做到 0,firefox 可以做到 7,chrome 可以做到 2。最好的结果是使用 ff。
  • 我猜你需要一个更具体的定位器。只是为了验证我们会找到一个可见的,当你这样做时你会得到什么browser.tds(:text =&gt; 'Add Intrinsic Filter').map(&amp;:visible?).uniq
  • map(&amp;:visible?) 表示为集合中的每个单元格收集调用.visible? 的结果(放入数组中)。 .uniq 获取数组并仅输出唯一值。鉴于结果是[false, true],这意味着有些单元格可见,有些则不可见。

标签: ruby selenium-webdriver watir watir-webdriver


【解决方案1】:

问题

从 cmets 中我们看到实际上有 51 个 td 元素具有文本“Add Intrinsic Filter”:

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

我们还看到,其中一些单元格是可见的,而有些则不可见 - 即,当为每个单元格调用 .visible? 时,一些返回 true,而另一些返回 false:

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

定位单个元素时,Watir 将选择第一个匹配的元素。在这种情况下,我们可以推断出第一个带有文本“Add Intrinsic Filter”的单元格是不可见的: * Selenium::WebDriver::Error::ElementNotVisibleError 异常是否不可见。 * 根据browser.tds(:text =&gt; 'Add Intrinsic Filter').map(&amp;:visible?).uniq的结果排序,第一个元素是不可见的。

没有看到页面,我们只能假设第一个匹配的单元格不是你真正想要点击的那个。

解决方案

您需要确定 51 个单元格中的哪一个实际上是您要单击的单元格,然后使用更具体的定位器。

根据 Selenium IDE 的结果,您可以这样做:

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

指定元素的整个路径可能难以更改,因此您可能想尝试一些不太具体的方法。也许尝试定位具有特定 id 的行,然后是具有特定文本的单元格:

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

请注意,:class 已添加为定位器,以尝试获取内部 td 而不是外部 td。

【讨论】:

  • 非常感谢贾斯汀。我也试过这个方法,好用吗? collection = browser.tds(:text =&gt; 'Add Intrinsic Filter'); collection.each do |td| td_vis = td.visible? if td_vis == true puts "Adding intrinsic filter..." td.click end end
  • 一般来说,这种方法可以工作,但对于大页面可能没有很好的性能。但是,它有可能不兼容跨浏览器——至少 Firefox 和 Chrome 会以不同的方式解释它。
  • 我对此有一个后续问题。你能帮我么 ? stackoverflow.com/questions/29503369/… 我就是找不到这些元素。我想知道我的女仆技能是否缺少一些关键的东西。
  • 你读过 Watir 上的my book 吗?这本书远未完成,但它确实涵盖了定位元素的许多基础知识。
  • Watir 仍然很活跃,所以我预计它不会很快消失。有比过去更多的竞争库/工具 - 例如 Capybara。但它们只是替代品,而不是替代品。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-05-21
  • 2018-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-01
  • 1970-01-01
相关资源
最近更新 更多