Object visible but not clickable


#1

Hi,

I would like to get some help.
In my testcase there are two steps for the same testobject.
Wait for element clickable and Click.
The first one passed but the second one failed.

The message is:

Test Cases/PIM/Menu catalogus FAILED because (of) Unable to click on object ‘Object Repository/PIM/2.Menu_onderdelen/Page_SRC-PIM Regressie (1)/span_Catalogus’ (Root cause: org.openqa.selenium.WebDriverException: unknown error: Element is not clickable at point (214, 12). Other element would receive the click:

(Session info: chrome=65.0.3325.181)

(Driver info: chromedriver=2.35.528161 (5b82f2d2aae0ca24b877009200ced9065a772e73),platform=Windows NT 10.0.16299 x86_64) (WARNING: The server did not provide any stacktrace information).

Why is that? I expect because the first one passes, it can proceed with the click action.


#2

Why is that? I expect because the first one passes, it can proceed with the click action.

Hi. I agree. I wish I knew what WebDriver does to “prove” something is clickable and then moves on to say it’s unable to do what it just claimed it can do.

What it’s saying in the error is, if it were to click the target, something else would receive the click because it’s in the way.

I suppose in a dynamic application that something could have changed on the page between the time when it made the first claim and the time when it tried to perform the click. However, I know my AUT intimately, and as a result, I know when WebDriver is talking crap. And in these situations (in my code base at least) it’s pretty much always talking crap. Hence I dispensed with asking it to perform those kinds operations since it is unable to perform them in a rigorous and reliable manner and used my own methods (using JavaScript and jQuery) to determine visibility and availability. Maybe you want to do the same.

If I had to take a guess (and that’s all this is – a guess) I’d say that WebDriver, communicating with the browser, not the page, is failing to build a coherent model of the complete rendering context of the page – and if the stacking context is missing (or otherwise messed up) between the two ends of the conversation, it would lead to the kind of thing you (we) are seeing here.

By leaving WebDriver out of the conversation, I no longer run into these issues – frustration over (for me, anyway).

More on stacking context here: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context and here https://www.w3.org/TR/CSS2/zindex.html

Russ


#3

Hi, Russ.
Are you able to share some of yours JS and jQuery methods? :slight_smile:

Because, this is something that intermittently happens to me, too. And I’m trying to make the tests as reliable as possible. And I’m guessing other people, especially the beginners as myself, have similar problems.


#4

Hi Russ,

Thank you for your answer. You are right the application is build dynamically.
So I guess I have to use a different approach for both checking for the visibility and the click action.

I will try to figure it out.


#5

Hi Mate

Well, I kind of have already… but they’re spread around various responses on the forum. What I’ve been thinking of doing is putting together a post for the tips forum with a generalized version that explains the Groovy class(es) and methods involved. I just need to find the time…


#6

Here you go…

You can add this to a custom Keyword class of your choosing.

  /**
   * Makes multiple attempts to verify element identified by <code>selector</code> is visible.
   * @param selector (String) CSS selector to be checked.
   * @param iFrameSelector (string) optional iframe selector.
   * @return true if item is visible, else false.
   */
  static boolean jQ_waitVisible(String selector, String iFrameSelector = null, int timeoutSeconds) {
    boolean viz = false
    String js = "return \$(arguments[0]).is(':visible');"
    if(iFrameSelector) {
      js = "return \$(arguments[1]).contents().find(arguments[0]).is(':visible');"
    }
    int count = 0;
    while (!viz) {
      count++
      comment('jQ_waitVisible checking visibility: ' + count + ' ' + selector)
      if(count > timeoutSeconds) {
        markFailed('jQ_waitVisible failed for ' + selector + ' (timeout).')
        return false
      }
      viz = (boolean) jsexec(js, Arrays.asList(selector, iFrameSelector))
      if(viz) {
       break
      }
      WebUI.delay(1)
    }
    markPassed('Success: ' + selector + ' is visible!')
    return viz
  }

The jsexec method is simply a wrapper around WebUI.executeJavaScript.

Realize that this code is always under development… looking at it now, I think it should probably throw a StepErrorException instead of trying to be a boolean .


#7

Thanks, Russ!
This is going to be a very useful tool!