selenium - PageFactory 中的 StaleElementReference 异常

标签 selenium selenium-webdriver pageobjects page-factory staleelementreferenceexception

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

我是否应该再次查找特定的 WebElement,并知道 DOM 中 WebElement 的属性可能会发生更改?或者还有其他方法来处理这个问题吗?

最佳答案

StaleElementReferenceException

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

<小时/>

常见原因

  • 面临背后的常见原因StaleElementReferenceException 如下:
    • 该元素已被完全删除。
    • 该元素不再附加到 DOM。
    • 该元素所在的网页已刷新。
    • (先前的)元素已被 JavaScriptAjaxCall 删除,并被具有相同 ID 的(新)元素替换。或其他属性。
  • 解决方案:如果(旧)元素已被新的相同元素替换,简单的策略是使用 findElement()findElements再次寻找该元素。
<小时/>

回答您的疑问

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

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

    这行代码将初始化 LoginPageNew.class 范围内定义的所有静态 WebElement无论何时何地从自动化脚本调用它。

  2. 我点击了一个 Web 元素,因此 DOM 中的其他 Web 元素之一发生了变化:这几乎是可能的。

    • 举个例子,一般调用 click()<input>上标记不会触发 HTML DOM 上任何 WebElement 的任何更改。
    • 在哪里调用 click()<button>上标签或 <a>标签可以调用 JavaScriptAjax ,而后者又可以删除元素或可以用具有相同 ID 的(新)元素替换(先前的)元素。或其他属性。
<小时/>

结论

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

<小时/>

解决方案

如果旧元素已被新的相同元素替换,简单的策略是调用 WebDriverWaitExpectedConditions 结合使用寻找元素。

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

<小时/>

引用文献

以下是本次讨论的引用资料:

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

相关文章:

从 iframe 中动态加载的表中抓取时出现 Python Selenium 超时异常

Java - Selenium - 无法找到与 CDP 版本 94 完全匹配的版本,因此返回找到的最接近的版本 : 93

javascript - 如何在 executeScript 方法中显示带有变量的 javascript 代码?

java - 使用页面工厂设计模式在页面对象中第二次调用 web 元素会出现陈旧元素异常

java - Selenium webdriver 页面对象模式和 ExtentReports

java - session 未创建异常 : session not created: This version of ChromeDriver only supports Chrome version 77 using Selenium ChromeDriver

selenium - 我无法使用机器人框架单击单选按钮。(和 selenium2Library)

firefox - Selenium-WebDriver 不适用于代理

javascript - Protractor 页面对象 - TypeError : Object #<Object> has no method 'methodName'

java - 使用 @Test(dependsOnMethods=..) testNG 注解标记测试方法,使它们不执行