0

I have a custom wait method defined as:

public IWebElement WaitForElementClickable(IWebDriver _driver, By elementName)
{
    var wait = new WebDriverWait(_driver, TimeSpan.FromSeconds(20));
    return wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementToBeClickable(elementName))    

}

I have one place where I click on a button and a new page loads, it sticks on "loading" for a few seconds (2-3 secs) and then I want to click on something else once it loads....

        public void enterSearchInfo()
        {

            //Thread.Sleep(2000);
            IWebElement selectElement = utility.WaitForElementClickable(_driver, element);
            selectElement.Click();
        }

Even though I have the wait method set to 20 secs this only works 5 times out of 10, the other 5 times I get the following error...

OpenQA.Selenium.ElementClickInterceptedException: element click intercepted:

When I uncomment Thread.Sleep(2000) it works 10 out of 10 times

Is there a better way to handle this than the wait for element clickable method? I'd rather not be hardcoding sleep waits in my code.

4
  • just use a webdriverwait when getting the element. Right now you're passing it in to a method... you can just use the Expected Condition to return the element. It will check if it exists, is visible and if it is clickable.... before returning the element. Commented Mar 26, 2021 at 16:21
  • @pcalkins That's basically what he's doing already in WaitForElementClickable() it just clicks the element instead of passing it back. Commented Mar 26, 2021 at 16:26
  • ah missed that it was a "By" there... that exception will tell you what element is retrieving the click. (it's probably on top of the element you are trying to click...) Include that part of the exception in your post. Commented Mar 26, 2021 at 16:32
  • @pcalkins Yeah the ElementClickInterceptedException message usually contains the HTML of the element that it receiving the click... it's just not posted in the question for some reason. Not sure if that means that it wasn't in the message or was left out. Commented Mar 26, 2021 at 16:38

1 Answer 1

2

This is what I use in a framework I've created. It eats ElementClickInterceptedException and StaleElementReferenceException and keeps trying until the timeout or success. It got rid of a lot of issues like what you are talking about. There are other ways to do it specific to each page but I found that this works really well in a large number of scenarios.

/// <summary>
/// Clicks on an element
/// </summary>
/// <param name="locator">The locator used to find the element.</param>
/// <param name="timeOut">[Optional] How long to wait for the element (in seconds). The default timeOut is 10s.</param>
public void Click(By locator, int timeOut = 10)
{
    DateTime now = DateTime.Now;
    while (DateTime.Now < now.AddSeconds(timeOut))
    {
        try
        {
            new WebDriverWait(Driver, TimeSpan.FromSeconds(timeOut)).Until(ExpectedConditions.ElementToBeClickable(locator)).Click();

            return;
        }

        catch (ElementClickInterceptedException)
        {
            // do nothing, loop again
        }
        catch (StaleElementReferenceException)
        {
            // do nothing, loop again
        }
    }

    throw new Exception($"Unable to click element <{locator}> within {timeOut}s.");
}
Sign up to request clarification or add additional context in comments.

4 Comments

Elegant solution for cases where the DOM is still being populated causing overlapping elements.
@JeffC. The only issue with this is ExpectedConditions throws the "obsolete/decremented" warning. I was trying to avoid that which is why I went the SeleniumExtras.WaitHelpers route. Are you worried about that being obsolete someday? Or is it just one of those warnings that will never really amount to anything
EDIT: Doesn't really matter, this could easily be switched to the other syntax. Thanks again
I think at some point it will eventually be deprecated. I switched over to SeleniumExtras a while ago but the code is still the same, the usings are different as you noted.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.