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 *
93 * @param String classname 94 * @return HTMLElement
94 * @param String name
95 * @param Number duration Test duration in milliseconds
96 */ 95 */
97 XUnitExporter.prototype.addSuccess = function addSuccess(classname, name, duration) { 96 XUnitExporter.prototype.getXML = function getXML() {
98 "use strict"; 97 "use strict";
99 var snode = utils.node('testcase', { 98 if (!(this.results instanceof require('tester').TestSuite)) {
100 classname: generateClassName(classname), 99 throw new CasperError('Results not set, cannot get XML.');
101 name: name
102 });
103 if (duration !== undefined) {
104 snode.setAttribute('time', utils.ms2seconds(duration));
105 } 100 }
106 this._xml.appendChild(snode); 101 this.results.forEach(function(result) {
107 }; 102 var suiteNode = utils.node('testsuite', {
108 103 name: result.name,
109 /** 104 tests: result.assertions,
110 * Adds a failed test result. 105 failures: result.failed,
111 * 106 time: utils.ms2seconds(result.calculateDuration()),
112 * @param String classname 107 'package': generateClassName(result.file),
113 * @param String name 108 });
114 * @param String message 109 result.passes.forEach(function(success) {
115 * @param String type 110 var testCase = utils.node('testcase', {
116 * @param Number duration Test duration in milliseconds 111 name: success.message || success.standard,
117 */ 112 classname: generateClassName(success.file),
118 XUnitExporter.prototype.addFailure = function addFailure(classname, name, message, type, duration) { 113 time: utils.ms2seconds(~~success.time)
119 "use strict"; 114 });
120 var fnode = utils.node('testcase', { 115 suiteNode.appendChild(testCase);
121 classname: generateClassName(classname),
122 name: name
123 }); 116 });
124 if (duration !== undefined) { 117 result.failures.forEach(function(failure) {
125 fnode.setAttribute('time', utils.ms2seconds(duration)); 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);
126 } 133 }
127 var failure = utils.node('failure', { 134 testCase.appendChild(failureNode);
128 type: type || "unknown" 135 suiteNode.appendChild(testCase);
129 }); 136 });
130 failure.appendChild(document.createTextNode(message || "no message left")); 137 this._xml.appendChild(suiteNode);
131 fnode.appendChild(failure); 138 }.bind(this));
132 this._xml.appendChild(fnode); 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 });
......