UNPKG

3.32 kBJavaScriptView Raw
1var os = require('os');
2var path = require('path');
3var fs = require('fs');
4var builder = require('xmlbuilder');
5
6
7var JUnitReporter = function(baseReporterDecorator, config, logger, helper, formatError) {
8 var log = logger.create('reporter.junit');
9 var reporterConfig = config.junitReporter || {};
10 var pkgName = reporterConfig.suite || '';
11 var outputFile = helper.normalizeWinPath(path.resolve(config.basePath, reporterConfig.outputFile
12 || 'test-results.xml'));
13
14 var xml;
15 var suites;
16 var pendingFileWritings = 0;
17 var fileWritingFinished = function() {};
18 var allMessages = [];
19
20 baseReporterDecorator(this);
21
22 this.adapters = [function(msg) {
23 allMessages.push(msg);
24 }];
25
26 var initliazeXmlForBrowser = function(browser) {
27 var timestamp = (new Date()).toISOString().substr(0, 19);
28 var suite = suites[browser.id] = xml.ele('testsuite', {
29 name: browser.name, 'package': pkgName, timestamp: timestamp, id: 0, hostname: os.hostname()
30 });
31 suite.ele('properties').ele('property', {name: 'browser.fullName', value: browser.fullName});
32 };
33
34 this.onRunStart = function(browsers) {
35 suites = Object.create(null);
36 xml = builder.create('testsuites');
37
38 // TODO(vojta): remove once we don't care about Karma 0.10
39 browsers.forEach(initliazeXmlForBrowser);
40 };
41
42 this.onBrowserStart = function(browser) {
43 initliazeXmlForBrowser(browser);
44 };
45
46 this.onBrowserComplete = function(browser) {
47 var suite = suites[browser.id];
48 var result = browser.lastResult;
49
50 suite.att('tests', result.total);
51 suite.att('errors', result.disconnected || result.error ? 1 : 0);
52 suite.att('failures', result.failed);
53 suite.att('time', (result.netTime || 0) / 1000);
54
55 suite.ele('system-out').dat(allMessages.join() + '\n');
56 suite.ele('system-err');
57 };
58
59 this.onRunComplete = function() {
60 var xmlToOutput = xml;
61
62 pendingFileWritings++;
63 helper.mkdirIfNotExists(path.dirname(outputFile), function() {
64 fs.writeFile(outputFile, xmlToOutput.end({pretty: true}), function(err) {
65 if (err) {
66 log.warn('Cannot write JUnit xml\n\t' + err.message);
67 } else {
68 log.debug('JUnit results written to "%s".', outputFile);
69 }
70
71 if (!--pendingFileWritings) {
72 fileWritingFinished();
73 }
74 });
75 });
76
77 suites = xml = null;
78 allMessages.length = 0;
79 };
80
81 this.specSuccess = this.specSkipped = this.specFailure = function(browser, result) {
82 var spec = suites[browser.id].ele('testcase', {
83 name: result.description, time: ((result.time || 0) / 1000),
84 classname: (pkgName ? pkgName + ' ' : '') + browser.name + '.' + result.suite.join(' ').replace(/\./g, '_')
85 });
86
87 if (result.skipped) {
88 spec.ele('skipped');
89 }
90
91 if (!result.success) {
92 result.log.forEach(function(err) {
93 spec.ele('failure', {type: ''}, formatError(err));
94 });
95 }
96 };
97
98 // wait for writing all the xml files, before exiting
99 this.onExit = function(done) {
100 if (pendingFileWritings) {
101 fileWritingFinished = done;
102 } else {
103 done();
104 }
105 };
106};
107
108JUnitReporter.$inject = ['baseReporterDecorator', 'config', 'logger', 'helper', 'formatError'];
109
110// PUBLISH DI MODULE
111module.exports = {
112 'reporter:junit': ['type', JUnitReporter]
113};