'Element is not clickable' error in chrome.

695 views
Skip to first unread message

Subrahmanyam Rentala

unread,
Mar 23, 2015, 6:18:47 AM3/23/15
to geb-...@googlegroups.com
Problem Statement: 'Element in not clickable error' comes while using the click action on any element in Chrome. Refer this site for more details:

How i overcome this issue ?
I used waitFor closure on click actions. This has resolved the issue.

I tried to override the click() method of NonEmptyNavigator Class, but i was unable to do that. 
Is there way that i can override this method in my Framework ?

If not, then i would like to make changes in click method by putting waitFor inside the the click method.
eg: I will replace the following code:

@Override
Navigator click() {
contextElements.first().click()
this
}
with 

@Override
Navigator click() {
getBrowser().waitFor {contextElements.first().click()}
this
}

Please suggest.

~Subrahmanyam





Varun Menon

unread,
Mar 23, 2015, 7:06:02 AM3/23/15
to geb-...@googlegroups.com
Hi Subrahmanyam,

According to the link you shared the main reason behind the failure is element not clickable for the given where you are clicking.
It will be good if you change the locator to exact clickable item on the page as suggested in the link shared by you.

Your solution will have multiple implications in your execution and hence I wont really suggest it to be used:
- Increases the execution time for all the browsers.
- Any failure thrown during click action will be overridden by timeout exception.


In case you still want to go with the implementation  you can do so by implementing your own InnerNavigatorFactory as mentioned below:

And then configuring Geb to use your Navigator Factory by setting the property "innerNavigatorFactory" in GebConfig.groovy as mentioned below.

innerNavigatorFactory = new CustomNavigatorFactory()

- Varun

--
You received this message because you are subscribed to the Google Groups "Geb User Mailing List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to geb-user+u...@googlegroups.com.
To post to this group, send email to geb-...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/geb-user/b681b234-3734-49fb-8bae-d95488bcd254%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Marcin Erdmann

unread,
Mar 23, 2015, 7:59:30 AM3/23/15
to geb-...@googlegroups.com
Both Varun's suggestions are spot on.

Subrahmanyam Rentala

unread,
Mar 23, 2015, 8:07:49 AM3/23/15
to geb-...@googlegroups.com
Hi Varun , 

Thanks. I can try the solution provided by you.
But using waitFors {} should not increase execution time, as the moment it gets the element to be clicked, it will do its action and will come out of the closure.

Also, the solution which was provided in the link to get the exact element locator was already considered, but still the error comes. 
The waitFors {} on click has actually solved the issue in chrome, and there was no increase in the time execution as well.

What we can do is, if we do not want this to effect other browser, we can just use: 

@Override
Navigator click() {
if(driver.toString().contains("chrome")){
getBrowser().waitFor {contextElements.first().click()}
}
else{
    contextElements.first().click() 
}
this
}

The only reason why i am proposing this solution is any body using click actions in chrome will face this issue.
We have drastically reduced our failure count by implementing this solution, with zero side effects.

~Subrahmanyam

Varun Menon

unread,
Mar 24, 2015, 2:25:24 AM3/24/15
to geb-...@googlegroups.com
Hi Subrahmanyam,

In your case there is not much extra time consumed but there is a probability of time consumption. Consider a scenario where the element is displayed after an Ajax call and we need to click on it after it is displayed. In a normal case we will do a "waitFor" element to be displayed and then call a click. If the element is not displayed in your case the code will take twice the actual time. 

Also your implementation will affect every click that you are going to do in your testcases but the said chrome issue may not be with all the elements. You can have a separate method click implemented in your base classes that you can use for such elements. 

Its your call as you know your framework and requirement better.

- Varun

Varun Menon

unread,
Mar 24, 2015, 4:32:33 AM3/24/15
to geb-...@googlegroups.com
Sorry wrong use case about the time taken. My bad. :)

Basically the program will take the default waitFor time to click an element even when the element is not displayed.

- Varun

Jacek Tołkanowicz

unread,
Feb 25, 2017, 4:15:13 PM2/25/17
to Geb User Mailing List
Hi Marcin,
is there possibility that Navigator could have property isClickable() which would mean that elememnt isDisplayed and you can click it? That there is no overlay on top of it.

Marcin Erdmann

unread,
Feb 26, 2017, 8:51:22 AM2/26/17
to geb-...@googlegroups.com
Everything is a possibilty, you know, Jacek. Why do you ask? Why would you need a method like that?

Jacek Tołkanowicz

unread,
Feb 28, 2017, 8:15:57 AM2/28/17
to Geb User Mailing List
Currently when I login to my portal, sometimes I get advertisment which overlays login button. Currently I use this code:
waitFor(){
   loginButton
.click()
}

It works but as I see in Geb source code Wait.waitFor executes click() and catches the exception thrown by Selenium. If we had sth like isClickable or isVisible that we could eliminate clicking and catching Exception from waitFor.
On the other hand Selenium probably check's this clickability/visibility underneath before executing click() so the main gain would come from not throwing (Selenium) and catching exception (Geb).

Milosz Prymula

unread,
Mar 1, 2017, 1:52:02 AM3/1/17
to Geb User Mailing List
You could try moving .click() outside of the waitFor clause, it works well in my project.

Jacek Tołkanowicz

unread,
Mar 1, 2017, 3:05:49 AM3/1/17
to Geb User Mailing List
If I move click outside waitFor I get ''Element in not clickable error'. That's the whole point of puting it in this clause. WaitFor not only checks the clause but also catches the exception, look here:

Marcin Erdmann

unread,
Mar 5, 2017, 1:45:47 PM3/5/17
to Geb User Mailing List
Jacek,

I personally would not depend on there being isClickable() or isVisible() but would have code that checks if an ad is shown when loading the page and dismiss it. On one of my projects we had a problem with a cookie bar overlaying some elements on pages causing flakiness in our tests. We solved it by dismissing the cookie bar in `onLoad()` of our pages:

class CookieBarPage extends Page {

    boolean autoCloseCookieBar = true

    static content = {
        cookieBar(required: false) { $('.cookie-message.is-visible-block ') }
    }

    void onLoad(Page previousPage) {
        if (autoCloseCookieBar && cookieBar) {
            cookieBarCloseButton.click()
        }
        super.onLoad(previousPage)
    }

}

Note that autoCloseCookieBar method can be used to disable closing the bar upon page load when testing the cookie bar itself:

to(new CookieBarPage(autoCloseCookieBar: false))
....


Cheers,
Marcin

To unsubscribe from this group and stop receiving emails from it, send an email to geb-user+unsubscribe@googlegroups.com.

To post to this group, send email to geb-...@googlegroups.com.

Jacek Tołkanowicz

unread,
Mar 9, 2017, 9:38:10 AM3/9/17
to Geb User Mailing List
Hi Marcin,
Fair point. I also tried doing this, but this overlay (advertisement), I couldn't deactivate it in 'deterministic way'. I can try doing it once more.
Anyway waitFor works for me for now.
Thanks for this suggestion
Reply all
Reply to author
Forward
0 new messages