8

I am using Selenium 2/WebDriver for automation. I have a table and am trying to select a row in it. When the test runs, I can see the row become highlighted as if it is clicked, but then immediately I get the "org.openqa.selenium.StaleElementReferenceException: Element is no longer attached to the DOM" error and the test fails.

The code is the following:

@Test
public void rowSelection() throws Exception
{
    SeleniumHelper helper = new SeleniumHelper();
    action = new SeleniumActionHelper(driver);

    helper.login();

    String testUrl = navigateToUrl("option/listOptions.xhtml");
    driver.get(testUrl);

    WebElement table = findElementById("tableSection:dataTableWrapped_data");
    List<WebElement> allRows = table.findElements(By.tagName("tr"));
    for (WebElement row : allRows)
        {
            List<WebElement> cells = row.findElements(By.tagName("td"));
            for (WebElement cell : cells)
            {
                WebElement listName = cell.findElement(By.xpath("./* [text()='body_build']"));
                listName.click();
            }
        }
}

I have put a Thread.sleep(2000) in front and after the listName.click() action, but neither has helped. Any help would be greatly appreciated.

1

3 Answers 3

7

I think that your page (or part of it) is reloaded after performing listName.click().

After reload there is also a table which seems to be same as that one from before reloading but it is not the same one. You can count rows/columns in the table and use iterators in your loops. You will need to repeat

WebElement table = findElementById("tableSection:dataTableWrapped_data");
List<WebElement> allRows = table.findElements(By.tagName("tr"));

after

listName.click();
1
  • The last answer shown is perfectly correct...go for the above one by Asia Wawrzyczek Dec 24, 2012 at 7:33
2

Two reasons for occurrence of Stale element

  1. An element that is found on a web page referenced as a WebElement in WebDriver then the DOM changes (probably due to JavaScript functions) that WebElement goes stale.

  2. The element has been deleted entirely.

When you try to interact with the staled WebElement[any above case], the StaleElementException is thrown.

Solutions to resolve them:

  1. Storing locators to your elements instead of references

DON'T

driver = webdriver.Firefox();
driver.get("http://www.github.com");
search_input = driver.find_element_by_name('q');

search_input.send_keys('hello world\n'); // Page contents refresh after typing in search results.
time.sleep(5);

search_input.send_keys('hello frank\n'); // StaleElementReferenceException

Do

driver = webdriver.Firefox();
driver.get("http://www.github.com");
search_input = lambda: driver.find_element_by_name('q');
search_input().send_keys('hello world\n'); 
time.sleep(5);

search_input().send_keys('hello frank\n') // no stale element exception
  1. Leverage hooks in the JS libraries used

    # Using Jquery queue to get animation queue length.
    animationQueueIs = """
    return $.queue( $("#%s")[0], "fx").length;
    """ % element_id
    wait_until(lambda: self.driver.execute_script(animationQueueIs)==0)
    
  2. Moving your actions into JavaScript injection

    self.driver.execute_script("$(\"li:contains('Narendra')\").click()");
    
  3. Proactively wait for the element to go stale

    # Wait till the element goes stale, this means the list has updated
    wait_until(lambda: is_element_stale(old_link_reference))
    

This solution, which worked for me, I have mentioned here if you have any additional scenario, which worked for you then comment below or contact me so that we can add into solution list

2
  • In your Do code block, what is this lambda: keyword ? Where does it come from ? What is it used for ?
    – Stephane
    Aug 19, 2019 at 9:06
  • Never use fixed waiting aka time.sleep()use var el = driver.wait(until.elementLocated(<DOM object>)), static timing always follows worst case scenarios
    – MortenB
    Sep 12, 2019 at 11:39
0

Any chance we could see the page you are trying to automate? I can think of one reason, which is that the way the table was developed is that there is javascript that when the element is interacted with rather than modifying the element instead it replaces it with a new element, in which case that element would no longer exist...

If you use something like firebug in firefox or IE developer tools to view the dom, does the element in question change when hovering over it? If the developer is in fact replacing the element instead of modifying it's class, that would be a very odd implementation and I would argue you should file a bug and have them change the way it's implemented.

2
  • Unfortunately I cannot show the page we are working on for various reasons. The class is being modified and is not having the element replaced...that's why I'm sitting here scratching my head, this doesn't make sense to me since I can see the row become selected before the DOM error is given
    – squeemish
    Jul 13, 2012 at 21:10
  • What does the javascript look like that alters the class? Selenium does try to act like a user and fires events such as onmouseover prior to performing a click. If mousing over the element causes it to look "selected" then it's possible that the stale element exception is happening after firing that event but prior to clicking.
    – Sam Woods
    Jul 13, 2012 at 21:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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