我们是不是有任何通用函数来检查页面是不是已在 Selenium 中完全加载
Posted
技术标签:
【中文标题】我们是不是有任何通用函数来检查页面是不是已在 Selenium 中完全加载【英文标题】:Do we have any generic function to check if page has completely loaded in Selenium我们是否有任何通用函数来检查页面是否已在 Selenium 中完全加载 【发布时间】:2018-10-23 22:13:01 【问题描述】:我正在尝试在 selenium 中检查网页是否加载完成(即检查所有控件是否已加载)。
我试过下面的代码:
new WebDriverWait(firefoxDriver, pageLoadTimeout).until(
webDriver -> ((javascriptExecutor) webDriver).executeScript("return document.readyState").equals("complete"));
但即使页面正在加载上面的代码也不会等待。
我知道我可以检查特定元素以检查其是否可见/可点击等,但我正在寻找一些通用解决方案
【问题讨论】:
可以查看URL的页面,看看页面是否加载? 【参考方案1】:正如你提到的,如果有任何通用函数可以检查页面是否已通过Selenium 完全加载,答案是否。
首先让我们看看你的代码试验如下:
new WebDriverWait(firefoxDriver, pageLoadTimeout).until(webDriver -> ((JavascriptExecutor) webDriver).executeScript("return document.readyState").equals("complete"));
上述代码行中的参数pageLoadTimeout
与实际的pageLoadTimeout() 并没有真正的相似之处。
这里可以找到pageLoadTimeout in Selenium not working的详细讨论
现在,由于您的 用例 与页面完全加载相关,您可以使用 pageLoadStrategy() 设置为 使用DesiredCapabilities类: 使用 ChromeOptions 类: 您可以在Page load strategy for Chrome driver (Updated till Selenium v3.12.0)找到详细讨论 现在将 PageLoadStrategy 设置为 NORMAL 并且您的代码试用都确保 Browser Client 具有(即 Web Browser em>) 已达到 您可以在Selenium IE WebDriver only works while debugging找到详细讨论 但是 Browser Client 达到 要等待所有 JavaScript 和 Ajax 调用 完成,您可以编写如下函数: 您可以在Wait for ajax request to complete - selenium webdriver找到详细讨论 现在,通过 PageLoadStrategy 和 现在,虽然 页面标题 可能与您的 应用程序标题 匹配,但您想要交互的所需元素尚未完成加载。因此,更精细的方法是诱导 WebDriverWait 与 ExpectedConditions 设置为 visibilityOfElementLocated() 方法的联合使用,这将使您的程序等待所需的元素可见,如下所示: 您可以在以下位置找到一些相关的详细讨论:normal
[支持的值为 none em>、eager 或 normal ] 通过 DesiredCapabilities 类或 ChromeOptions 类的实例使用如下:
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.remote.DesiredCapabilities;
public class myDemo
public static void main(String[] args) throws Exception
System.setProperty("webdriver.gecko.driver", "C:\\Utility\\BrowserDrivers\\geckodriver.exe");
DesiredCapabilities dcap = new DesiredCapabilities();
dcap.setCapability("pageLoadStrategy", "normal");
FirefoxOptions opt = new FirefoxOptions();
opt.merge(dcap);
WebDriver driver = new FirefoxDriver(opt);
driver.get("https://www.google.com/");
System.out.println(driver.getTitle());
driver.quit();
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.PageLoadStrategy;
public class myDemo
public static void main(String[] args) throws Exception
System.setProperty("webdriver.gecko.driver", "C:\\Utility\\BrowserDrivers\\geckodriver.exe");
FirefoxOptions opt = new FirefoxOptions();
opt.setPageLoadStrategy(PageLoadStrategy.NORMAL);
WebDriver driver = new FirefoxDriver(opt);
driver.get("https://www.google.com/");
System.out.println(driver.getTitle());
driver.quit();
'document.readyState'
等于"complete"
。一旦满足这个条件,Selenium 就会执行下一行代码。'document.readyState'
等于 "complete"
仍然不能保证所有 JavaScript 和 Ajax 调用完成。
public void WaitForAjax2Complete() throws InterruptedException
while (true)
if ((Boolean) ((JavascriptExecutor)driver).executeScript("return jQuery.active == 0"))
break;
Thread.sleep(100);
"return jQuery.active == 0"
的上述两种方法看起来正在等待不确定的事件。因此,对于一个明确的等待,您可以将WebDriverWait 与ExpectedConditions 设置为titleContains() 方法相结合,这将确保页面标题(即网页)是可见并假设所有元素也是可见的,如下所示:driver.get("https://www.google.com/");
new WebDriverWait(driver, 10).until(ExpectedConditions.titleContains("partial_title_of_application_under_test"));
System.out.println(driver.getTitle());
driver.quit();
driver.get("https://www.google.com/");
WebElement ele = new WebDriverWait(driver, 10).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("xpath_of_the_desired_element")));
System.out.println(ele.getText());
driver.quit();
参考文献
【讨论】:
【参考方案2】:我也使用 selenium,但我也遇到了同样的问题,为了解决这个问题,我也只是等待 jQuery 加载。
所以如果你有同样的问题也试试这个
((Long) ((JavascriptExecutor) browser).executeScript("return jQuery.active") == 0);
您可以将这两个函数包装在一个方法中并检查直到页面和 jQuery 都被加载
【讨论】:
您假设由 Selenium 驱动的网站使用 JQuery...【参考方案3】:实现这一点,它适用于包括我在内的许多人。它包括在 JavaScript、Angular、JQuery 上等待的网页(如果有的话)。
如果您的应用程序包含 Javascript 和 JQuery,您可以只为它们编写代码,
通过在单个方法中定义它,您可以在任何地方调用它:
// Wait for jQuery to load
ExpectedCondition<Boolean> jQueryLoad = driver -> ((Long) ((JavascriptExecutor) driver).executeScript("return jQuery.active") == 0);
boolean jqueryReady = (Boolean) js.executeScript("return jQuery.active==0");
if (!jqueryReady)
// System.out.println("JQuery is NOT Ready!");
wait.until(jQueryLoad);
wait.until(jQueryLoad);
// Wait for ANGULAR to load
String angularReadyScript = "return angular.element(document).injector().get('$http').pendingRequests.length === 0";
ExpectedCondition<Boolean> angularLoad = driver -> Boolean.valueOf(((JavascriptExecutor) driver).executeScript(angularReadyScript).toString());
boolean angularReady = Boolean.valueOf(js.executeScript(angularReadyScript).toString());
if (!angularReady)
// System.out.println("ANGULAR is NOT Ready!");
wait.until(angularLoad);
// Wait for Javascript to load
ExpectedCondition<Boolean> jsLoad = driver -> ((JavascriptExecutor) driver).executeScript("return document.readyState").toString()
.equals("complete");
boolean jsReady = (Boolean) js.executeScript("return document.readyState").toString().equals("complete");
// Wait Javascript until it is Ready!
if (!jsReady)
// System.out.println("JS in NOT Ready!");
wait.until(jsLoad);
Click here for Reference Link
让我知道您是否通过实施陷入困境。
它克服了线程或显式等待的使用。
【讨论】:
虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review @Zabuza :添加了代码。谢谢。【参考方案4】: public static void waitForPageToLoad(long timeOutInSeconds)
ExpectedCondition<Boolean> expectation = new ExpectedCondition<Boolean>()
public Boolean apply(WebDriver driver)
return ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("complete");
;
try
System.out.println("Waiting for page to load...");
WebDriverWait wait = new WebDriverWait(Driver.getDriver(), timeOutInSeconds);
wait.until(expectation);
catch (Throwable error)
System.out.println(
"Timeout waiting for Page Load Request to complete after " + timeOutInSeconds + " seconds");
试试这个方法
【讨论】:
【参考方案5】:这对我来说很适合动态呈现的网站:
-
等待完整页面加载
WebDriverWait wait = new WebDriverWait(driver, 50);
wait.until((ExpectedCondition<Boolean>) wd -> ((JavascriptExecutor) wd).executeScript("return document.readyState").equals("complete"));
-
使用一个总是会失败的虚拟条件进行另一个隐式等待
try
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[contains(text(),'" + "This text will always fail :)" + "')]"))); // condition you are certain won't be true
catch (TimeoutException te)
-
最后,不要获取 html 源代码(在大多数单页应用程序中会给您带来不同的结果),而是拉取第一个 html 标记的 outerhtml
String script = "return document.getElementsByTagName(\"html\")[0].outerHTML;";
content = ((JavascriptExecutor) driver).executeScript(script).toString();
【讨论】:
【参考方案6】:有一种简单的方法可以做到这一点。当你第一次通过javascript请求状态时,它会告诉你页面是complete
,但之后它会进入状态loading
。第一个complete
状态是初始页面!
所以我的建议是在loading
状态之后检查complete
状态。用 php 检查这段代码,很容易翻译成另一种语言。
$prevStatus = '';
$checkStatus = function ($driver) use (&$prevStatus)
$status = $driver->executeScript("return document.readyState");
if ($prevStatus=='' && $status=='loading')
//save the previous status and continue waiting
$prevStatus = $status;
return false;
if ($prevStatus=='loading' && $status=='complete')
//loading -> complete, stop waiting, it is finish!
return true;
//continue waiting
return false;
;
$this->driver->wait(20, 150)->until($checkStatus);
检查是否存在的元素也很有效,但您需要确保该元素仅存在于目标页面中。
【讨论】:
【参考方案7】:这样的东西应该可以工作(请原谅java答案中的python):
idle = driver.execute_async_script("""
window.requestIdleCallback(() =>
arguments[0](true)
)
""")
这应该阻塞,直到事件循环空闲,这意味着应该加载所有资产。
【讨论】:
以上是关于我们是不是有任何通用函数来检查页面是不是已在 Selenium 中完全加载的主要内容,如果未能解决你的问题,请参考以下文章