Table of contents
If you’ve tried to do Selenium testing of a
it’s rather tricky, and Ajax just makes it worse. You’ll be
regularly hit with tests that should work, but don’t seem to, and
you don’t know why.
There are many, many posts about various aspects of these problems,
but I’ve yet to see a coherent guide to the issue as a whole, so I’m
writing this, and we’ll see how it goes.
to get the test to continue to the next step; you can’t get that
dropdown to activate, or whatever.
You’ll know you’ve hit an ajax problem when your test keeps firing
off too early, and you keep putting “sleep” commands in to make the
timing right, except then the server is really overloaded one day
and they all fail and everything explodes.
hook code to; “when X happens to Y, do Z”.
In a modern browser, for example, you can put
into basically any html element:
<p onClick="alert('foo')">blah blah blah</p>
When the user clicks in the element, an alert will pop up. So far,
click, mouseover, focus, mouseup, mousedown, ...
Selenium does basically everything that it does by forcing
behavior inside the browser.
When you just need to click a basic html button, no big deal; simulate a click event.
? Or onMouseDown ? If you just send a click event, neither of those
get activated at all.
So you end up playing hunt-the-event-type.
and which HTML elements they make sense for.
Probably the most useful debugging tool for a Selenium script here is getHTMLSource. At the point in your script where you can’t figure out what HTML element to click or where it is in an xpath sense or what event to use to trigger it, sleep a long time (like 30 seconds), and dump the HTML source to a file. See if you can find your element in there, since that’s what Selenium is actually seeing.
Ajax is a means of loading parts of a page separately from the page
as a whole. The problem is that normal web transactions are based
on the whole page, so you’ll end up thinking everything is reading
when parts of the page are still loading.
This one is actually fairly easy to fix once you’ve gotten used to
it, and consists of two basic steps:
- When doing the initial testing of the tests, put in “sleep” statements wherever necessary
- When the test script is stable, replace all the sleep commands with a waitFor of some kind
For the second part, usually waitForTextPresent or waitForElementPresent will do what you want. All you need to know
is a piece of text or an html element (respectively) that will be on the page after everything is done loading.
Some ajax libraries will say “loaded” or something, you can wait on that.
More generally, you can do something that always works for your ajax library. For some, this will be a waitForCondition
Most ajax libraries have an actual value you can query that will tell you when everything is done, though.
Here’s an excellent post that has per-library reccomendations about
that sort of thing.
This isn’t my solution; I found a blog post about it.
The issue is that jquery autocompletion creates the options live as you type, and it puts them in a totally different part of the HTML file; they’re actually rooted at the body.
The xpaths shown there were not the ones that we saw when we did our HTML dump, which might be a jquery versioning issue. Ours were //body/div...FIXME