How To Handle staleelementreferenceexception Selenium Webdriver

staleelementreferenceexception

There are many different exceptions In selenium webdriver software testing tool. I have described 5 of them on THIS PAGE which we are facing frequently. One more webdriver exception Is stale element reference exception. I think some of you have faced or will face this exception when you run selenium webdriver test for your software web application. Just recently I have faced this exception In my test with exception message as bellow.


Exception : 
org.openqa.selenium.StaleElementReferenceException: Element not found in the cache - perhaps the page has changed since it was looked up
Command duration or timeout: 10.03 seconds

What Is StaleElementReferenceException?
Stale means old or we can say no longer fresh element. Let me describe you In very simple words. Example : You have a search text box on software web page. When you search for some keyword, text box's position get changed on page. So In this case, Look and feel, Identifiers etc. of text box will remain same but what Internally happened Is -> JS library has deleted previous text box and replaced It with new same text box. So now If you will go to use same text box using previously located reference In your software test, You will get StaleElementReferenceException In console.

If you will run bellow given example, It will throw StaleElementReferenceException.
package Testing_Pack;

import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;

public class StaleElement {
 WebDriver driver;
 @BeforeTest
 public void setup() throws Exception {
  driver =new FirefoxDriver();     
  driver.manage().window().maximize();
  driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
  driver.get("http://www.github.com");
 }
 
 @Test
 public void getExe() throws InterruptedException{  
  //Located element and stored It's reference In variable.
  WebElement Search_Box = driver.findElement(By.xpath("//input[@name='q']"));
  //Used element reference variable to locate element and perform search.
  Search_Box.sendKeys("Hello");
  Search_Box.sendKeys(Keys.ENTER);
  Thread.sleep(5000);
  
  //After search operation, Element's position Is changed.
  //Now I am using same reference variable to clear search text box.
  //So here, WebDriver will be not able to locate element using same reference and It will throw StaleElementReferenceException.
  Search_Box.clear();  
 }
}

This Is just example. You can have different situation or scenario. This will happen only some times but you must know how to resolve It.There may be some other reasons too for this exception. Now let us try to resolve or handle this exception.

So Exception Is generating on Search_Box.clear(); line because software web application page has been refreshed and search text box's position Is changed during previous search operation. In some cases, After refreshing the page or javascript action, Position of element will remains same but still you will get this exception.

I have two possible solutions to handle this situation.

Proposed Solution 1 :
Create a function and perform text box clear operation Inside It as shown In bellow example using while loop. Replace @Test method of above example with bellow given.
@Test
 public void getExe() throws InterruptedException {
  // Located element and stored It's reference In variable.
  WebElement Search_Box = driver.findElement(By.xpath("//input[@name='q']"));
  // Used element reference variable to locate element and perform search.
  Search_Box.sendKeys("Hello");
  Search_Box.sendKeys(Keys.ENTER);
  Thread.sleep(5000);

  // After search operation, Element's position Is changed.
  //Call function with element name to perform clear operation.
  handleStaleElement("q");
 }

 // This function will handle stalelement reference exception
 public void handleStaleElement(String elementName) {
  int count = 0;
  //It will try 4 times to find same element using name.
  while (count < 4) {
   try {
    //If exception generated that means It Is not able to find element then catch block will handle It.
    WebElement staledElement = driver.findElement(By.name(elementName));
    //If exception not generated that means element found and element text get cleared.
    staledElement.clear();    
   } catch (StaleElementReferenceException e) {
    e.toString();
    System.out.println("Trying to recover from a stale element :" + e.getMessage());
    count = count + 1;
   }
   count = count + 4;
  }
 }




Proposed Solution 2 :
You can do same thing using for loop Inside @Test method as bellow.
@Test
 public void getExe() throws InterruptedException {
  // Located element and stored It's reference In variable.
  WebElement Search_Box = driver.findElement(By.xpath("//input[@name='q']"));
  // Used element reference variable to locate element and perform search.
  Search_Box.sendKeys("Hello");
  Search_Box.sendKeys(Keys.ENTER);
  Thread.sleep(5000);

  // After search operation, Element's position Is changed.
  //use for loop.
  for(int i=0; i<4;i++)
            try {
             driver.findElement(By.xpath("//input[@name='q']")).clear();
                break;
            } catch(StaleElementReferenceException e) {
              e.toString();
        System.out.println("Trying to recover from a stale element :" + e.getMessage());
          
        }
 }

If anyone of you have faced same problem of staleelementreferenceexception and resolved It In any other way then you can post your solution by commenting bellow so others can use It.

8 comments:

  1. Thanks Aravind G, It really works
    Great explanation in detail

    ReplyDelete
  2. Really thanks for this best explanation. this made my day. while loop trick works for me.

    ReplyDelete
  3. hi
    i am facing same problem here can someplz hep on this

    WebElement popup= driver.findElement(By.xpath("//div[@class='content_row']"));
    List links = popup.findElements(By.xpath("//span[@id]"));
    int cntnames = links.size();
    System.out.println(cntnames);

    for(int i=1; i<cntnames-1; i++){
    String name1 = links.get(i).getText();
    links.get(i).click();
    driver.findElement(By.id("continueBtn")).click();
    String crcy = driver.findElement(By.cssSelector("#priceOrder")).getText();
    System.out.println(name1+"|--|"+crcy);
    driver.findElement(By.cssSelector("#countryFlag")).click();
    }
    }
    since "By.cssSelector("#countryFlag")).click();" after here its throwing the error
    can some one help me on this same -stale-element-reference.html

    ReplyDelete
  4. even after 100 iterations iam facing same issue staleElementReferenceException

    ReplyDelete
  5. Even after 100 iteration this solution is not working for me can some one suggest me a working solution..

    ReplyDelete
  6. StaleObjectReference could be a real nightmare. I got the idea of StableWebElement - a wrapper which could detect Stale reference situation and try to find a new reference to the original element. All method for locating WebElement in my test always return StableWebElement wrapper and the problem with StaleObjectReferenceException disappeared.

    The C# implementation is available on my project's page but I think it could be easily
    translated into java https://github.com/cezarypiatek/Tellurium/blob/master/Src/MvcPages/SeleniumUtils/StableWebElement.cs

    ReplyDelete
  7. I tried with 2nd solution:' for loop' and my problem got solved.
    Thanks.

    ReplyDelete