Saleh Qadan
Saleh Qadan

Reputation: 141

Selenium clicks an element 'successfully', yet, it is not actually clicked

I have a method that clicks on a button, however, when it is run, selenium returns the outcome as clicked successfully, when, in reality, the button is not actually clicked. If I run the test several times, occasionally, it'll be clicked as expected. I have my test framework set as an implicit wait for about 15 seconds, I have set an explicit wait for this element, and still see the same issue. When I do <element>.isDisplayed(), the element is always found. I placed the .click in a while loop to click it a few times which works most of the time, however, still sometimes the test fails. Is it possible to have an if statement to check if an element is actually displayed before clicking the button?

I've tried:

if(!element.isDisplayed){
    element.click
}

Here is the button I am having issues with:

<button class="notkoButton listNew">
<div class="l6e iconAdd">New List</div>
</button>

Here is my method:

public marketing_lists_page navigateToNewListPage() throws Throwable {
    try {
        int x = 0;
        while(x < 5) {
            newListBtn.click();
            x++;
        }
       //newListPageHeader.isDisplayed();
    } catch (NoSuchElementException e){
        logs.errorDetails("Could not navigate to New List Page");
        Assert.fail();
    }
    return this;
}

Upvotes: 12

Views: 34134

Answers (8)

JacksonWong
JacksonWong

Reputation: 303

I've noticed clicks being inconsistent with Selenium as well, this seems to be a known issue to a certain extent:

https://github.com/SeleniumHQ/selenium/issues/4075

In my case there is practically no way for the element to not be ready. I had a wait, but more importantly my test case was filling in a very large form, the button that was to be clicked to initiate a drop-down is very simple and I can see it being loaded close to half a minute before my test interacts with it, yet every so often it would still fail. To the point where I wrote a silly while loop to click every 100 millisecond until the expected dropdown showed up.

This is all guessing but from personal observance and some comments from others in that thread - such as one user mentioning they notice more issues like this when running parallel tests, seem to indicate it is possible for what seems to be a missed event, and perhaps this is due to the lag introduced from it's architecture. Specifically I'm comparing this to how Cypress works with native commands given to the browser directly without the intermediary server.

Upvotes: 0

John Rix
John Rix

Reputation: 6673

I had what looked like a similar problem on the surface of it while using the JavaScript WebDriver - the click() promise resolved successfully, and yet nothing happened.

In my case, it turned out to be related to an invalid image src attribute on the page (unrelated to the button I was clicking). For whatever reason, fixing the image link solved the problem!

I know the OP was using Java rather than JS, but my own searches brought me here, so others using JavaScript will likely come the same way.

Upvotes: 0

Shaz
Shaz

Reputation: 607

I was facing the exact same issue but only after I updated my selenium libraries from 2.45 to 2.48.2. "Click" method call never fails which mean the element is always found by the driver, what I think it fails to do is clicking the right spot may be. My test would run fine on a higher res screen and would sometimes pass (but mostly fail due to click issues) on a lower res screen. I tried many things but in the end what worked for me was ZOOM.

Before running the test I call the following method and the "click" method works as expected on that low res screen now.

public void zoomOut () {
        WebElement html = driver.findElement(By.tagName("html"));
        html.sendKeys(Keys.chord(Keys.CONTROL, Keys.SUBTRACT));
}

Upvotes: 0

e1che
e1che

Reputation: 1251

Selenium suffers from lack of GUI "dynamism". By that i advice you to send a refresh to the page after your click.

Tell me what's up.

Upvotes: 0

marchocolate
marchocolate

Reputation: 53

You say you have tried an explicit wait, but it sounds like what you are asking for can be best accomplished by a fluentWait (which is type of explicit wait):

public WebElement fluentWait(final By locator) {
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
        .withTimeout(30, TimeUnit.SECONDS)
        .pollingEvery(5, TimeUnit.SECONDS)
        .ignoring(NoSuchElementException.class);

WebElement foo = wait.until(new Function<WebDriver, WebElement>() {
    public WebElement apply(WebDriver driver) {
        return driver.findElement(locator);
    }
});

return  foo; };;

Here the WebElement would be the button you are trying to click. The cool thing about FluentWait is that the element itself is returned if it is found. From the documentation:

An implementation of the Wait interface that may have its timeout and polling interval configured on the fly. Each FluentWait instance defines the maximum amount of time to wait for a condition, as well as the frequency with which to check the condition. Furthermore, the user may configure the wait to ignore specific types of exceptions whilst waiting, such as NoSuchElementExceptions when searching for an element on the page.

To use it simply do:

WebElement newListBtn = fluentWait(By.id("button"));

Also try:

Driver.SwitchTo().DefaultContent();

before clicking just in case it is a frame issue.

Upvotes: 0

Prat0567
Prat0567

Reputation: 21

Try scrolling to the element before clicking on it. This mostly happens when you test on chrome. You can use JavaScriptExecutor to scroll.

Something like this:

JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("window.scrollTo(0," + element.getLocation().Y + ")"); 

Upvotes: 2

Shubham Jain
Shubham Jain

Reputation: 17553

Try this, Click using javascript and feel free to change the locate for the element according to your convenience:-

WebElement element= driver.findElement(By.xpath("YOUR XPATH"));

JavascriptExecutor executor = (JavascriptExecutor) driver;
executor.executeScript("arguments[0].click();", element);

Hope it will help you :)

Upvotes: 2

AGill
AGill

Reputation: 778

Seems like the element is not enabled or not clickable initially. And to answer your question, yes there is an explicit wait you can use and wait for the element to be clickable:

WebDriverWait wait = new WebDriverWait(driver, timeOut);
wait.until(ExpectedConditions.elementToBeClickable(locator));

Upvotes: 5

Related Questions