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


当前回答

SeleniumWaiter:

import com.google.common.base.Function;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

public class SeleniumWaiter {

      private WebDriver driver;

      public SeleniumWaiter(WebDriver driver) {
           this.driver = driver;
      }

      public WebElement waitForMe(By locatorname, int timeout){
           WebDriverWait wait = new WebDriverWait(driver, timeout);
           return wait.until(SeleniumWaiter.presenceOfElementLocated(locatorname));
      }

      public static Function<WebDriver, WebElement> presenceOfElementLocated(final By locator) {
            // TODO Auto-generated method stub
            return new Function<WebDriver, WebElement>() {
                 @Override
                 public WebElement apply(WebDriver driver) {
                      return driver.findElement(locator);
                 }
            };
      }
 }

对你来说:

_waiter = new SeleniumWaiter(_driver);

try {
   _waiter.waitForMe(By.xpath("//..."), 10);
} 
catch (Exception e) {
   // Error
}

其他回答

如果你设置了驱动程序的隐式等待,然后调用findElement方法在你期望加载页面上的元素上,WebDriver将轮询该元素,直到找到该元素或达到超时值。

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

来源:implicit-waits

在脚本中调用下面的函数,这将等待页面未使用javascript加载

public static boolean isloadComplete(WebDriver driver)
{
    return ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("loaded")
            || ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("complete");
}

对于隐式等待,你可以使用如下代码:

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS)

为了使网页等待一个特定的对象是可见的或某些条件是真实的。您可以使用网页驱动程序等羽。

//120 is maximum number of seconds to wait.
WebDriverWait wait = new WebDriverWait(driver,120);  
wait.until(ExpectedConditions.elementToBeClickable("CONDITITON"));

在Java中,另一种选择是让线程在特定的时间内休眠。

Thread.sleep(numberOfSeconds*1000); 
//This line will cause thread to sleep for seconds as variable

我创建了一个方法来简化线程。睡眠的方法

public static void wait_time(int seconds){
    try {
        Thread.sleep(seconds*1000);
        }catch (InterruptedException e) {
        // TODO Auto-generated catch block
            e.printStackTrace();
        }
}

使用wait_time(10)方法;线程将休眠10秒。

您可以尝试这段代码,让页面完全加载,直到找到元素为止。

public void waitForBrowserToLoadCompletely() {
    String state = null;
    String oldstate = null;
    try {
        System.out.print("Waiting for browser loading to complete");

        int i = 0;
        while (i < 5) {
            Thread.sleep(1000);
            state = ((JavascriptExecutor) driver).executeScript("return document.readyState;").toString();
            System.out.print("." + Character.toUpperCase(state.charAt(0)) + ".");
            if (state.equals("interactive") || state.equals("loading"))
                break;
            /*
             * If browser in 'complete' state since last X seconds. Return.
             */

            if (i == 1 && state.equals("complete")) {
                System.out.println();
                return;
            }
            i++;
        }
        i = 0;
        oldstate = null;
        Thread.sleep(2000);

        /*
         * Now wait for state to become complete
         */
        while (true) {
            state = ((JavascriptExecutor) driver).executeScript("return document.readyState;").toString();
            System.out.print("." + state.charAt(0) + ".");
            if (state.equals("complete"))
                break;

            if (state.equals(oldstate))
                i++;
            else
                i = 0;
            /*
             * If browser state is same (loading/interactive) since last 60
             * secs. Refresh the page.
             */
            if (i == 15 && state.equals("loading")) {
                System.out.println("\nBrowser in " + state + " state since last 60 secs. So refreshing browser.");
                driver.navigate().refresh();
                System.out.print("Waiting for browser loading to complete");
                i = 0;
            } else if (i == 6 && state.equals("interactive")) {
                System.out.println(
                        "\nBrowser in " + state + " state since last 30 secs. So starting with execution.");
                return;
            }

            Thread.sleep(4000);
            oldstate = state;

        }
        System.out.println();

    } catch (InterruptedException ie) {
        ie.printStackTrace();
    }
}
private static void checkPageIsReady(WebDriver driver) {
    JavascriptExecutor js = (JavascriptExecutor) driver;

    // Initially bellow given if condition will check ready state of page.
    if (js.executeScript("return document.readyState").toString().equals("complete")) {
        System.out.println("Page Is loaded.");
        return;
    }

    // This loop will rotate for 25 times to check If page Is ready after
    // every 1 second.
    // You can replace your value with 25 If you wants to Increase or
    // decrease wait time.
    for (int i = 0; i < 25; i++) {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
        }
        // To check page ready state.
        if (js.executeScript("return document.readyState").toString().equals("complete")) {
            break;
        }
    }
}