In another thread (Verify Element Attribute Value - #36 by Mate_Mrse), @Mate_Mrse suggested I post a Tip about using JS + DOM to wait for elements to be come visible/invisible. Since responding directly on that thread would have been a significant derailing of the thread’s topic, I did as he suggested and posted my response here.
But I do know JS
Sorry. Couldn’t resist.
You happened to choose the most (IMO) “needless” WebUI API:
Profound statement: waitForElementClickable is essentially pointless
Providing an element is visible it is clickable (visibility itself is an exercise in pedantics and semantics but “we know what we mean”, right?)
Let me say that again, another way…
Testing if an element is clickable when all elements are intrinsically clickable, is pointless. You’re testing the browser’s implementation of HTML and DOM, not your AUT.
If it’s visible and in the viewport, it’s clickable, end of story.
The reason for the pedancy offered by WebDriver is simply that it is trying ensure that they mimic a HUMAN. Hence, your target needs to be on screen, visible, and in the viewport. That is completely worthwhile but can sometimes get in your way. If a human does NOT have an issue at some point in your test, then don’t let WebDriver stand in your way (I expanded on this point here: Send Keys or Set Text - #2 by Russ_Thomas)
I don’t know what Kat does in that clickable API (don’t really care, either). But since the purpose I (and you) have in mind is best dealt with by the removal of another element from the scene which reveals my target element, that, to me, is the better way to go. I’m saying, the clickability of elements is not in question - unless you work for google, or mozilla… see?
Anyway, back to your question:
Then THAT is what it is. Doesn’t matter if you think there’s something else going on under the covers, you have one thing to deal with and its effect(s) on the client. Don’t get bogged down with shit you can’t nail down. Absolutely and fundamentally, when that guy has left the scene, you can proceed. Period.
Profound statement 2: WebDriver is a very faithful but very dumb robot
The most likely cause of your grief is synchronicity. WebDriver is a very faithful but very dumb robot. He does exactly what you tell him, exactly when you tell him. Your task is to make sure you tell him when the time is right.
Yes, I know you know all this, but ask yourself if that’s exactly what you are doing when you bump into an issue like this. I can virtually guarantee the times you have issues, you’re not getting the timing right (for whatever reason).
Okay. Enough theory.
Instead of giving you working code, I’ll give you well-commented pseudo-code. Your (or anyone else’s) situation is unlikely to fit my situation exactly, so pseudo code will help us better.
// Generate a conversation (ajax perhaps) between AUT and Server clickSomething() // Expect a spinner. If network is super-quick, spinner might not be seen // (destroyed even before browser gets chance to show it) // handleSpinner must handle that situation too! handleSpinner()
So now let’s look at
Now, a little more theorizing…
Because we know everything is essentially clickable, we’re not waiting until our target is visible and clickable, we are inferring our target is clickable after ensuring that the thing blocking it is invisible. That’s pragmatic and meaningful. Better still, it’s testable
And if something is testable you can reason about it. When it isn’t, you get this: