0

I am using selenium 3.9.1 and java to automate testing of a web application. The web application has some dynamic content based on pressing of a button for example. The page refreshes whenever this button is clicked. A java script runs on button click and updates the DOM I think. At this time, when I try to access the button (which is visible on the page), I get a staleElementReferenceException.

Does Selenium automatically reload the DOM once it is changed? I am relatively new to selenium. I have researched into this and I have tried to refresh the page using driver.navigate().Refresh() to try to see whether this will solve the problem. It does not solve the issue.

Any pointers will be deeply appreciated.

JKumar
  • 1
  • 1

4 Answers4

1

Since the page has been refreshed, the button reference you have is to the button on the old page that no longer exists.

I'd say you need to get a new reference to the button on the refreshed page (eg call FindElementById).

dan gibson
  • 3,605
  • 3
  • 39
  • 57
1

If the page is refreshed all the items in the DOM are now stale. What this means is that all items found before the button press will have to be found again. Any attempts to use those items will more than likely be treated with a stale element exception.

However, if the button click mearilly affects items on the page without having to ask the webserver to give you a new page you could interact with the old items.

Mike Cook
  • 99
  • 5
1

You could do something like this:

public void SaveAndAgainClick() throws Exception{
        try{
            clicksaveButton(); //method to click save button
            WebElement someValue = driver.findElement(By.xpath("(//input[@name='someValue'])[1]"));
            someValue.click();
        }catch (StaleElementException e){
            WebElement someValue = driver.findElement(By.xpath("(//input[@name='someValue'])[1]");
            someValue.click();
        }       
    }

If findElement gets staleElementError while looking for (//input[@name='someValue'])[1] then it will again try one more time in the catch block and most certainly find the element and clicks on it. Your test will pass if you follow this approach.

Chuchoo
  • 823
  • 2
  • 17
  • 36
  • First, I guess that you many to write StaleElementReferenceException in the catch block and not NoAlertPresentException. Second, IMHO what you suggest is a bad practice. StaleElementReferenceException is not just a random error that you need to retry when it happens. You should understand why it happens and write your code accordingly in a robust way. See http://blogs.microsoft.co.il/arnona/2017/03/06/selenium-in-depth-the-demos/ to better understand StaleElementReferenceException. – Arnon Axelrod Mar 22 '18 at 05:11
  • I always thought once we hit staleErrorElement Exception, we immediately know the element we are trying to identify is out of context and we should retry capturing that element. But I guess I was not fully right. Thanks for your input and the blog seems wonderful. I will read it now. Thanks @ArnonAxelrod – Chuchoo Mar 22 '18 at 13:36
0

Here are the answers to your questions :

  • A java script runs on button click and updates the DOM I think : If you inspect the HTML of the element through Development Tools / Inspect Element the element attributes will reveal it all.
  • Consider the following HTML :

    <input value="Click me" onclick="alert('Click!')" type="button">
    
  • In the given HTML as per the onclick attribute of this element, if you invoke click() method on the WebElement, an alert would be generated. Similarly the onclick attribute may invoke a JavaScript or Ajax which may bring-in/phase-out new/old elements from the HTML DOM

  • At this time, when I try to access the button I get a staleElementReferenceException : In this case you should induce WebDriverWait for the WebElement to be interactive before attempting to interact with the element. Else you may face either of the following exceptions :
  • Does Selenium automatically reload the DOM once it is changed? Short answer, Yes it does.
  • Refresh the page using driver.navigate().refresh() : No invoking driver.navigate().refresh() wouldn't be a optimum solution as it may not invoke the intended JavaScript or Ajax properly. Hence the intended WebElement may not be interactive in a optimum way.
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352