Headless Browser Testing: Dart, DumpRenderTree, drone.io
A lot of great testing can be done of algorithms, data models, and business logic without booting up Chrome.
Node.js enabled this with Javascript. Dart has had an out-of-browser--read console--story since day one.
But some things you must test in a browser.
The Dart Bag of Tricks (BOT) has had browser tests since the beginning. There are only a few tests that must be run in the browser, but I make sure to run all tests both on the console and in the browser if they can run both places.
Browser tests are great, but they don't fit well into a build workflow or a continuous integration tool.
For that you need a way to run and control a browser (or a browser-like thing) via the console and get results out. Enter DumpRenderTree.
DumpRenderTree - Chrome without the chrome
DumpRenderTree (DRT) is a great little tool hidden in the guts of WebKit.
By default, DRT prints out an obscure text format representing the hierarchy of elements on the provided page.
By default, DRT prints out an obscure text format representing the hierarchy of elements on the provided page.
Here's the output for
DumpRenderTree example/fract/fract_demo.html
Content-Type: text/plain
layer at (0,0) size 808x820
RenderView at (0,0) size 800x600
layer at (0,0) size 800x820
RenderBlock {HTML} at (0,0) size 800x820
RenderBody {BODY} at (8,8) size 784x804
RenderHTMLCanvas {CANVAS} at (0,0) size 800x800 [bgcolor=#808080]
RenderText {#text} at (0,0) size 0x0
#EOF
#EOF
DRT is controlled mostly through Javascript in the test page by via
window.testRunner
.Here's the script block that lives in
test/harness_browser.html
:<script>
// only run if testRunner is defined -- we're in DRT
if (window.testRunner) {
// Don't dump the structure. Just the text of the output plus console output
testRunner.dumpAsText();
// Don't finish when layout is done. Instead, wait to be notified
testRunner.waitUntilDone();
// listen for messages from the test harness
window.addEventListener("message", receiveMessage, false);
// listen for unhandled exceptions
window.addEventListener('error', onError);
}
// if there is an unhandled exception, tell DRT we're done
function onError(event) {
testRunner.notifyDone();
}
// if the test harness sends a done message, tell DRT we're done
function receiveMessage(event) {
if(event.data == 'unittest-suite-done') {
testRunner.notifyDone();
}
}
</script>
And since everything is keyed off the existence of
window.testRunner
, none of this affects the behavior of tests running normally in a browser.Here's the first few lines of output from
DumpRenderTree test/harness_browser.html
:Content-Type: text/plain
PASS
All 109 tests passed
Collapse All
bot
(4/4)
bot - Enumerable
(19/19)
bot - Enumerable - group
Compare to the content running the tests in the browser:
Getting DumpRenderTree
DRT is part of Linux and Windows builds of the Dart Editor now (look in the chromium) directory. It will be part of builds for Mac soon.
If you want to get DRT that is compatible with the latest integration build of Dart - 0.3.2.0 (r17657) - grab this guy.
Just make sure the DumpRenderTree executable is on your path when running tests.
Bringing it all together
The trick is creating a script that returns an exit code of zero for success and not zero (1 is pretty standard) for failure.
Check out the script I created for BOT.
And let me know how it goes for you.
Happy hacking.