Dana Yeger Dana Yeger - 3 months ago 62
C# Question

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'

Answer

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