Headless Browser Testing with Selenium2 and PhantomJS
Published on May 13, 2013
This is a guest blogpost by Jon Phipps. Jon explains how to use PhantomJS – the most anticipated testing backend in Codeception.
The Selenium2 driver actually loads and runs an active browser session, manipulating the browser just as a human would. ZombieJS is a ‘headless’ browser that provides all of the features of a regular browser, but without a display interface. Without the extra time spent waiting for the display to actually render, a headless browser like ZombieJS can run far faster than a normal browser, so you’re tests will execute in as little as half the time. But ZombieJS requires installing Node.js and can be a little buggy, plus it has its own API (which has both pros and cons). The Selenium2 driver is well tested and implements a standard API – the WebDriver Wire Protocol – across all of the browsers it has drivers for.
Now there’s a headless browser that includes a WebDriver Wire Protocol implementation – PhantomJS. The latest version of PhantomJS is an easy to install, stand-alone binary that doesn’t require installing Node.js or any other dependencies, and ships with its own ‘Ghost Driver’ for implementing the WebDriver Wire Protocol. Which means you can drive it using the Selenium2 driver in Codeception, and anything that you can test in Chrome, Firefox, Safari, or IE using Selenium2, you can now test in half the time using PhantomJS
Even though it’s not needed to run the most recent PhantomJS, it’s a good idea to have Selenium2 installed so you can test in other browsers. If you haven’t installed Selenium2, you just need to follow the instructions on the Codeception web site for installing and running the Selenium2 driver. It’s pretty simple, but totally optional.
To get started with PhantomJS, just download PhantomJS. The binary is setup and ready to use for Linux, Mac OSX, and Windows. Put it, or a symlink to it, somewhere in your path so you can launch it from anywhere.
You’re done with installation!
Next, open up a new terminal window and launch PhantomJS, telling it to use the its built-in WebDriver extension to use the port Codeception is listening to (4444 is the default), and leave the window open:
You should see a response like this in your terminal:
Now just enable the Selenium2 driver in your
acceptance.suite.yml file and use the browser setting
browser: phantomjs (an example file is on the Selenium2 driver page). If you’re changing modules then you should also run
php codecept.phar build.
Check it out by doing a fresh Codeception run:
Your tests should now run quietly and silently, and much faster.
You should see some output in your PhantomJS terminal window providing some useful feedback on this session’s capabilities provisioning. This happens on every run (the output below are the defaults):
You can adjust these capabilities in your
acceptance.suite.yml file like so:
I have no idea if capabilities from the larger list of Selenium DesiredCapabilities that are not on the list you see reported from the driver are enabled for PhantomJS.
Headless testing can be a bit of a challenge, since it’s impossible to ‘see’ what failed. But in this case, Codeceptions default logging and screenshot capture on failure can be extremely helpful, since you can then actually see the state of the browser at the point of failure.
There’s quite a bit more that you can do with PhantomJS. The CasperJS project makes good use of the PhantomJS API and if you already have NodeJS installed it’s a quick and easy way to play with some of the PhantomJS capabilities. CapserJS, aside from requiring NodeJS, only drives PhantomJS. So its not a reasonable alternative to Codeception. Maybe at some point there will be a native Mink driver for the PhantomJS API which will more fully exploit it.