Commit 0e69c75e 0e69c75e96483bbabeebe3675dec11e55ff6a868 by Nicolas Perriault

Merged branch '1.1-dev'

2 parents 0628688c a8d6b513
......@@ -10,26 +10,26 @@ oncletom
hannyu
Chris Lorenzo
Victor Yap
Rob Barreca
Tyler Ritchie
nrabinowitz
pborreli
Rob Barreca
Dave Lee
Andrew Childs
Solomon White
reina.sweet
Dave Lee
Reina Sweet
Jan Schaumann
Elmar Langholz
Jason Funk
Clochix
Donovan Hutchinson
Julien Moulin
Michael Geers
Jan Schaumann
Clochix
Raphaël Benitte
Tim Bunce
alfetopito
Jason Funk
Vladimir Chizhov
jean-philippe serafin
snkashis
Rafael
Andrew de Andrade
Ben Lowery
Chris Winters
......@@ -48,6 +48,8 @@ Mathieu Agopian
Mehdi Kabab
Mikko Peltonen
Pascal Borreli
Rafael
Rafael Garcia
Raphaël Benitte
Tim Bunce
alfetopito
```
......
......@@ -1370,6 +1370,19 @@ Casper.prototype.sendKeys = function(selector, keys, options) {
};
/**
* Sets current page content.
*
* @param String content Desired page content
* @return Casper
*/
Casper.prototype.setContent = function setContent(content) {
"use strict";
this.checkStarted();
this.page.content = content;
return this;
};
/**
* Sets current WebPage instance the credentials for HTTP authentication.
*
* @param String username
......
......@@ -200,6 +200,43 @@ function format(f) {
exports.format = format;
/**
* Formats a test value.
*
* @param Mixed value
* @return String
*/
function formatTestValue(value, name) {
"use strict";
var formatted = '';
if (value instanceof Error) {
formatted += value.message + '\n';
if (value.stack) {
formatted += indent(value.stack, 12, '#');
}
} else if (name === 'stack') {
if (isArray(value)) {
formatted += value.map(function(entry) {
return format('in %s() in %s:%d', (entry.function || "anonymous"), entry.file, entry.line);
}).join('\n');
} else {
formatted += 'not provided';
}
} else {
try {
formatted += serialize(value);
} catch (e) {
try {
formatted += serialize(value.toString());
} catch (e2) {
formatted += '(unserializable value)';
}
}
}
return formatted;
}
exports.formatTestValue = formatTestValue;
/**
* Retrieves the value of an Object foreign property using a dot-separated
* path string.
*
......@@ -226,6 +263,22 @@ function getPropertyPath(obj, path) {
exports.getPropertyPath = getPropertyPath;
/**
* Indents a string.
*
* @param String string
* @param Number nchars
* @param String prefix
* @return String
*/
function indent(string, nchars, prefix) {
"use strict";
return string.split('\n').map(function(line) {
return (prefix || '') + new Array(nchars).join(' ') + line;
}).join('\n');
}
exports.indent = indent;
/**
* Inherit the prototype methods from one constructor into another.
*
* @param {function} ctor Constructor function which needs to inherit the
......
......@@ -80,76 +80,75 @@ exports.create = function create() {
*/
function XUnitExporter() {
"use strict";
this._xml = utils.node('testsuite');
this.results = undefined;
this._xml = utils.node('testsuites');
this._xml.toString = function toString() {
return this.outerHTML; // ouch
return '<?xml version="1.0" encoding="UTF-8"?>' + this.outerHTML; // ouch
};
}
exports.XUnitExporter = XUnitExporter;
/**
* Adds a successful test result.
*
* @param String classname
* @param String name
* @param Number duration Test duration in milliseconds
*/
XUnitExporter.prototype.addSuccess = function addSuccess(classname, name, duration) {
"use strict";
var snode = utils.node('testcase', {
classname: generateClassName(classname),
name: name
});
if (duration !== undefined) {
snode.setAttribute('time', utils.ms2seconds(duration));
}
this._xml.appendChild(snode);
};
/**
* Adds a failed test result.
* Retrieves generated XML object - actually an HTMLElement.
*
* @param String classname
* @param String name
* @param String message
* @param String type
* @param Number duration Test duration in milliseconds
* @return HTMLElement
*/
XUnitExporter.prototype.addFailure = function addFailure(classname, name, message, type, duration) {
XUnitExporter.prototype.getXML = function getXML() {
"use strict";
var fnode = utils.node('testcase', {
classname: generateClassName(classname),
name: name
});
if (duration !== undefined) {
fnode.setAttribute('time', utils.ms2seconds(duration));
if (!(this.results instanceof require('tester').TestSuite)) {
throw new CasperError('Results not set, cannot get XML.');
}
var failure = utils.node('failure', {
type: type || "unknown"
});
failure.appendChild(document.createTextNode(message || "no message left"));
fnode.appendChild(failure);
this._xml.appendChild(fnode);
this.results.forEach(function(result) {
var suiteNode = utils.node('testsuite', {
name: result.name,
tests: result.assertions,
failures: result.failed,
time: utils.ms2seconds(result.calculateDuration()),
'package': generateClassName(result.file),
});
result.passes.forEach(function(success) {
var testCase = utils.node('testcase', {
name: success.message || success.standard,
classname: generateClassName(success.file),
time: utils.ms2seconds(~~success.time)
});
suiteNode.appendChild(testCase);
});
result.failures.forEach(function(failure) {
var testCase = utils.node('testcase', {
name: failure.message || failure.standard,
classname: generateClassName(failure.file),
time: utils.ms2seconds(~~failure.time)
});
var failureNode = utils.node('failure', {
type: failure.type || "failure"
});
failureNode.appendChild(document.createTextNode(failure.message || "no message left"));
if (failure.values && failure.values.error instanceof Error) {
var errorNode = utils.node('error', {
type: utils.betterTypeOf(failure.values.error)
});
errorNode.appendChild(document.createTextNode(failure.values.error.stack));
testCase.appendChild(errorNode);
}
testCase.appendChild(failureNode);
suiteNode.appendChild(testCase);
});
this._xml.appendChild(suiteNode);
}.bind(this));
this._xml.setAttribute('duration', utils.ms2seconds(this.results.calculateDuration()));
return this._xml;
};
/**
* Adds test suite duration
* Sets test results.
*
* @param Number duration Test duration in milliseconds
* @param TestSuite results
*/
XUnitExporter.prototype.setSuiteDuration = function setSuiteDuration(duration) {
XUnitExporter.prototype.setResults = function setResults(results) {
"use strict";
if (!isNaN(duration)) {
this._xml.setAttribute("time", utils.ms2seconds(duration));
if (!(results instanceof require('tester').TestSuite)) {
throw new CasperError('Invalid results type.');
}
};
/**
* Retrieves generated XML object - actually an HTMLElement.
*
* @return HTMLElement
*/
XUnitExporter.prototype.getXML = function getXML() {
"use strict";
return this._xml;
return this.results = results;
};
......
......@@ -200,27 +200,6 @@ casper.reload(function() {
t.assertField('checklist[]', [], 'Tester.assertField() works as expected with check lists');
});
casper.then(function() {
t.comment('Tester.getFailures()');
t.assertEquals(typeof t.getFailures().length, "number", "Tester.getFailures() works as expected");
var passCount = t.getPasses().length;
t.comment('Tester.getPasses()');
t.assertEquals(1, 1, "Rogue assertEquals pass case");
t.assertEquals(t.getPasses().length, passCount + 1, "Tester.getPasses() works as expected");
});
casper.then(function() {
t.comment('Tester.calculateSuiteDuration()');
function add(a, b) {
return a + b;
}
var passedTime = t.getPassesTime().reduce(add, 0),
failedTime = t.getFailuresTime().reduce(add, 0),
calculatedSum = t.calculateSuiteDuration();
t.assertEquals(calculatedSum, passedTime + failedTime, "Tester.calculateSuiteDuration() works as expected")
});
casper.run(function() {
t.done(59);
t.done(55);
});
......
/*global casper*/
/*jshint strict:false*/
casper.test.comment('phantom.Casper.XUnitExporter');
var tester = require('tester');
var testpage = require('webpage').create();
var xunit = require('xunit').create();
xunit.addSuccess('foo', 'bar');
casper.test.assertMatch(xunit.getXML(),
/<testcase classname="foo" name="bar"/,
'XUnitExporter.addSuccess() adds a successful testcase');
xunit.addFailure('bar', 'baz', 'wrong', 'chucknorriz');
casper.test.assertMatch(xunit.getXML(),
/<testcase classname="bar" name="baz"><failure type="chucknorriz">wrong/,
'XUnitExporter.addFailure() adds a failed testcase');
casper.test.begin('XUnitReporter() initialization', function suite() {
var xunit = require('xunit').create();
var results = new tester.TestSuite();
xunit.setResults(results);
this.assertTruthy(xunit.getXML());
this.done(1);
});
// named classname
xunit = require('xunit').create();
xunit.addSuccess(require('fs').workingDirectory + '/plop.js', 'It worked');
casper.test.assertMatch(xunit.getXML(),
/<testcase classname="(.*)plop" name="It worked"/,
'XUnitExporter.addSuccess() handles class name');
xunit.addSuccess(require('fs').workingDirectory + '/plip.js', 'Failure');
casper.test.assertMatch(xunit.getXML(),
/<testcase classname="(.*)plip" name="Failure"/,
'XUnitExporter.addFailure() handles class name');
casper.test.begin('XUnitReporter() can hold test suites', function suite() {
var xunit = require('xunit').create();
var results = new tester.TestSuite();
var suite1 = new tester.TestSuiteResult({
name: 'foo',
file: '/foo'
});
results.push(suite1);
var suite2 = new tester.TestSuiteResult({
name: 'bar',
file: '/bar'
});
results.push(suite2);
xunit.setResults(results);
casper.start().setContent(xunit.getXML());
this.assertEvalEquals(function() {
return __utils__.findAll('testsuite').length;
}, 2);
this.assertExists('testsuites[duration]');
this.assertExists('testsuite[name="foo"][package="foo"]');
this.assertExists('testsuite[name="bar"][package="bar"]');
this.done(4);
});
// named with time
xunit = require('xunit').create();
xunit.addSuccess('foo', 'It worked', 1024);
casper.test.assertMatch(xunit.getXML(),
/<testcase classname="foo" name="It worked" time="(.*)"/,
'XUnitExporter.addSuccess() writes duration of test');
xunit.addFailure('bar', 'baz', 'wrong', 'chucknorriz', 1024);
casper.test.assertMatch(xunit.getXML(),
/<testcase classname="bar" name="baz" time="(.*)"><failure type="chucknorriz">wrong/,
'XUnitExporter.addFailure() adds a failed testcase with duration');
casper.test.begin('XUnitReporter() can hold a suite with a succesful test', function suite() {
var xunit = require('xunit').create();
var results = new tester.TestSuite();
var suite1 = new tester.TestSuiteResult({
name: 'foo',
file: '/foo'
});
suite1.addSuccess({
success: true,
type: "footype",
message: "footext",
file: "/foo"
});
results.push(suite1);
xunit.setResults(results);
casper.start().setContent(xunit.getXML());
this.assertExists('testsuite[name="foo"][package="foo"][tests="1"][failures="0"] testcase[name="footext"]');
casper.test.done(1);
});
// named with time
xunit = require('xunit').create();
casper.test.assertMatch(xunit.getXML(),
/<testsuite>/,
'XUnitExporter.create() created <testsuite> without time');
xunit.setSuiteDuration(1024);
casper.test.assertMatch(xunit.getXML(),
/<testsuite time="1.024">/,
'XUnitExporter.setSuiteDuration() sets time in seconds');
casper.test.done(8);
casper.test.begin('XUnitReporter() can handle a failed test', function suite() {
var xunit = require('xunit').create();
var results = new tester.TestSuite();
var suite1 = new tester.TestSuiteResult({
name: 'foo',
file: '/foo'
});
suite1.addFailure({
success: false,
type: "footype",
message: "footext",
file: "/foo"
});
results.push(suite1);
xunit.setResults(results);
casper.start().setContent(xunit.getXML());
this.assertExists('testsuite[name="foo"][package="foo"][tests="1"][failures="1"] testcase[name="footext"] failure[type="footype"]');
this.assertEquals(casper.getElementInfo('failure[type="footype"]').text, 'footext');
casper.test.done(2);
});
......