Java Selenium -- 如何等待页面完全加载
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/36590274/
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
Selenium -- How to wait until page is completely loaded
提问by stackoverflow
I am trying to automate some test cases using Java and Selenium WebDriver. I have the following scenario:
我正在尝试使用 Java 和 Selenium WebDriver 自动化一些测试用例。我有以下场景:
- There is a page named 'Products'. When I click on 'View Details' link in the 'Product' page, a popup (modal-dialog) containing the details of the item appears.
- When I click on the 'Close' button in the popup the popup closes and the page automatically refreshes (the page is just reloading, the contents remain unchanged).
After closing the popup I need to click on 'Add Item' button in the same page. But when WebDriver trying to find the 'Add Item' button, if the internet speed is too fast, WebDriver can find and click the element.
But if the internet is slow, WebDriver finds the button before the page refresh, but as soon as the WebDriver click on the button, the page refreshes and
StaleElementReferenceException
occurs.- Even if different waits are used, all the wait conditions become true
(since the contents in the page are same before and after reload)
even before the page is reloaded and
StaleElementReferenceException
occurs.
- 有一个名为“产品”的页面。当我单击“产品”页面中的“查看详细信息”链接时,会出现一个包含该项目详细信息的弹出窗口(模态对话框)。
- 当我点击弹出窗口中的“关闭”按钮时,弹出窗口关闭并且页面自动刷新(页面只是重新加载,内容保持不变)。
关闭弹出窗口后,我需要单击同一页面中的“添加项目”按钮。但是当 WebDriver 试图找到“添加项目”按钮时,如果互联网速度太快,WebDriver 可以找到并单击该元素。
但是如果网速慢,WebDriver 会在页面刷新前找到按钮,但是WebDriver 一点击按钮,页面就会刷新并
StaleElementReferenceException
出现。- 即使使用不同的等待,所有等待条件都会在页面重新加载并
StaleElementReferenceException
发生之前变为真(因为页面中的内容在重新加载之前和之后是相同的)。
The test case works fine if Thread.sleep(3000);
is used before clicking on the 'Add Item' button. Is there any other workaround for this problem?
如果Thread.sleep(3000);
在单击“添加项目”按钮之前使用,则测试用例工作正常。这个问题还有其他解决方法吗?
回答by Kim Homann
3 answers, which you can combine:
3个答案,你可以结合:
Set implicit wait immediately after creating the web driver instance:
_ = driver.Manage().Timeouts().ImplicitWait;
This will try to wait until the page is fully loaded on every page navigation or page reload.
After page navigation, call JavaScript
return document.readyState
until"complete"
is returned. The web driver instance can serve as JavaScript executor. Sample code:C#
new WebDriverWait(driver, MyDefaultTimeout).Until( d => ((IJavaScriptExecutor) d).ExecuteScript("return document.readyState").Equals("complete"));
Java
new WebDriverWait(firefoxDriver, pageLoadTimeout).until( webDriver -> ((JavascriptExecutor) webDriver).executeScript("return document.readyState").equals("complete"));
Check if the URL matches the pattern you expect.
创建 Web 驱动程序实例后立即设置隐式等待:
_ = driver.Manage().Timeouts().ImplicitWait;
这将尝试等到页面在每个页面导航或页面重新加载时完全加载。
页面导航后,调用 JavaScript
return document.readyState
直到"complete"
返回。Web 驱动程序实例可以作为 JavaScript 执行器。示例代码:C#
new WebDriverWait(driver, MyDefaultTimeout).Until( d => ((IJavaScriptExecutor) d).ExecuteScript("return document.readyState").Equals("complete"));
爪哇
new WebDriverWait(firefoxDriver, pageLoadTimeout).until( webDriver -> ((JavascriptExecutor) webDriver).executeScript("return document.readyState").equals("complete"));
检查 URL 是否与您期望的模式匹配。
回答by eduliant
yes stale element error is thrown when (taking your scenario) you have defined locator strategy to click on 'Add Item' first and then when you close the pop up the page gets refreshed hence the reference defined for 'Add Item' is lost in the memory so to overcome this you have to redefine the locator strategy for 'Add Item' again
是的,当(考虑您的场景)您已定义定位器策略以首先单击“添加项目”时,会引发陈旧元素错误,然后当您关闭弹出窗口时,页面会刷新,因此为“添加项目”定义的引用在内存,因此要克服这个问题,您必须再次重新定义“添加项目”的定位器策略
understand it with a dummy code
用虚拟代码理解它
// clicking on view details
driver.findElement(By.id("")).click();
// closing the pop up
driver.findElement(By.id("")).click();
// and when you try to click on Add Item
driver.findElement(By.id("")).click();
// you get stale element exception as reference to add item is lost
// so to overcome this you have to re identify the locator strategy for add item
// Please note : this is one of the way to overcome stale element exception
// Step 1 please add a universal wait in your script like below
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS); // just after you have initiated browser
回答by shahzad ali
There are two different ways to use delay in selenium one which is most commonly in use. Please try this:
在 selenium 中使用延迟有两种不同的方法,一种是最常用的。请试试这个:
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
second one which you can use that is simply try catch method by using that method you can get your desire result.if you want example code feel free to contact me defiantly I will provide related code
您可以使用的第二个方法是通过使用该方法简单地尝试 catch 方法,您可以获得您想要的结果。如果您想要示例代码,请随时与我联系,我将提供相关代码
回答by noor
You can do this in many ways before clicking on add items:
在单击添加项目之前,您可以通过多种方式执行此操作:
WebDriverWait wait = new WebDriverWait(driver, 40);
wait.until(ExpectedConditions.elementToBeClickable(By.id("urelementid")));// instead of id u can use cssSelector or xpath of ur element.
or
wait.until(ExpectedConditions.visibilityOfElementLocated("urelement"));
you can also wait like this. If you want to wait until invisible of previous page element:
你也可以这样等。如果要等到上一页元素不可见:
wait.until(ExpectedConditions.invisibilityOfElementLocated("urelement"));
here is the link where u find all the selenium webdriver api that can be used for wait and its documentation.
这是您可以找到所有可用于等待及其文档的 selenium webdriver api 的链接。
回答by Florent B.
It seems that you need to wait for the page to be reloaded before clicking on the "Add" button. In this case you could wait for the "Add Item" element to become stale before clicking on the reloaded element:
似乎您需要等待页面重新加载才能单击“添加”按钮。在这种情况下,您可以在单击重新加载的元素之前等待“添加项目”元素变得陈旧:
WebDriverWait wait = new WebDriverWait(driver, 20);
By addItem = By.xpath("//input[.='Add Item']");
// get the "Add Item" element
WebElement element = wait.until(ExpectedConditions.presenceOfElementLocated(addItem));
//trigger the reaload of the page
driver.findElement(By.id("...")).click();
// wait the element "Add Item" to become stale
wait.until(ExpectedConditions.stalenessOf(element));
// click on "Add Item" once the page is reloaded
wait.until(ExpectedConditions.presenceOfElementLocated(addItem)).click();