在Selenium中,命令是什么,等待页面加载停止"

时间:2014-10-11 03:35:10

标签: selenium selenium-webdriver webdriver

如何使WebDriver等到页面加载完全停止。

表示它等待并检查整个页面是否已加载,然后只进行下一行执行。

4 个答案:

答案 0 :(得分:9)

最大的问题是,没有适用于大多数用户的通用,一刀切的解决方案。 “当我的页面完成加载时”的概念在当今动态的,AJAX密集的,依赖于JavaScript的Web中几乎毫无意义。可以等待浏览器确定网络流量已完成,但这不会将JavaScript执行考虑在内。可以将“完成”定义为已触发的页面onload事件,但忽略了使用setTimeout()页面的可能性。此外,这些定义都不考虑帧或iframe。

谈到Selenium,需要考虑几个因素。请记住,Selenium RC API已有10年历史。在设计和开发时,典型网页的体系结构使waitForPageToLoad实用的方法成为可能。另一方面,WebDriver API识别当前的现实。单个驱动程序实现通常会尝试在显式页面导航期间等待页面加载(例如,driver.get()),但此等待将是“尽力而为”,并且不是保证。请注意,由用户交互引起的导航(例如element.click())将不太可能完全等待,因为此类交互是异步的,因此本身就具有竞争条件。

WebDriver的正确方法是等待您要与之交互的元素出现在后续页面上。最好用WebDriverWait或类似的结构来完成。您可能会在支持库中找到一些其他构造,主要是那些处理页面对象模式的构造。您也可以尝试在驱动程序实例中设置隐式等待超时,但我相信使用它会掩盖意图。

答案 1 :(得分:1)

这实际上是Selenium的默认行为 - 它等待所有请求完成后再继续下一行代码。

答案 2 :(得分:1)

通过Selenium支持库SlowLoadableComponent提供的设计模式可以满足您的需求:https://selenium.googlecode.com/svn/trunk/docs/api/java/org/openqa/selenium/support/ui/SlowLoadableComponent.html。要点是您将页面对象写入extend SlowLoadableComponent。您必须在abstract中为两个SlowLoadableComponent方法提供实施:load()isLoaded()

isLoaded()方法应该检查您认为页面已加载的所有内容'。 load()方法执行加载页面对象所需的操作。您为页面对象指定加载超时(我通过页面对象的构造函数执行此操作)。当您在页面对象上调用get()方法时,它会从SlowLoadableComponent继承,它会调用isLoaded()。如果未加载页面对象,则会调用load()加载页面对象。它将继续执行此操作,直到您的页面对象被加载或超时为止。

但是,您必须自己定义对页面对象的加载方式。 Selenium没有开箱即用的方法来确定您的特定页面对象是否已加载,因为这些确定对上下文非常敏感。例如,考虑表示Web应用程序的登录页面的页面对象。它被加载了#39;如果用户名和密码输入文本框和提交登录按钮可见。这不适用于表示Web应用程序中某些其他页面的页面对象。您必须自定义定制“已加载”#39;任何给定页面对象的标准。

这是一个简单的例子。基本的抽象可加载对象:

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.SlowLoadableComponent;
import org.openqa.selenium.support.ui.SystemClock;

public abstract class AbstractLoadableComponent<T extends AbstractLoadableComponent<T>> extends SlowLoadableComponent<T> {

    public static final int DEFAULT_TIMEOUT_IN_SECONDS = 30;
    private final WebDriver driver;
    private final int timeoutInSeconds;

    public AbstractLoadableComponent(final WebDriver driver, final int timeoutInSeconds) {
        super(new SystemClock(), timeoutInSeconds);

        this.driver = driver;
        this.timeoutInSeconds = timeoutInSeconds;
        this.load();
    }

    public final WebDriver getDriver() {
        return driver;
    }

    public final int getTimeoutInSeconds() {
        return timeoutInSeconds;
    }

    @Override
    protected void load() {
        PageFactory.initElements(getDriver(), this);
    }
}

基本抽象页面对象:

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.ui.SlowLoadableComponent;

public abstract class AbstractPage<T extends AbstractPage<T>> extends AbstractLoadableComponent<T> {

    private final String url;

    public AbstractPage(final WebDriver driver) {
        this(driver, driver.getCurrentUrl(), DEFAULT_TIMEOUT_IN_SECONDS);
    }

    public AbstractPage(final WebDriver driver, final String url) {
        this(driver, url, DEFAULT_TIMEOUT_IN_SECONDS);
    }

    public AbstractPage(final WebDriver driver, final String url, final int timeoutInSeconds) {
        super(driver, timeoutInSeconds);
        this.url = url;
    }

    public final String getUrl() {
        return url;
    }

    @Override
    protected void load() {
        super.load();

        if(url != null) {
            getDriver().get(url);
        }
    }
}

登录页面的基本具体页面对象类:

import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.How;

import static org.testng.Assert.assertTrue;

public final class LoginPage extends AbstractPage<LoginPage>  {

    @FindBy(how = How.ID, using = "username")
    private WebElement usernameBox;

    @FindBy(how = How.ID, using = "password")
    private WebElement passwordBox;

    @FindBy(how = How.NAME, using = "login")
    private WebElement loginButton;

    public LoginPage(final WebDriver driver) {
        this(driver, driver.getCurrentUrl(), DEFAULT_TIMEOUT_IN_SECONDS);
    }

    public LoginPage(final WebDriver driver, final String url) {
        this(driver, url, DEFAULT_TIMEOUT_IN_SECONDS);
    }

    public LoginPage(final WebDriver driver, final String url, final int timeoutInSeconds) {
        super(driver, url, timeoutInSeconds);
    }

    @Override
    protected final void isLoaded() throws Error {
        try {
            assertTrue(usernameBox.isDisplayed(), "Username text box is not displayed");
            assertTrue(passwordBox.isDisplayed(), "Password text box is not displayed");
            assertTrue(loginButton.isDisplayed(), "Login button is not displayed");
        } catch(NoSuchElementException nsee) {
            throw new Error(nsee);
        }
    }
}

答案 3 :(得分:0)

driver.manage.implicitlywait(3,TimeUnit.Seconds)将为hep。