1

I am using a fluent wait so I can ignore certain exceptions for a certain time, especially the ElementClickInterceptedException This is how I declare the wait:

private Wait<WebDriver> initiateWebDriverWait(int timeoutSeconds) {
        List allExceptions = new ArrayList();
        allExceptions.add(NoSuchElementException.class);
        allExceptions.add(ElementNotVisibleException.class);
        allExceptions.add(StaleElementReferenceException.class);
        allExceptions.add(ElementClickInterceptedException.class);

        return new FluentWait<>(driver)
                .withTimeout(Duration.ofSeconds(timeoutSeconds))
                .pollingEvery(Duration.ofMillis(100))
                .ignoreAll(allExceptions);
    }

usage:

    public void waitForElementThenClick(WebElement webElement, int timeOutSeconds) {
        waitForElementToBeClickable(webElement, timeOutSeconds);
        webElement.click();
    }


    public void waitForElementToBeClickable(WebElement webElement, int timeoutSeconds) {
        Wait<WebDriver> wait = initiateWebDriverWait(timeoutSeconds);
        wait.until(ExpectedConditions.elementToBeClickable(webElement));
    }

So when I'm using waitForElementThenClick I still get

org.openqa.selenium.ElementClickInterceptedException: element click intercepted: Element ... is not clickable at point (1338, 202). Other element would receive the click:

This is some random overlay that is there for just a smallest fraction of time, and I could add a 100ms wait and whatnot, but my main issue is why am I even seeing this exception, when I specifically said it to ignore it for at least 5 seconds? And it's not waiting these 5 seconds, so this is not a timeout thing.

Any ideas? is the webElement.click(); throwing the exception? if So, why the waitForElementToBeClickable returned true?

Thanks

AciD
  • 113
  • 3
  • 8
  • Excuse me, what do you mean by that? Of course the element I'm trying to click is present in the DOM as even the exception sees it. So I'm not sure what you mean, sorry : ( Why did you close it? These topics don't address my issue. I know why it's intercepted, I don't know why fluent wait is not catching that... – AciD Nov 21 '19 at 14:00
  • Interesting - do you think it just ignores the list? I'll try that. – AciD Nov 21 '19 at 14:19
  • Chaning the list type did not help, so that's not it. Well, so if waitForElementToBeClickable does not REALLY wait for it to be clickable [which is, well... let's say not GREAT] I just have to add that additional wait for the overlay to be gone. – AciD Nov 21 '19 at 14:36

2 Answers2

1

If webdriver says the element is clickable, it's not always mean that element is really clickable. It's can be while the target element is covered by another element. Here is an example. Open https://stackoverflow.com/jobs?so_medium=StackOverflow&so_source=SiteNav . Let's try to check if this element is clickable and click it: enter image description here

But, we hide this element under dropdown like that: enter image description here

There is xpath: By.xpath("//*[text()='Developer jobs']")

So, if we check this element for condition ExpectedConditions.elementToBeClickable, it will return true(like element is clickable). But while you execute element.clickm you will occur an ElementClickInterceptedException.

  • That whhat I thought, but I also tried `public void waitForElementThenClick(WebElement webElement, int timeOutSeconds) { Wait wait = initiateWebDriverWait(timeOutSeconds); wait.until(ExpectedConditions.elementToBeClickable(webElement)).click(); }` Wouldn't THAT catch the exception? – AciD Nov 21 '19 at 14:10
  • You catch the exception by action click. Not in wait. If you know, which element hides your target element, you can initiate both elements, and compare their z-index. – Gennady Zyablitsev Nov 21 '19 at 14:14
  • Wouldn't in this case click be executed by the wait? – AciD Nov 21 '19 at 14:38
  • No. Wait.until() returns instance of WebElement. Action click performs with an instance of WebElement, not with an instance of Wait. – Gennady Zyablitsev Nov 21 '19 at 14:59
  • 1
    Gotcha, thanks! So I guess that's the answer - the 'waitForElementToBeClickable' does not always wait for element to REALLY be clickable... bummer. – AciD Nov 21 '19 at 15:04
1

The exceptions list is considered only while until is waiting for the condition to be true. The click() occurs after that, so there is nothing to catch the ElementClickInterceptedException.

elementToBeClickable checks if the element is visible, which will be true if even part of the element is visible, and if the element is enabled, that will be true unless it has explicit disabled attribute, but Selenium tries to click in the middle of the element which might be covered. To pass this problem you can wait for the overlay to disappear and then wait for the element to be clickable

wait.until(ExpectedConditions.invisibilityOfElementLocated(ovferlayLocator));
waitForElementThenClick();
Guy
  • 46,488
  • 10
  • 44
  • 88