0

HTMLCODE

I am getting StaleElementReferenceException: element is not attached to the page document. I went through some of the solutions that are already there in StackOverflow. It did not work and it continues to throw the same error. Here is the code I am using which is throwing the stale reference error

WebElement table2 = driver.findElement(By.cssSelector("body > div:nth-child(74) > div.sp-palette-container"));
List<WebElement> allrows2 = table2.findElements(By.tagName("div"));

    for(WebElement row2: allrows2){
        List<WebElement> cells = row2.findElements(By.tagName("span"));
        for(WebElement cell:cells){
                if (cell.getAttribute("title").equals("rgb(0, 158, 236)")) {
                cell.click(); 

                }          
          }
    } 
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
Bob Jones
  • 171
  • 1
  • 4
  • 22
  • Add relevant `HTML` and what's your purpose. As far as I can see, you can switch the above code to maybe 2-3 lines of code by adjusting a selector. You don't have to iterate over 2 lists. You can create just 1 list with proper selector – Fenio Mar 08 '18 at 12:50
  • Please the HTML code attached. Thanks – Bob Jones Mar 08 '18 at 13:33

3 Answers3

1

Because clicking the found cell lead some HTML changes on the current page , due to this changes selenium will treat the page(after click) is an "new" page (even though not redirect to another page actually).

In the next iteration of the loop, the loop still refer to element belongs to "previous" page, this is the root cause of "StateElementReference" exception.

So you need to find those elements again on the "new" page to change the reference of element comes from "new" page.

WebElement table2 = driver.findElement(By.cssSelector("body > div:nth-child(74) > div.sp-palette-container"));
List<WebElement> allrows2 = table2.findElements(By.tagName("div"));

int rowSize, cellSize = 0;
rowSize = allrows2.sie();

for(int rowIndex=0;rowIndex<rowSize;rowIndex++){
    WebElement row2 = allrows2.get(rowIndex);
    List<WebElement> cells = row2.findElements(By.tagName("span"));
    cellSize = cells.size();

    for(int cellIndex=0;cellIndex<cellSize;cellIndex++){
        WebElement cell = cells.get(cellIndex);

        if (cell.getAttribute("title").equals("rgb(0, 158, 236)")) {
            cell.click();
            // find cells again on "new" page
            cells = row2.findElements(By.tagName("span"));
             // find rows again on "new" page
            allrows2 = table2.findElements(By.tagName("div"));
        }
    }
}
yong
  • 13,357
  • 1
  • 16
  • 27
1

If your usecase is to click() on the elements with title as rgb(0, 158, 236) you can use the following code block :

    String baseURL = driver.getCurrentUrl();
    List<WebElement> total_cells = driver.findElements(By.xpath("//div[@class='sp-palette-container']//div//span"));
    int size = total_cells.size();
    for(int i=0;i<size;i++)
    {
        List<WebElement> cells = driver.findElements(By.xpath("//div[@class='sp-palette-container']//div//span"));
        if (cells.get(i).getAttribute("title").contains("rgb(0, 158, 236)")) 
        {
            cells.get(i).click(); 
            //do your other tasks
            driver.get(baseURL);
        }
    } 
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
1

Use a "break" after clicking on the element found. The exception occurs because, after clicking on your element, the loop continues.

WebElement table2 = driver.findElement(By.cssSelector("body > div:nth-child(74) > div.sp-palette-container"));
List<WebElement> allrows2 = table2.findElements(By.tagName("div"));

    for(WebElement row2: allrows2){
        List<WebElement> cells = row2.findElements(By.tagName("span"));
        for(WebElement cell:cells){
                if (cell.getAttribute("title").equals("rgb(0, 158, 236)")) {
                cell.click(); 
                break;
                }          
          }
    }