【问题标题】:In Selenium, What is the command to "wait until the page loading stops"在 Selenium 中,“等到页面加载停止”的命令是什么
【发布时间】:2014-10-11 03:35:09
【问题描述】:

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

意味着,它等待并检查整个页面是否已加载,然后才继续执行下一行。

【问题讨论】:

    标签: selenium selenium-webdriver webdriver


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 但不包括javascript & jQuery等?
      • 答案有点简单。虽然大部分是正确的,但它掩盖了许多所涉及的微妙之处。有更好的答案,如果看到这个成为得分最高的答案,我会非常失望。
      【解决方案3】:

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

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

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

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

      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);
              }
          }
      }
      

      【讨论】:

        【解决方案4】:

        driver.manage.implicitlywait(3, TimeUnit.Seconds) 会帮助。

        【讨论】:

          猜你喜欢
          • 2014-01-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-01-18
          • 1970-01-01
          • 2012-04-16
          • 1970-01-01
          • 2017-11-11
          相关资源
          最近更新 更多