我正在尝试学习PageFactory模型。我了解以下事实:当我们执行initElements时,将定位WebElement。举例来说,我单击一个Web元素,因此DOM中的其他Web元素之一发生了变化。现在,显然我会在这里得到一个StaleElementReferenceException。我该如何解决这个问题?

我是否应该再次知道特定的WebElement知道DOM中WebElement的属性可能发生变化的事实?还是有另一种方法来解决这个问题?

最佳答案

StaleElementReferenceException

StaleElementReferenceException扩展了WebDriverException并指示该元素的先前引用现在已过时,并且该元素引用不再存在于页面的DOM上。



常见原因


面对StaleElementReferenceException的常见原因如下:


该元素已被完全删除。
元素不再附加到DOM。
刷新了元素所在的网页。
(上一个)元素已被JavaScript或AjaxCall删除,并被具有相同ID或其他属性的(新)元素替换。

解决方案:如果将一个(旧)元素替换为新的相同元素,则简单的策略是使用findElement()findElements再次查找该元素。




回答您的疑问


当我们执行initElements时,WebElements位于:当您调用initElements()方法时,该页面的所有WebElements将被初始化。例如,

LoginPageNew login_page = PageFactory.initElements(driver, LoginPageNew.class);


此代码行将随时随地从自动化脚本中调用LoginPageNew.class范围内定义的所有静态WebElement初始化。
我单击一个webelement,因此DOM中的其他webelements之一发生了变化:这几乎是可能的。


例如,通常在click()标记上调用<input>不会触发HTML DOM上任何WebElement的任何更改。
click()标记或<button>标记上调用<a>的地方可能会调用JavaScript或Ajax,而JavaScript或Ajax可能会删除一个元素,或者可以用相同的ID用(新)元素替换(先前)元素。或其他属性。





结论

因此,如果WebDriver抛出StaleElementReferenceException,则意味着即使该元素仍然存在,该引用也会丢失。我们应该丢弃当前的引用,并在将WebElement附加到DOM时再次定位它来替换它。这意味着您必须再次通过initElements()方法重新初始化该类,而该方法又将重新初始化该页面中定义的所有WebElement。





如果将旧元素替换为新的相同元素,则简单的策略是调用与WebDriverWait不连贯的ExpectedConditions以寻找该元素。

您可以在以下位置找到相关的详细讨论:


How to add explicit wait in PageFactory in PageObjectModel?




参考文献

以下是此讨论的参考:


Stale Element Reference Exception
Class StaleElementReferenceException
Selenium: How to tell if RemoteWebDriver.findElements(By) can throw StaleElementReferenceException at all?

关于selenium - PageFactory中的StaleElementReference异常,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54898379/

10-12 00:59