hhrzc
hhrzc

Reputation: 2050

wait.until(ExpectedConditions.elementToBeClickable) not working

I need to take all elements by By locator from page and determine clickable element from them.

Invisible element

Invisible element

Visible and clickable element

Visible and clickable element


So, I search elements by //a[@class='quick-view'] xpath locator and try to filter them by wait.until(ExpectedConditions.elementToBeClickable):

public List<WebElement> getElementsIfClickable(PageElement element){
    List<WebElement> e = findAll(element);
    //e.get(0).click(); //WebDriverException: unknown error: Element <a href="#" class="quick-view" data-link-action="quickview">...</a> is not clickable at point (534, 840)
    WebDriverWait wait = new WebDriverWait(driver, 2);
    return  e.stream()
            .filter(p -> isClickable(p, wait))
            .collect(Collectors.toList());
}

private boolean isClickable(WebElement element, WebDriverWait wait) {
    try {
        WebElement el = wait.until(ExpectedConditions.elementToBeClickable(element));
        System.out.println(el.isDisplayed()); //DEBUG: always "true"
//el.click();  //no exception
        return el.isDisplayed();
    } catch (Exception e) {
        return false;
    }
}

So, in "DEBUG" line I am always had true, but elemnts is not clickable and not displayed.

I do not need to cleck on each element - I just need to check clickable property.

Question:

How to check element by clickable property

Upvotes: 0

Views: 1970

Answers (3)

Malki Mohamed
Malki Mohamed

Reputation: 1688

With selenium 4 and HtmlUnitDriver this was worked for me:

WebDriverWait wait = new WebDriverWait(driver,Duration.ofSeconds(20));

wait.until(ExpectedConditions.elementToBeClickable(((HtmlUnitDriver) driver).findElementById("btnRechercheAnnByDateTypeJur"))).click();

Upvotes: 0

DMart
DMart

Reputation: 2461

All it means to selenium to be clickable is that it is visible & enabled: https://github.com/SeleniumHQ/selenium/blob/c982edfbd3eed3ffb9666c4f3e9df7c004834c22/java/client/src/org/openqa/selenium/support/ui/ExpectedConditions.java#L632

so all you have to do is check that the webElement isDisplayed() & isEnabled().

    List<WebElement> webElements  = driver.findElements(By.xpath("//a[@class='quick-view']"));
    for (WebElement e :webElements) { 
        if (e.isDisplayed() && e.isEnabled()) {
            System.out.println(e.getAttribute("href"));
        }
    }

Upvotes: 1

Elliott Weeks
Elliott Weeks

Reputation: 83

I'm not sure exactly what you mean by clickable property. As technically everything on the page is a clickable element. For example, you can click text but nothing will happen. Below is the only reason an element will not be clickable is if the disabled attribute is used like so:

<button type="button" disabled>Click Me!</button>

Below are some links is the disabled attribute: Input Disabled Field Disabled

However, in your case, you are referring to an anchor tag which is always clickable but may be disabled by three ways(By disabled I mean when you click it nothing happens):

  1. The "href" attribute is not set
  2. Disabled by css
  3. href set or onclick set to return false:

<a href="javascript:function() { return false; }">link</a>
<a href="/" onclick="return false;">link</a>
If you still want to test if this element is clickable you could use a dirty javascript way like so:

JavascriptExecutor js= (JavascriptExecutor)driver;
String url = driver.getCurrentUrl();
js.executeScript("arguments[0].click();", element);
//may need a wait here
if(url.equalsIgnoreCase(driver.getCurrentUrl())) {
        js.executeScript("window.history.go(-1);");
    }else {
        //element is not clickable
    }

Might not be the best solution but it works :)

Upvotes: 1

Related Questions