我正在使用带有Ruby 1.9.3的Capybara 2.1使用selenium驱动程序(使用Minitest和测试单元)来测试Web应用程序。
我正在努力解决StaleElementReferenceException
问题。我已经看过很多关于这个主题的讨论,但我无法找到解决我所面临的问题的方法。
基本上,我正在尝试使用以下代码在我的页面上找到所有分页元素:
pagination_elements = page.all('.pagination a')
然后我对这些元素做了一些断言,如:
pagination_elements.first.must_have_content('1')
在这些断言之后,我通过单击Next Page链接继续测试,以确保我未来的第一个分页元素将是Previous Page。 要做到这一点,我再次检索分页元素:
new_pagination_elements = page.all('.pagination a')
Stale Error正在这里发生,因为我已经达到了我已经达到过的元素。 (Here is the error)
您可以看到链接状态here。
我真的不知道如何使这个常见的测试工作正常。 你有什么建议可以更好地达到我的分页元素吗?
答案 0 :(得分:3)
我有时会遇到一些AJAX密集型页面的问题,在我的情况下,这种解决方法可以解决它:
begin
...
rescue Selenium::WebDriver::Error::StaleElementReferenceError
sleep 1
retry
end
答案 1 :(得分:1)
我看到要点中的主要信息是:
Element not found in the cache -
perhaps the page has changed since it was looked up
我之前有类似的情况。有两种解决方案:
如果您在page.reload
Capybara.automatic_reload = false
,则在检查新页面中的相同内容之前添加spec_helper
find
新页面中的特殊元素,上一页没有。这种效果相当于等待。
另一种方法是使用特定的选择器。例如,而不是
pagination_elements = page.all('.pagination a')
使用
pagination_elements = page.all('#post_123 .pagination a')
在选择器中附加一个唯一的ID区域,您不应该遇到这样的问题。
答案 2 :(得分:1)
有关此错误的有趣链接以及如何解决此错误:http://stefan.haflidason.com/testing-with-rails-and-capybara-methods-that-wait-method-that-wont/
答案 3 :(得分:1)
显然,除了竞争条件之外,由于误用word = input("\nPlease enter the word you want to look up > ")
with open("recents.txt", 'r+') as file:
contents = file.readlines()
if len(contents) == 10:
contents = contents[-1:]+contents[:-1]
contents[0] = word + "\n"
file.seek(0,0)
file.truncate()
for i in contents:
file.write(i)
else:
file.write("\n"+word)
块也会出现此错误。例如:
within
答案 4 :(得分:0)
你是否试图直接使用WebDriver而不是通过Capybara?这个woudl可能会让你更好地控制何时以及何时不缓存对象。
e.g。 (对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”意味着我们重新找到该元素。知道何时何时以及何时不重新分配是关键决定如何缓存你的元素。
我没有使用Capybara,但我认为它隐藏了你的缓存策略?