Selenium 中 PageFactory 中的 StaleElementReferenceException

StaleElementReferenceException in PageFactory in Selenium

提问人:PleasePlease 提问时间:10/3/2023 最后编辑:PleasePlease 更新时间:10/4/2023 访问量:55

问:

我正在尝试在更新元素之前或之后与元素进行交互。当我在更新元素后尝试与元素交互时,我得到 StaleElementReferenceException。

注意:-我的简单问题是,我们是否可以处理 StaleElementReferenceException,这是在永久删除 WebElement 的先前引用时发生的。 如果不可能,我会考虑使用 By 定位器而不是使用 @FindBy 的 WebElement

我尝试使用重试机制处理 StaleElementReferenceException,但仍然徒劳无功。我什至尝试重新初始化相应页面中的所有元素,但仍然徒劳无功。我最近用PageFactory创建了我的框架。

有人可以告诉我如何处理这种情况吗?

我听说我们无法在 PageFactory 中处理 StaleElementReferenceException。许多人建议使用 By 定位器,而不是使用 @FindBy 的 WebElement

可重复使用的组件之一:-

    public void click(WebElement element, int timeout) {
    int attempts = 0;
    while (attempts < 10) {
        try {
            waitUntilElementIsClickable(element, timeout);
            moveToElement(element, timeout);
            element.click();
            break;
        } catch (ElementClickInterceptedException e) {
            log.info("Reperforming click operation since 
           ElementClickInterceptedException is occured");
            if (attempts == 9) {
                e.printStackTrace();
                throw new ElementClickInterceptedException(
                        "Retried clicking 10 times, hence 
   throwing this exception");
            }

        } catch (StaleElementReferenceException e) {
            log.info("Reperforming click operation since 
     StaleElementReferenceException is occured");
            if (attempts == 9) {
                e.printStackTrace();
                throw new ElementNotInteractableException(
                        "Retried clicking 10 times, hence 
   throwing this exception");
            }
        }
        attempts++;
    }
}
java selenium-webdriver cucumber testng

评论

0赞 Alexey R. 10/3/2023
你能把你得到的代码展示出来吗? 只是为字段提供包装器。每次访问它时,它都会从头开始执行查找。所以不能有陈旧的元素。PageFactory
0赞 JeffC 10/4/2023
@AlexeyR。 事实并非如此。它第一次查找元素时,它会从头开始查找它。此后每次引用变量时,它都会使用现有的引用,这很容易导致过时的元素。这是 PageFactory 的一个主要且有据可查的问题。Each time you access it it performs lookup from scratch. So there cannot be stale elements.
0赞 Community 10/4/2023
请提供足够的代码,以便其他人可以更好地理解或重现问题。
0赞 Alexey R. 10/4/2023
@JeffC你能提供这个有据可查的问题的任何链接吗?我一直认为默认行为是重新查找,除非您应用注释。@CacheLookup
0赞 PleasePlease 10/4/2023
@AlexeyR。在问题中添加了一个可重用的组件。

答:

0赞 JeffC 10/4/2023 #1

我建议您放弃页面对象模型的 PageFactory,使用页面对象中定义的定位器。然后,在方法中,每次使用定义的定位符获取元素。By

登录页面页面对象的简单示例是......

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

public class LoginPage {
    WebDriver driver;
    private final By usernameLocator = By.id("username");
    private final By passwordLocator = By.id("password");
    private final By submitButtonLocator = By.cssSelector("button[type='submit']");

    public LoginPage(WebDriver driver) {
        this.driver = driver;
    }

    public void login(String username, String password) {
        driver.findElement(usernameLocator).sendKeys(username);
        driver.findElement(passwordLocator).sendKeys(password);
        driver.findElement(submitButtonLocator).click();
    }
}

你会这样称呼它

String username = "username";
String password = "password";
...
LoginPage loginPage = new LoginPage(driver);
loginPage.login(username, password);

评论

0赞 PleasePlease 10/4/2023
是的,由于这个可悲的 StaleElementReferenceException,我也希望切换到 By 定位器
0赞 JeffC 10/5/2023
@PleasePlease 如果这个或任何其他答案有用,请投赞成票。找到问题的答案后,请将其标记为已接受,以免问题未得到解答。