陈旧元素参考错误

问题描述 投票:4回答:1

使用页面对象gem和Watir webdriver,我们偶尔在页面上遇到Selenium :: WebDriver :: Error :: StaleElementReferenceError,它会加载一些基本内容,发出ajax请求,并重新填充更多信息(对于速度幻觉)在页面上)。

发生这种情况是因为那里会有一个HTML元素,它会很快消失并在用户真正意识到之前再次出现。

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

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

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 }

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

谢谢

page-object-gem
1个回答
3
投票

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

有一种方法可以使用page-object复制上面的代码。我不确定您提供的上述代码是否在您的页面内部,或者是否在其他地方(如步骤定义或其他地方)。这是我使用页面对象gem做的事情:

在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。这与您上面的所有代码具有相同的效果。如果错误发生,那么您将继续另一次。

© www.soinside.com 2019 - 2024. All rights reserved.