C# Selenium 'ExpectedConditions is obsolete'

C#SeleniumWebdriver

C# Problem Overview


When trying to explicitly wait for an element to become visible using ExpectedConditions, Visual Studio warns me that it is now obsolete and will be removed from Selenium soon.

What is the current/new method to achieve the same result?

var wait = new WebDriverWait(driver, new TimeSpan(0, 0, 30));
var element = wait.Until(ExpectedConditions.ElementIsVisible(By.Id("content-section")));

C# Solutions


Solution 1 - C#

How to resolve this with the latest version of Selenium.

Using NuGet, search for DotNetSeleniumExtras.WaitHelpers, and import that namespace into your class. Now you can do this:

var wait = new WebDriverWait(driver, new TimeSpan(0, 0, 30));
var element = wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementIsVisible(By.Id("content-section")));

And the warning in the IDE will be gone.

Solution 2 - C#

If you don't want to download an extra NuGet package, it is quite easy to declare your own function (or condition), especially using a lambda expression, e.g.

var wait = new WebDriverWait(driver, new TimeSpan(0, 0, 30));
var element = wait.Until(condition =>
{
    try
    {
        var elementToBeDisplayed = driver.FindElement(By.Id("content-section"));
        return elementToBeDisplayed.Displayed;
    }
    catch (StaleElementReferenceException)
    {
        return false;
    }
    catch (NoSuchElementException)
    {
        return false;
    }
});

This is also very versatile, since it is now possible to evaluate any kind of Boolean expression.

Solution 3 - C#

The answers to change to an anonymous function is the most correct one. Or write your own class of your own, needed, wait conditions.

An example of using an anonymous function for the explicit scenario above would be something like:

var wait = new WebDriverWait(driver, new TimeSpan(0, 0, 30));
wait.IgnoreExceptionTypes(typeof(NoSuchElementException), typeof(ElementNotVisibleException));
var element = wait.Until(() =>
{
    var e = Driver.FindElement(By.Id("content-section"));
    if(e.Displayed)
        return e;
});

And at that point, the function itself could be off on its own in some class in your solution that you can call. The nice thing with this is that you can modify as needed; I have seen several cases where really poorly made websites end up breaking how the ExpectedConditions work, and that was solved with the team writing our own function.

As per the C# contributor:

> With respect to ExpectedConditions, again, this was an addition that > was created in .NET solely because "Java has it." At the time the > ExpectedConditions class in Java was created, the syntax for creating > a lambda function (or something that acted like one) was particularly > arcane and difficult to understand. In that case, a helper class made > lots of sense for the Java bindings. However, C# isn't Java. In C#, > the syntax for creating lambda functions ("anonymous methods" in the > language of Microsoft's documentation) has been well understood by C# > developers for many years, and is a standard tool in their arsenal. > > In this case, the question of code verbosity does have some merit, but > since wait conditions are rarely one-size-fits-all, it would be a much > cleaner approach for users to develop their own conditions class that > has the wait conditions they're interested in. This, however, is > something users have an aversion to. Additionally, the thought of a > 'standard' collection of implementations of specific wait conditions > seems to be a good idea on its face, but there is a great deal of > variation on the way users want any given condition to work. Having a > collection of wait conditions might be a good thing, but the Selenium > project is not the place for it.

Rantings of a Selenium Contributor

Solution 4 - C#

It's very simple. Just change Wait.Until(ExpectedConditions.ElementIsVisible(By.Id("content-section")));

to

Wait.Until(c => c.FindElement(By.Id("content-section")));

Solution 5 - C#

Based on Rob F.'s answer, I added extension methods to my project. (Actually I added two, WaitUntilVisible(...) and WaitUntilClickable(...).)

These return the element, instead of a bool, so it is more like the Wait.Until(ExpectedConditions...)

// use: element = driver.WaitUntilVisible(By.XPath("//input[@value='Save']"));
public static IWebElement WaitUntilVisible(
    this IWebDriver driver,
    By itemSpecifier,
    int secondsTimeout = 10)
{
    var wait = new WebDriverWait(driver, new TimeSpan(0, 0, secondsTimeout));
    var element = wait.Until<IWebElement>(driver =>
    {
        try
        {
            var elementToBeDisplayed = driver.FindElement(itemSpecifier);
            if(elementToBeDisplayed.Displayed)
            {
                return elementToBeDisplayed;
            }
            return null;
        }
        catch (StaleElementReferenceException)
        {
            return null;
        }
        catch (NoSuchElementException)
        {
            return null;
        }
    });
    return element;
}

Solution 6 - C#

NuGet is required - DotNetSeleniumExtras.WaitHelpers

WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementToBeClickable(By.XPath("")));

I just demonstrated the element clickable event. Similarly, other events can be used with the required parameters.

Solution 7 - C#

The following C# code works for me:

new WebDriverWait(webDriver, TimeSpan.FromSeconds(10)).Until(c => c.FindElement(By.Id("name")));

Solution 8 - C#

Check which version of the Selenium.Support and Selenium.WebDriver NuGet package you have installed.

I got the same issue now with the latest version, 3.11.2. I downgraded to 3.10.0 and it fixed the problem.

Solution 9 - C#

You can use the NuGet package Gravity.Core - it is maintained by Gravity API community and it contains A LOT more than just the ExpectedConditions class.

How to use

  1. Download the NuGet using NuGet package manager.
  2. Add using OpenQA.Selenium.Extensions

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJohnWickView Question on Stackoverflow
Solution 1 - C#JohnWickView Answer on Stackoverflow
Solution 2 - C#Rob F.View Answer on Stackoverflow
Solution 3 - C#PandaMagnusView Answer on Stackoverflow
Solution 4 - C#Everton RochaView Answer on Stackoverflow
Solution 5 - C#Jamie FView Answer on Stackoverflow
Solution 6 - C#Krunal PatelView Answer on Stackoverflow
Solution 7 - C#Leo BarbasView Answer on Stackoverflow
Solution 8 - C#martin pbView Answer on Stackoverflow
Solution 9 - C#Gravity APIView Answer on Stackoverflow