-
Notifications
You must be signed in to change notification settings - Fork 0
/
parser.js
195 lines (186 loc) · 9.36 KB
/
parser.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
/**
* Parsing MSTest (.trx) test results report.
*/
"use strict"
const fs = require('fs');
const globby = require('globby');
const xml2js = require('xml2js');
const packageJson = require('./package.json');
/**
* Convert MSTest test case outcome status to qTest compatible test case outcome status.
* @param {string} testCaseStatus Test case status from MSTest (.trx) results file.
* @returns qTest compatible test case outcome status.
*/
function getTestCaseStatus(testCaseStatus) {
if (testCaseStatus == 'Failed') {
return "FAIL";
} else if (testCaseStatus == 'Inconclusive') {
return "SKIP";
} else if (testCaseStatus == 'Passed') {
return "PASS";
} else if (testCaseStatus == 'Error') {
return "FAIL";
} else if (testCaseStatus == 'Timeout') {
return "FAIL";
} else if (testCaseStatus == 'Aborted') {
return "FAIL";
} else if (testCaseStatus == 'Unknown') {
return "SKIP";
} else if (testCaseStatus == 'NotExecuted') {
return "SKIP";
}
return "FAIL";
}
/**
* Convert string data to HTML entities.
* @param {string} str String to convert.
* @returns String with HTML entities.
*/
function htmlEntities(str) {
return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
}
/**
* Adds delay to the parser execution.
* @param {string} ms Time in milliseconds (max 20 secs).
*/
function delay(ms) {
if (ms > 20000) {
ms = 20000
}
ms += new Date().getTime();
while (new Date() < ms) {}
}
/**
* Parse multiple MSTest (.trx) test result files.
* @param {string} pathToTestResult Path to result file directory or test result (.trx) file.
* @param {object} options Parser options. None Implemented.
* @returns Test results.
*/
function parse(pathToTestResult, options) {
return new Promise((resolve, reject) => {
if (options != null && options['delay'] != undefined) {
delay(options['delay']);
}
//Parser (Start)
console.log(` == Parser name: ${packageJson.name}, version ${packageJson.version} ==`);
console.log("Path to test result: " + pathToTestResult);
let resultFiles = [];
if (-1 !== pathToTestResult.indexOf("*")) {
resultFiles = globby.sync(pathToTestResult);
} else if (fs.statSync(pathToTestResult).isFile()) {
resultFiles.push(pathToTestResult);
} else if (fs.statSync(pathToTestResult).isDirectory()) {
let pattern = undefined;
pathToTestResult = pathToTestResult.replace(/\\/g, "/");
if (pathToTestResult[pathToTestResult.length - 1] === '/') {
pattern = pathToTestResult + "**/*.trx";
} else {
pattern = pathToTestResult + "/**/*.trx";
}
resultFiles = globby.sync(pattern);
}
if (0 === resultFiles.length) {
throw new Error(`Could not find any result log-file(s) in: '${pathToTestResult}'`);
}
let resultMap = new Map();
let order = 1;
for (let file of resultFiles) {
var outPut = undefined;
var errorInfoMessage = undefined;
var logOut = undefined;
var addResultFilesAttachments = undefined;
console.log(`== Parsing ${file} ... ==`);
try {
var testResults = fs.readFileSync(file, "utf-8");
xml2js.parseString(testResults, {
preserveChildrenOrder: true,
explicitArray: false,
explicitChildren: false
}, function(err, result) {
if (err) {
throw err;
} else {
var testruns = Array.isArray(result['TestRun']) ? result['TestRun'] : [result['TestRun']];
testruns.forEach(function(ts) {
var runName = ts.$.id;
var results = Array.isArray(ts['Results']) ? ts['Results'] : [ts['Results']];
results.forEach(function(tc) {
var unitTestResults = Array.isArray(tc['UnitTestResult']) ? tc['UnitTestResult'] : [tc['UnitTestResult']];
unitTestResults.forEach(function(tm) {
var testCaseName = tm.$.testName;
var testCaseId = tm.$.testId;
var testCaseStatus = getTestCaseStatus(tm.$.outcome);
var startTime = new Date(tm.$.startTime).toISOString();
var endTime = new Date(tm.$.endTime).toISOString();
var testLog = {
name: testCaseName,
status: testCaseStatus,
attachments: [],
exe_start_date: startTime,
exe_end_date: endTime,
automation_content: htmlEntities(testCaseName),
module_names: [runName],
order: order++
};
outPut = tm['Output'];
errorInfoMessage = outPut['ErrorInfo'];
addResultFilesAttachments = tm['ResultFiles'];
if ((typeof outPut !== 'undefined') && (outPut)) {
var stdOut = outPut['StdOut'];
if ((typeof stdOut !== 'undefined') && (stdOut)) {
logOut = '== OUTPUT == \n' + outPut['StdOut'] + '\n\n';
} else {
logOut = '== OUTPUT == \n\n';
}
if ((typeof errorInfoMessage !== 'undefined') && (errorInfoMessage)) {
var errorMessage = errorInfoMessage['Message'];
if ((typeof errorMessage !== 'undefined') && (errorMessage)) {
logOut = logOut + '== ERROR INFO (MESSAGE) == \n' + errorMessage + '\n\n';
}
var errorStackTrace = errorInfoMessage['StackTrace'];
if ((typeof errorStackTrace !== 'undefined') && (errorStackTrace)) {
logOut = logOut + '== ERROR INFO (STACKTRACE) == \n' + errorStackTrace + '\n\n';
}
}
if ((typeof addResultFilesAttachments !== 'undefined') && (addResultFilesAttachments)) {
var resultFilesAttachments = Array.isArray(addResultFilesAttachments['ResultFile']) ? addResultFilesAttachments['ResultFile'] : [addResultFilesAttachments['ResultFile']];
if ((typeof resultFilesAttachments !== 'undefined') && (resultFilesAttachments)) {
logOut = logOut + '== RESULT FILE ATTACHMENTS == \n\n';
let index = 0;
for (let resultFilesAttachment of resultFilesAttachments) {
index++;
var fileName = resultFilesAttachment.$.path.split('\\').pop().split('/').pop();
logOut = logOut + index + ". " + fileName + '\n';
}
}
}
if ((typeof logOut !== 'undefined') && (logOut)) {
testLog.attachments.push({
name: `${testCaseName}.log`,
data: Buffer.from(logOut).toString("base64"),
content_type: "text/plain"
});
}
}
resultMap.set(order, testLog)
});
});
});
}
});
} catch (error) {
console.error(`Could not parse ${file}`, error);
continue;
}
console.log(`== Finish parsing ${file} ... ==`);
}
return resolve(Array.from(resultMap.values()));
//Parser (End)
});
}
module.exports = {
parse: parse,
getTestCaseStatus: getTestCaseStatus,
htmlEntities: htmlEntities,
delay: delay
}