Software Quality Assurance & Testing Stack Exchange is a question and answer site for software quality control experts, automation engineers, and software testers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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.

share|improve this question
    
This may help in handling such elements - stackoverflow.com/questions/4846454/… – Tarun Jul 26 '12 at 4:53

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();
share|improve this answer
    
The last answer shown is perfectly correct...go for the above one by Asia Wawrzyczek – Bipin Tiwari Dec 24 '12 at 7:33

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.

share|improve this answer
    
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 '12 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 '12 at 21:33

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)
  1. Moving your actions into JavaScript injection
 self.driver.execute_script("$(\"li:contains('Narendra')\").click()");
  1. 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

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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