再次 "Stale element reference: element is not attached to the page document"

Again "Stale element reference: element is not attached to the page document"

我知道当 DOM 树发生变化时会抛出异常,对此的解决方案是在刷新后再次查找元素但是...

我正在进行以下操作:

    sessionsView.filterSession(sessionName);
    lockSession();
    approveSession();
    completeSession();

在开始执行时,此代码 completeButton 被禁用,看起来像这样:

<button _ngcontent-mfo-c209="" class="btn btn-default btn-xs pull-right" style="margin-right: 10px;" disabled="">Complete</button>

锁定和批准操作由其余 API 服务完成。批准完成按钮启用后,我在刷新后寻找它,然后尝试单击它。

public void completeSession() {
    By completeButtonByXpath = By.xpath("*//button[text()='Complete']");
    WebElement completeButton = driver.findElement(completeButtonByXpath);
    WebDriverWait wait = new WebDriverWait(driver, 30);
    wait.until(ExpectedConditions.elementToBeClickable(completeButton));
    completeButton.click();
}

但我收到了

org.openqa.selenium.StaleElementReferenceException: stale element reference: element is not attached to the page document

当我点击 completeButton

我也试过这样等待 wait.until(not(ExpectedConditions.attributeContains(completeButtonByXpath, "disabled", ""))); 但没有帮助。

有什么解决办法吗?

当你在做的时候

driver.findElement(completeButtonByXpath);

那么此时selenium正在寻找*//button[text()='Complete'] xPath.

并且可能在这个时候,它没有附加到 HTML-DOM 导致 staleness

解法:

  1. 一个非常简单的解决方案是像这样硬编码睡眠:

    Thread.sleep(5000);
    

现在寻找 WebElement completeButton = driver.findElement(completeButtonByXpath);

  1. completeSession 修改为仅进行显式等待。

    public void completeSession() {
     By completeButtonByXpath = By.xpath("*//button[text()='Complete']");
     //WebElement completeButton = driver.findElement(completeButtonByXpath);
     WebDriverWait wait = new WebDriverWait(driver, 30);
     wait.until(ExpectedConditions.elementToBeClickable(completeButtonByXpath)).click();
    }
    
  2. 重试clicking

代码:

public void completeSession() {
    By completeButtonByXpath = By.xpath("*//button[text()='Complete']");
    WebElement completeButton = driver.findElement(completeButtonByXpath);
    int attempts = 0;
    while(attempts < 5) {
        try {
            completeButton.click();
            break;
        }
        catch(StaleElementReferenceException staleException) {
            staleException.printStackTrace();
        }
        attempts++;
    }
}