Commit 491d40ff 491d40ff5d5501f01caab7af1adb0973c5d015c5 by Nicolas Perriault

fixed #215 - added a `--fail-fast` option to `casper test`

In order to terminate a test suite execution as soon as any
failure is encountered.
1 parent 83e3f84e
......@@ -5,6 +5,7 @@ XXXX-XX-XX, v1.0.0
------------------
- fixed [#266](https://github.com/n1k0/casperjs/issues/266) - Fix `tester` module and its self tests
- fixed [#215](https://github.com/n1k0/casperjs/issues/215) - added a `--fail-fast` option to the `casper test` command, in order to terminate a test suite execution as soon as any failure is encountered
- added `Tester.assertFalse()` as an alias of `Tester.assertNot()`
2012-10-31, v1.0.0-RC4
......
......@@ -154,6 +154,9 @@ var Casper = function Casper(options) {
this.initErrorHandler();
this.on('error', function(msg, backtrace) {
if (msg === this.test.SKIP_MESSAGE) {
return this.warn(f('--fail-fast: aborted remaining tests in "%s"', this.test.currentTestFile));
}
var c = this.getColorizer();
var match = /^(.*): __mod_error(.*):: (.*)/.exec(msg);
var notices = [];
......
......@@ -55,6 +55,8 @@ var Tester = function Tester(casper, options) {
this.casper = casper;
this.SKIP_MESSAGE = '__termination__';
this.currentTestFile = null;
this.currentSuiteNum = 0;
this.exporter = require('xunit').create();
......@@ -66,6 +68,7 @@ var Tester = function Tester(casper, options) {
this.running = false;
this.suites = [];
this.options = utils.mergeObjects({
failFast: false, // terminates a suite as soon as a test fails?
failText: "FAIL", // text to use for a successful test
passText: "PASS", // text to use for a failed test
pad: 80 // maximum number of chars for a result line
......@@ -648,11 +651,13 @@ Tester.prototype.configure = function configure() {
// events
this.casper.on('error', function(msg, backtrace) {
var line = 0;
try {
line = backtrace[0].line;
} catch (e) {}
tester.uncaughtError(msg, tester.currentTestFile, line);
if (!utils.isString(msg) && msg.indexOf(this.SKIP_MESSAGE) === -1) {
var line = 0;
try {
line = backtrace[0].line;
} catch (e) {}
tester.uncaughtError(msg, tester.currentTestFile, line);
}
tester.done();
});
......@@ -816,21 +821,23 @@ Tester.prototype.pass = function pass(message) {
*/
Tester.prototype.processAssertionResult = function processAssertionResult(result) {
"use strict";
var eventName, style, status;
if (result.success === true) {
eventName = 'success';
style = 'INFO';
var eventName= 'success',
message = result.message || result.standard,
style = 'INFO',
status = this.options.passText;
this.testResults.passed++;
} else {
if (!result.success) {
eventName = 'fail';
style = 'RED_BAR';
status = this.options.failText;
this.testResults.failed++;
} else {
this.testResults.passed++;
}
var message = result.message || result.standard;
this.casper.echo([this.colorize(status, style), this.formatMessage(message)].join(' '));
this.emit(eventName, result);
if (this.options.failFast && !result.success) {
throw this.SKIP_MESSAGE;
}
return result;
};
......
......@@ -60,6 +60,7 @@ if (casper.cli.get('no-colors') === true) {
casper.options.colorizerType = cls;
casper.colorizer = colorizer.create(cls);
}
casper.test.options.failFast = casper.cli.get('fail-fast') || false;
// test paths are passed as args
if (casper.cli.args.length) {
......@@ -97,6 +98,9 @@ this.loadIncludes.forEach(function(include){
casper.test.on('tests.complete', function() {
"use strict";
this.renderResults(true, undefined, casper.cli.get('xunit') || undefined);
if (this.options.failFast && this.testResults.failures.length > 0) {
casper.warn('Test suite failed fast, all tests may not have been executed.');
}
});
// run all the suites
......
......@@ -27,7 +27,7 @@ var codes = [100, 101, 102, 118, 200, 201, 202, 203, 204, 205, 206, 207, 210,
414, 415, 416, 417, 418, 422, 423, 424, 425, 426, 449, 450,
500, 501, 502, 503, 504, 505, 507, 509];
casper.thenOpen('http://google.com').each(codes, function(self, code) {
casper.each(codes, function(self, code) {
if (code === 100) {
// HTTP 100 is CONTINUE, so don't expect a terminated response
return;
......