6

我正在使用 Capybara 2.1 和 Ruby 1.9.3,使用 selenium 驱动程序(带有 Minitest 和测试单元)来测试 Web 应用程序。

我正在努力解决这个StaleElementReferenceException问题。我已经看到很多关于该主题的讨论,但我无法找到解决我面临的问题的方法。

所以基本上,我正在尝试使用以下代码在我的页面上查找所有分页元素:

pagination_elements = page.all('.pagination a')

然后我对这些元素做一些断言,比如:

pagination_elements.first.must_have_content('1')

在这些断言之后,我将通过单击下一页链接继续测试,以确保我未来的第一个分页元素将是上一页。为此,我再次检索分页元素:

new_pagination_elements = page.all('.pagination a')

这里发生了过时错误,因为我正在达到我已经达到的元素。(这里是错误

您可以在此处查看链接状态。

我真的不知道如何使这个常见的测试正常工作。您有什么提示可以更好地访问我的分页元素吗?

4

5 回答 5

3

我有时对 AJAX 密集型页面有一些问题,在我的情况下,这个解决方法可以解决它:

begin
  ...
rescue Selenium::WebDriver::Error::StaleElementReferenceError
  sleep 1
  retry
end
于 2013-08-27T09:37:58.757 回答
1

关于这个错误以及如何修复它的有趣链接:http: //stefan.haflidason.com/testing-with-rails-and-capybara-methods-that-wait-method-that-wont/

于 2015-03-19T08:48:27.743 回答
1

我看到要点中的主要信息是:

Element not found in the cache - 
perhaps the page has changed since it was looked up

我以前也有类似的情况。有两种解决方案:

  1. 如果您已设置,page.reload请在新页面中检查相同内容之前添加Capybara.automatic_reload = falsespec_helper

  2. find新页面中前一页没有的特殊元素。这个效果相当于等待。

另一种方法是使用特定的选择器。例如,而不是

pagination_elements = page.all('.pagination a')

利用

pagination_elements = page.all('#post_123 .pagination a')

在选择器上附加一个唯一的 id 区域,您应该不会遇到这样的问题。

于 2013-08-27T09:19:05.157 回答
1

显然,除了竞态条件之外,这个错误也会由于滥用within块而出现。例如:

within '.edit_form' do
  click '.edit_button'
  # The error will appear here if the 'edit_button' is not a
  # descendant of the 'edit_form'
end
于 2016-04-12T09:04:48.103 回答
0

您是否尝试过直接使用 WebDriver 而不是通过 Capybara?这可能会让您更好地控制何时以及何时不缓存对象。

例如(为java语法道歉,但应该明白)

WebElement searchField = driver.findElement(By.CssSelector("input.foo"));

searchField.click();

searchField.sendKeys("foo foo");

System.out.println(searchField.getText());

//Do something elsewhere on the page which causes html to change (e.g. submit form)

.....
....

//This next line would throw stale object

System.out.println(searchField.getText());

//This line will not throw exception

searchField = driver.findElement(By.CssSelector("input.foo"));

System.out.println(searchField.getText());

再次将“findElement”分配给“searchField”意味着我们重新找到该元素。知道何时以及何时不重新分配是决定如何缓存 web 元素的关键。

我没有使用 Capybara,但我认为它对你隐藏了缓存策略?

于 2013-08-27T12:42:35.493 回答