extending.rst 3.74 KB

.. _extending:

.. index:: extending, inheritance, prototype

=========
Extending
=========

Sometimes it can be convenient to add your own methods to a ``Casper`` object instance; you can easily do so as illustrated in the example below::

var casper = require('casper').create({
verbose: true,
logLevel: "debug"
});

var links = {
'http://edition.cnn.com/': 0,
'http://www.nytimes.com/': 0,
'http://www.bbc.co.uk/': 0,
'http://www.guardian.co.uk/': 0
};

casper.countLinks = function() {
return this.evaluate(function() {
return __utils__.findAll('a[href]').length;
});
};

casper.renderJSON = function(what) {
return this.echo(JSON.stringify(what, null, ' '));
};

casper.start();

casper.each(Object.keys(links), function(casper, link) {
this.thenOpen(link, function() {
links[link] = this.countLinks();
});
});

casper.run(function() {
this.renderJSON(links).exit();
});

But that's just plain old *monkey-patching* the ``casper`` object, and you may probably want a more OO approach… That's where the ``inherits()`` function from the ``utils`` module and ported from `nodejs `_ comes handy::

var Casper = require('casper').Casper;
var utils = require('utils');
var links = {
'http://edition.cnn.com/': 0,
'http://www.nytimes.com/': 0,
'http://www.bbc.co.uk/': 0,
'http://www.guardian.co.uk/': 0
};

function Fantomas() {
Fantomas.super_.apply(this, arguments);
}

// Let's make our Fantomas class extending the Casper one
// please note that at this point, CHILD CLASS PROTOTYPE WILL BE OVERRIDEN
utils.inherits(Fantomas, Casper);

Fantomas.prototype.countLinks = function() {
return this.evaluate(function() {
return __utils__.findAll('a[href]').length;
});
};

Fantomas.prototype.renderJSON = function(what) {
return this.echo(JSON.stringify(what, null, ' '));
};

var fantomas = new Fantomas({
verbose: true,
logLevel: "debug"
});

fantomas.start();

Object.keys(links).forEach(function(url) {
fantomas.thenOpen(url, function() {
links[url] = this.countLinks();
});
});

fantomas.run(function() {
this.renderJSON(links).exit();
});

.. note::

The use of the ``super_`` child class property which becomes available once its parent has been defined using ``inherits()``; it contains a reference to the parent constructor.

**Don't forget to call ``Casper``'s parent constructor!**

Of course this approach is bit more verbose than the easy *monkey-patching* one, so please ensure you're not just overengineering stuff by subclassing the ``Casper`` class.

.. index:: coffeescript

Using CoffeeScript
~~~~~~~~~~~~~~~~~~

If you're writing your casper scripts using `CoffeeScript `_, extending casper is getting a bit more straightforward:

.. code-block:: coffeescript

links =
'http://edition.cnn.com/': 0
'http://www.nytimes.com/': 0
'http://www.bbc.co.uk/': 0
'http://www.guardian.co.uk/': 0

class Fantomas extends require('casper').Casper
countLinks: ->
@evaluate ->
__utils__.findAll('a').length

renderJSON: (what) ->
@echo JSON.stringify what, null, ' '

fantomas = new Fantomas
loadImages: false
logLevel: "debug"
verbose: true

fantomas.start()

for url of links
do (url) ->
fantomas.thenOpen url, ->
links[url] = @countLinks()

fantomas.run ->
@renderJSON links
@exit()