.. index:: FAQ, Help
Here's a selection of the most frequently asked questions by CasperJS newcomers.
.. index:: Node.js
Is CasperJS a node.js library?
No. CasperJS is written on top of PhantomJS, which is a node-independent Qt/WebKit based library. If you try to run your CasperJS script with node, it just won't work out of the box.
Hint
If you want to drive CasperJS from node, try SpookyJS.
.. index:: Bugs, Contributing, error
Before rage-tweeting:
- Read the docs
- Check if an issue has been open about your problem already
- Check you're running the latest stable tag
- Check you're running the latest version of PhantomJS
- Ask on the project mailing list:
- try to post a reproducible, minimal test case
- compare casperjs results with native phantomjs ones
- if the problem also occurs with native phantomjs, ask on phantomjs mailing list
- Eventually, file an issue.
.. index:: Testing
That's because as of 1.1, the casper.test
property is only set to a :doc:`Tester <modules/tester>` instance when using the casperjs test
subcommand.
You may want to read the :doc:`testing documentation <testing>` for more information.
.. index:: Code reuse
Have a look at this gist, it might help.
Also, don't forget that CasperJS supports a CommonJS-compliant module pattern implementation.
Note
CasperJS' implementation of require()
differs a bit from the one provided by PhantomJS, but I personnaly never really encountered any functional difference.
.. index:: Versionning
Releases will follow the SemVer standard; they will be numbered with the follow format:
<major>.<minor>.<patch>[-<identifier>]
And constructed with the following guidelines:
- Breaking backwards compatibility bumps the major
- New additions without breaking backwards compatibility bumps the minor
- Bug fixes and misc changes bump the patch
- Unstable, special and trunk versions will have a proper identifier
.. index:: jQuery
Sure, you can use jQuery, as every single other javascript library on Earth.
A first solution is to inject it into the remote DOM environment by hand using the standard WebPage.injectJs()
method:
casper.page.injectJs('/path/to/jquery.js');
If you need jQuery being available everytime, you can also make it being injected in every received response by setting the clientScripts
option of CasperJS:
var casper = require('casper').create({ clientScripts: ["includes/jquery.min.js"] });
Note
You can't inject scripts using the HTTP protocol, you actually have to use a relative/absolute filesystem path to the script resource.
.. index:: Windows, Python, Ruby
Yes, you can call a CasperJS script directly with the phantomjs
executable, but if you do so, you must set the phantom.casperPath
property to the path where the library root is located on your system:
// casperscript.js phantom.casperPath = '/path/to/casperjs'; phantom.injectJs(phantom.casperPath + '/bin/bootstrap.js'); var casper = require('casper').create(); // ...
You can run such a script like any other standard PhantomJS script:
$ phantomjs casperscript.js
If you're on Windows, this is the way you may manage to get casper working the most easily:
phantom.casperPath = 'C:\\path\\to\\your\\repo\\lib\\casperjs-0.6.X'; phantom.injectJs(phantom.casperPath + '\\bin\\bootstrap.js'); var casper = require('casper').create(); // do stuff
.. index:: HTTP
You can define your own HTTP status
code handlers
by using the httpStatusHandlers
option of the Casper object. You can
also catch other HTTP status codes as well, as demoed below:
var casper = require('casper').create(); casper.on('http.status.404', function(resource) { this.echo('wait, this url is 404: ' + resource.url); }); casper.on('http.status.500', function(resource) { this.echo('woops, 500 error: ' + resource.url); }); casper.start('http://mywebsite/404', function() { this.echo('We suppose this url return an HTTP 404'); }); casper.thenOpen('http://mywebsite/500', function() { this.echo('We suppose this url return an HTTP 500'); }); casper.run(function() { this.echo('Done.').exit(); });
Hint
Check out all the other cool :doc:`events <events-filters>` you may use as well.
.. index:: __utils__, AJAX
The __utils__
object is actually a :ref:`ClientUtils object <clientutils_prototype>` which have been automatically injected into the page DOM and is therefore alway available.
So everytime to perform an :ref:`evaluate() <casper_evaluate>` call, you have this instance available to perform common operation like:
- fetching nodes using CSS3 or XPath selectors,
- retrieving information about element properties (attributes, size, bounds, etc.),
- sending AJAX requests,
- triggering DOM events
Check out the :doc:`whole API <modules/clientutils>`. You even have :ref:`a bookmarklet <bookmarklet>` to play around with this __utils__
instance right within your browser console!
Note
You're not obliged at all to use the __utils__
instance in your scripts. It's just there because it's used by CasperJS internals.
.. index:: Step stack, Asynchronicity
Disclaimer This entry is based on an answer I made on Stack Overflow.
The then()
method basically adds a new navigation step in a stack. A step is a javascript function which can do two different things:
- waiting for the previous step - if any - being executed
- waiting for a requested url and related page to load
Let's take a simple navigation scenario:
var casper = require('casper').create(); casper.start(); casper.then(function step1() { this.echo('this is step one'); }); casper.then(function step2() { this.echo('this is step two'); }); casper.thenOpen('http://google.com/', function step3() { this.echo('this is step 3 (google.com is loaded)'); });
You can print out all the created steps within the stack like this:
require('utils').dump(casper.steps.map(function(step) { return step.toString(); }));
That gives:
$ casperjs test-steps.js [ "function step1() { this.echo('this is step one'); }", "function step2() { this.echo('this is step two'); }", "function _step() { this.open(location, settings); }", "function step3() { this.echo('this is step 3 (google.com is loaded)'); }" ]
Notice the _step()
function which has been added automatically by CasperJS to load the url for us; when the url is loaded, the next step available in the stack — which is step3()
— is then called.
When you have defined your navigation steps, run()
executes them one by one sequentially:
casper.run();
Note
The callback/listener stuff is an implementation of the Promise pattern.
Officially no, but you may want to try.
Don't worry, you're not alone. Javascript is a great language, but it's far more difficult to master than one might expect at first look.
Here are some great resources to get started efficiently with the language:
- Learn and practice Javascript online at Code Academy
- Eloquent Javascript
- JavaScript Enlightenment (PDF)
- last, a great tutorial on Advanced Javascript Techniques by John Resig, the author of jQuery. If you master this one, you're almost done with the language.