diff --git a/package-lock.json b/package-lock.json
index 5ab5fbb..2ceaeb3 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "test-results-parser",
- "version": "0.1.10",
+ "version": "0.1.11",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "test-results-parser",
- "version": "0.1.10",
+ "version": "0.1.11",
"license": "MIT",
"dependencies": {
"fast-xml-parser": "^4.3.2",
diff --git a/package.json b/package.json
index 8ee509a..40c4df4 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "test-results-parser",
- "version": "0.1.10",
+ "version": "0.1.11",
"description": "Parse test results from JUnit, TestNG, xUnit, cucumber and many more",
"main": "src/index.js",
"types": "./src/index.d.ts",
diff --git a/src/parsers/junit.js b/src/parsers/junit.js
index 0325272..33addb2 100644
--- a/src/parsers/junit.js
+++ b/src/parsers/junit.js
@@ -11,7 +11,7 @@ function getTestCase(rawCase, suite_meta) {
test_case.duration = rawCase["@_time"] * 1000;
test_case.meta_data = new Map(suite_meta);
setAttachments(rawCase, test_case);
- setMetaData(rawCase, test_case);
+ setMetaData(rawCase, test_case);
if (rawCase.failure && rawCase.failure.length > 0) {
test_case.status = 'FAIL';
test_case.setFailure(rawCase.failure[0]["@_message"]);
@@ -50,7 +50,7 @@ function getTestSuite(rawSuite) {
/**
* @param {import('./junit.result').JUnitTestSuite | import('./junit.result').JUnitTestCase} rawElement
- * @param {TestCase | TestSuite} test_element
+ * @param {TestCase | TestSuite} test_element
*/
function setMetaData(rawElement, test_element) {
if (rawElement.properties && rawElement.properties.property.length > 0) {
@@ -88,7 +88,7 @@ function setAttachments(rawCase, test_element) {
if (filePath.length > 0) {
const attachment = new TestAttachment();
- attachment.path = filePath;
+ attachment.path = filePath;
test_element.attachments.push(attachment);
}
}
@@ -96,7 +96,7 @@ function setAttachments(rawCase, test_element) {
}
/**
- * @param {TestResult} result
+ * @param {TestResult} result
*/
function setAggregateResults(result) {
if (Number.isNaN(result.passed) || Number.isNaN(result.failed)) {
@@ -105,30 +105,32 @@ function setAggregateResults(result) {
let failed = 0;
let errors = 0;
let skipped = 0;
- let duration = 0;
result.suites.forEach(_suite => {
total = _suite.total + total;
passed = _suite.passed + passed;
failed = _suite.failed + failed;
errors = _suite.errors + errors;
skipped = _suite.skipped + skipped;
- duration = _suite.duration + duration;
});
result.passed = passed;
result.failed = failed;
result.errors = errors;
result.skipped = skipped;
result.total = total;
- if (Number.isNaN(result.duration)) {
- result.duration = duration;
- }
+ }
+ if (Number.isNaN(result.duration)) {
+ let duration = 0;
+ result.suites.forEach(_suite => {
+ duration = _suite.duration + duration;
+ });
+ result.duration = duration;
}
}
/**
- *
- * @param {import('./junit.result').JUnitResultJson} json
- * @returns
+ *
+ * @param {import('./junit.result').JUnitResultJson} json
+ * @returns
*/
function getTestResult(json) {
const result = new TestResult();
@@ -147,18 +149,21 @@ function getTestResult(json) {
result.total = result.total - result.skipped;
result.passed = result.total - result.failed - result.errors;
result.duration = rawResult["@_time"] * 1000;
- if (json["testsuites"]) { // top-level element is testsuites
+ // top-level element is testsuites
+ if (json["testsuites"]) {
const rawSuites = rawResult["testsuite"];
- if (!(typeof rawSuites === "undefined")) { // Don't filter if there are no testsuite objects
+ // Don't filter if there are no testsuite objects
+ if (!(typeof rawSuites === "undefined")) {
const filteredSuites = rawSuites.filter(suite => suite.testcase);
for (let i = 0; i < filteredSuites.length; i++) {
result.suites.push(getTestSuite(filteredSuites[i]));
}
}
- } else { // top level element is testsuite
+ } else {
+ // top level element is testsuite
result.suites.push(getTestSuite(rawResult));
}
-
+
setAggregateResults(result);
result.status = result.total === result.passed ? 'PASS' : 'FAIL';
return result;
diff --git a/tests/data/junit/wdio/results-0-0.xml b/tests/data/junit/wdio/results-0-0.xml
new file mode 100644
index 0000000..d707b38
--- /dev/null
+++ b/tests/data/junit/wdio/results-0-0.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/data/junit/wdio/results-0-1.xml b/tests/data/junit/wdio/results-0-1.xml
new file mode 100644
index 0000000..b8f38b0
--- /dev/null
+++ b/tests/data/junit/wdio/results-0-1.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/parser.junit.spec.js b/tests/parser.junit.spec.js
index a799184..951e34b 100644
--- a/tests/parser.junit.spec.js
+++ b/tests/parser.junit.spec.js
@@ -3,9 +3,9 @@ const assert = require('assert');
const path = require('path');
describe('Parser - JUnit', () => {
-
+
const testDataPath = "tests/data/junit"
-
+
it('single suite with single test', () => {
const result = parse({ type: 'junit', files: [`${testDataPath}/single-suite.xml`] });
assert.deepEqual(result, {
@@ -450,7 +450,7 @@ describe('Parser - JUnit', () => {
it('parse spekt/junit.testlogger', () => {
const result = parse({ type: 'junit', files: [`${testDataPath}/junit.testlogger.xml`] });
- var inheritedProperties = new Map([ ["hostname", "REDACTED"] ]);
+ var inheritedProperties = new Map([["hostname", "REDACTED"]]);
assert.deepEqual(result, {
id: "",
name: "",
@@ -574,10 +574,10 @@ describe('Parser - JUnit', () => {
let absolutePath = path.resolve(relativePath);
const result1 = parse({ type: 'junit', files: [absolutePath] });
assert.notEqual(null, result1);
- const result2 = parse({ type: 'junit', files: [relativePath]});
+ const result2 = parse({ type: 'junit', files: [relativePath] });
assert.notEqual(null, result2);
});
-
+
it('meta-data from suite merged with testcase', () => {
const result = parse({ type: 'junit', files: ['tests/data/junit/multiple-suites-properties.xml'] });
@@ -594,7 +594,7 @@ describe('Parser - JUnit', () => {
it('include hostname in meta-data from suite and testcase', () => {
const result = parse({ type: 'junit', files: ['tests/data/junit/playwright.xml'] });
-
+
assert.equal(result.suites[0].meta_data.get("hostname"), "chromium");
assert.equal(result.suites[0].cases[0].meta_data.get("hostname"), "chromium");
assert.equal(result.suites[0].cases[1].meta_data.get("hostname"), "chromium");
@@ -606,7 +606,7 @@ describe('Parser - JUnit', () => {
assert.equal(result.suites[2].meta_data.get("hostname"), "webkit");
assert.equal(result.suites[2].cases[0].meta_data.get("hostname"), "webkit");
assert.equal(result.suites[2].cases[1].meta_data.get("hostname"), "webkit");
-
+
});
it('parse system.out to locate attachments', () => {
@@ -628,4 +628,13 @@ describe('Parser - JUnit', () => {
assert.equal(result.suites[0].cases[3].attachments.length, 0);
});
+ it('wdio - multiple files', () => {
+ const result = parse({ type: 'junit', files: [`${testDataPath}/wdio/*.xml`] });
+ assert.equal(result.total, 9);
+ assert.equal(result.passed, 9);
+ assert.equal(result.failed, 0);
+ assert.equal(result.duration, 157489);
+ assert.equal(result.status, 'PASS');
+ });
+
});
\ No newline at end of file