Commit 0e69c75e 0e69c75e96483bbabeebe3675dec11e55ff6a868 by Nicolas Perriault

Merged branch '1.1-dev'

2 parents 0628688c a8d6b513
...@@ -10,26 +10,26 @@ oncletom ...@@ -10,26 +10,26 @@ oncletom
10 hannyu 10 hannyu
11 Chris Lorenzo 11 Chris Lorenzo
12 Victor Yap 12 Victor Yap
13 Rob Barreca
14 Tyler Ritchie
13 nrabinowitz 15 nrabinowitz
14 pborreli 16 pborreli
15 Rob Barreca 17 Dave Lee
16 Andrew Childs 18 Andrew Childs
17 Solomon White 19 Solomon White
18 reina.sweet 20 reina.sweet
19 Dave Lee
20 Reina Sweet 21 Reina Sweet
22 Jan Schaumann
21 Elmar Langholz 23 Elmar Langholz
22 Jason Funk 24 Clochix
23 Donovan Hutchinson 25 Donovan Hutchinson
24 Julien Moulin 26 Julien Moulin
25 Michael Geers 27 Michael Geers
26 Jan Schaumann 28 Jason Funk
27 Clochix 29 Vladimir Chizhov
28 Raphaël Benitte
29 Tim Bunce
30 alfetopito
31 jean-philippe serafin 30 jean-philippe serafin
32 snkashis 31 snkashis
32 Rafael
33 Andrew de Andrade 33 Andrew de Andrade
34 Ben Lowery 34 Ben Lowery
35 Chris Winters 35 Chris Winters
...@@ -48,6 +48,8 @@ Mathieu Agopian ...@@ -48,6 +48,8 @@ Mathieu Agopian
48 Mehdi Kabab 48 Mehdi Kabab
49 Mikko Peltonen 49 Mikko Peltonen
50 Pascal Borreli 50 Pascal Borreli
51 Rafael
52 Rafael Garcia 51 Rafael Garcia
52 Raphaël Benitte
53 Tim Bunce
54 alfetopito
53 ``` 55 ```
......
...@@ -1370,6 +1370,19 @@ Casper.prototype.sendKeys = function(selector, keys, options) { ...@@ -1370,6 +1370,19 @@ Casper.prototype.sendKeys = function(selector, keys, options) {
1370 }; 1370 };
1371 1371
1372 /** 1372 /**
1373 * Sets current page content.
1374 *
1375 * @param String content Desired page content
1376 * @return Casper
1377 */
1378 Casper.prototype.setContent = function setContent(content) {
1379 "use strict";
1380 this.checkStarted();
1381 this.page.content = content;
1382 return this;
1383 };
1384
1385 /**
1373 * Sets current WebPage instance the credentials for HTTP authentication. 1386 * Sets current WebPage instance the credentials for HTTP authentication.
1374 * 1387 *
1375 * @param String username 1388 * @param String username
......
...@@ -200,6 +200,43 @@ function format(f) { ...@@ -200,6 +200,43 @@ function format(f) {
200 exports.format = format; 200 exports.format = format;
201 201
202 /** 202 /**
203 * Formats a test value.
204 *
205 * @param Mixed value
206 * @return String
207 */
208 function formatTestValue(value, name) {
209 "use strict";
210 var formatted = '';
211 if (value instanceof Error) {
212 formatted += value.message + '\n';
213 if (value.stack) {
214 formatted += indent(value.stack, 12, '#');
215 }
216 } else if (name === 'stack') {
217 if (isArray(value)) {
218 formatted += value.map(function(entry) {
219 return format('in %s() in %s:%d', (entry.function || "anonymous"), entry.file, entry.line);
220 }).join('\n');
221 } else {
222 formatted += 'not provided';
223 }
224 } else {
225 try {
226 formatted += serialize(value);
227 } catch (e) {
228 try {
229 formatted += serialize(value.toString());
230 } catch (e2) {
231 formatted += '(unserializable value)';
232 }
233 }
234 }
235 return formatted;
236 }
237 exports.formatTestValue = formatTestValue;
238
239 /**
203 * Retrieves the value of an Object foreign property using a dot-separated 240 * Retrieves the value of an Object foreign property using a dot-separated
204 * path string. 241 * path string.
205 * 242 *
...@@ -226,6 +263,22 @@ function getPropertyPath(obj, path) { ...@@ -226,6 +263,22 @@ function getPropertyPath(obj, path) {
226 exports.getPropertyPath = getPropertyPath; 263 exports.getPropertyPath = getPropertyPath;
227 264
228 /** 265 /**
266 * Indents a string.
267 *
268 * @param String string
269 * @param Number nchars
270 * @param String prefix
271 * @return String
272 */
273 function indent(string, nchars, prefix) {
274 "use strict";
275 return string.split('\n').map(function(line) {
276 return (prefix || '') + new Array(nchars).join(' ') + line;
277 }).join('\n');
278 }
279 exports.indent = indent;
280
281 /**
229 * Inherit the prototype methods from one constructor into another. 282 * Inherit the prototype methods from one constructor into another.
230 * 283 *
231 * @param {function} ctor Constructor function which needs to inherit the 284 * @param {function} ctor Constructor function which needs to inherit the
......
...@@ -80,76 +80,75 @@ exports.create = function create() { ...@@ -80,76 +80,75 @@ exports.create = function create() {
80 */ 80 */
81 function XUnitExporter() { 81 function XUnitExporter() {
82 "use strict"; 82 "use strict";
83 this._xml = utils.node('testsuite'); 83 this.results = undefined;
84 this._xml = utils.node('testsuites');
84 this._xml.toString = function toString() { 85 this._xml.toString = function toString() {
85 return this.outerHTML; // ouch 86 return '<?xml version="1.0" encoding="UTF-8"?>' + this.outerHTML; // ouch
86 }; 87 };
87 } 88 }
88 exports.XUnitExporter = XUnitExporter; 89 exports.XUnitExporter = XUnitExporter;
89 90
90 /** 91 /**
91 * Adds a successful test result. 92 * Retrieves generated XML object - actually an HTMLElement.
92 *
93 * @param String classname
94 * @param String name
95 * @param Number duration Test duration in milliseconds
96 */
97 XUnitExporter.prototype.addSuccess = function addSuccess(classname, name, duration) {
98 "use strict";
99 var snode = utils.node('testcase', {
100 classname: generateClassName(classname),
101 name: name
102 });
103 if (duration !== undefined) {
104 snode.setAttribute('time', utils.ms2seconds(duration));
105 }
106 this._xml.appendChild(snode);
107 };
108
109 /**
110 * Adds a failed test result.
111 * 93 *
112 * @param String classname 94 * @return HTMLElement
113 * @param String name
114 * @param String message
115 * @param String type
116 * @param Number duration Test duration in milliseconds
117 */ 95 */
118 XUnitExporter.prototype.addFailure = function addFailure(classname, name, message, type, duration) { 96 XUnitExporter.prototype.getXML = function getXML() {
119 "use strict"; 97 "use strict";
120 var fnode = utils.node('testcase', { 98 if (!(this.results instanceof require('tester').TestSuite)) {
121 classname: generateClassName(classname), 99 throw new CasperError('Results not set, cannot get XML.');
122 name: name
123 });
124 if (duration !== undefined) {
125 fnode.setAttribute('time', utils.ms2seconds(duration));
126 } 100 }
127 var failure = utils.node('failure', { 101 this.results.forEach(function(result) {
128 type: type || "unknown" 102 var suiteNode = utils.node('testsuite', {
129 }); 103 name: result.name,
130 failure.appendChild(document.createTextNode(message || "no message left")); 104 tests: result.assertions,
131 fnode.appendChild(failure); 105 failures: result.failed,
132 this._xml.appendChild(fnode); 106 time: utils.ms2seconds(result.calculateDuration()),
107 'package': generateClassName(result.file),
108 });
109 result.passes.forEach(function(success) {
110 var testCase = utils.node('testcase', {
111 name: success.message || success.standard,
112 classname: generateClassName(success.file),
113 time: utils.ms2seconds(~~success.time)
114 });
115 suiteNode.appendChild(testCase);
116 });
117 result.failures.forEach(function(failure) {
118 var testCase = utils.node('testcase', {
119 name: failure.message || failure.standard,
120 classname: generateClassName(failure.file),
121 time: utils.ms2seconds(~~failure.time)
122 });
123 var failureNode = utils.node('failure', {
124 type: failure.type || "failure"
125 });
126 failureNode.appendChild(document.createTextNode(failure.message || "no message left"));
127 if (failure.values && failure.values.error instanceof Error) {
128 var errorNode = utils.node('error', {
129 type: utils.betterTypeOf(failure.values.error)
130 });
131 errorNode.appendChild(document.createTextNode(failure.values.error.stack));
132 testCase.appendChild(errorNode);
133 }
134 testCase.appendChild(failureNode);
135 suiteNode.appendChild(testCase);
136 });
137 this._xml.appendChild(suiteNode);
138 }.bind(this));
139 this._xml.setAttribute('duration', utils.ms2seconds(this.results.calculateDuration()));
140 return this._xml;
133 }; 141 };
134 142
135 /** 143 /**
136 * Adds test suite duration 144 * Sets test results.
137 * 145 *
138 * @param Number duration Test duration in milliseconds 146 * @param TestSuite results
139 */ 147 */
140 XUnitExporter.prototype.setSuiteDuration = function setSuiteDuration(duration) { 148 XUnitExporter.prototype.setResults = function setResults(results) {
141 "use strict"; 149 "use strict";
142 if (!isNaN(duration)) { 150 if (!(results instanceof require('tester').TestSuite)) {
143 this._xml.setAttribute("time", utils.ms2seconds(duration)); 151 throw new CasperError('Invalid results type.');
144 } 152 }
145 }; 153 return this.results = results;
146
147 /**
148 * Retrieves generated XML object - actually an HTMLElement.
149 *
150 * @return HTMLElement
151 */
152 XUnitExporter.prototype.getXML = function getXML() {
153 "use strict";
154 return this._xml;
155 }; 154 };
......
...@@ -200,27 +200,6 @@ casper.reload(function() { ...@@ -200,27 +200,6 @@ casper.reload(function() {
200 t.assertField('checklist[]', [], 'Tester.assertField() works as expected with check lists'); 200 t.assertField('checklist[]', [], 'Tester.assertField() works as expected with check lists');
201 }); 201 });
202 202
203 casper.then(function() {
204 t.comment('Tester.getFailures()');
205 t.assertEquals(typeof t.getFailures().length, "number", "Tester.getFailures() works as expected");
206
207 var passCount = t.getPasses().length;
208 t.comment('Tester.getPasses()');
209 t.assertEquals(1, 1, "Rogue assertEquals pass case");
210 t.assertEquals(t.getPasses().length, passCount + 1, "Tester.getPasses() works as expected");
211 });
212
213 casper.then(function() {
214 t.comment('Tester.calculateSuiteDuration()');
215 function add(a, b) {
216 return a + b;
217 }
218 var passedTime = t.getPassesTime().reduce(add, 0),
219 failedTime = t.getFailuresTime().reduce(add, 0),
220 calculatedSum = t.calculateSuiteDuration();
221 t.assertEquals(calculatedSum, passedTime + failedTime, "Tester.calculateSuiteDuration() works as expected")
222 });
223
224 casper.run(function() { 203 casper.run(function() {
225 t.done(59); 204 t.done(55);
226 }); 205 });
......
1 /*global casper*/ 1 /*global casper*/
2 /*jshint strict:false*/ 2 /*jshint strict:false*/
3 casper.test.comment('phantom.Casper.XUnitExporter'); 3 var tester = require('tester');
4 var testpage = require('webpage').create();
4 5
5 var xunit = require('xunit').create(); 6 casper.test.begin('XUnitReporter() initialization', function suite() {
6 xunit.addSuccess('foo', 'bar'); 7 var xunit = require('xunit').create();
7 casper.test.assertMatch(xunit.getXML(), 8 var results = new tester.TestSuite();
8 /<testcase classname="foo" name="bar"/, 9 xunit.setResults(results);
9 'XUnitExporter.addSuccess() adds a successful testcase'); 10 this.assertTruthy(xunit.getXML());
10 xunit.addFailure('bar', 'baz', 'wrong', 'chucknorriz'); 11 this.done(1);
11 casper.test.assertMatch(xunit.getXML(), 12 });
12 /<testcase classname="bar" name="baz"><failure type="chucknorriz">wrong/,
13 'XUnitExporter.addFailure() adds a failed testcase');
14 13
15 // named classname 14 casper.test.begin('XUnitReporter() can hold test suites', function suite() {
16 xunit = require('xunit').create(); 15 var xunit = require('xunit').create();
17 xunit.addSuccess(require('fs').workingDirectory + '/plop.js', 'It worked'); 16 var results = new tester.TestSuite();
18 casper.test.assertMatch(xunit.getXML(), 17 var suite1 = new tester.TestSuiteResult({
19 /<testcase classname="(.*)plop" name="It worked"/, 18 name: 'foo',
20 'XUnitExporter.addSuccess() handles class name'); 19 file: '/foo'
21 xunit.addSuccess(require('fs').workingDirectory + '/plip.js', 'Failure'); 20 });
22 casper.test.assertMatch(xunit.getXML(), 21 results.push(suite1);
23 /<testcase classname="(.*)plip" name="Failure"/, 22 var suite2 = new tester.TestSuiteResult({
24 'XUnitExporter.addFailure() handles class name'); 23 name: 'bar',
24 file: '/bar'
25 });
26 results.push(suite2);
27 xunit.setResults(results);
28 casper.start().setContent(xunit.getXML());
29 this.assertEvalEquals(function() {
30 return __utils__.findAll('testsuite').length;
31 }, 2);
32 this.assertExists('testsuites[duration]');
33 this.assertExists('testsuite[name="foo"][package="foo"]');
34 this.assertExists('testsuite[name="bar"][package="bar"]');
35 this.done(4);
36 });
25 37
26 // named with time 38 casper.test.begin('XUnitReporter() can hold a suite with a succesful test', function suite() {
27 xunit = require('xunit').create(); 39 var xunit = require('xunit').create();
28 xunit.addSuccess('foo', 'It worked', 1024); 40 var results = new tester.TestSuite();
29 casper.test.assertMatch(xunit.getXML(), 41 var suite1 = new tester.TestSuiteResult({
30 /<testcase classname="foo" name="It worked" time="(.*)"/, 42 name: 'foo',
31 'XUnitExporter.addSuccess() writes duration of test'); 43 file: '/foo'
32 xunit.addFailure('bar', 'baz', 'wrong', 'chucknorriz', 1024); 44 });
33 casper.test.assertMatch(xunit.getXML(), 45 suite1.addSuccess({
34 /<testcase classname="bar" name="baz" time="(.*)"><failure type="chucknorriz">wrong/, 46 success: true,
35 'XUnitExporter.addFailure() adds a failed testcase with duration'); 47 type: "footype",
48 message: "footext",
49 file: "/foo"
50 });
51 results.push(suite1);
52 xunit.setResults(results);
53 casper.start().setContent(xunit.getXML());
54 this.assertExists('testsuite[name="foo"][package="foo"][tests="1"][failures="0"] testcase[name="footext"]');
55 casper.test.done(1);
56 });
36 57
37 // named with time 58 casper.test.begin('XUnitReporter() can handle a failed test', function suite() {
38 xunit = require('xunit').create(); 59 var xunit = require('xunit').create();
39 casper.test.assertMatch(xunit.getXML(), 60 var results = new tester.TestSuite();
40 /<testsuite>/, 61 var suite1 = new tester.TestSuiteResult({
41 'XUnitExporter.create() created <testsuite> without time'); 62 name: 'foo',
42 xunit.setSuiteDuration(1024); 63 file: '/foo'
43 casper.test.assertMatch(xunit.getXML(), 64 });
44 /<testsuite time="1.024">/, 65 suite1.addFailure({
45 'XUnitExporter.setSuiteDuration() sets time in seconds'); 66 success: false,
46 67 type: "footype",
47 casper.test.done(8); 68 message: "footext",
69 file: "/foo"
70 });
71 results.push(suite1);
72 xunit.setResults(results);
73 casper.start().setContent(xunit.getXML());
74 this.assertExists('testsuite[name="foo"][package="foo"][tests="1"][failures="1"] testcase[name="footext"] failure[type="footype"]');
75 this.assertEquals(casper.getElementInfo('failure[type="footype"]').text, 'footext');
76 casper.test.done(2);
77 });
......