0

How can I stop my code throwing a staleElementReferenceException occasionally, 2/5 runs I will encounter this exception running the same test method, the others it will pass as expected

    public boolean checkTextBoxMaxLength(String Textbox, int maxLength) {
    int overMaxLength = maxLength + 1;
        char[] chars = "abcdefghijklmnopqrstuvwxyz".toCharArray();
        StringBuilder sb = new StringBuilder();
        Random random = new Random();
        for (int i = 0; i < overMaxLength; i++) {
            char c = chars[random.nextInt(chars.length)];
            sb.append(c);
        }
    String output = sb.toString();
    System.out.println(output);

    WebElement ele = driver.findElement(By.id(Textbox));
    ele = driver.findElement(By.id(Textbox));

    String maximum = ele.getAttribute("maxlength");
    System.out.println("Element maxlenght is: " +maximum);

    ele.sendKeys(output);
    String input = ele.getAttribute("value");
    System.out.println(input);
    System.out.println(output.substring(0,output.length()-1));

    if (input.equals(output.substring(0,output.length()-1))) {  
    return true;
} else {
    return false;
}
}

the exception occurs around my WebElement ele. Sometimes the exception occurs at:

ele = driver.findElement(By.id(Textbox));

(the reason I am reassigning ele is because if I don't the exception will occur at the line declaring WebElement ele, and sometimes it will occur here:

ele.sendKeys(output);

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

Resetting my element before the exception does not seem to help either.

    ele = driver.findElement(By.id(Textbox));
    String maximum = ele.getAttribute("maxlength");
    System.out.println("Element maxlenght is: " +maximum);

My exception is still thrown here @ line 2

  • stale element happens when the elements get updated (including disappearing from its DOM), can you please try re-find your elements just before this stale element exception pops up? – Yu Zhang Mar 10 '17 at 10:45
  • @YuZhang, please see my edited post, however your solution does not work for me – symon Mar 10 '17 at 10:53
  • Check out the solution in one blog if this help and how to avoid staleElementException – zishan paya Mar 10 '17 at 13:41
  • What are you testing here? If your intent here is to test the implementation of the control then go ahead and use the maxlength attribute. If your intent is to check the web application meets your application requirements then your length should be data driven based on your actual requirements. – Martin Spamer Mar 11 '17 at 8:55
1

I agree with everything George said. I would add that dealing with these kinds of exceptions requires a sound understanding of how the DOM changes in response to every action you take. If any action changes an element you already have a reference to, that reference will likely become stale. Even if you try to use an element on the very same line that you find it.

To deal with this (and any similar situation), I would first run the test steps manually and observe how the DOM changes in response to my actions. I would pay attention to the time it takes for elements to update. Then I would add a few sleep statements after each action to give the DOM changes time to settle before the next statement is executed. Finally, if all is well I would replace the static sleeps with the appropriate explicit waits.

In this case you say that you get stale element exceptions even on the first find statement. This means that the DOM is still changing when this method is called. I'd recommend finding out what actions are causing the changes and then add in appropriate waits after those actions. For now, add a sleep before the find. And you shouldn't need the second find statement because the DOM should not be changing any more.

The next action that might change the DOM is the sendKeys call, so sleep after that. Finally, if there is javascript that changes the element in response to entering text, that might cause the element to become stale so find it again. So the code temporarily looks something like this:

public boolean checkTextBoxMaxLength(String Textbox, int maxLength) throws InterruptedException {
    int overMaxLength = maxLength + 1;
        char[] chars = "abcdefghijklmnopqrstuvwxyz".toCharArray();
        StringBuilder sb = new StringBuilder();
        Random random = new Random();
        for (int i = 0; i < overMaxLength; i++) {
            char c = chars[random.nextInt(chars.length)];
            sb.append(c);
        }
    String output = sb.toString();
    System.out.println(output);

    Thread.sleep(5000); // pause for 5 seconds
    WebElement ele = driver.findElement(By.id(Textbox));

    String maximum = ele.getAttribute("maxlength");
    System.out.println("Element maxlenght is: " +maximum);

    ele.sendKeys(output);
    Thread.sleep(5000);

    ele = driver.findElement(By.id(Textbox)); // Only necessary if you have javascript that changes the element in response to you entering text

    String input = ele.getAttribute("value");
    System.out.println(input);
    System.out.println(output.substring(0,output.length()-1));

    if (input.equals(output.substring(0,output.length()-1))) {  
        return true;
    } else {
        return false;
    }
}

If that works, remove the long static sleeps and replace them with explicit waits. Unfortunately the actions that change the DOM must occur before the checkTextBoxMaxLength method is called, so that's out of scope for this question. If you can isolate a section of code that results includes calls to this method we might be able to identify the root cause.

The selenium documentation here on waits might help get you started.

0

This is really annoying exception (among others), and the more test code there is and the more dynamic the system is the more often you encounter those, making pure usage of selenium methods in your tests extremely flaky.

I guess in Java you need to put selenium methods in your own methods for Click, GetAttribute etc, that will handle all the exceptions that those can throw.

  • it may well be what I'm going to do, I am encountering this exception on multiple pages very inconsistently, the system itself is extremely complicated. – symon Mar 10 '17 at 11:48
  • After some digging, would it be safe to assume that due to my driver not properly having the following applied, these stale exceptions would be more prevalent? driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); – symon Mar 10 '17 at 13:06
  • 1
    Not sure but i think it wont help since element is already found (implicit wait just waits until its found), just when interacting with it theres stale reference (something updated) and you need to find it again before doing something. – George Mar 10 '17 at 14:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.