Selenium c # Webdriver: дождитесь появления элемента - PullRequest
165 голосов
/ 09 августа 2011

Я хочу убедиться, что элемент присутствует, прежде чем веб-драйвер начнет делать вещи.

Я пытаюсь заставить что-то вроде этого работать:

WebDriverWait wait = new WebDriverWait(driver, new TimeSpan(0,0,5));
wait.Until(By.Id("login"));

Я в основном изо всех сил пытаюсь настроить любую функцию ..

Ответы [ 23 ]

2 голосов
/ 17 августа 2017

Попробуйте этот код:

 New WebDriverWait(driver, TimeSpan.FromSeconds(10)).Until(Function(d) d.FindElement(By.Id("controlName")).Displayed)
1 голос
/ 14 сентября 2018

Поскольку я разделяю определения элементов страницы и сценарии тестирования страницы, используя уже найденный IWebElement для наглядности, это можно сделать так:

public static void WaitForElementToBecomeVisibleWithinTimeout(IWebDriver driver, IWebElement element, int timeout)
{
    new WebDriverWait(driver, TimeSpan.FromSeconds(timeout)).Until(ElementIsVisible(element));
}

private static Func<IWebDriver, bool> ElementIsVisible(IWebElement element)
{
    return driver => {
        try
        {
            return element.Displayed;              
        }
        catch(Exception)
        {
            // If element is null, stale or if it cannot be located
            return false;
        }
    };
}
1 голос
/ 17 февраля 2016

Явное ожидание

public static  WebDriverWait wait = new WebDriverWait(driver, 60);

Пример:

wait.until(ExpectedConditions.visibilityOfElementLocated(UiprofileCre.UiaddChangeUserLink));
1 голос
/ 13 июня 2017

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


WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromMilliseconds(2000));
wait.Until(ExpectedConditions.VisibilityOfAllElementsLocatedBy(By.Name("html-name")));

1 голос
/ 27 апреля 2015
public bool doesWebElementExist(string linkexist)
{
     try
     {
        driver.FindElement(By.XPath(linkexist));
        return true;
     }
     catch (NoSuchElementException e)
     {
        return false;
     }
}
0 голосов
/ 30 мая 2019

WebDriverWait не вступит в силу.

var driver = new FirefoxDriver(
    new FirefoxOptions().PageLoadStrategy = PageLoadStrategy.Eager
);
driver.Navigate().GoToUrl("xxx");
new WebDriverWait(driver, TimeSpan.FromSeconds(60))
    .Until(d => d.FindElement(By.Id("xxx"))); // a tag that close to the end

Это сразу вызовет исключение, когда страница станет "интерактивной". Я не знаю почему, но тайм-аут действует так, как будто его не существует.

Возможно, SeleniumExtras.WaitHelpers работает, но я не пробовал. Это официально, но было разделено на другой пакет nuget. Вы можете сослаться на C # Selenium «Ожидаемые условия устарели» .

Сам пользуюсь FindElements и проверь, действительно ли Count == 0, если true, использовать await Task.Delay. Это действительно не совсем эффективно.

0 голосов
/ 24 мая 2019

Мы можем достичь этого следующим образом:

public static IWebElement WaitForObject(IWebDriver DriverObj, By by, int TimeOut = 30)
{
    try
    {
        WebDriverWait Wait1 = new WebDriverWait(DriverObj, TimeSpan.FromSeconds(TimeOut));
        var WaitS = Wait1.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.PresenceOfAllElementsLocatedBy(by));
        return WaitS[0];
    }
    catch (NoSuchElementException)
    {
        Reports.TestStep("Wait for Element(s) with xPath was failed in current context page.");
        throw;
    }
}
0 голосов
/ 19 марта 2019

This is the reusable function to wait for an element present in DOM using Explicit Wait. Public void WaitForElement(IWebElement element, int timeout = 2){ WebDriverWait wait = new WebDriverWait(webDriver, TimeSpan.FromMinutes(timeout)); wait.IgnoreExceptionTypes(typeof(NoSuchElementException)); wait.IgnoreExceptionTypes(typeof(StaleElementReferenceException)); wait.Until<bool> (driver => { try { return element.Displayed; } catch(Exception) { return false; } }); }

