2013-04-10 83 views
4

使用页面对象宝石和webdriver的的Watir,我们偶尔碰到硒:: webdriver的::错误:: StaleElementReferenceError加载一些基本的东西,一个Ajax请求的页面上,并与更多的重新填充信息(对于页面速度的错觉)。陈旧元素参考错误

这是因为将有一个HTML元素存在,它迅速消失,之前用户是真正意识到它再次重现。

我们使用页面对象的“.when_present”方法要等到对象在页面上的访问之前的第一次。然而,即使在代码找到元素后,通常它会得到陈旧的元素错误,因为原始的HTML元素消失了,而另一个元素在尝试访问它时再次出现。

我们发现了一种使用Watir(而不是页面对象)的方法。我们基本上捕获了Watir :: Wait.until块中的StaleElementReferenceError。如果它得到一个异常,块返回false,并且Wait.until再次尝试,直到它变为true或最终超时。我们发现,这通常是第一次(下面的第3行)得到陈旧元素,从救援中返回false,Wait.until再次执行该块,第2次它是真的,测试继续并通过。

1 Watir::Wait.until { 
2 begin 
3  tds = page.my_element.when_present.element.tds 
4  table_data_classes = tds.map{|cell| cell.attribute_value("class") } 
5 
6  # Should have at least one with a class of "xyz" 
7  xyz = table_data_classes.select{|data| data.include?("xyz")} 
8  xyz.size > 0 
9 rescue Selenium::WebDriver::Error::StaleElementReferenceError 
10  false 
11 end 
12 } 

我真的只是想知道如果有对这种事情任何页面对象包装的。我找不到任何东西。如果没有,那没关系,因为上述工作。只是好奇。

谢谢

回答

2

盖尔,很好的问题。此时,如果StaleElementReferenceError发生在页面对象gem中,则没有特定的重试处理。我从另一个人那里听说他们定期得到这个错误,这是我可以研究的东西。你使用的是什么版本的watir-webdriver?

有一种方法可以使用页面对象复制上面的代码。我不确定您提供的上述代码是否位于您的页面内,或者是否位于其他位置(如步骤定义或其他位置)。这里是我会做什么用的页面对象宝石:

内,您的PageObject类

def has_element_with_class(clz) 
    wait_until 
    begin 
     cells = my_element.when_present.cell_elements 
     cells.any? { |cell| cell.attribute('class').include? clz } 
    rescue Selenium::WebDriver::Error::StaleElementReferenceError 
     false 
    end 
end 

我只是让所有嵌套在my_element到一个数组细胞(TDS)的。我在该数组上调用any?方法,如果任何块返回true,则返回true,否则返回false。这与上面所有的代码具有相同的效果。如果发生错误,那么您将继续另一次。

+0

我们使用的是watir-webdriver 0.6.3。 – Gayle 2013-05-13 15:25:09

+0

上面的代码是在页面的上下文中,所以我们肯定可以使用wait_until而不是Watir :: Wait.until。有点清洁,读得更好。我完全错过了那个存在。谢谢! – Gayle 2013-05-13 15:26:21

相关问题