当前位置: 动力学知识库 > 问答 > 编程问答 >

ruby on rails - StaleElementReference Error Element not found in the cache

问题描述:

I'm using Capybara 2.1 with Ruby 1.9.3 using the selenium driver (with Minitest and Test Unit) in order to test a web app.

I am struggling with the StaleElementReferenceException problem. I have seen quite a number of discussions on the topic but I haven't been able to find a solution to the issue that I am facing.

So basically, I'm trying to find all pagination elements on my page using this code:

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

Then I'm doing some assertions on those elements like:

pagination_elements.first.must_have_content('1')

After those assertions, I'm continuing the test by clicking on the Next Page link to make sure that my future first pagination element will be the Previous Page.

To do that I'm retrieving paginations elements again :

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

And the Stale Error is occurring here, because I'm reaching elements that I've already reached. ( Here is the error )

You can see the link states here.

I really have no idea how to make this common test work properly.

Do you have any tips for a better way to reach my pagination elements?

网友答案:

I sometimes have some problem with AJAX intensive pages, in my case this workaround solves it:

begin
  ...
rescue Selenium::WebDriver::Error::StaleElementReferenceError
  sleep 1
  retry
end
网友答案:

I saw the main message in the gist is:

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

I have similar case before. There are two solutions:

  1. Add page.reload before checking same stuff in new page, if you have set Capybara.automatic_reload = false in spec_helper

  2. find a special element in new page which previous page doesn't have. This effect is equivalent to wait.

Another method is to use specific selector. For example, instead of

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

Use

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

Append a unique id area to the selector and you should not meet such problem.

网友答案:

Interesting link about this error and how to fix it : http://stefan.haflidason.com/testing-with-rails-and-capybara-methods-that-wait-method-that-wont/

网友答案:

HAve you tried to use WebDriver directly rather than via Capybara? This woudl potentially give you more control of when to and when to not cache objects.

e.g. (Apologies for the java syntax but should get the idea)

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());

Assigning "findElement" again to "searchField" means that we re-find the element. Knowing when to and when not re-assign is key went deciding how to cache your webelements.

I have not used Capybara, but I assume that it hides the caching strategy from you?

网友答案:

Apparently, in addition to race conditions, this error also appears due to misused within blocks. For example:

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
分享给朋友:
您可能感兴趣的文章:
随机阅读: