如何让Selenium 2.0等待页面加载?


当前回答

/**
 * Call this method before an event that will change the page.
 */
private void beforePageLoad() {
    JavascriptExecutor js = (JavascriptExecutor) driver;
    js.executeScript("document.mpPageReloaded='notYet';");
}

/**
 * Call this method after an event that will change the page.
 * 
 * @see #beforePageLoad
 * 
 *      Waits for the previous page to disappear.
 */
private void afterPageLoad() throws Exception {
    (new WebDriverWait(driver, 10)).until(new Predicate<WebDriver>() {

        @Override
        public boolean apply(WebDriver driver) {
            JavascriptExecutor js = (JavascriptExecutor) driver;
            Object obj = js.executeScript("return document.mpPageReloaded;");
            if (obj == null) {
                return true;
            }
            String str = (String) obj;
            if (!str.equals("notYet")) {
                return true;
            }
            return false;
        }
    });
}

在只更改部分文档的情况下,您可以从文档更改为元素。

这个技巧的灵感来自于sincebasic的答案。

其他回答

这段代码将等待页面上的所有元素都加载到DOM中。

WebDriver driver = new WebDriver();
WebDriverWait wait = new WebDriverWait(driver, timeout);

wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*")));

您可以删除系统。线。添加它是为了调试目的。

WebDriver driver_;

public void waitForPageLoad() {

    Wait<WebDriver> wait = new WebDriverWait(driver_, 30);
    wait.until(new Function<WebDriver, Boolean>() {
        public Boolean apply(WebDriver driver) {
            System.out.println("Current Window State       : "
                + String.valueOf(((JavascriptExecutor) driver).executeScript("return document.readyState")));
            return String
                .valueOf(((JavascriptExecutor) driver).executeScript("return document.readyState"))
                .equals("complete");
        }
    });
}

对于使用java 8向前的程序员,可以使用下面的代码来使用显式等待等待页面加载。

JavascriptExecutor js = (JavascriptExecutor) driver;  
new WebDriverWait(driver, 10).until(webDriver ->
(js).executeScript("return document.readyState;").equals("complete"));

注意:在我上面的代码中使用Lambda表达式,它只在java 8的后续版本中可用。

对于使用低版本Java(即Java 8以下)的程序员,可以使用:

ExpectedCondition<Boolean> cond = new ExpectedCondition<Boolean>() {
    @Override
    public Boolean apply(WebDriver input) {
        JavascriptExecutor js = (JavascriptExecutor) driver; 
        return js.executeScript("return document.readyState;").equals("complete");
            }
        };
         
    new WebDriverWait(driver, 100).until(cond);

您可以使用下面的现有方法来设置pageLoadTimeout。在下面的例子中,如果页面加载时间超过20秒,那么它将抛出一个页面重新加载异常:

WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().pageLoadTimeout(20, TimeUnit.SECONDS);

下面是一个Java 8版本的目前被点赞最多的答案:

WebDriverWait wait = new WebDriverWait(myDriver, Duration.ofSeconds(15));
wait.until(webDriver -> "complete".equals(((JavascriptExecutor) webDriver)
    .executeScript("return document.readyState")));
    

其中myDriver是一个WebDriver对象(前面声明过)。

注意:注意这个方法(document.readyState)只检查DOM。