3

我遇到了一个问题。我的网页有一个DropDownList控件。一旦DropDownList值更改(通过选择不同的值),页面就会刷新并呈现内容。

然后我必须Thread.Sleep(2000);在它去之前使用 and FindElement

我的问题:等待页面加载的最佳方法是什么?

我的代码中有很多实例,Thread.Sleep(2000)以至于我开始认为这不是解决问题的最佳方法。

这是我的代码:

[TestInitialize()]
public void Setup()
{
    if (BaseIntegrationTest.browserType.Equals(BaseIntegrationTest.IE))
    {
        driver = new InternetExplorerDriver();
    }
    else if (BaseIntegrationTest.browserType.Equals(BaseIntegrationTest.CHROME))
    {
        //driver = new ChromeDriver();
    }
    else if (BaseIntegrationTest.browserType.Equals(BaseIntegrationTest.FIREFOX))
    {
        driver = new FirefoxDriver();
    }
}

第二部分:

[TestMethod]
public void testVerifyData()
{
    // ...................
    // ...................
    driver.FindElement(By.XPath("//*[@id='ctl00_NavigationControl1_lnke']")).Click();

    Thread.Sleep(2000);

    //select from the dropdownlist.
    IWebElement catagory = driver.FindElement(By.Id("ctl00_ContentPlaceHolder1_Filter"));
    SelectElement selectCatagory = new SelectElement(catagory);
    selectCatagory.SelectByText("Employee");

    Thread.Sleep(2000);
    // ...................
    // ...................
}
4

6 回答 6

7

Thread.Sleep() 是一种非常不鼓励实现等待的方法

此代码在 selenium 文档http://seleniumhq.org/docs/04_webdriver_advanced.html中进行了概述

WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
IWebElement category = wait.Until<IWebElement>((d) =>
    {
        return d.FindElement(By.Id("ctl00_ContentPlaceHolder1_Filter"));
    });

这是一个显式等待的示例,其中 selenium 在找到您的元素之前不会执行任何操作

隐式等待的一个示例是:

driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));
IWebElement category = driver.FindElement(By.Id("ctl00_ContentPlaceHolder1_Filter"));

在隐式等待中,驱动程序将等待给定的时间并轮询 DOM 以查找任何不存在的元素。

编辑

public WaitForElement(string el_id)
{
    WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
    IWebElement category = wait.Until<IWebElement>((d) =>
    {
        return d.FindElement(By.Id(el_id));
    });
}
于 2012-08-15T22:07:01.737 回答
1

我也通过使用 WebDriverWait 解决了这个问题。

但我设置等到最后一个元素出现(例如:页脚,列表中的最后一项)。

WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until(d => d.FindElement(By.Id("footer")).Displayed);

或者

WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until(d => d.FindElements(By.TagName("li")).Last().Displayed);
于 2014-12-19T07:16:52.067 回答
1

在某些情况下您确实需要等待,在这种情况下,Task.Delay 方法将提供比 Thread.Sleep 更可预测的结果

Task.Delay(1000).Wait(); // 等待 1 秒

于 2016-03-23T17:43:55.653 回答
0

假设由交互引起的刷新是 Selenium 可以检测到的,那么以下方法可能会满足您的需求:

等待页面加载

据我所知,此方法检查浏览器中的状态以查看浏览器是否认为它正在加载某些内容,并等待该状态被清除。然而,这种就绪状态有点陈旧——有很多方法可以动态加载页面或页面的一部分,以至于就绪状态并不总是准确描述正在发生的事情。

如果您知道您的操作会发生什么变化 - 也就是说,如果您知道在与下拉列表交互后,将出现以前不在页面上的特定 UI 元素 - 那么您可能会更好等待那些特定的 UI 元素出现。您可以通过编写一个重复检查isTextPresent并以小增量等待的方法来做到这一点,直到达到超时或出现预期的元素。在这些方法中可以使用其他“is X Present”方法,您可以在我链接到的 Selenium 接口的其他地方找到这些方法。

于 2012-08-14T19:44:59.160 回答
0

我为自己制作了一个自定义功能,也许它对某人有用:

 public static void waitForPageToBeLoaded(WebDriver driver, int time) {

     ExpectedCondition<Boolean> expectation = new
     ExpectedCondition<Boolean>() {     
         public Boolean apply(WebDriver driver) {
             return ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("complete");
            }
     };

     Wait<WebDriver> wait = new WebDriverWait(driver, Long.valueOf(time)); 
     try {
         wait.until(expectation);
     } catch(Throwable error) {
         System.out.println(error);
         mainFunctions.reportFailure("[waitForPageToBeLoaded] Page load took longer than " + time/60 + " min.");
     }
 }  // waitForPageLoaded
于 2015-02-04T12:07:29.607 回答
0

如果您想在页面加载或超时过期后获取 html:

using (var chromeDriver = new ChromeDriver())
        {
            chromeDriver.Manage().Timeouts().SetPageLoadTimeout(TimeSpan.FromSeconds(30));

            try
            {
                chromeDriver.Navigate().GoToUrl(link);
                return chromeDriver.PageSource;
            }
            catch (WebDriverTimeoutException)
            {
                return chromeDriver.PageSource;
            }
        }
于 2014-06-20T06:04:32.530 回答