Ruby on rails 在缓存中找不到StaleElementReference错误元素

Ruby on rails 在缓存中找不到StaleElementReference错误元素,ruby-on-rails,ruby,capybara,Ruby On Rails,Ruby,Capybara,我正在使用Capybara 2.1和Ruby 1.9.3,并使用selenium驱动程序(带有Minitest和测试单元)来测试web应用程序 我正在努力解决StaleElementReferenceException问题。我已经看过很多关于这个话题的讨论,但是我还没有找到解决我所面临问题的方法 因此,基本上,我尝试使用以下代码查找页面上的所有分页元素: pagination_elements = page.all('.pagination a') 然后我对这些元素做了一些断言,比如: pag

我正在使用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')
这里发生了陈旧的错误,因为我正在访问我已经访问过的元素。()

您可以看到链接状态

我真的不知道如何使这个普通测试正常工作。
您有什么更好的方法来访问我的分页元素的提示吗?

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

Element not found in the cache - 
perhaps the page has changed since it was looked up
我以前也有类似的案例。有两种解决方案:

  • 如果在
    spec\u helper

  • 在新页面中查找上一页没有的特殊元素。这种效果相当于等待

  • 另一种方法是使用特定的选择器。例如,代替

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


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

    我有时会遇到AJAX密集型页面的一些问题,在我的情况下,这个解决方法解决了这个问题:

    begin
      ...
    rescue Selenium::WebDriver::Error::StaleElementReferenceError
      sleep 1
      retry
    end
    

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

    e、 g.(对java语法表示歉意,但我应该明白这一点)

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


    我没有使用过Capybara,但我假设它对您隐藏了缓存策略?

    关于此错误以及如何修复此错误的有趣链接:

    显然,除了竞争条件外,此错误也是由于在
    块中误用
    而出现的。例如:

    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
    

    请查看@RajarshiDas,我已经阅读了这个主题和相关主题,但这是一个非常老的问题,来自以前版本的Capybara,它对我的问题没有帮助。我希望避免使用page.reload,因为我的集成测试遵循用户流,而重新加载页面不是其中的一部分。@Evers,这里没有问题。默认设置为
    true
    ,因此每个操作都将重新加载内容,而您只是没有注意到而已。我总是将其设置为false,因为我经常使用Javascript进行交互。如果您在
    spec\u helper
    中没有这样的设置,请忘记这一部分,但是如果您两次检查相同的内容,强制
    重新加载可能会有所帮助。值得一试。谢谢!它现在工作得很好!附加唯一ID是一种更好的方法。启动此特定测试10次只会导致一次测试失败。所以它仍然不是100%准确。我们已经在我们的其他项目中使用了水豚,并且我们不考虑回滚到Webdriver本身。水豚为我们节省了很多时间。但你是对的,水豚有很多缓存策略:)我将要转向Ruby,并试图决定使用哪个库。正是这样的事情让我觉得我将直接使用Webdriver。我喜欢控制太多而不能使用像CapybaraI这样的东西我是Selenium Webdrivers的伟大捍卫者,但我必须承认,Capybara非常适合等待。。。让你专注于你的测试,这就是我的情况!我被锁在
    块中的一个
    中,该块在其内部的陈旧对象上导致了一个人造错误-陈旧的不是我在
    #查找
    ,而是块本身!
    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());
    
    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