I am trying to test the GeeksForGeeks UI. When I click the tutorials dropdown, then select languages and select Java, it links to a new page and the following error occurs org.openqa.selenium.StaleElementReferenceException. How can I solve this issue? I have tried all the possible solutions from stackoverflow.
public class SeleniumTest {
public static WebDriver driver;
@BeforeClass
public static void setupClass() {
System.setProperty("webdriver.chrome.driver", "driver/chromedriver.exe");
}
@Before
public void setup() {
driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
}
@After
public void after() {
driver.close();
}
@Test
public void testGeeksForGeeksR() throws InterruptedException {
driver.get("https://www.geeksforgeeks.org/");
WebElement tutorialsMenu = driver.findElement(By.className("header-main__list-item"));
tutorialsMenu.click();
List<WebElement> tutorialsList = tutorialsMenu.findElements(By.tagName("li"));
for (WebElement li : tutorialsList) {
if (li.getText().equals("Languages")) {
li.click();
List<WebElement> languages = driver.findElements(By.tagName("a"));
for (WebElement a : languages) {
if (a.getText().equals("Java")) {
WebDriverWait wait = new WebDriverWait(driver, 20);
wait.until(ExpectedConditions.elementToBeClickable(a));
a.click();
WebElement title = driver.findElement(By.className("entry-title"));
assertEquals("Java Programming Language", title.getText());
}
}
}
}
Thread.sleep(6000);
}
}
Solution:
@Test
public void testGeeksForGeeksR() throws InterruptedException {
driver.get("https://www.geeksforgeeks.org/");
WebElement tutorialsMenu = driver.findElement(By.className("header-main__list-item"));
tutorialsMenu.click();
List<WebElement> tutorialsList = tutorialsMenu.findElements(By.tagName("li"));
WebElement javaLanguage = null;
for (WebElement li : tutorialsList) {
if (li.getText().equals("Languages")) {
li.click();
List<WebElement> languages = driver.findElements(By.tagName("a"));
for (WebElement a : languages) {
if (a.getText().equals("Java")) {
javaLanguage = a;
break;
}
}
}
}
javaLanguage.click();
driver.switchTo().activeElement();
WebElement title = driver.findElement(By.className("entry-title"));
assertEquals("Java Programming Language", title.getText());
Thread.sleep(3000);
}
CodePudding user response:
After clicking on the a
element with Java
text the Java Programming Language
page is opened.
At this point all the element references collected on the previous page are becoming Stale
.
Generally, each Selenium WebElement
object is actually a reference (pointer) to physical web element object.
So, when you are opening another web page or refreshing the existing page (reloading the web elements there) all the references to the web elements on the previous web page are no more valid.
In the Selenium terminology this situation is called Stale Element.
Getting back to your specific code flow.
Looks like your target here is to open the Java Programming Language
page. If so, all what you are missing here is to exit your loop once that page is opened and finish the test.
In case you wish to continue opening another tutorials from the menu on the main page you will have to go back from the internal page you opened and then get all the elements you wish to use there again.