如何覆盖Selenium Webdriver FindElement并添加等待?

时间:2014-06-10 16:09:36

标签: c# selenium-webdriver

我使用Selenium Webdriver和C#,我想知道是否有办法覆盖FindElement方法?我想做的 - 如果可能的话 - 是在方法中添加一个额外的参数和代码,迫使它在继续之前等待元素可见。 例如,它会是这样的:

Driver.FindElement(By.Id("orion.dialog.box.ok"), 60).Click();

这将等待最多60秒,以便元素显示并可以点击。

任何想法如何做到这一点? 谢谢, 约翰

3 个答案:

答案 0 :(得分:0)

你可以使用ImplicitWait。您可以创建一个新的用户定义函数来接受By对象和超时秒,并让函数返回IWebElement,如下所示:

 IWebElement elem = MyOwnGetElement(By.id("test"),60);

上述函数可能包含以下代码,其中time_out_sec是函数参数。

WebDriver driver = new FirefoxDriver();

driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(time_out_sec));

driver.Url = "http://somedomain/url_that_delays_loading";
IWebElement myDynamicElement = driver.FindElement(By.Id("someDynamicElement"));

答案 1 :(得分:0)

我建议您将其添加为扩展方法。伪代码:

public static IWebElement WaitForAndFindElement(this IWebDriver driver, By by)
{
    // do a wait
    // something like...
    WebDriverWait wait = new WebDriverWait(TimeSpan.FromSeconds(60)); // hard code it here if you want to avoid each calling method passing in a value

    return wait.Until(webDriver => 
        {
            if (webDriver.FindElement(by).Displayed)
            {
                return webDriver.FindElement(by);
            }
            return null; // returning null with force the wait class to iterate around again.
        });
}

只是说明,隐含的等待将成为您解决方案的第一部分。它将导致Selenium等待最多60秒,因为元素存在于DOM 中,但可见是完全不同的。

.Displayed将处理该问题,并且必须在WebDriverWait内处理。

答案 2 :(得分:0)

我用Selenium编写了6个多月的代码,我和你的问题一样。我创建了这个扩展方法,每次都适合我。

代码的作用是: 在20秒内,它会检查每个500毫秒,无论页面上是否存在该元素。如果在20秒之后,它没有找到,它将抛出异常。 这将有助于您进行动态等待。

  public static class SeleniumExtensionMethods {
      public static WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(20));
      public static void SafeClick(this IWebElement webElement) {
          try {
              wait.Until(ExpectedConditions.ElementToBeClickable(webElement)).Click();
          } catch (TargetInvocationException ex) {
              Console.WriteLine(ex.InnerException);
          }

      }

然后像这样使用它:

IWebElement x = driver.FindElement(By.Id("username"));
x.SafeClick();