Writing Brittle (Yet Useful!) Acceptance Tests for ExtJS Applications Using Selenium’s getEval()
Friday, August 15th, 2008I’m a somewhat enthusiastic fan of Selenium these days. It works consistently well in most situations, and it provides some mechanisms for “going deep” when its more regular API calls prove insufficient.
Recently, I was testing an application we’re writing that has a front-end built using the ExtJS framework. Normally, with a bit of XPath-fu, testing our (neatly!) tangled messmass of Javascript is no big deal, but occasionally, ExtJS produces a div or other element that Selenium just can’t seem to find. I ran into such an element (a div with a handler) that I *really* wanted to have my test click(), but no amount of XPath munging would get the job done. Perhaps Selenium is more strict about what elements are click()able than I thought, but no matter, getEval() to the rescue.
I found a number of interesting blog posts on the subject, with the best being Darren Deridder’s. This got me started on using this.browserbot.getCurrentWindow().Ext in the getEval()… the Ext object provides get() and getCmp(), which are gateways into basically any element in your application.
Of course, the one downside to this is that your effectively shortcutting the entire idea of acceptance testing, as your user-agent is now (but only briefly) doing something that your real end user wouldn’t do. I will only use this sparingly, I promise!
The end result are lines something like this in your testing code (C# here, broken up because our CSS won’t wrap it properly):
DefaultSelenium _selenium = new DefaultSelenium(
"localhost",
4444,
"*iexplore",
"http://localhost");
_selenium.Start();
String evalString = "this.browserbot.getCurrentWindow()."
evalString += "Ext.getCmp('my_component_id').items.get('some_subcomponent_key').doSomething()"
_selenium.GetEval(evalString);
You don’t even have to use the Ext object here… the scope this.browserbot.getCurrentWindow() is your application. The possibilities are endless, but remember the caveat: you’re doing something a real user-agent won’t, so be careful with this in an acceptance-testing scenario.
(Another thing to make the most of this technique is Firebug’s console.dir() function, which you can use while debugging to quickly examine object dumps.)