Selenium Webdriver How to Resolve Stale Element Reference Exception

How to avoid StaleElementReferenceException in Selenium?

This can happen if a DOM operation happening on the page is temporarily causing the element to be inaccessible. To allow for those cases, you can try to access the element several times in a loop before finally throwing an exception.

Try this excellent solution from darrelgrainger.blogspot.com:

public boolean retryingFindClick(By by) {
boolean result = false;
int attempts = 0;
while(attempts < 2) {
try {
driver.findElement(by).click();
result = true;
break;
} catch(StaleElementException e) {
}
attempts++;
}
return result;
}

How to overcome state Element Reference exception

You never find elements and then right away try to click on them. When the page is loading the elements are created, but after a few milliseconds they change their attributes, size and or location. This exception means that you found the element but as of now you "lost" it.

In order to avoid StateElementReferecneException use WebDriverWait object. You can wait for element to be visible / clickable as well as other options. Best option is to wait for the element to be clickable:

  WebDriverWait wait = new WebDriverWait(driver, 20, 10);        
wait.until(ExpectedConditions.elementToBeClickable
(By.id("elementID")));

Why I'm getting StaleElementReferenceException on just retrieved elements by Driver.FindElementsByCssSelector();

As described here and in many other tutorials and questions describing the StaleElementReferenceException by Driver.FindElementsByCssSelector(".simple-grid .sg-row>.sg-cell") command you actually catching the web element matching the passed locator and storing a reference to it in IWebElement FirstCell.

But since the web page is still dynamically changing, not yet finally built, a moment after that the reference you stored becomes stale, old, invalid since the web element was changed.

This is why by involving the FirstCell.Click() inside the try block you are getting the StaleElementReferenceException.

Trying to involve the absolutely same action inside the catch block will throw StaleElementReferenceException again since you still using the already known as invalid (stale) FirstCell reference.

What you can do to make your code work is to get that element reference Again inside the catch block and try click it.

Like this:

IWebElement FirstCell => Driver.FindElementsByCssSelector(".simple-grid .sg-row>.sg-cell").FirstOrDefault();

void Test()
{
try
{
FirstCell.Click();
}
catch (StaleElementReferenceException)
{
FirstCell = Driver.FindElementsByCssSelector(".simple-grid .sg-row>.sg-cell").FirstOrDefault();
FirstCell.Click(); //retry - Now this indeed should find element again and return new instance
}
}

However this will also not surely work since possibly the page is still not fully, finally stable.

To make this work you can do this in a loop, something like this:

void Test()
{
IWebElement FirstCell;
for(int i=0;i<10;i++){
try
{
FirstCell = Driver.FindElementsByCssSelector(".simple-grid .sg-row>.sg-cell").FirstOrDefault();
FirstCell.Click();
}
catch (StaleElementReferenceException)
{
System.Threading.Thread.Sleep(200);
}
}
}

Stale Element Reference Exception in Selenium web driver - Java?

In your code you wait for a refresh - if your DOM is changed, old references are not usable anymore (your driver tells you this). You will have to reacquire reference to LIs in the next every time after you clicked it again

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

Stale element exception means element is there on web page but selenium could not interct that element , there are 2 ways to resolve that
1.Try with page refresh(driver.navigate().refresh();)
2.Just use loop element until click that element

How to fix 'stale element reference exception' while trying to pick date from date-picker?

In your first code, after you clicked on the element, the DOM changed, as in the Date became "14", and since the both the for-loop were still iterating, hence it threw StaleElementReferenceException.

Similarly, in the second code, you did break the "inside for-loop" that was iterating the td elements, but you didn't break the "outside" one, that continued with iterating the tr elements, hence it threw StaleElementReferenceException yet again.

Resolution:- You should've come out of both the for-loops using break after the element was clicked, and hence averting the StaleElementReferenceException, in the process.

Below code shows how you could've broken out of both the for-loops without any exception:

    WebDriver d=new FirefoxDriver();
d.manage().window().maximize(); //Maximizing window
d.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS); //Implicit wait for 20 seconds

Actions a=new Actions(d);
String date="14";
int flag=0;

d.get("http://www.eyecon.ro/bootstrap-datepicker/");
d.findElement(By.cssSelector("div#dp3>span")).click();
List<WebElement> trs=d.findElements(By.cssSelector("div.datepicker-days>table>tbody>tr"));
for(WebElement tr:trs) {
List<WebElement> tds=tr.findElements(By.tagName("td"));
for(WebElement td:tds) {
if(date.equals(td.getText())) {
a.moveToElement(td).click().build().perform();
flag=1; // Set to 1 when the required element was found and clicked.
break; //To come out of the first for-loop
}
}
if(flag==1)
break; //Since the element was found, come out of the second for-loop.
}

NOTE:- I have added the code for maximizing windows and providing implicit wait too, which is actually advised when you are writing selenium scripts.

Selenium: How to avoid StaleElementReferenceException when looping through a set of elements?

Well after tearing my hair out for a day, I finally realized what was happening. It should have been obvious to me. When the "Next" button is clicked, it takes some time for the new page to load. By simply adding a delay, the new DOM is loaded and processing begins on it, not again on the previous one!

            driver.findElement(By.xpath(".//*[@class='PageRight']")).click();
try {
Thread.sleep(4000); //provide some time for the page to load before processing it
} catch (InterruptedException ex) {
Logger.getLogger(RealAuction.class.getName()).log(Level.SEVERE, null, ex);
}

Now it runs to completion with no StaleElementReferenceException.



Related Topics



Leave a reply



Submit