Home > Software design >  Again "Stale element reference: element is not attached to the page document"
Again "Stale element reference: element is not attached to the page document"

Time:04-15

I know that is exception is thrown when DOM tree has changed and solution for this is to find element again after refresh but...

I'm doing following operations:

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

At the beginning of execution this code completeButton is disabled and looks like this:

<button _ngcontent-mfo-c209="" style="margin-right: 10px;" disabled="">Complete</button>

Lock and approve operations are done by rest API services. After approve complete button becomes enabled so I'm looking for it after this refresh and then try to click it.

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();
}

but I receive

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

when I click completeButton

I also tried with such wait wait.until(not(ExpectedConditions.attributeContains(completeButtonByXpath, "disabled", ""))); but it didn't help.

Any solutions ?

CodePudding user response:

When you are doing

driver.findElement(completeButtonByXpath);

then at this time selenium is looking for *//button[text()='Complete'] xPath.

And probably at this time, it is not attached to HTML-DOM causing staleness.

Solution:

  1. A very simple solution is to put hardcoded sleep like this:

    Thread.sleep(5000);
    

and now look for WebElement completeButton = driver.findElement(completeButtonByXpath);

  1. Modify completeSession to Just have explicit waits.

    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. Retry clicking.

Code:

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  ;
    }
}
  • Related