org.openqa.selenium.StaleElementReferenceException: 元素未附加到页面文档
org.openqa.selenium.StaleElementReferenceException: element is not attached to the page document
我正在尝试测试 GeeksForGeeks UI。当我单击教程下拉菜单,然后单击 select 语言和 select Java,它链接到一个新页面并发生以下错误 org.openqa.selenium.StaleElementReferenceException。我该如何解决这个问题?我已经尝试了 Whosebug 中所有可能的解决方案。
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);
}
}
解决方案:
@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);
}
单击带有 Java
文本的 a
元素后,将打开 Java Programming Language
页面。
此时所有上一页收集到的元素引用都变成了Stale
.
通常,每个 Selenium WebElement
对象实际上是对物理 Web 元素对象的引用(指针)。
因此,当您打开另一个网页或刷新现有页面(在那里重新加载网络元素)时,对前一个网页上的网络元素的所有引用都不再有效。
在 Selenium 术语中,这种情况称为 Stale Element.
回到您的特定代码流。
看起来您的目标是打开 Java Programming Language
页面。如果是这样,您在这里所缺少的就是在该页面打开后退出循环并完成测试。
如果您希望继续从主页面的菜单中打开另一个教程,您将必须从您打开的内部页面返回,然后再次获取您希望在那里使用的所有元素。
我正在尝试测试 GeeksForGeeks UI。当我单击教程下拉菜单,然后单击 select 语言和 select Java,它链接到一个新页面并发生以下错误 org.openqa.selenium.StaleElementReferenceException。我该如何解决这个问题?我已经尝试了 Whosebug 中所有可能的解决方案。
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);
}
}
解决方案:
@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);
}
单击带有 Java
文本的 a
元素后,将打开 Java Programming Language
页面。
此时所有上一页收集到的元素引用都变成了Stale
.
通常,每个 Selenium WebElement
对象实际上是对物理 Web 元素对象的引用(指针)。
因此,当您打开另一个网页或刷新现有页面(在那里重新加载网络元素)时,对前一个网页上的网络元素的所有引用都不再有效。
在 Selenium 术语中,这种情况称为 Stale Element.
回到您的特定代码流。
看起来您的目标是打开 Java Programming Language
页面。如果是这样,您在这里所缺少的就是在该页面打开后退出循环并完成测试。
如果您希望继续从主页面的菜单中打开另一个教程,您将必须从您打开的内部页面返回,然后再次获取您希望在那里使用的所有元素。