Selenium Webdriver ждать щелчка элемента? - PullRequest
10 голосов
/ 08 марта 2012

Я искал решение для этого, но безрезультатно. У меня есть кнопка, которую я нажимаю, для возврата данных иногда требуется много времени, и драйвер, по-моему, отключает тайм-аут и просто убивает приложение.

Я пытаюсь использовать класс WebDriverWait для достижения этой цели, но метод Click () недоступен из-за того, как я его использую.

WebDriverWait wait = new WebDriverWait(browser, new TimeSpan(0, 5, 0));

bool clicked = wait.Until<bool>((elem) =>
{
     elem.Click(); //Doesn't Work
     return true;
});

Метод ImplicitlyWait () предназначен только для ожидания загрузки элементов, но на этот раз по клику (), поэтому он даже не может искать элемент.

Метод SetScriptTimeout () просто работает с выполнением JavaScript, чего я не делаю.

Кто-нибудь знает способ сделать это?

Ответы [ 5 ]

12 голосов
/ 08 августа 2012

попробуйте это:

WebDriverWait wait = new WebDriverWait(driver , 1000) ;
wait.until(ExcepctedConditions.elementToBeClickable(ById("element"));

Элемент может быть идентификатором любого элемента, присутствующего на следующей странице, на которую вы перенаправлены. Как только страница загрузится полностью, она начнет выполнять ваш код.

5 голосов
/ 08 марта 2012

Вместо Click вы можете попробовать использовать SendKeys. В отличие от Click, SendKeys не ожидает загрузки страницы до возобновления выполнения кода. Таким образом, вы можете сделать что-то вроде этого:

WebDriverWait wait = new WebDriverWait(browser, new TimeSpan(0, 5, 0));

elem.SendKeys(Keys.Enter);    
wait.Until<bool>((_driver) =>
{         
     //Check here if results have loaded yet
     return true;
});

В качестве примечания, я почти уверен, что Until принимает IWebBrowser в качестве ввода, а не элемент, поэтому вы не можете нажать elem.

5 голосов
/ 09 марта 2012

В дополнение к решению prestomanifesto я могу предложить не идеальное решение, которое я реализовал для решения этой проблемы.Оказывается, это вызывает исключение - Нет ответа и т. Д. - поэтому я просто окружил его попыткой, а затем дождался закрытия всплывающего окна, которое, кажется, работает нормально.хочу в вашем цикле, просто убедитесь, что счетчик, чтобы он не зацикливался вечно.

try
{
    element.Click();
}
catch
{
    cnt++;
    do
    {
      //wait for whatever
      cnt++;
      Thread.Sleep(1000);
      // Wait for 30 seconds for popup to close
    } while (!string.IsNullOrEmpty(browser.CurrentWindowHandle) && cnt < 30);
}
0 голосов
/ 11 февраля 2016

Метод расширения RepeatUntil с использованием лямбда-выражений LINQ

Скопируйте этот код в свой проект:

public static class SeleniumExtensionMethods
    {
        public static IWebElement RepeatUntil<T>(this T obj, 
             Func<T, IEnumerable<IWebElement>> func, 
                Func<IWebElement, bool> compare,
                  int MaxRetry = 20)
        {
            //call function to get elements
            var eles = func(obj);
            IWebElement element = null;
            while (element == null && MaxRetry > 0)
            {
                MaxRetry-=1;
                //call the iterator
                element = IterateCollection(compare, eles);
                if (element == null)
                {
                    Thread.Sleep(500);
                    //get new collection of elements
                    eles = func(obj);
                }
            };

            return element;
        }

        private static IWebElement IterateCollection(
           Func<IWebElement, bool> compare, 
           IEnumerable<IWebElement> eles){
            IWebElement element = null;
            eles.ToList().ForEach(
                ele =>
                {
                    //call the comparator
                    var found = compare(ele);
                    if (found) element = ele;
                });
            return element;
        }
    }

Вызовите его с использованием следующего синтаксиса:

 // You can change PageObjectType to IWebDriver or IWebElement so that 
 // cb is of any type.
 var element = cb.RepeatUntil<MyPageObjectType>(
    //This is the first function to provide the elements
    p => p.FindElements(By.ClassName("TreeNode")), 
    //This is the comparator
    ele => ele.Text == nodeText && ele.Location.Y>YLocation);

Примечание. В приведенном выше примере мы передаем PageObjectType, но вы можете изменить его на тип IWebDriver или событие IWebElement.Все параметры типа позволяют использовать его как метод расширения для указанного вами типа.

Обратите внимание на гибкость метода расширения в том смысле, что вызывающая сторона может определять сбор, а также компаратор.

0 голосов
/ 08 марта 2012

Я использую этот скрипт:

  private static void waitUntilScriptFoundAndExecute(String script) {
    int tries = 0;
    boolean found = false;
    do {
      tries++;
      try {
        driver.executeScript(script);
        found = true;
      } catch (NoSuchElementException nse) {
        System.out.println("Wait for script NSE (" + tries + ")");
      } catch (WebDriverException wde) {
        System.out.println("Wait for script WDE (" + tries + ")");
      } catch (Exception e) {
        System.out.println("Wait for script E (" + tries + ")");
      }

      // Waiting
      if (!found) {
        System.out.println("Wait for script Not found (" + tries + ")");
        waiting(SCRIPT_WAITING_INTERVAL);
      }
    } while (!found && tries < MAX_SCRIPT_WAIT_TRIES);

    if (!found) {
        System.out.println("Script aborted: " + script);
    }
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...