CasperJS is no longer actively maintained. Navigation scripting and testing utility for PhantomJS and SlimerJS
Fixed #523 - Make CasperJS installable & usable from npm using:
$ npm install casperjs
Or if you want to install it globally on your system:
$ npm install -g casperjs
Notes:
- Only 1.1 beta versions are installable from npm;
- CasperJS is still not a NodeJS package, it needs either PhantomJS or SlimerJS to run.
Fixed #728 - Prevent overriding of preconfigured casper instance in a test environment
This was a hard decision to make, but too many people just don't read the docs and create new casper instance in a test env, overriding the preconfigured one which creates cumbersome and hard to understand situation.
Hopefully this change will inform users right from the place they read docs the most, fatal error messages.
Fixed #722 - Thrown step, complete and wait errors are no more silenced by default, though a new silentErrors
Casper option is available if you want to reproduce the previous behavior
Fixed #715 - Enhanced element visibility computation method
Fixed #665 - Renamed --direct
cli option to --verbose
; --direct
still works but is to be considered deprecated
Fixed #596 - added a new .NET launcher for Windows environments; just switch to using bin/casperjs.exe
today
Note: The previous
batchbin/casperjs.bat
executable is deprecated and won't be maintained anymore.
Added an --auto-exit=no
test runner option and an exit
tester event to hook on before runner exits (#704):
// $ casperjs test test.js --auto-exit=no
casper.test.on("exit", function() {
console.log("exited");
});
casper.test.begin("sample", function(test) {
test.assert(true);
test.done();
});
Added Casper#scrollTo()
& Casper#scrollToBottom()
scrolling helpers
Added a resource-error
event on resource loading failure (#649)
Added a reset
option to Casper#sendKeys()
Added CSS selector support to Tester#assertField()
Added a details
property bag to waitFor.timeout
events
Added a new improved RPM package build script
withFrame()
now switches back to parent frame instead of main onecheckStep()
turns into an infinite loop when navigationLocked
is true
getPageContent()
throws error when content is not HTML.bind()
polyfillbetterInstanceOf
for Gecko (SlimerJS)testsuite
attribute duration
to time
to avoid errors on JenkinsENGINE_EXECUTABLE
env varFixed version number in package.json
Please consider using 1.1 betas or latest master instead of this version.
require()
preventing to require sub modulesrequire()
nodejs modulescontenteditable
in Casper#sendKeys()
Tester#assertInstanceOf()
imgOptions
parameter to Casper#capture*()
methods1.0 users, an upgrading guide is available here.
PhantomJS 1.8.1 or later is required for 1.1.
CasperJS can now be launched with SlimerJS instead of PhantomJS.
It allows you to execute tests with the rendering engine of Firefox. Just launch CasperJS
with the flag --engine=slimerjs
.
SlimerJS 0.8 or later is required.
require()
in custom modulesCasperJS 1.1 now internally uses PhantomJS' native require()
function, but it has side effect if you write your own casperjs modules; in any casperjs module, you now have to use the new global patchRequire()
function first:
// casperjs module code
var require = patchRequire(require);
// now you can require casperjs builtins
var utils = require('utils');
exports = {
// ...
};
Note: you don't have to use patchRequire()
in a standard casperjs script.
A new Tester.begin()
method has been introduced to help organizing tests better:
function Cow() {
this.mowed = false;
this.moo = function moo() {
this.mowed = true; // mootable state: don't do that
return 'moo!';
};
}
// unit style synchronous test case
casper.test.begin('Cow can moo', 2, function suite(test) {
var cow = new Cow();
test.assertEquals(cow.moo(), 'moo!');
test.assert(cow.mowed);
test.done();
});
// asynchronous test case
casper.test.begin('Casperjs.org is navigable', 2, function suite(test) {
casper.start('http://casperjs.org/', function() {
test.assertTitleMatches(/casperjs/i);
this.clickLabel('Testing');
});
casper.then(function() {
test.assertUrlMatches(/testing\.html$/);
});
casper.run(function() {
test.done();
});
});
Tester#setUp()
and Tester#tearDown()
methods have been also added in order to ease the definition of operations to be performed before and after each test defined using Tester#begin()
:
casper.test.setUp(function() {
console.log('executed before each test');
});
casper.test.tearDown(function() {
console.log('executed after each test');
});
Both can work asynchronously as well of you define the done
argument:
casper.test.setUp(function(done) {
setTimeout(function() {
console.log('asynchronously executed before each test');
done();
}, 1000);
});
casper.test.tearDown(function(done) {
setTimeout(function() {
console.log('asynchronously executed after each test');
done();
}, 1000);
});
Tester#begin()
itself has also local setUp()
and tearDown()
capabilities if you pass it a configuration object instead of a function:
casper.test.begin('range tests', 1, {
setUp: function(test) {
this.range.push(1);
this.range.push(2);
this.range.push(3);
},
tearDown: function(test) {
this.range = [];
},
test: function(test) {
test.assertEquals(this.range.length, 3);
test.done();
}
});
Scraping and testing are now better separated in CasperJS. That involves breaking up BC on some points though:
test
reference if not invoked using the casperjs test
command, therefore the ability to run any test without calling it has been dropped. I know, get over it.casper.done()
has been dropped as well, because done()
may be never called at all when big troubles happen; rather use the new begin()
method and provide the expected number of tests using the second argument:casper.test.begin("Planning 4 tests", 4, function(test) {
[1, 2, 3, 4].forEach(function() {
test.assert(true);
});
test.done();
});
Last, all the casper test suites have been upgraded to use the new testing features, you may want to have a look at the changes.
When using PhantomJS >=1.9.0, you can now abort outgoing requests:
casper.on('page.resource.requested', function(requestData, request) {
if (requestData.url.indexOf('http://adserver.com') === 0) {
request.abort();
}
});
mousedown
and mousedown
events on clickassertField("field", "")
will always pass even though the field
doesn't exist--direct
& --log-level
options available for the casperjs
executableCasper#waitForSelectorTextChange()
methodCasper#bypass
, Casper#thenBypass
, Casper#thenBypassIf
, Casper#thenBypassUnless
methodsTester#skip
methodCasper#eachThen()
keepFocus
option to Casper#sendKeys()
--ssl-protocol
option support to the casperjs
executableCasper#open()
sendKeys
for inputs without text attribute should not be restrictedCasper#fillSelectors()
and Casper#fillXPath()
Casper#getElementsAttribute()
and Casper#getElementsInfo()
Casper#waitForUrl()
Casper#sendKeys()
cli
: Now dropping an arg or an option will be reflected in their raw equivalentcli.get()
now supports fallback valuesThis release is not compatible with PhantomJS >= 1.9. If you want to use later version of PhantomJS, please switch to the master
branch.
wait*
operations (expect average execution time to be divided by 4)utils.cleanUrl()
Casper#getElementAttribute()
broken compatibility with XPath selectorschild_process
modulechild_process
phantomjs modulewait*
methods executionCasper.waitForText()
click()
input
event after setting input value (required to support angular.js apps)injector
module has been removed from the codebase (RIP dude)1.0
maintenance branch has been createdmaster
branchpage.initialized
event didn't get the initialized WebPage
instanceCasper.options.onPageInitialized()
from being called--fail-fast
option creating an endless loop on errorTester.renderFailureDetails()
which couldn't print failure details correctly in certain circumstancesCasper.getHTML()
wasn't retrieving active frame contents when using Casper.withFrame()
page.confirm
always returns trueCasper.withFrame()
thenEvaluate()
should be updated to take the same parameters as evaluate()
, while maintaining backwards compatibility.Casper.userAgent()
does not require the instance to be started anymorecasperjs
command call is detectedI'm still expecting a 1.0 stable for Christmas. Feedback: bring it on.
A minimal convenient API has been added to Casper in order to ease the switch of current page context:
casper.start('tests/site/frames.html', function() {
this.test.assertTitle('CasperJS frameset');
});
casper.withFrame('frame1', function() {
this.test.assertTitle('CasperJS frame 1');
});
casper.then(function() {
this.test.assertTitle('CasperJS frameset');
});
Native mouse events didn't play well with (i)frames, because the computed element coordinates of the clicked element were erroneous.
So programmatic mouse events are reintroduced back into this corrective RC until a better solution is found.
I told you there won't be an 1.0.0-RC5? I lied. Expect 1.0 stable for Christmas, probably.
Casper.evaluate()
method signature is now compatible with PhantomJS' one, so you can now write:
casper.evaluate(function(a, b) {
return a === "foo" && b === "bar";
}, "foo", "bar"); // true
The old way to pass arguments has been kept backward compatible in order not to break your existing scripts though:
casper.evaluate(function(a, b) {
return a === "foo" && b === "bar";
}, {a: "foo", b: "bar"}); // true
In order to check that every planned test has actuall been executed, a new optional planned
parameter has been added to Tester.done()
:
casper.test.assert(true);
casper.test.assert(true);
casper.test.assert(true);
casper.test.done(4);
Will trigger a failure:
fail: 4 tests planned, 3 tests executed.
That's especially useful in case a given test script is abruptly interrupted leaving you with no obvious way to know it and an erroneous success status.
The whole CapserJS test suite has been migrated to use this new feature.
PhantomJS 1.7 ships with support for new opened pages — aka popups. CasperJS can now wait for a popup to be opened and loaded to react accordingly using the new Casper.waitForPopup()
and Casper.withPopup()
methods:
casper.start('http://foo.bar/').then(function() {
this.test.assertTitle('Main page title');
this.clickLabel('Open me a popup');
});
// this will wait for the popup to be opened and loaded
casper.waitForPopup(/popup\.html$/, function() {
this.test.assertEquals(this.popups.length, 1);
});
// this will set the popup DOM as the main active one only for time the
// step closure being executed
casper.withPopup(/popup\.html$/, function() {
this.test.assertTitle('Popup title');
});
// next step will automatically revert the current page to the initial one
casper.then(function() {
this.test.assertTitle('Main page title');
});
Casper.mouseEvent()
now uses native events for most operationsNative mouse events from PhantomJS bring a far more accurate behavior.
Also, Casper.mouseEvent()
will now directly trigger an error on failure instead of just logging an error
event.
findOne()
and findAll()
observe the scope for XPath expressions, not just when passed CSS selectorsCasper.evaluate()
should take an array as context not objecttester
module and its self tests--fail-fast
option to the casper test
command, in order to terminate a test suite execution as soon as any failure is encounteredClientUtils.echo()
remoteScripts
casper optionutils.betterTypeOf()
to properly handle undefined
and null
valuesCasper.die()
and Casper.evaluateOrDie()
were not printing the error onto the consolerequire()
Tester.assertTruthy()
and Tester.assertFalsy()
Casper.sendKeys()
to send native keyboard events to the element matching a given selectorCasper.getFormValues()
to check for the field values of a given formTester.assertTextDoesntExist()
Tester.assertFalse()
as an alias of Tester.assertNot()
page.resource.requested
and page.resource.received
eventstranslate.js
and translate.coffee
samples