1

我正在title使用以下语法基于属性形成链接集合

in_frame(name: 'example frame') do |frame|
  links(:example_link, {title: 'This is an example title', frame: frame})
end

片段 - 1

然后我尝试单击每个链接(集合中有 2 个)并从弹出的窗口中获取一些信息

self.example_link_elements.each do |one_link|
  one_link.click
  @browser.window(index: 1).use do
    # do something here
    @browser.window.close
  end
end

片段 - 2

这对于第一个链接运行良好,但它在语句Element is no longer valid (Selenium::WebDriver::Error::StaleElementReferenceError)的第二次迭代中引发错误!one_link.click我当时试着这样做

2.times do |i|
  self.example_link_elements[i].click
    @browser.window(index: 1).use do
      # do something here
      @browser.window.close
    end
  end
end

上面提到的片段工作正常!!我不明白为什么第一个片段会抛出该错误!任何人都可以解释第一个片段出现的原因吗?!

更新

为了确保我理解它,我刚刚编写了以下测试页面

<html>
<body>
    <a target="_blank" href="http://www.google.com">click here</a>
    <a target="_blank" href="http://www.google.com">click here</a>  
</body>
</html>

并在其上运行以下 ruby​​ 代码

require 'watir-webdriver'
require 'page-object'

class MyPageObject
  include PageObject

  def initialize(browser, visit)
    @browser = browser
    super browser, visit
  end

  def goto
    @browser.goto "file:///C:/Users/raveej1/Desktop/test.html"
  end
end

browser = Watir::Browser.new :firefox
page = MyPageObject.new browser, true
page.class.send(:links, :search_link, text: "click here")
page.search_link_elements.each_with_index do |p, p_index|
  p.click
  browser.window(index: 1).use do
    page.class.send(:link, :singin_link, text: "Sign in")
    page.singin_link
    browser.window.close
  end
end

有效!!我相信它与片段 1 完全相同。为什么两个页面的行为不同?!

4

1 回答 1

1

Selenium Element#clickone_link.click最终称为)的文档说:

单击此元素。如果这导致加载新页面,则此方法将尝试阻止,直到页面加载。此时,您应该放弃对该元素的所有引用,并且对该元素执行的任何进一步操作都将引发 StaleElementReferenceError,除非您知道该元素和页面仍然存在。如果 click() 导致通过事件加载新页面或通过发送本机事件完成,则该方法将 等待加载,调用者应验证是否已加载新页面。

在您的情况下,打开弹出窗口意味着您对元素的引用将被视为陈旧。

您看到的不同行为是由于您引用元素的方式。

在您的第一个代码段中:

  1. 您将获得对所有匹配元素的引用
  2. 您单击打开弹出窗口的第一个链接,这会使您现有的所有参考资料都过时
  3. 您单击第二个链接,该链接现在已过时

在您的第二个代码段中:

  1. 您将获得对所有匹配元素的引用
  2. 您单击打开弹出窗口的第一个链接,这会使您现有的所有参考资料都过时
  3. 您将获得对所有匹配元素的新引用
  4. 您单击打开弹出窗口的第二个链接,这会使您现有的所有参考资料都过时

如您所见,您的第二个代码片段始终使用对元素的新引用,这就是您没有收到 StaleReferenceError 的原因。

于 2013-11-13T20:06:42.237 回答