20

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

Anand S
  • 760
  • 5
  • 13
  • 28

4 Answers4

44

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#):

  1. Wait until the element is returned from the DOM
  2. Wait until the element's .Displayed property is true (which is essentially what visibilityOfElementLocated is checking for).
  3. Wait until the element's .Enabled property is true (which is essentially what the elementToBeClickable 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.

Arran
  • 24,648
  • 6
  • 68
  • 78
  • 1
    Thank u The above problem i mentioned was due to the fact there was block ui , I solved it, Your solution helped me solve a different issue once again thank u.Your solution is correct solution and it represents the isClickAble correctly – Anand S Apr 17 '13 at 13:14
  • 12
    This solution will not ensure that element is *Clickable*. Element could be `Displayed` and `Enabled`, however *not Clickable* due to **Other element would receive the click**. – Alex Okrushko May 28 '13 at 18:29
  • 2
    @AlexOkrushko, expand on what you mean, give reproducible scenarios, examples, full errors etc. I would expect that error message to be covered when checking both `.Displayed` & `.Enabled` but it is not a sure thing, there may well be edge cases - therefore I'd kindly ask you to come up with an actual scenario this is not the case. This should then be submitted as an issue to the Selenium dev's. – Arran May 28 '13 at 19:09
  • what all packages i need to include to make wait.Until(ExpectedConditions.ElementIsClickable... work ? – Ranadheer Reddy Oct 30 '14 at 09:27
  • 1
    @AlexOkrushko , Arran is correct. he basically ported this right to c#. The [Java implementation](https://github.com/SeleniumHQ/selenium/blob/master/java/client/src/org/openqa/selenium/support/ui/ExpectedConditions.java#L519) literally checks the same thing. it makes sure it's visible, and enabled. nothing else. – ddavison Mar 18 '15 at 14:25
  • @K.R.R. using OpenQA.Selenium.Support.UI; and Reference to WebDriver.Support – kirsche40 Jul 29 '15 at 11:05
  • If getting problems ExpectedConditions then refer this thread. – N. Raj May 23 '21 at 06:51
2

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("/");
            }
Phil Hudson
  • 3,819
  • 8
  • 35
  • 59
1

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"));
}
tetenal
  • 119
  • 1
  • 5
1

On our slower test runner computers it seemed the input element would be findable first, but still not clickable by the time that the script tried to send keys or a click to the input control. Waiting for "ElementToBeClickable" helped. Faster, more powerful test runner systems did not have this problem nearly as much.

Here is code with a bit of context that seems to have improved things on my C# based Selenium tests. Also using SpecFlow and xUnit. We are using IE11 and IEDriverServer.exe.

As of May 2019, the NuGet package containing this is DotNetSeleniumExtras.WaitHelpers.

The key line is this one:

wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementToBeClickable(By...

Do this for the first input field on a new page, using a selector that points to the first input field you want to interact with. (By.XPath("")

[Given(@"I have selected the link to the OrgPlus application")]
public void GivenIHaveSelectedTheLinkToTheOrgPlusApplication()
{
    _driver.Navigate().GoToUrl("http://orgplus.myorg.org/ope?footer");
}

[Given(@"I have selected the link to the OrgPlus Directory lookup")]
public void GivenIHaveSelectedTheLinkToTheOrgPlusDirectoryLookup()
{
    var wait = new WebDriverWait(_driver, new TimeSpan(0, 0, 30));
    var element = wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementToBeClickable(By.XPath("//*[@id=\"lnkDir\"]")));
    IWebElement btnSearch = _driver.FindElement(By.XPath("//*[@id=\"lnkDir\"]"));
    btnSearch.SendKeys(Keys.Enter);
}
Developer63
  • 640
  • 7
  • 19