使用watir-webdriver将间歇性“元素不再附加到DOM”错误

时间:2012-02-24 15:16:11

标签: firefox webdriver watir-webdriver

我正在使用Watir-webdriver 0.5.3。在大约0.4.x的版本之前,这绝不是麻烦:

 while  $browser.div(:class =>  /^expander$/).exists?   
  $browser.div(:class => /^expander$/).click; sleep 1.5
 end

点击会导致一些javascript被执行,这会更改被点击的div的类,从而扩展了树视图控件。该脚本的目标是继续扩展节点,直到没有剩余未扩展节点。

我经常在 .exists?行上获得“元素不再附加到DOM”,即esp。麻烦,因为我开始广泛使用.exists?的原因是为了避免这样的错误,这些错误会立即使脚本崩溃。

视觉上我确实在.click之后几乎立即观察到了扩展,如果我在那里暂停一下,Firebug会确认只有class ='expandder'的div已被替换为div而不是class = '扩展器hasChildren扩展',只有那个div。

错误似乎来自webdriver。

是否还有其他人遇到过此问题或推荐解决方法?

earlier question中,我需要切换到/^expander$/表单,以便在新的watir-webdriver行为更改后完全匹配该类。

3 个答案:

答案 0 :(得分:1)

试试这个

Watir::Wait.until do
  $browser.div(:class => /^expander$/).click
  not $browser.div(:class => /^expander$/).exists?
end

答案 1 :(得分:1)

这个怎么样?

while  $browser.div(:class =>  /^expander$/).exists?
  count = $browser.divs(:class => 'expander hasChildren expanded').size   
  $browser.div(:class => /^expander$/).click
  $browser.wait_until{$browser.div(:class => 'expander hasChildren expanded', :index => count).exists?}
 end

我使用的另一种方法是,操作导致事情消失,得到一个计数,然后按索引工作,从最后一个项目回到第一个项目,那样你要解决的“下一件事”应该仍然存在。这可能比总是解决你的先前行动刚刚删除'第一个'的'第一个'更可靠。如果扩展的东西打开了新的“扩展器”类,那么你可能不得不在波浪中执行此操作,最后扩展第一层,然后是第二层等,直到你看到它们不再扩展为止。它可能意味着创建一个方法来扩展所有当前可见的扩展器,然后检查它何时完成以查看是否有任何可见的扩展器,如果是,则再次调用该方法。

答案 2 :(得分:0)

Chuck's approach之后,此代码还会首先枚举所有需要点击以进行展开的候选项,然后在单行foreach循环中,从页面底部点击它们:

hitlist = $browser.divs(:class => /^expander$/)  # put all candidates into an array

hitlist.to_a.reverse.each {|r| r.click; sleep 0.1}  # loop in reverse

$browser.wait_until { $browser.divs(:class => /^expander$/).size < 1}  # Wait until they're all AJAXed out of existence

第1行和第1行如果您认为临时$browser.divs(:class => /^expander$/).to_a.reverse.each {|r| r.click; sleep 0.1}集合可能不方便,那么2甚至可以简化为hitlist ...但是永远不要明白。

即使代码看起来很合理,但我在这里主要担心的是使用像/^expander$/这样的正则表达式定位器的严重性能损失显然......不是他们在文档中告诉你的东西!当标准的引用类定位器如:class => "expander"完全匹配时,我不会在0.5.3之前遇到过这种情况。

一次或两次是可以原谅的(在我看来div(:class => /^expander$/)每次<&lt; 100kB html页面每次需要5-50秒)但是我特别担心线路3:如果条件最终得到满足,谁将被{boolean test block}执行多少次以进行轮询?