谁能告诉我我怎样才能使硒等到时机页面加载完全? 我想要的东西通用的,我知道我可以配置WebDriverWait并呼吁像“发现”,使其等待,但我不走那么远。 我只需要测试页面加载成功,并移动到下一个页面进行测试。
我发现在.net中的东西,但不能使它在Java工作...
IWait<IWebDriver> wait = new OpenQA.Selenium.Support.UI.WebDriverWait(driver, TimeSpan.FromSeconds(30.00));
wait.Until(driver1 => ((IJavaScriptExecutor)driver).ExecuteScript("return document.readyState").Equals("complete"));
任何想法的人?
Answer 1:
试试这个代码:
driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);
上面的代码将等待10秒钟,页面加载。 如果页面加载超过时间就会抛出TimeoutException
。 你捕获异常,做你的需求。 我不知道它是否退出引发的异常后,页面加载。 我没有尝试这个代码呢。 只想试试吧。
这是一个隐含的等待。 如果设置此一次,以后有范围,直到Web驱动程序实例销毁。
欲了解更多信息。
Answer 2:
你所建议的解决方案只等待DOM readyState
信号complete
。 但硒默认试图等待这些(和多一点点)通过在页面加载driver.get()
和element.click()
方法。 他们已经封锁,他们在等待页面完全加载和那些应该工作正常。
问题很明显,是通过AJAX请求和运行脚本重定向 - 那些无法通过硒被抓住了,它不会等待他们完成。 此外,您不能可靠地通过抓住他们readyState
-它等待了一下,也可能是有用的,但它会发出信号complete
所有的AJAX内容下载之前长。
没有将工作无处不在,每个人都通用的解决方案,这就是为什么它的努力,每个人都使用的东西有点不同。
一般的规则是依靠webdriver的做他的一部分,然后使用隐式等待,然后用明确的等待要断言页面上的元素,但还有很多技术是可以做到的。 你应该挑选最适合你的情况,你的测试页面上的一个(或几个它们的组合)。
见我对此了解更多信息两个答案:
- 如何我可以检查是否页面在网络驱动器完全或没有加载
- 硒的webdriver:等待复杂的页面使用JavaScript加载
Answer 3:
这是你给的例子的工作Java版本:
void waitForLoad(WebDriver driver) {
new WebDriverWait(driver, 30).until((ExpectedCondition<Boolean>) wd ->
((JavascriptExecutor) wd).executeScript("return document.readyState").equals("complete"));
}
例如对于C#:
public static void WaitForLoad(IWebDriver driver, int timeoutSec = 15)
{
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
WebDriverWait wait = new WebDriverWait(driver, new TimeSpan(0, 0, timeoutSec));
wait.Until(wd => js.ExecuteScript("return document.readyState").ToString() == "complete");
}
Answer 4:
这是我在一个完全通用的解决方案的尝试,在Python:
首先,通用的“等待”功能(如果你喜欢使用WebDriverWait,我觉得他们丑陋的):
def wait_for(condition_function):
start_time = time.time()
while time.time() < start_time + 3:
if condition_function():
return True
else:
time.sleep(0.1)
raise Exception('Timeout waiting for {}'.format(condition_function.__name__))
接下来,将溶液依赖于硒记录一次(内部)对页面上的所有元素,包括顶级ID号码的事实<html>
元素。 当一个页面刷新或负载,它就会有一个新的ID一个新的HTML元素。
因此,假设你想点击文本“我的链接”,例如一个链接:
old_page = browser.find_element_by_tag_name('html')
browser.find_element_by_link_text('my link').click()
def page_has_loaded():
new_page = browser.find_element_by_tag_name('html')
return new_page.id != old_page.id
wait_for(page_has_loaded)
对于更Python,可重复使用的,通用的帮手,你可以做一个上下文管理器:
from contextlib import contextmanager
@contextmanager
def wait_for_page_load(browser):
old_page = browser.find_element_by_tag_name('html')
yield
def page_has_loaded():
new_page = browser.find_element_by_tag_name('html')
return new_page.id != old_page.id
wait_for(page_has_loaded)
然后你就可以使用它在几乎任何硒互动:
with wait_for_page_load(browser):
browser.find_element_by_link_text('my link').click()
我认为这是防弹的! 你怎么看?
在更多信息博客文章在这里
Answer 5:
我有一个类似的问题。 我需要等到我的文件已经准备好,而且直到所有的Ajax调用已经完成。 第二个条件被证明是难以察觉。 最后,我检查了积极的Ajax调用和它的工作。
使用Javascript:
return (document.readyState == 'complete' && jQuery.active == 0)
完整的C#方法:
private void WaitUntilDocumentIsReady(TimeSpan timeout)
{
var javaScriptExecutor = WebDriver as IJavaScriptExecutor;
var wait = new WebDriverWait(WebDriver, timeout);
// Check if document is ready
Func<IWebDriver, bool> readyCondition = webDriver => javaScriptExecutor
.ExecuteScript("return (document.readyState == 'complete' && jQuery.active == 0)");
wait.Until(readyCondition);
}
Answer 6:
WebDriverWait wait = new WebDriverWait(dr, 30);
wait.until(ExpectedConditions.jsReturnsValue("return document.readyState==\"complete\";"));
Answer 7:
对于C#NUnit的,你需要的webdriver转换为JSExecuter,然后执行该脚本检查的document.ready状态是否完成。 检查下面的代码,以供参考:
public static void WaitForLoad(IWebDriver driver)
{
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
int timeoutSec = 15;
WebDriverWait wait = new WebDriverWait(driver, new TimeSpan(0, 0, timeoutSec));
wait.Until(wd => js.ExecuteScript("return document.readyState").ToString() == "complete");
}
这将等到条件满足或超时。
Answer 8:
对于初始页面加载我注意到,“最大化”的浏览器窗口几乎等待页面加载完成(包括源代码)
更换:
AppDriver.Navigate().GoToUrl(url);
附:
public void OpenURL(IWebDriver AppDriver, string Url)
{
try
{
AppDriver.Navigate().GoToUrl(Url);
AppDriver.Manage().Window.Maximize();
AppDriver.SwitchTo().ActiveElement();
}
catch (Exception e)
{
Console.WriteLine("ERR: {0}; {1}", e.TargetSite, e.Message);
throw;
}
}
不是使用:
OpenURL(myDriver, myUrl);
这将加载页面,等到完成,最大化和聚焦。 我不知道为什么它是这样,但它的工作原理。
如果你想点击下一步或任何其他网页导航触发其他则“导航()”,本代尔的回答(在这个线程)将做的工作之后等待页面加载。
Answer 9:
看看挂毯网络框架。 您可以下载源代码存在。
这样做是为了发送信号指示该页面是身体的HTML属性准备。 您可以使用这种想法忽略复杂起诉的案件。
<html>
<head>
</head>
<body data-page-initialized="false">
<p>Write you page here</p>
<script>
$(document).ready(function () {
$(document.body).attr('data-page-initialized', 'true');
});
</script>
</body>
</html>
然后(根据Tapestry框架)创建硒的webdriver的延伸
public static void WaitForPageToLoad(this IWebDriver driver, int timeout = 15000)
{
//wait a bit for the page to start loading
Thread.Sleep(100);
//// In a limited number of cases, a "page" is an container error page or raw HTML content
// that does not include the body element and data-page-initialized element. In those cases,
// there will never be page initialization in the Tapestry sense and we return immediately.
if (!driver.ElementIsDisplayed("/html/body[@data-page-initialized]"))
{
return;
}
Stopwatch stopwatch = Stopwatch.StartNew();
int sleepTime = 20;
while(true)
{
if (driver.ElementIsDisplayed("/html/body[@data-page-initialized='true']"))
{
return;
}
if (stopwatch.ElapsedMilliseconds > 30000)
{
throw new Exception("Page did not finish initializing after 30 seconds.");
}
Thread.Sleep(sleepTime);
sleepTime *= 2; // geometric row of sleep time
}
}
使用延长ElementIsDisplayed 通过阿利斯特·斯科特写 。
public static bool ElementIsDisplayed(this IWebDriver driver, string xpath)
{
try
{
return driver.FindElement(By.XPath(xpath)).Displayed;
}
catch(NoSuchElementException)
{
return false;
}
}
最后创建测试:
driver.Url = this.GetAbsoluteUrl("/Account/Login");
driver.WaitForPageToLoad();
Answer 10:
本机的回答并没有在我的机器上编译( "The method until(Predicate<WebDriver>) is ambiguous for the type WebDriverWait"
)。
工作的Java版本8:
Predicate<WebDriver> pageLoaded = wd -> ((JavascriptExecutor) wd).executeScript(
"return document.readyState").equals("complete");
new FluentWait<WebDriver>(driver).until(pageLoaded);
Java 7的版本:
Predicate<WebDriver> pageLoaded = new Predicate<WebDriver>() {
@Override
public boolean apply(WebDriver input) {
return ((JavascriptExecutor) input).executeScript("return document.readyState").equals("complete");
}
};
new FluentWait<WebDriver>(driver).until(pageLoaded);
Answer 11:
我想这个代码,它为我工作。 我调用这个函数每次我移动到另一个网页的时间
public static void waitForPageToBeReady()
{
JavascriptExecutor js = (JavascriptExecutor)driver;
//This loop will rotate for 100 times to check If page Is ready after every 1 second.
//You can replace your if you wants to Increase or decrease wait time.
for (int i=0; i<400; i++)
{
try
{
Thread.sleep(1000);
}catch (InterruptedException e) {}
//To check page ready state.
if (js.executeScript("return document.readyState").toString().equals("complete"))
{
break;
}
}
}
Answer 12:
在你的NodeJS可以通过承诺得到它...
如果你写的代码,你可以肯定,当你到了当时的页面完全加载...
driver.get('www.sidanmor.com').then(()=> {
// here the page is fully loaded!!!
// do your stuff...
}).catch(console.log.bind(console));
如果你写的代码,你将导航和硒会等待3秒...
driver.get('www.sidanmor.com');
driver.sleep(3000);
// you can't be sure that the page is fully loaded!!!
// do your stuff... hope it will be OK...
硒文档:
this.get(URL)→Thenable
调度命令导航到指定的URL。
返回当文档加载完成后 ,将可以解决的承诺。
硒文档(的NodeJS)
Answer 13:
在等待的document.ready事件不是整个修复这个问题,因为这个代码仍处于竞争状态:有时这个代码被触发之前被处理的点击事件,因此这将直接返回,因为浏览器还没有开始加载新的页面呢。
经过一番搜索,我发现一个帖子上Obay测试山羊 ,其中有针对此问题的解决方案。 该解决方案的C#代码是这样的:
IWebElement page = null;
...
public void WaitForPageLoad()
{
if (page != null)
{
var waitForCurrentPageToStale = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
waitForCurrentPageToStale.Until(ExpectedConditions.StalenessOf(page));
}
var waitForDocumentReady = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
waitForDocumentReady.Until((wdriver) => (driver as IJavaScriptExecutor).ExecuteScript("return document.readyState").Equals("complete"));
page = driver.FindElement(By.TagName("html"));
}
`我的driver.navigate.gotourl后直接触发此方法,使之尽快获取页面的参考越好。 有它的乐趣!
Answer 14:
normaly当硒从点击打开一个新页面或提交或get方法,它会等待untell页面加载但probleme是当页面有一个XHR调用(AJAX),他将永远不会等待XHR来加载,所以创建一个新的梅索德监控XHR恨不得这将是很好的。 (抱歉我的英文不好:d)
public boolean waitForJSandJQueryToLoad() {
WebDriverWait wait = new WebDriverWait(webDriver, 30);
// wait for jQuery to load
ExpectedCondition<Boolean> jQueryLoad = new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver driver) {
try {
Long r = (Long)((JavascriptExecutor)driver).executeScript("return $.active");
return r == 0;
} catch (Exception e) {
LOG.info("no jquery present");
return true;
}
}
};
// wait for Javascript to load
ExpectedCondition<Boolean> jsLoad = new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver driver) {
return ((JavascriptExecutor)driver).executeScript("return document.readyState")
.toString().equals("complete");
}
};
return wait.until(jQueryLoad) && wait.until(jsLoad);
}
如果$。主动== 0,因此是不活跃XHR时调用(即工作只用jQuery)。 JavaScript的Ajax调用,你必须在项目中创建一个变量,并模拟它。
Answer 15:
你可以写一些逻辑来处理这个问题。 我有写会返回一个方法WebElement
这种方法将被调用三次,或者你可以增加时间,并添加一个空支票WebElement
下面是一个例子
public static void main(String[] args) {
WebDriver driver = new FirefoxDriver();
driver.get("https://www.crowdanalytix.com/#home");
WebElement webElement = getWebElement(driver, "homekkkkkkkkkkkk");
int i = 1;
while (webElement == null && i < 4) {
webElement = getWebElement(driver, "homessssssssssss");
System.out.println("calling");
i++;
}
System.out.println(webElement.getTagName());
System.out.println("End");
driver.close();
}
public static WebElement getWebElement(WebDriver driver, String id) {
WebElement myDynamicElement = null;
try {
myDynamicElement = (new WebDriverWait(driver, 10))
.until(ExpectedConditions.presenceOfElementLocated(By
.id(id)));
return myDynamicElement;
} catch (TimeoutException ex) {
return null;
}
}
Answer 16:
我执行JavaScript代码来检查,如果该文件已准备就绪。 我节省了很多时间的调试具有客户端绘制的网站Selenium测试。
public static boolean waitUntilDOMIsReady(WebDriver driver) {
def maxSeconds = DEFAULT_WAIT_SECONDS * 10
for (count in 1..maxSeconds) {
Thread.sleep(100)
def ready = isDOMReady(driver);
if (ready) {
break;
}
}
}
public static boolean isDOMReady(WebDriver driver){
return driver.executeScript("return document.readyState");
}
Answer 17:
public boolean waitForElement(String zoneName, String element, int index, int timeout) {
WebDriverWait wait = new WebDriverWait(appiumDriver, timeout/1000);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(element)));
return true;
}
Answer 18:
像Rubanov写了C#,我把它写为Java,它是:
public void waitForPageLoaded() {
ExpectedCondition<Boolean> expectation = new
ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
return (((JavascriptExecutor) driver).executeScript("return document.readyState").toString().equals("complete")&&((Boolean)((JavascriptExecutor)driver).executeScript("return jQuery.active == 0")));
}
};
try {
Thread.sleep(100);
WebDriverWait waitForLoad = new WebDriverWait(driver, 30);
waitForLoad.until(expectation);
} catch (Throwable error) {
Assert.fail("Timeout waiting for Page Load Request to complete.");
}
}
Answer 19:
在Java中它会象下面这样: -
private static boolean isloadComplete(WebDriver driver)
{
return ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("loaded")
|| ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("complete");
}
Answer 20:
下面的代码可能应该工作:
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.presenceOfAllElementsLocated(By.xpath("//*")));
Answer 21:
如果你有一个缓慢的网页或网络连接,有机会,没有以上的正常工作。 我把它们都试过,只说工作对我来说是等待页面上的最后一个可见元素的东西。 举个例子Bing的网页。 他们已经把一个相机图标(通过图像按钮搜索)旁边的主搜索按钮是可见完整的页面加载之后。 如果每个人都这样做,那么我们要做的是使用一个明确的等待就像上面的例子。
Answer 22:
public void waitForPageToLoad()
{
(new WebDriverWait(driver, DEFAULT_WAIT_TIME)).until(new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver d) {
return (((org.openqa.selenium.JavascriptExecutor) driver).executeScript("return document.readyState").equals("complete"));
}
});//Here DEFAULT_WAIT_TIME is a integer correspond to wait time in seconds
Answer 23:
下面是类似的东西,在Ruby中:
wait = Selenium::WebDriver::Wait.new(:timeout => 10)
wait.until { @driver.execute_script('return document.readyState').eql?('complete') }
Answer 24:
你可以有螺纹睡到重新加载页面。 这是不是最好的解决办法,因为你需要有确实的页面需要多长时间来加载的估计。
driver.get(homeUrl);
Thread.sleep(5000);
driver.findElement(By.xpath("Your_Xpath_here")).sendKeys(userName);
driver.findElement(By.xpath("Your_Xpath_here")).sendKeys(passWord);
driver.findElement(By.xpath("Your_Xpath_here")).click();
Answer 25:
我查了页面加载完成后,工作硒3.14.0
public static void UntilPageLoadComplete(IWebDriver driver, long timeoutInSeconds)
{
Until(driver, (d) =>
{
Boolean isPageLoaded = (Boolean)((IJavaScriptExecutor)driver).ExecuteScript("return document.readyState").Equals("complete");
if (!isPageLoaded) Console.WriteLine("Document is loading");
return isPageLoaded;
}, timeoutInSeconds);
}
public static void Until(IWebDriver driver, Func<IWebDriver, Boolean> waitCondition, long timeoutInSeconds)
{
WebDriverWait webDriverWait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSeconds));
webDriverWait.Timeout = TimeSpan.FromSeconds(timeoutInSeconds);
try
{
webDriverWait.Until(waitCondition);
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
Answer 26:
对于谁需要等待一个特定的元素展现出来的人。 (使用C#)
public static void WaitForElement(IWebDriver driver, By element)
{
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(20));
wait.Until(ExpectedConditions.ElementIsVisible(element));
}
然后,如果你想等待例如,如果一个班级=“错误消息”中你只需做DOM存在:
WaitForElement(driver, By.ClassName("error-message"));
对于ID,它就会是
WaitForElement(driver, By.Id("yourid"));
Answer 27:
您使用的角度? 如果你是有可能的webdriver的不承认,异步调用已经完成。
我建议在看保罗Hammants ngWebDriver 。 该方法waitForAngularRequestsToFinish()可以派上用场。
文章来源: Selenium wait until document is ready