Как переопределить Selenium Webdriver FindElement и добавить к нему ожидание?

1

Я использую Selenium Webdriver с С#, и мне интересно, есть ли способ переопределить метод FindElement? То, что я хотел бы сделать - если возможно, - добавить дополнительный параметр и код в метод, который заставит его дождаться, пока элемент станет видимым, прежде чем продолжить. Например, это было бы примерно так:

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

Это будет ждать до 60 секунд, пока элемент появится и будет доступен для клика.

Есть идеи, как это сделать? Спасибо, Джон

  • 0
    один из способов - добавить неявное ожидание ((stackoverflow.com/a/11244854/2504101). Другой - использовать EventFiringWebDriver, который позволяет добавить любое действие (даже элемент выделения) до / после того, как действие будет выполнено stackoverflow.com/a / 23787258/2504101
Теги:
selenium-webdriver

3 ответа

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();
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.

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"));
  • 0
    Неявное ожидание будет касаться только присутствия элемента, но быть видимым - это отдельная история.
  • 0
    После присутствия в DOM элемент может быть проверен на видимость.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню