Webdriver How to wait until the element is clickable in webdriver C#
There is a block Ui which covers all the elements for a few seconds after the Element have been generated in the browser because of this i facing a problem ,Since element has come into existence the web-driver try to click the element but the click is received by Block UI . I have tried to use the wait Until but i did not help ,Since i can find isClickAble in C# webdriver
var example = _wait.Until<IWebElement>((d) => d.FindElement(By.XPath("Example")));
var example2 = _wait.Until<IWebElement>(ExpectedConditions.ElementIsVisible(By.XPath("Example")));
example.click();
example2.click();
Is there C# equivalent for isClickAble ,Thanks in advance
Well taking a look into the Java source, tells me it is basically doing two things to determine if it's 'clickable':
https://code.google.com/p/selenium/source/browse/java/client/src/org/openqa/selenium/support/ui/ExpectedConditions.java
Firstly, it'll check if it's 'visible' by using the standard ExpectedConditions.visibilityOfElementLocated
, it'll then simply check if the element.isEnabled()
is true
or not.
This can be condensed slightly, this basically means (simplified, in C#):
- Wait until the element is returned from the DOM
- Wait until the element's
.Displayed
property is true (which is essentially whatvisibilityOfElementLocated
is checking for). - Wait until the element's
.Enabled
property is true (which is essentially what theelementToBeClickable
is checking for).
I would implement this like so (adding onto the current set of ExpectedConditions
, but there are multiple ways of doing it:
/// <summary>
/// An expectation for checking whether an element is visible.
/// </summary>
/// <param name="locator">The locator used to find the element.</param>
/// <returns>The <see cref="IWebElement"/> once it is located, visible and clickable.</returns>
public static Func<IWebDriver, IWebElement> ElementIsClickable(By locator)
{
return driver =>
{
var element = driver.FindElement(locator);
return (element != null && element.Displayed && element.Enabled) ? element : null;
};
}
Usable in something like:
var wait = new WebDriverWait(driver, TimeSpan.FromMinutes(1));
var clickableElement = wait.Until(ExpectedConditions.ElementIsClickable(By.Id("id")));
However, you might have a different idea of what clickable might mean, in which case, this solution may not work - but it is a direct translation of what the Java code is doing.
Here's the code I use to check if it's clickable, else go to another URL.
if (logOutLink.Exists() && ExpectedConditions.ElementToBeClickable(logOutLink).Equals(true))
{
logOutLink.Click();
}
else
{
Browser.Goto("/");
}
If you are having an issue such as "Another element would receive the click", a way around this is to use a while loop that waits for that overlay box to go away.
//The below code waits 2 times in order for the problem element to go away.
int attempts = 2;
var elementsWeWantGone = WebDriver.FindElements(By.Id("id"));
while (attempts > 0 && elementsWeWantGone.Count > 0)
{
Thread.Sleep(500);
elementsWeWantGone = WebDriver.FindElements(By.Id("id"));
}