Monday, March 10, 2008

Selenium IDE Internals

When porting the original flowcontrol plugin for using goto and while loops in Selenium IDE (original Sideflow post) I found the following techniques useful for digging into the internals of Selenium IDE.

using getEval / storeEval

The functionality Selenium provides is great, but at times you may need to do something beyond the ordinary. One of the most useful commands in Selenium IDE for this is getEval. Get eval executes an arbitrary string of JavaScript code. If you've upgraded to the new Selenium IDE 1.0 Beta 1 you can also use the new "runScript" command.

getEval with alert

Most people will have tried this, I'm sure. Some say this is bad form, but I use this sort of thing all the time and it's usually the fastest way to get what I need for debugging.

|getEval | alert("simple is always better"); |
|getEval | alert("first command = "+testCase.commands[0].command); |
You'll want to remove these kinds of alerts once your test case is ready for production.

Selenium Internals

Selenium's greatest fault may be its poor documentation. Technical documentation is basically non-existent. These "can-opener" scripts can show you what's under Selenium's hood. They also show you how to open up a window and write stuff to it, an alternative to plumbing the depths of Selenium's inscrutable logging internals.

This will crack the Selenium object open for you:
|getEval| var result = "<h2>Selenium.prototype</h2><ul>"; for (var i in Selenium.prototype) { result += "<li>this." + i + " = " + Selenium.prototype[i] + " <br>";} result+="</ul>"; var debugWin ="about:blank", "debugWin");; debugWin.document.write(result); debugWin.document.close();

Here's the browserbot object:
var result = "<h2>this.browserbot</h2><ul>"; for (var i in this.browserbot) { result += "<li>this." + i + " = " + this.browserbot[i] + " <br>";} result+="</ul>";var debugWin ="about:blank", "debugWin");; debugWin.document.write(result); debugWin.document.close();

Try it with TestLoop.prototype, currentTest, testCase, and, of course, 'this'.

Looking at Constructors

Another handy trick is to check an object's constructor. It can be used sort of like a typeOf.
|getEval| alert(currentTest.currentCommand.constructor.toString());

How all these pieces fit together, and hacking new and nifty things out of them is left as an exercise for the reader (you).

Note: According to Matt Raible's blog post on the Selenium User's Meet-up, the next release of Selenium is going to feature some major changes including the merging of Google's webdriver code. So a lot of this is likely to change.


M said...

Im going to leave a link to this article from my linkedin group "selenium user group".

thanks for posting.


Darren DeRidder said...

Thanks for reading Mike.

Bayar said...

Hi Darren,
thank you for very helpful posts.
How to call command line external tool from selenium ide.
For example i want to run dir in command prompt and get stdout result in text.
I tried to use runScript using

javascript{ var exec = document.require('child_process').exec; exec('dir', function callback(error, stdout, stderr){alert(stdout); });}

but it raises error: TypeError: document.require is not a function.

Thank you.