0

Can someone help with it ? I have error

"Exception in thread “main” org.openqa.selenium.StaleElementReferenceException: Element not found in the cache"

Why showing this error? I need to hover on each category menu than click on each text in sub-menu.

public class santander {
  private static WebDriver driver = null;     
  public static JavascriptExecutor js = (JavascriptExecutor) driver;
  public static void main(String[] args) throws FileNotFoundException, InterruptedException, IOException {
        // TODO Auto-generated method stub
        driver = new FirefoxDriver();
        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
        driver.get("http://www.santander.co.uk/uk/index");




    driver.manage().window().maximize();
    driver.get("http://www.santander.co.uk/uk/index");

    JavascriptExecutor js = (JavascriptExecutor) driver;

    WebDriverWait wait = new WebDriverWait(driver, 10);  

    String submenutxtlinks = "submenu.txt";

    List<String> submenu = new ArrayList<String>();
    BufferedReader reader = new BufferedReader(new FileReader(submenutxtlinks));
    String line;
      while ((line = reader.readLine()) != null) {
          submenu.add(line);
      }
      reader.close();



      Actions action = new Actions(driver);
     /* 
     WebElement menu = driver.findElement(By.linkText("Current Accounts"));
     action.moveToElement(menu).perform();
     WebElement submenu = driver.findElement(By.linkText("See all current accounts"));
     action.moveToElement(submenu);
     action.click();
     action.perform();
     */   



       // String title = driver.getTitle();

       // wait.until(ExpectedConditions.titleIs(title));
      //  driver.navigate().back();

    //Loop to read all lines one by one from file and print It.
     // while((menu = BR.readLine())!= null && !menu.isEmpty()){



         // driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

        //  Action hovering = action.moveToElement(a).build();
        //  hovering.perform();

          //action.moveToElement(a).perform();
          //action.clickAndHold(a).perform();
      WebElement a = driver.findElement(By.cssSelector("#nav > div.navMain > div.nav_menu > nav > ul > li:nth-child(1) > a"));
      Action hovering = action.moveToElement(a).build();
      //Thread.sleep(2000);

    for (int i=0;i<=submenu.size()-1;i++ ) {

        //String b = submenu.get(i);

       // System.out.println(b); 

        //WebElement b = driver.findElement(By.xpath(submenu.get(i)));
        try{
            //Your code which causes exception




        hovering.perform();


        //action.moveToElement(b).click(b).build().perform();
        Thread.sleep(1000); 

        clickAnElementByLinkText(submenu.get(i));
        //b.click();
        Thread.sleep(1000);
          /*
        wait.until(ExpectedConditions.visibilityOf(b));
        action.moveToElement(b);
        action.click();
        action.perform();
        */
  //  wait.until(ExpectedConditions.titleIs(title));

      driver.navigate().back();

        //driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
        Thread.sleep(2000);
   // driver.get("http://www.santander.co.uk/uk/index");
        //driver.navigate();
        Thread.sleep(2000);
  //  driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
        }
        catch(org.openqa.selenium.StaleElementReferenceException e){
            //Repeat the code in try
            }


}

 // } 

    driver.close();
}



public static void clickAnElementByLinkText(String linkText) {

  WebDriverWait wait = new WebDriverWait(driver, 10);
  wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath(linkText)));
  driver.findElement(By.xpath(linkText)).click();
  }
}
depperm
  • 10,606
  • 4
  • 43
  • 67
Jack
  • 121
  • 3
  • 15

2 Answers2

0

You are trying to access an element which does not exists.

  • The code collects the elements on the page,
  • then the code clicks an element which changes the source
  • then it try to access an object he collected before but it is not longer there (what you see is a new one).

You can enter the finding of the elements process into the loop and loop changing the 'i' element in every iteration (If you must click the element in every iteration).

Avishay
  • 305
  • 1
  • 11
  • You mean something like this - right? `while(!submenu.isEmpty()){ String b = null; for (int i=0;i<=submenu.size()-1;i++ ) { b = submenu.get(i); } hovering.perform(); Thread.sleep(1000);clickAnElementByLinkText(b);Thread.sleep(1000); driver.navigate().back(); }` @Avishay – Jack Jul 20 '15 at 13:59
  • Try changing and moving the lines : IReadOnlyCollection a = driver.findElements(By.cssSelector("#nav > div.navMain > div.nav_menu > nav > ul > li:nth-child(1) > a")).ElementAt(i); and Action hovering = action.moveToElement(a).build(); under the line: for (int i=0;i<=submenu.size()-1;i++ ) { (I don't have an open selenium project so the syntax might need a fix) – Avishay Jul 20 '15 at 15:18
  • IReadOnlyCollection supposed to be just WebElement – Avishay Jul 20 '15 at 15:31
0

Dont mix ImplicitWait ExplicitWait and Thread.Sleep all in the same context.
Learn when and where those should be used.

The hoverElement wont work because the driver navigates to different page and element no longer exists you have find it again inside the forLoop

For the sake of test I've hardcoded the submenulist

This code will do what you've asked for

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

public class ListTest {

static WebDriver driver;

public static void main(String[] args) {
    List<String> submenu = new ArrayList<>(Arrays.asList(new String[]{"See all current accounts", "1|2|3 Current Account", "Everyday Current Account", "Basic Current Account", "Choice Current Account"}));
    driver = new FirefoxDriver();
    driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
    driver.manage().window().maximize();
    driver.get("http://www.santander.co.uk/uk/index");
    for (String sMenu : submenu) {
        WebElement a = driver.findElement(By.cssSelector("#nav > div.navMain > div.nav_menu > nav > ul > li:nth-child(1) > a"));
        new Actions(driver).moveToElement(a).build().perform();
        clickAnElementByLinkText("//li[@role='listitem']/a[normalize-space(text())='" + sMenu + "']");
        driver.navigate().back();
    }
    driver.quit();
}

public static void clickAnElementByLinkText(String linkText) {
    WebDriverWait wait = new WebDriverWait(driver, 10);
    wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath(linkText))).click();
}
}
Community
  • 1
  • 1
Madhan
  • 5,750
  • 4
  • 28
  • 61