From db4b903e858c8f551d9866698c1bf8c172cb41f1 Mon Sep 17 00:00:00 2001 From: Anudeep Date: Mon, 8 Apr 2024 22:56:16 +0530 Subject: [PATCH] feat: copy duration to root from suite (#58) --- package-lock.json | 4 +-- package.json | 2 +- src/parsers/junit.js | 37 +++++++++++++++------------ tests/data/junit/wdio/results-0-0.xml | 31 ++++++++++++++++++++++ tests/data/junit/wdio/results-0-1.xml | 36 ++++++++++++++++++++++++++ tests/parser.junit.spec.js | 23 ++++++++++++----- 6 files changed, 107 insertions(+), 26 deletions(-) create mode 100644 tests/data/junit/wdio/results-0-0.xml create mode 100644 tests/data/junit/wdio/results-0-1.xml 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