-1

I am getting an error while running my selenium tests

Exception in thread "main" 
org.openqa.selenium.StaleElementReferenceException: stale element 
reference: element is not attached to the page document
  (Session info: chrome=63.0.3239.84)
  (Driver info: chromedriver=2.34.522932 ( 
4140ab217e1ca1bec0c4b4d1b148f3361eb3a03e),platform=Mac OS X 10.12.6 
x86_64) (WARNING: The server did not provide any stacktrace 
information)
Command duration or timeout: 0 milliseconds
For documentation on this error, please visit: 
 http://seleniumhq.org/exceptions/stale_element_reference.html
01T19:05:14.666Z'.

Here is the code

        List<WebElement> category = 
driver.findElements(By.className("a2s-skill-block"));


for(int i = 0;i<category.size();i++) {

        category.get(i).click();
        Thread.sleep(7000);


        driver.navigate().back();
    //  WebElement skills1 = driver.findElement(By.id("iApps"));
        //skills1.click();
        Thread.sleep(15000);


    }

I went through similar thread posts on this question and tried a lot of solutions mentioned by fellow members but somehow the wait and Expected COnditions don't seem to work.Any other direction of thought is really appreciated.

These are the options I tried

  1. Increased the wait time through Thread.sleep() method
  2. Introduced wait and Expected Conditions

    WebDriverWait wait = new WebDriverWait(driver, 150);

    wait.until(ExpectedConditions. presenceOfAllElementsLocatedBy(By.className("text-heading")));

Ankur
  • 1
  • 2
  • Possible duplicate of [StaleElementReference Exception in PageFactory](https://stackoverflow.com/questions/44838538/staleelementreference-exception-in-pagefactory) – undetected Selenium Jan 01 '18 at 12:13

2 Answers2

1

You should spend some time reading about and understanding what a StaleElementReferenceException is. It is important to understand what causes it and what to do to avoid it.

In this case, you are scraping the page and loading category with elements off of Page 1. You then click some link that takes you to page 2. At that point, all the references in category are stale but an exception isn't thrown yet because you haven't accessed any of the variables yet. You then use .back() to return to Page 1 and attempt to do something with category and get the exception.

To avoid this, you need to rescrape the elements into category on Page 1 after you use .back() from another page. One way is what I've written below. The page is scraped at the bottom of each loop.

List<WebElement> category = driver.findElements(By.className("a2s-skill-block"));
for (int i = 0; i < category.size(); i++)
{
    category.get(i).click();
    // sleeps are a bad practice, use WebDriverWait instead
    driver.navigate().back();
    driver.findElement(By.id("iApps")).click();
    // sleeps are a bad practice, use WebDriverWait instead
    category = driver.findElements(By.className("a2s-skill-block"));
}
JeffC
  • 22,180
  • 5
  • 32
  • 55
  • Thanks a ton for your assistance! this works for me and also I got a great idea on how to tackle these types of problems for future – Ankur Jan 02 '18 at 19:40
  • If this, or any other answer, was useful please upvote it. Once you find the answer to your question, please mark it as accepted so the question isn't left unanswered. – JeffC Jan 02 '18 at 19:47
0

You find out all category on the page before for loop. When you click something inside loop to enter another page, Actually the 'Stale Element Refrence' had been triggered, regrardless of you back to the last page finally.

Below conditions will trigger 'Stale Element Refrence'

Condition 1

Use the found element when you enter the page last time and you leave the page at least one time (even you back again).

You can think as when you enter a page Selenium will assign a reference to the page inside Selenium, Even you entered the same page, but Selenium can't know they are same so it will assign an new reference.

You can only use found element which page reference is same as current page you are on.

Condition 2

Stay on the page(not leave it), but your script triggered the HTML DOM Node of the found elements change/reattach/delete. for example some attribute of the DOM Node changed or the DOM Node removed and added back again desipte all atttibutes not change.

Thus any change/move on the DOM Node of found elements will trigger 'Stale Element Refrence'. You can think Condition 1 is just another way of change/move DOM Node.

To fix you issue, you should read out an attribute of all category which can be used to identify the category later in the loop.

Below code assume each category has unique text:

List<WebElement> category = 
    driver.findElements(By.className("a2s-skill-block"));

List<String> categoryTexts = new ArrayList<String>();

for(WebElement it: category) {
    categoryTexts.add(it.getText());
}

for(int i = 0;i<category.size();i++) {

    driver.findElement(By.xpath("//*[text()='"+categoryTexts.get(i)+"']")).click();
    Thread.sleep(7000);

    driver.navigate().back();
    Thread.sleep(15000);
yong
  • 13,357
  • 1
  • 16
  • 27