测试抛出 StaleElementReferenceException:元素不再附加到 DOM 或页面已刷新
Test throws StaleElementReferenceException: either the element is no longer attached to the DOM or the page has been refreshed
我查看了在线论坛和本网站上的讨论并添加了等待功能。但是,它继续显示此错误
问题代码如下:
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.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import com.google.common.base.Function;
public class WebDriverNavigate {
public static void main(String[] args) throws InterruptedException {
System.setProperty("webdriver.gecko.driver",System.getProperty("user.dir")+"/GeckoDriver/geckodriver.exe");
WebDriver driver = new FirefoxDriver();
driver.navigate().to("http://www.google.com");
WebElement textbox = driver.findElement(By.id("lst-ib"));
textbox.sendKeys("Search on Google");
WebDriverWait wait = new WebDriverWait(driver,10);
wait.until(visibilityOfElementLocated(By.id("lst-ib")));
driver.findElement(By.name("btnK")).click();;
textbox.clear();
textbox.sendKeys("This is the second search");
WebElement searchbutton2 = driver.findElement(By.id("fZl"));
searchbutton2.click();
driver.navigate().back();
driver.navigate().forward();
driver.navigate().refresh();
}
private static Function<WebDriver,WebElement> visibilityOfElementLocated(final By locator) {
return new Function<WebDriver, WebElement>() {
@Override
public WebElement apply(WebDriver driver) {
return driver.findElement(locator);
}
};
}
}
这是 HTML 片段:
<input class="gsfi" id="lst-ib" maxlength="2048" name="q" autocomplete="off" title="Search" value="Search on Google" aria-label="Search" aria-haspopup="false" role="combobox" aria-autocomplete="list" style="border: medium none; padding: 0px; margin: 0px; height: auto; width: 100%; background: transparent url("data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw%3D%3D") repeat scroll 0% 0%; position: absolute; z-index: 6; left: 0px; outline: medium none;" dir="ltr" spellcheck="false" type="text">
控制台上的错误消息:
线程中出现异常 "main" org.openqa.selenium.StaleElementReferenceException:过时的元素引用:元素不再附加到 DOM 或页面已刷新
这个问题我遇到过很多次,有时解决不了。
首先,您应该找到带有 Wait 或 WaitFluent selenium 类 的元素。因为也许您尝试在元素尚未加载之前找到该元素。类似的东西:
new FluentWait<WebDriver>(driver)
.withTimeout(IMPLICIT_TIMEOUT, TimeUnit.SECONDS)
.pollingEvery(RETRY_TIME, TimeUnit.SECONDS)
.ignoring(StaleElementReferenceException.class,
NoSuchElementException.class)
.until(ExpectedConditions
.visibilityOfElementLocated(By.xpath(xpath)));
其他方法是在一个里面有 driver.sleep() 的 for 中尝试多次。
大多数情况下,这是因为 DOM 正在更新并且您试图访问 updated/new 元素。所以this Question&Answers应该覆盖你。
您还可以查看 Selenium Documentation。
在大多数情况下 explicit wait 有效。
或者您可以忽略该错误,直到元素可以点击为止
new WebDriverWait(driver, timeout).ignoring(StaleElementReferenceException.class).until(ExpectedConditions.elementToBeClickable(By.name("btnK")));
driver.findElement(By.name("btnK")).click();
我可以通过按以下顺序重新排列代码来解决问题:
WebElement searchbutton = driver.findElement(By.name("btnK"));
driver.findElement(By.name("btnK")).click();
WebDriverWait wait = new WebDriverWait(driver,10);
WebElement text2 = wait.until(visibilityOfElementLocated(By.id("lst-ib")));
text2.clear();
看起来我试图在 click() 之前等待,但应该在 click() 之后但在 clear() 之前等待元素加载
现在它不会抛出那个错误
感谢大家的建议和解决方案。我相信它们在将来解决更复杂的代码问题时会有用。
我查看了在线论坛和本网站上的讨论并添加了等待功能。但是,它继续显示此错误 问题代码如下:
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.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import com.google.common.base.Function;
public class WebDriverNavigate {
public static void main(String[] args) throws InterruptedException {
System.setProperty("webdriver.gecko.driver",System.getProperty("user.dir")+"/GeckoDriver/geckodriver.exe");
WebDriver driver = new FirefoxDriver();
driver.navigate().to("http://www.google.com");
WebElement textbox = driver.findElement(By.id("lst-ib"));
textbox.sendKeys("Search on Google");
WebDriverWait wait = new WebDriverWait(driver,10);
wait.until(visibilityOfElementLocated(By.id("lst-ib")));
driver.findElement(By.name("btnK")).click();;
textbox.clear();
textbox.sendKeys("This is the second search");
WebElement searchbutton2 = driver.findElement(By.id("fZl"));
searchbutton2.click();
driver.navigate().back();
driver.navigate().forward();
driver.navigate().refresh();
}
private static Function<WebDriver,WebElement> visibilityOfElementLocated(final By locator) {
return new Function<WebDriver, WebElement>() {
@Override
public WebElement apply(WebDriver driver) {
return driver.findElement(locator);
}
};
}
}
这是 HTML 片段:
<input class="gsfi" id="lst-ib" maxlength="2048" name="q" autocomplete="off" title="Search" value="Search on Google" aria-label="Search" aria-haspopup="false" role="combobox" aria-autocomplete="list" style="border: medium none; padding: 0px; margin: 0px; height: auto; width: 100%; background: transparent url("data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw%3D%3D") repeat scroll 0% 0%; position: absolute; z-index: 6; left: 0px; outline: medium none;" dir="ltr" spellcheck="false" type="text">
控制台上的错误消息:
线程中出现异常 "main" org.openqa.selenium.StaleElementReferenceException:过时的元素引用:元素不再附加到 DOM 或页面已刷新
这个问题我遇到过很多次,有时解决不了。
首先,您应该找到带有 Wait 或 WaitFluent selenium 类 的元素。因为也许您尝试在元素尚未加载之前找到该元素。类似的东西:
new FluentWait<WebDriver>(driver)
.withTimeout(IMPLICIT_TIMEOUT, TimeUnit.SECONDS)
.pollingEvery(RETRY_TIME, TimeUnit.SECONDS)
.ignoring(StaleElementReferenceException.class,
NoSuchElementException.class)
.until(ExpectedConditions
.visibilityOfElementLocated(By.xpath(xpath)));
其他方法是在一个里面有 driver.sleep() 的 for 中尝试多次。
大多数情况下,这是因为 DOM 正在更新并且您试图访问 updated/new 元素。所以this Question&Answers应该覆盖你。
您还可以查看 Selenium Documentation。
在大多数情况下 explicit wait 有效。
或者您可以忽略该错误,直到元素可以点击为止
new WebDriverWait(driver, timeout).ignoring(StaleElementReferenceException.class).until(ExpectedConditions.elementToBeClickable(By.name("btnK")));
driver.findElement(By.name("btnK")).click();
我可以通过按以下顺序重新排列代码来解决问题:
WebElement searchbutton = driver.findElement(By.name("btnK"));
driver.findElement(By.name("btnK")).click();
WebDriverWait wait = new WebDriverWait(driver,10);
WebElement text2 = wait.until(visibilityOfElementLocated(By.id("lst-ib")));
text2.clear();
看起来我试图在 click() 之前等待,但应该在 click() 之后但在 clear() 之前等待元素加载 现在它不会抛出那个错误
感谢大家的建议和解决方案。我相信它们在将来解决更复杂的代码问题时会有用。