我正在尝试学习PageFactory模型。我理解这样一个事实:当我们执行 initElements
时,WebElements 就被定位了。举例来说,我单击了一个 Web 元素,因此 DOM 中的其他 Web 元素之一发生了变化。现在,显然我会在这里得到一个 StaleElementReferenceException
。我该如何解决这个问题?
我是否应该再次查找特定的 WebElement,并知道 DOM 中 WebElement 的属性可能会发生更改?或者还有其他方法来处理这个问题吗?
最佳答案
StaleElementReferenceException
StaleElementReferenceException延伸WebDriverException并指示该元素的先前引用现在已过时,并且该元素引用不再存在于页面的 DOM 上。
<小时/>常见原因
- 面临背后的常见原因
StaleElementReferenceException
如下:- 该元素已被完全删除。
- 该元素不再附加到 DOM。
- 该元素所在的网页已刷新。
- (先前的)元素已被 JavaScript 或 AjaxCall 删除,并被具有相同
ID
的(新)元素替换。或其他属性。
- 解决方案:如果(旧)元素已被新的相同元素替换,简单的策略是使用
findElement()
或findElements
再次寻找该元素。
回答您的疑问
当我们执行 initElements 时,WebElement 位于:当您调用
initElements()
时方法,该页面的所有WebElement都将被初始化。例如,LoginPageNew login_page = PageFactory.initElements(driver, LoginPageNew.class);
这行代码将初始化
LoginPageNew.class
范围内定义的所有静态 WebElement无论何时何地从自动化脚本调用它。我点击了一个 Web 元素,因此 DOM 中的其他 Web 元素之一发生了变化:这几乎是可能的。
- 举个例子,一般调用
click()
在<input>
上标记不会触发 HTML DOM 上任何 WebElement 的任何更改。 - 在哪里调用
click()
在<button>
上标签或<a>
标签可以调用 JavaScript 或 Ajax ,而后者又可以删除元素或可以用具有相同ID
的(新)元素替换(先前的)元素。或其他属性。
- 举个例子,一般调用
结论
因此,如果WebDriver抛出StaleElementReferenceException,这意味着即使元素仍然存在,引用也会丢失。我们应该放弃当前的引用,并在它附加到 DOM 时再次定位 WebElement 来替换它。这意味着您必须通过 initElements()
再次重新初始化该类。方法,该方法又重新初始化该页面中定义的所有WebElement。
解决方案
如果旧元素已被新的相同元素替换,简单的策略是调用 WebDriverWait与 ExpectedConditions 结合使用寻找元素。
您可以在以下位置找到相关的详细讨论:
<小时/>引用文献
以下是本次讨论的引用资料:
关于selenium - PageFactory 中的 StaleElementReference 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54898379/