0 голосов
/ 26 февраля 2018

Использовал Rn222 и Aknuds1 для использования ISearchContext, который возвращает либо один элемент, либо список.Можно указать минимальное количество элементов:

public static class SearchContextExtensions
{
    /// <summary>
    ///     Method that finds an element based on the search parameters within a specified timeout.
    /// </summary>
    /// <param name="context">The context where this is searched. Required for extension methods</param>
    /// <param name="by">The search parameters that are used to identify the element</param>
    /// <param name="timeOutInSeconds">The time that the tool should wait before throwing an exception</param>
    /// <returns> The first element found that matches the condition specified</returns>
    public static IWebElement FindElement(this ISearchContext context, By by, uint timeOutInSeconds)
    {
        if (timeOutInSeconds > 0)
        {
            var wait = new DefaultWait<ISearchContext>(context);
            wait.Timeout = TimeSpan.FromSeconds(timeOutInSeconds);
            return wait.Until<IWebElement>(ctx => ctx.FindElement(by));
        }
        return context.FindElement(by);
    }
    /// <summary>
    ///     Method that finds a list of elements based on the search parameters within a specified timeout.
    /// </summary>
    /// <param name="context">The context where this is searched. Required for extension methods</param>
    /// <param name="by">The search parameters that are used to identify the element</param>
    /// <param name="timeoutInSeconds">The time that the tool should wait before throwing an exception</param>
    /// <returns>A list of all the web elements that match the condition specified</returns>
    public static IReadOnlyCollection<IWebElement> FindElements(this ISearchContext context, By by, uint timeoutInSeconds)
    {

        if (timeoutInSeconds > 0)
        {
            var wait = new DefaultWait<ISearchContext>(context);
            wait.Timeout = TimeSpan.FromSeconds(timeoutInSeconds);
            return wait.Until<IReadOnlyCollection<IWebElement>>(ctx => ctx.FindElements(by));
        }
        return context.FindElements(by);
    }
    /// <summary>
    ///     Method that finds a list of elements with the minimum amount specified based on the search parameters within a specified timeout.<br/>
    /// </summary>
    /// <param name="context">The context where this is searched. Required for extension methods</param>
    /// <param name="by">The search parameters that are used to identify the element</param>
    /// <param name="timeoutInSeconds">The time that the tool should wait before throwing an exception</param>
    /// <param name="minNumberOfElements">
    ///     The minimum number of elements that should meet the criteria before returning the list <para/>
    ///     If this number is not met, an exception will be thrown and no elements will be returned
    ///     even if some did meet the criteria
    /// </param>
    /// <returns>A list of all the web elements that match the condition specified</returns>
    public static IReadOnlyCollection<IWebElement> FindElements(this ISearchContext context, By by, uint timeoutInSeconds, int minNumberOfElements)
    {
        var wait = new DefaultWait<ISearchContext>(context);
        if (timeoutInSeconds > 0)
        {
            wait.Timeout = TimeSpan.FromSeconds(timeoutInSeconds);
        }

        // Wait until the current context found the minimum number of elements. If not found after timeout, an exception is thrown
        wait.Until<bool>(ctx => ctx.FindElements(by).Count >= minNumberOfElements);

        //If the elements were successfuly found, just return the list
        return context.FindElements(by);
    }

}

Пример использования:

var driver = new FirefoxDriver();
driver.Navigate().GoToUrl("http://localhost");
var main = driver.FindElement(By.Id("main"));
// It can be now used to wait when using elements to search
var btn = main.FindElement(By.Id("button"),10);
btn.Click();
//This will wait up to 10 seconds until a button is found
var button = driver.FindElement(By.TagName("button"),10)
//This will wait up to 10 seconds until a button is found, and return all the buttons found
var buttonList = driver.FindElements(By.TagName("button"),10)
//This will wait for 10 seconds until we find at least 5 buttons
var buttonsMin= driver.FindElements(By.TagName("button"), 10, 5);
driver.Close();
0 голосов
/ 08 октября 2016

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

Если выполучите ту же проблему

restart you visual studio и убедитесь, что all the exceptions are handled правильно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...