处理StaleElement异常

时间:2017-03-23 14:41:13

标签: ruby selenium-webdriver capybara

我有一个表,通过选择一些过滤器复选框可以刷新数据。可以选择一个或多个复选框,在选择每个复选框后,页面上会显示微调器。只有在前一个选择刷新表后,才能选择后续过滤器。我面临的问题是我一直在间歇地获得StaleElementException。 这就是我在水豚所做的事情 -

  visit('/table-page') # table with default values is displayed

  # select all filters one by one. Wait for spinner to disappear after each selection
  filters.each {|filter| check(filter); has_no_css?('.loading-overlay', wait: 15)}

  # get table data as array of arrays. Added *minimum* so it waits for table
  all('tbody tr', minimum: 1).map { |row| row.all('th,td').map(&:text) }

我很难理解为什么我会看到StaleElementException。在给定节点上使用文本方法时,AFAIK Capybara使用synchronize重新加载节点。有时表数据会返回陈旧数据(即最后一次过滤器更新之前的数据)

1 个答案:

答案 0 :(得分:0)

使用allfirst禁用重新加载返回的任何元素(如果使用find,则元素可重新加载,因为用于定位元素的查询是完全已知的)。这意味着如果在代码的最后一行运行期间页面完全发生更改,则最终会出现StaleElement错误。这可以在你的代码中使用,因为has_no_css?可以在叠加层出现之前运行。一个解决方案是使用has_css?等待时间很短,在检查叠加之前检测叠加是否消失。 has_xxx?方法只返回true / false并且不会引发错误,所以最坏的情况是has_css?完全错过了叠加层的出现/消失,并基本上在指定的等待时间内进入睡眠状态。

visit('/table-page') # table with default values is displayed

# select all filters one by one. Wait for spinner to disappear after each selection
filters.each do |filter| 
  check(filter); 
  has_css?('.loading_overlay', wait: 1)
  assert_no_selector('.loading-overlay', wait: 15)
end

# get table data as array of arrays. Added *minimum* so it waits for table
all('tbody tr', minimum: 1).map { |row| row.all('th,td').map(&:text) }