Dana Yeger
Dana Yeger

Reputation: 645

How to add Expected Condition into generic findElement method

Please see this function:

public static IWebElement WaitAndFindElement(By by, int timeoutInSeconds)
{
    DefaultWait<IWebDriver> wait = new DefaultWait<IWebDriver>(driver);
    wait.Timeout = TimeSpan.FromSeconds(timeoutInSeconds);
    wait.PollingInterval = TimeSpan.FromMilliseconds(10000);
    wait.IgnoreExceptionTypes(typeof(NoSuchElementException));
    return wait.Until<IWebElement>(ExpectedConditions.ElementIsVisible(by));
}

As you can see in this function i am using ElementIsVisible ExpectedConditions but i want to be able to send to this function ExpectedConditions in case i want another one. Any suggestions ?

Update

    public static IWebElement find(By by, Func<ExpectedConditions, bool> condition, int timeOut)
    {
        WebDriverWait webDriverWait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeOut));
        webDriverWait.IgnoreExceptionTypes(typeof(NoSuchElementException));
        IWebElement elem = webDriverWait.Until<IWebElement>(ExpectedConditions.ElementIsVisible(by));
        return elem;
    }

So now its almost done, i sill cannot replace ExpectedConditions.ElementIsVisible with the condition:

Argument 1: cannot convert from 'OpenQA.Selenium.By' to 'OpenQA.Selenium.Support.UI.ExpectedConditions'

Upvotes: 1

Views: 1272

Answers (2)

Saurabh Gaur
Saurabh Gaur

Reputation: 23805

Actually Selenium WebDriver C# bindings ExpectedConditions implementation only has a few methods and their is no way to add multiple ExpectedConditions together.

But you can create a custom wait like you're asking for would look something like as below :

public static IWebElement WaitAndFindElement(By by, int timeoutInSeconds)
{
    WebDriverWait webDriverWait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSeconds));

     return webDriverWait.Until(d => d.FindElement(by).Enabled
      && d.FindElement(by).Displayed);
 }

Edited :- If you want different ExpectedConditions according to you choice, try as below :

public static IWebElement WaitAndFindElement(Func<IWebDriver, IWebElement> expectedCondtions, int timeoutInSeconds)
{
    WebDriverWait webDriverWait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSeconds));

     return webDriverWait.Until(expectedCondtions);
 }


//Now you can call above function as
IWebElement el = WaitAndFindElement(ExpectedConditions.ElementExists(by), timeoutInSeconds);

Or

IWebElement el = WaitAndFindElement(ExpectedConditions.elementToBeClickable(by),  timeoutInSeconds);

Upvotes: 1

Grasshopper
Grasshopper

Reputation: 9058

In java i wld try something like this. No idea about C# though

private <T> void webwait(int timeOut, int retry, ExpectedCondition<T> expCond)   {
    new WebDriverWait(driver, timeOut, retry).until(expCond);
}

to use it

webwait(2, 100, ExpectedConditions.visibilityOfElementLocated(
            By.id("divid")));

I have a void return, in your case you can return the element. Then you can remove the genric T and put in ExpectedCondition parameter.

Upvotes: 0

Related Questions