Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

selenium stale element when traversing pages using for-each loop

I've been trying to make a little program that will interact with a website (a browser game to be more precise), get some information from different pages and print it to a GUI.

I got the printing working ok, i can login no problem and navigate the site. But when i try to get the data i need (which is done using a for-each loop) selenium keeps throwing an "element appears to be stale" error and terminates the application.

I get the data from the first planet ok but that's where it ends. Here's the code snippet:

public void getResources()
    {
        List<WebElement> planets = driver.findElements(By.className("smallplanet"));
        String name;
        int metal;
        int crystal;
        int deuterium;
        int energy;
        boolean firstPlanet = true;

        for(WebElement planet : planets)
        {       
            if(!firstPlanet)
            {
                WebElement tag = planet.findElement(By.tagName("a"));
                tag.click();
            } else
            {
                firstPlanet = false;
            }

            name = planet.findElement(By.className("planet-name")).getText();
            System.out.println(name);
            metal = Integer.parseInt(driver.findElement(By.id("resources_metal")).getText().replace(".", ""));
            crystal = Integer.parseInt(driver.findElement(By.id("resources_crystal")).getText().replace(".", ""));
            deuterium = Integer.parseInt(driver.findElement(By.id("resources_deuterium")).getText().replace(".", ""));
            energy = Integer.parseInt(driver.findElement(By.id("resources_energy")).getText().replace(".", ""));        

            resources.add(new ResourceLine(name, metal, crystal, deuterium, energy));
        }
    }

and this is the error:

Element appears to be stale. Did you navigate away from the page that contained it?  And is the current window focussed the same as the one holding this element?
For documentation on this error, please visit: http://seleniumhq.org/exceptions/stale_element_reference.html
Build info: version: '2.35.0', revision: 'c916b9d', time: '2013-08-12 15:42:01'
System info: os.name: 'Windows 7', os.arch: 'amd64', os.version: '6.1', java.version: '1.7.0_03'
Driver info: driver.version: HtmlUnitDriver

I figured that it might be because selenium isn't given enough time to load the page? But I thought that selenium halted the EDT while it waits for the page download to complete? I know it does this while i'm logging in because my UI is running on the same thread for now and it does not update until selenium is done loading the page.

In any case i've tried using Thread.sleep() and driver.wait with varying lenghts between 50 and 500 but neither seem to have any effect.

(note: I have enabled javascript for the HtmlUnitDriver)

edit: I've been debugging some more and I can now confirm that it is not because selenium isn't given enough time to load the page. The program does wait for the new page to load but for some strange reason it still throws that exception...

another edit:

i now wrapped each findElement statement in a while loop that keeps executing the same try-catch block as long as an exception is thrown. But it's simply an infinite loop that keeps throwing the same stale element exception.

I might also want to add that the page is indeed "self refreshing". As in, the values i'm trying to retrieve update once every 500ms or so.

like image 435
killernerd Avatar asked Mar 24 '26 05:03

killernerd


1 Answers

You are getting StaleElementReferenceException. This usually occurs when you first successfully locate WebElement and then you

  • reloaded the page or navigated to different page and navigated back or
  • performed some actions with Selenium which resulted in changes in DOM

and still you tried to interact with that element. The latter seems to be the problem in your case. You are performing tag.click() in your code. I don't now what it does but I suppose it causes some data to appear? This results in changes in DOM so you cannot reference the elements you located before click. You will probably need to look up the list of planets every time after calling tag.click(). (this is just my guess as you didn't write in which line the error occured)

WebElement planet;
int size = driver.findElements(By.className("smallplanet")).size();
for(int i=0; i < size; i++)
{           
    if(!firstPlanet)
    {
        planet = driver.findElements(By.className("smallplanet")).get(i);
        WebElement tag = planet.findElement(By.tagName("a"));
        tag.click();
        planet = driver.findElements(By.className("smallplanet")).get(i);

    } else
    {
        firstPlanet = false;
        planet = driver.findElements(By.className("smallplanet")).get(i);
    }
    //rest of the code...
}
like image 132
JacekM Avatar answered Mar 26 '26 18:03

JacekM



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!