PDStat
PDStat

Reputation: 5825

Selenium StaleElementReferenceException explicit wait

In my Selenium test code I have a few lines that

  1. Clicks a check box
  2. Selects an item from a select box
  3. Clicks a buttom to submit a form

Here is the code

WebElement selectAllElement = driver.findElement(By.id("filterForm:selectAll"));
if (selectAllElement.isSelected())
{
    selectAllElement.click();
}

Select selectLocation = new Select(new WebDriverWait(driver, 30)
    .until(ExpectedConditions
    .presenceOfElementLocated(By.id("filterForm:selectLocation"))));

selectLocation.selectByVisibleText(location);

WebElement filterButton = driver.findElement(By.id("filterForm:filterButton"));
filterButton.click();

I was receiving a StaleElementReferenceException when trying to retrieve the Select element on the page, to try and get around this I added an explicit wait on this element as can be seen in the code above.

I am however still getting a StaleElementReferenceException

EDIT (HTML for those elements)

<form id="filterForm" name="filterForm" method="post" action="/UsersJSFMavenApplication/faces/index.xhtml" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="filterForm" value="filterForm" />
<input id="filterForm:selectAll" type="checkbox" name="filterForm:selectAll" checked="checked" title="allUsers" onclick="mojarra.ab(this,event,'valueChange',0,'filterForm:filterGrid usersForm')" />All users<table id="filterForm:filterGrid">
<tbody>
<tr>
<td><input id="filterForm:userName" type="text" name="filterForm:userName" disabled="disabled" /></td>
<td><select id="filterForm:selectLocation" name="filterForm:selectLocation" size="1" disabled="disabled">   <option value="Keynsham">Keynsham</option>
    <option value="London">London</option>
    <option value="Silicon Valley">Silicon Valley</option>
</select></td>
<td><input id="filterForm:filterButton" type="submit" name="filterForm:filterButton" value="Filter" disabled="disabled" /></td>
</tr>
</tbody>
</table>
<input type="hidden" name="javax.faces.ViewState" id="j_id1:javax.faces.ViewState:0" value="-8198231560613594227:-8434387391056535341" autocomplete="off" />
</form>

Upvotes: 2

Views: 2472

Answers (5)

Vishal Jagtap
Vishal Jagtap

Reputation: 896

We usually get the stale element exception when the element is no longer attached to the DOM. So, try to refresh your page if the required element is not found.

 try {
    WebElement expectedStaleElement = driver.findElement(By.xpath(""));
    expectedStaleElement.click(); 
    } catch (StaleElementReferenceException e){
    e.toString();
    System.out.println("Trying to recover from a stale element :" +    e.getMessage());
    driver.navigate().refresh(); //refresh your web page
    WebElement expectedStaleElement= driver.findElement(By.xpath(""));//again re- declare web element
    expectedStaleElement.click(); 
    }

Upvotes: 0

chavanNil
chavanNil

Reputation: 169

driver.manage().timeOuts().implicitWait(timeUnit.SECONDS,10);

Upvotes: -1

PDStat
PDStat

Reputation: 5825

I've managed to fix the issue by changing

Select selectLocation = new Select(new WebDriverWait(driver, 30)
    .until(ExpectedConditions
    .presenceOfElementLocated(By.id("filterForm:selectLocation"))));

To

Select selectLocation = new Select(new WebDriverWait(driver, 30)
    .until(ExpectedConditions
    .elementToBeClickable(By.id("filterForm:selectLocation"))));

Why it made a difference I don't know, perhaps someone could shed some light as a comment.

Upvotes: 2

Saritha G
Saritha G

Reputation: 2608

You can click on the checkbox if that check box is not selected or not enabled.

try like this:

  WebElement checkboxEle = driver.findElement(By.id("filterForm:selectAll"));
  if (!checkboxEle.isEnable())
   {
        checkboxEle.click();
   }

  //To Select option
 WebElement selectElement = driver.findElement(By.xpath("//select[@name='filterForm:selectLocation']"));
 Select selectLocation = new Select(selectElement);

 selectLocation.selectByVisibleText("London");

Upvotes: 0

Cathal
Cathal

Reputation: 1338

I ran into a similar problem a few weeks back. Might be a good idea to read up on what StaleElementException is first.

My problem was an asynchronous call was being made between the time of selecting an element and carrying out some action. My solution was to wrap a try catch in a while loop and attempt to click element a number of times before throwing an Exception. So like this:

     public static void clickElement(By by) throws Exception {
        boolean isClicked = false;
        int attempts = 0;
        while(!isClicked && attempts < 5) {
            try {
                WebElement element = driver().findElement(by);
                element.click();
                isClicked = true;
            } catch(StaleElementReferenceException e) {
                attempts++;
                System.out.println("[DEBUG] StaleElementReference exception caught, trying to locate and click element again");
            }
        }
        if(!isClicked) {
          throw new Exception("Could not click " + by + ", after 5 attempts");
        }
     }

Upvotes: 2

Related Questions