C# 如何覆盖Selenium Webdriver FindElement并向其添加等待?

C# 如何覆盖Selenium Webdriver FindElement并向其添加等待?,c#,selenium-webdriver,C#,Selenium Webdriver,我正在将Selenium Webdriver与C#一起使用,我想知道是否有一种方法可以覆盖FindElement方法?如果可能的话,我想做的是在方法中添加一个额外的参数和代码,迫使它在继续之前等待元素可见。 例如,它将是这样的: Driver.FindElement(By.Id("orion.dialog.box.ok"), 60).Click(); IWebElement x = driver.FindElement(By.Id("username")); x.SafeClick(); 这

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

Driver.FindElement(By.Id("orion.dialog.box.ok"), 60).Click();
IWebElement x = driver.FindElement(By.Id("username"));
x.SafeClick();
这将等待最多60秒,以便元素显示并可供单击

有什么办法吗? 谢谢
约翰

你可以用它等着。您可以创建一个新的用户定义函数来接受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"));

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

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
中处理该问题。我使用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);
          }

      }
然后像这样使用它:

Driver.FindElement(By.Id("orion.dialog.box.ok"), 60).Click();
IWebElement x = driver.FindElement(By.Id("username"));
x.SafeClick();

一种方法是添加隐式等待((stackoverflow.com/a/11244854/2504101)。另一种方法是使用EventFiringWebDriver,它允许添加任何操作(甚至高亮显示元素)before/after action的格式为stackoverflow.com/a/23787258/2504101隐式等待只与元素的存在有关,但可见则是另一回事。在DOM中存在元素后,可以检查元素的可见性。