java 元素未附加到页面文档
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32781962/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
element is not attached to the page document
提问by Hyman Jason F
While clicking on javascript components Im getting:
在单击 javascript 组件时,我得到:
org.openqa.selenium.StaleElementReferenceException: stale element reference: element is not attached to the page document
org.openqa.selenium.StaleElementReferenceException:过时的元素引用:元素未附加到页面文档
One way to fix it is to stop script for some short period of time with : Thread.sleep(200);
修复它的一种方法是使用以下命令在短时间内停止脚本:Thread.sleep(200);
I have my implicitlyWait set for 10 seconds, and I think there wasnt such problems with older selenium
我将我的implicitlyWait 设置为10 秒,我认为较旧的硒没有这样的问题
But is there any other way to do it globally ?
但是有没有其他方法可以在全球范围内做到这一点?
driver.findElement(By.cssSelector("button.btn.btn-default")).click();
driver.findElement(By.xpath("//div[@id='content']/div/form")).click();
driver.findElement(By.linkText("Order")).click();
But in the middle of this i have to put sleep's to make it work:
但在这中间我必须把睡眠让它工作:
driver.findElement(By.cssSelector("button.btn.btn-default")).click();
Thread.sleep(200);
driver.findElement(By.xpath("//div[@id='content']/div/form")).click();
Thread.sleep(200);
driver.findElement(By.linkText("Order")).click();
回答by ekostadinov
Your problems are indicator that you need to construct the test cases better and/or lack of understanding of how the website you are automating works. Especially
您的问题表明您需要更好地构建测试用例和/或缺乏对您正在自动化的网站的工作方式的了解。尤其
stop script for some short period of time with : Thread.sleep(200);
使用以下命令在短时间内停止脚本:Thread.sleep(200);
is considered a really bad practice. Whatever you do don't mix implicit and explicit waits, things will start going wrong, explicit waits are the recommended solution.
被认为是一种非常糟糕的做法。不管你做什么,不要混合隐式和显式等待,事情会开始出错,显式等待是推荐的解决方案。
Waiting for the page to be loaded won't work if (as it seems to be your case) the page is being modified by AJAX operations. Instead of waiting for the page to load, wait for the condition you are testing to become true. This way, you give the AJAX operation time to execute and if your there is a problem you will get an error when the time out occurs.
如果(这似乎是您的情况)页面正在被 AJAX 操作修改,则等待页面加载将不起作用。不要等待页面加载,而是等待您正在测试的条件变为真。这样,您就可以给 AJAX 操作执行时间,如果出现问题,您将在超时发生时收到错误消息。
StaleElementReferenceException
is caused by the DOM being refreshed
after you found an element. Remember that a WebElement is a reference
to a specific element on the page, if the DOM get's refreshed this
reference is broken and you need to find the element again to be able to
interact with it.
StaleElementReferenceException
是由于找到元素后刷新 DOM 引起的。请记住,WebElement 是对页面上特定元素的引用,如果 DOM 刷新,则此引用已损坏,您需要再次找到该元素才能与其交互。
回答by Anuj Kumar
In my example replace getWebDriver() with your drive instance.
在我的示例中,将 getWebDriver() 替换为您的驱动器实例。
The best practice is to first assert & verify that, that particular element is present or not. if you see function assertAndVerifyElement() --- it continuously checks for element for 5 secs and then assert it accordingly.
最佳做法是首先断言并验证该特定元素是否存在。如果您看到函数 assertAndVerifyElement() --- 它会连续检查元素 5 秒,然后相应地断言它。
package com.stackoverflow;
import org.openqa.selenium.By;
import org.testng.Assert;
import org.testng.annotations.Test;
import com.services.Init;
public class Issue3 extends Init {
@Test
public void solutionOfIssue() throws InterruptedException {
/*
* The best thing is to first assert & verify that, that particular
* element is present or not. if you see function
* assertAndVerifyElement() --- it continuously checks for element for 5
* secs and then assert it accordingly.
*/
assertAndVerifyElement(By.cssSelector("button.btn.btn-default"));
getWebDriver().findElement(By.cssSelector("button.btn.btn-default")).click();
assertAndVerifyElement(By.xpath("//div[@id='content']/div/form"));
getWebDriver().findElement(By.xpath("//div[@id='content']/div/form")).click();
assertAndVerifyElement(By.linkText("Order"));
getWebDriver().findElement(By.linkText("Order")).click();
}
public void assertAndVerifyElement(By element) throws InterruptedException {
boolean isPresent = false;
for (int i = 0; i < 5; i++) {
try {
if (getWebDriver().findElement(element) != null) {
isPresent = true;
break;
}
} catch (Exception e) {
// System.out.println(e.getLocalizedMessage());
Thread.sleep(1000);
}
}
Assert.assertTrue(isPresent, "\"" + element + "\" is not present.");
}
}
Hope this will work for you. :)
希望这对你有用。:)
回答by Würgspa?
In order to avoid that, you should locate the element again. After you aquired the element, the reference of its Java object might become stale. Do something like:
WebElement element = WebDriver.findElement(By by)
again.
为了避免这种情况,您应该再次定位该元素。获取元素后,其 Java 对象的引用可能会过时。做这样的事情:
WebElement element = WebDriver.findElement(By by)
再次。
EDIT: For your example try this
编辑:对于你的例子试试这个
driver.findElement(By.cssSelector("button.btn.btn-default")).click();
//30s timeout, use timeout not sleep
WebDriverWait wait = new WebDriverWait(driver, 30);
By xpath = By.xpath("//div[@id='content']/div/form")
//wait for element to be clickable, then click
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(xpath));
element.click();
回答by Thanh Le
Error "element is not attached to the page document" display when the element is not exist in current page anymore. It happen because you got element for page 1, and used it in page 1 (or the page was refresh after getting the element, HTML was change by AJAX)
当元素不再存在于当前页面时,会显示错误“元素未附加到页面文档”。发生这种情况是因为您获得了第 1 页的元素,并在第 1 页中使用了它(或者在获得元素后页面刷新,HTML 被 AJAX 更改)