1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 | var xmlSpecialChars = [{
|
17 | search: /&/g,
|
18 | replace: '&'
|
19 | }, {
|
20 | search: /</g,
|
21 | replace: '<'
|
22 | }, {
|
23 | search: />/g,
|
24 | replace: '>'
|
25 | }, {
|
26 | search: /"/g,
|
27 | replace: '"'
|
28 | }, {
|
29 | search: /'/g,
|
30 | replace: '''
|
31 | }];
|
32 | var testNameSpecialChars = /[^._a-zA-Z0-9]+/g;
|
33 | var endingUnderscores = /_+$/;
|
34 |
|
35 | function escapeXML(value) {
|
36 | value = value + '';
|
37 | for (var i = 0, l = xmlSpecialChars.length; i < l; i++) {
|
38 | var specChar = xmlSpecialChars[i];
|
39 | value = value.replace(specChar.search, specChar.replace);
|
40 | }
|
41 | return value;
|
42 | }
|
43 |
|
44 | function filterTestName(name) {
|
45 | if (name) {
|
46 | name = name + '';
|
47 | name = name.replace(testNameSpecialChars, '_');
|
48 | name = name.replace(endingUnderscores, '');
|
49 | } else {
|
50 | name = "Unknown_test";
|
51 | }
|
52 | return name;
|
53 | }
|
54 |
|
55 | function getReportContent(jsonReport, fixedLevels) {
|
56 | var res = ['<?xml version="1.0" encoding="UTF-8" ?>\n'];
|
57 |
|
58 | function processError(error) {
|
59 | var tagName = error.failure ? "failure" : "error";
|
60 | res.push('<', tagName, ' message="', escapeXML(error.message), '">');
|
61 | res.push(escapeXML(error.message), '\n');
|
62 | var stack = error.stack;
|
63 | if (stack) {
|
64 | for (var i = 0, l = stack.length; i < l; i++) {
|
65 | var stackItem = stack[i];
|
66 | res.push('\tat ');
|
67 | if (stackItem.className) {
|
68 | res.push(escapeXML(stackItem.className));
|
69 | if (stackItem['function']) {
|
70 | res.push('.');
|
71 | }
|
72 | }
|
73 | res.push(escapeXML(stackItem['function']));
|
74 | res.push('(', escapeXML(stackItem.file), ':', escapeXML(stackItem.line), ')\n');
|
75 | }
|
76 | }
|
77 | res.push('\n');
|
78 | res.push('</', tagName, '>');
|
79 | }
|
80 |
|
81 | function processErrorsArray(errors) {
|
82 | for (var i = 0, l = errors.length; i < l; i++) {
|
83 | processError(errors[i]);
|
84 | }
|
85 | }
|
86 |
|
87 | function processTest(test, first) {
|
88 | var subItems = test.subTasks || test.subTests;
|
89 | if (subItems) {
|
90 | res.push('<testsuite name="', filterTestName(test.name), '"');
|
91 | } else {
|
92 | res.push('<testcase name="', filterTestName(test.method || test.name), '" classname="', filterTestName(test.name), '"');
|
93 | }
|
94 | if (test.duration != null ) {
|
95 | res.push(' time="', test.duration / 1000, '"');
|
96 | }
|
97 | res.push('>');
|
98 | if (!subItems && test.ignored) {
|
99 | res.push('<skipped/>');
|
100 | }
|
101 | if (test.errors) {
|
102 | processErrorsArray(test.errors);
|
103 | }
|
104 | if (subItems) {
|
105 | processTestsArray(subItems);
|
106 | res.push('</testsuite>');
|
107 | } else {
|
108 | res.push('</testcase>');
|
109 | }
|
110 | }
|
111 |
|
112 | function processTestsArray(array) {
|
113 | for (var i = 0, l = array.length; i < l; i++) {
|
114 | processTest(array[i]);
|
115 | }
|
116 | }
|
117 |
|
118 | if (jsonReport.subTasks || jsonReport.subTests) {
|
119 | processTest(jsonReport);
|
120 | } else {
|
121 | processTest({
|
122 | name: jsonReport.name,
|
123 | subTests: [jsonReport]
|
124 | });
|
125 | }
|
126 | return res.join('');
|
127 | }
|
128 |
|
129 | function xmlDirectoryReport(report) {
|
130 | var reports = [];
|
131 | for (var i = 0, l = report.length; i < l; i++) {
|
132 | var curItem = report[i];
|
133 | reports.push({
|
134 | name: "TEST-" + filterTestName(curItem.name) + ".xml",
|
135 | content: getReportContent(curItem, true)
|
136 | });
|
137 | }
|
138 | return reports;
|
139 | }
|
140 |
|
141 | function xmlFileReport(item) {
|
142 | return getReportContent(item, false);
|
143 | }
|
144 |
|
145 | module.exports = {
|
146 | xmlFileReport: xmlFileReport,
|
147 | xmlDirectoryReport: xmlDirectoryReport
|
148 | };
|