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


当前回答

在我的例子中,我使用以下方法来了解页面加载状态。在我们的应用程序加载gif(s)是存在的,我听他们如下,以消除不必要的等待时间在脚本。

public static void processing(){ 
    WebDriverWait wait = new WebDriverWait(driver, 30);
    wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[@id='Msgpanel']/div/div/img")));
    wait.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("//div[@id='Msgpanel']/div/div/img")));
}

xpath在HTML DOM中定位gif的位置。 在此之后,您还可以实现您的动作方法单击。

public static void click(WebElement elementToBeClicked){
    WebDriverWait wait = new WebDriverWait(driver, 45);
    wait.until(ExpectedConditions.visibilityOf(element));
    wait.until(ExpectedConditions.elementToBeClickable(element)); 
    wait.ignoring(NoSuchElementException.class).ignoring(StaleElementReferenceException.class); elementToBeClicked.click(); 
 }

其他回答

Ruby实现:

wait = Selenium::WebDriver::Wait.new(:timeout => 10)
wait.until {
    @driver.execute_script("return document.readyState;") == "complete" 
}

这似乎是WebDriver的一个严重限制。显然,等待一个元素并不意味着页面正在加载,特别是DOM可以完全构建(onready状态),此时JS仍在执行,CSS和图像仍在加载。

我相信最简单的解决方案是在onload事件上设置一个JS变量,在所有东西初始化后,在Selenium中检查和等待这个JS变量。

伙计,所有这些答案都需要太多代码。这应该是一个简单的事情,因为它很常见。

为什么不注入一些简单的Javascript与web驱动程序和检查。 这就是我在webscraper课上使用的方法。Javascript是相当基本的,即使你不知道它。

def js_get_page_state(self):
"""
Javascript for getting document.readyState
:return: Pages state. See doc link below.
"""
ready_state = self.driver.execute_script('return document.readyState')
if ready_state == 'loading':
    self.logger.info("Loading Page...")
elif ready_state == 'interactive':
    self.logger.info("Page is interactive")
elif ready_state == 'complete':
    self.logger.info("The page is fully loaded!")
return ready_state

更多信息见“文档”。MDN Web Docs的readyState: https://developer.mozilla.org/en-US/docs/Web/API/Document/readyState

使用类WebDriverWait

也可以看这里

您可以期望显示一些元素。类似于c#:

WebDriver _driver = new WebDriver();
WebDriverWait _wait = new WebDriverWait(_driver, new TimeSpan(0, 1, 0));

_wait.Until(d => d.FindElement(By.Id("Id_Your_UIElement")));

我很惊讶,谓词不是首选,因为您通常知道您将在等待加载的页面上与哪些元素进行下一步交互。我的方法一直是构建谓词/函数,如waitForElementByID(String id)和waitForElemetVisibleByClass(String className)等,然后在我需要它们的地方使用和重用这些,无论是我正在等待的页面加载或页面内容更改。

例如,

在我的测试类中:

driverWait.until(textIsPresent("expectedText");

在我的测试类parent中:

protected Predicate<WebDriver> textIsPresent(String text){
    final String t = text;
    return new Predicate<WebDriver>(){
        public boolean apply(WebDriver driver){
            return isTextPresent(t);
        }
    };
}

protected boolean isTextPresent(String text){
    return driver.getPageSource().contains(text);
}

虽然这看起来很多,但它会为你反复检查 检查频率的间隔可以和最终值一起设置 在计时之前等待一段时间。此外,您将重用这些方法。

在这个例子中,父类定义并启动了WebDriver驱动程序和WebDriverWait驱动程序。

我希望这能有所帮助。