我正在尝试学习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/