Andy Kelk


Headless browser testing with PhantomJS and CasperJS

This is a follow up to yesterday’s post on headless browser testing using Selenium and PhantomJS. It was pointed out in the comments (thanks, shanna!) that by testing directly within PhantomJS and cutting out Selenium the tests would run even faster.

I’ve done a little proof of concept to rewrite my previous C# Selenium tests to run with CasperJS – a scripting and testing utility based on PhantomJS. The nice thing about CasperJS is that it can run tests and provide a simple output or it can export the results in the xUnit XML format (so it can be dropped into Jenkins).

The CasperJS API is well documented and there’s lots of examples of how to achieve common tasks. I will admit to struggling a little with getting an HTML <select> to work properly, but everything else was relatively easy to adapt from the examples given.

var casper = require('casper').create();

casper.start('http://www.iproperty.com.my/', function() {
  this.test.assertExists(
    'select#s_searchBoxState',
    'State dropdown is found'
  );
  this.test.assertExists(
    'select#s_searchBoxState option[value="SE"]',
    'Selangor option is found'
  );
  this.fill(
    'form[name="frmSaleSearchbox"]',
    {'searchBoxState': 'SE'},
    false
  );
  this.click('#s_imgBtnSearch');
});

casper.then(function() {
  this.test.assertTitle(
    'All Residential For Sale In All Cities, Selangor for RM0 to RM999,999,999',
    'Search results title is ok'
  );
});

casper.thenOpen('http://www.iproperty.com.my/useracc/Login.aspx', function(){
  this.test.assertExists('form#frm', 'Login form is found');
  this.fill('form[id="frm"]', {
    txtEmail: '[email protected]',
    txtPassword: 'xxxxx'
  }, true);
});

casper.then(function() {
  this.test.assertTitle('My Account', 'Login title is ok');
  this.test.assertEquals(
    this.evaluate(function() {
      return __utils__.findOne('span.sidebar-text5').innerText}
    ),
    'Andy',
    'Account name is retrieved ok'
  );
});

casper.run(function() {
  this.test.done(6);
  this.test.renderResults(true);
});

It’s about the same number of lines of code as the Selenium version of the same tests. Performance-wise, the two tests run with CasperJS in around 15 seconds compared to 25 to 30 seconds for the Selenium + PhantomJS version so there’s definitely a decent saving in execution time.

For us, JavaScript provides some advantages and disadvantages. On the positive side, almost all developers write some JavaScript and so are familiar with it and it’s a language common to all of our teams (be they PHP or .Net devs); on the downside, JavaScript is not core to anyone’s job and so it will be a mindset shift compared to writing tests in C#.

Cutting execution time for tests from 50+ seconds with Firefox to 15 seconds with CasperJS should provide many benefits to our team and our testing.


5 thoughts on “Headless browser testing with PhantomJS and CasperJS

  1. Thanks for sharing. One question about choosing between CasperJS and Selenium:
    despite the Selenum timing issue you mentioned in your last post, is Selenium a better choice since you can reuse the test for headless unit test (using phantom) and cross browser testing (using firefox driver or similar)?


    • I think it would depend whether you intended to run your entire test suite across both platforms. Using Selenium would absolutely give you the ability to test across multiple browsers which would be a point in favour of doing it with Selenium.


  2. Pingback: Web scraping with CasperJS | Andy Kelk


  3. Pingback: /dev | MEAN 2


  4. Hi Andy,

    we are using PhantonJS ( Selenium+ C#) for headless browser testing. can we download a file using phantomjs? is there any workaround for this.


Leave a Reply to Swapna Cancel reply

Your email address will not be published. Required fields are marked *

*
*


Archives