Skip to content

Commit

Permalink
junit and cucumber stack trace (#61)
Browse files Browse the repository at this point in the history
  • Loading branch information
ASaiAnudeep authored Apr 16, 2024
1 parent 9948282 commit bb91b92
Show file tree
Hide file tree
Showing 8 changed files with 49 additions and 18 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "test-results-parser",
"version": "0.1.12",
"version": "0.1.13",
"description": "Parse test results from JUnit, TestNG, xUnit, cucumber and many more",
"main": "src/index.js",
"types": "./src/index.d.ts",
Expand Down
6 changes: 4 additions & 2 deletions src/helpers/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ const FORCED_ARRAY_KEYS = [
"testsuites.testsuite",
"testsuites.testsuite.testcase",
"testsuites.testsuite.testcase.failure",
"testsuites.testsuite.testcase.error",
"testsuites.testsuite.testcase.system-err",
"testsuites.testsuite.testcase.properties.property",
"assemblies",
"assemblies.assembly",
Expand All @@ -43,7 +45,7 @@ const configured_parser = new XMLParser({
isArray: (name, jpath, isLeafNode, isAttribute) => {
if( FORCED_ARRAY_KEYS.indexOf(jpath) !== -1) {
return true;
}
}
// handle nunit deep hierarchy
else if (jpath.startsWith("test-results") || jpath.startsWith("test-run")) {
let parts = jpath.split(".");
Expand Down Expand Up @@ -74,7 +76,7 @@ function getJsonFromXMLFile(filePath) {
}

/**
* @param {string} file_path
* @param {string} file_path
*/
function getMatchingFilePaths(file_path) {
if (file_path.includes('*')) {
Expand Down
34 changes: 26 additions & 8 deletions src/parsers/cucumber.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ function getTestCase(rawCase) {
setMetaData(rawCase, test_case);
if (rawCase.state && rawCase.state === "failed") {
test_case.status = 'FAIL';
test_case.setFailure(rawCase.errorStack);
set_error_and_stack_trace(test_case, rawCase.errorStack);
}
else {
test_case.status = 'PASS';
Expand All @@ -20,9 +20,27 @@ function getTestCase(rawCase) {
}

/**
*
* @param {import('./cucumber.result').CucumberElement} element
* @param {TestCase | TestSuite} test_element
* @param {TestCase} test_case
* @param {string?} message
*/
function set_error_and_stack_trace(test_case, message) {
if (message) {
const stack_trace_start_index = message.indexOf(' at ');
if (stack_trace_start_index) {
const failure = message.slice(0, stack_trace_start_index);
const stack_trace = message.slice(stack_trace_start_index);
test_case.setFailure(failure);
test_case.stack_trace = stack_trace;
} else {
test_case.setFailure(message);
}
}
}

/**
*
* @param {import('./cucumber.result').CucumberElement} element
* @param {TestCase | TestSuite} test_element
*/
function setMetaData(element, test_element) {
const meta_tags = [];
Expand Down Expand Up @@ -62,7 +80,7 @@ function getTestSuite(rawSuite) {
}

/**
* @param {import("./cucumber.result").CucumberJsonResult} json
* @param {import("./cucumber.result").CucumberJsonResult} json
*/
function getTestResult(json) {
const result = new TestResult();
Expand All @@ -88,7 +106,7 @@ function getTestResult(json) {

/**
* Function to format the raw json report
* @param {import("./cucumber.result").CucumberJsonResult} json
* @param {import("./cucumber.result").CucumberJsonResult} json
* @returns formatted json object
*/
function preprocess(json) {
Expand All @@ -113,15 +131,15 @@ function preprocess(json) {

formattedResult.stats.suites = formattedResult.suites.length;
for (const statsType of ["tests", "passes", "failures", "errors", "duration"]) {
formattedResult.stats[statsType] = formattedResult.suites.map(testSuite => testSuite[statsType]).reduce((total, currVal) => total + currVal, 0) || 0;
formattedResult.stats[statsType] = formattedResult.suites.map(testSuite => testSuite[statsType]).reduce((total, currVal) => total + currVal, 0) || 0;
}
return formattedResult;
}

function parse(file) {
const json = require(resolveFilePath(file));
return getTestResult(json);
}
}

module.exports = {
parse
Expand Down
7 changes: 7 additions & 0 deletions src/parsers/junit.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ function getTestCase(rawCase, suite_meta) {
if (rawCase.failure && rawCase.failure.length > 0) {
test_case.status = 'FAIL';
test_case.setFailure(rawCase.failure[0]["@_message"]);
// wdio junit reporter
if (!test_case.failure && rawCase.error && rawCase.error.length > 0) {
test_case.setFailure(rawCase.error[0]["@_message"]);
}
if (rawCase['system-err'] && rawCase['system-err'].length > 0) {
test_case.stack_trace = rawCase['system-err'][0];
}
} else {
test_case.status = 'PASS';
}
Expand Down
2 changes: 1 addition & 1 deletion src/parsers/testng.js
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ function parse(file) {
const suite = suites[0];
result.name = suite['@_name'];
result.duration = suite['@_duration-ms'];
console.log("No suites with tests found");
console.warn("No suites with tests found");
}
result.status = result.total === result.passed ? 'PASS' : 'FAIL';
return result;
Expand Down
8 changes: 4 additions & 4 deletions tests/parser.cucumber.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ const assert = require('assert');
const path = require('path');

describe('Parser - Cucumber Json', () => {

const testDataPath = "tests/data/cucumber"

it('single suite with single test', () => {
const result = parse({ type: 'cucumber', files: [`${testDataPath}/single-suite-single-test.json`] });
assert.deepEqual(result, {
Expand Down Expand Up @@ -102,12 +102,12 @@ describe('Parser - Cucumber Json', () => {
duration: 2.56,
errors: 0,
failed: 0,
failure: "AssertionError [ERR_ASSERTION]: 13 == 14\n + expected - actual\n\n -13\n +14\n\n at CustomWorld.<anonymous> (D:\\workspace\\nodejs\\cc-tests\\features\\support\\steps.js:18:12)",
failure: "AssertionError [ERR_ASSERTION]: 13 == 14\n + expected - actual\n\n -13\n +14\n\n",
id: "",
name: "Addition of two numbers",
passed: 0,
skipped: 0,
stack_trace: "",
stack_trace: " at CustomWorld.<anonymous> (D:\\workspace\\nodejs\\cc-tests\\features\\support\\steps.js:18:12)",
status: "FAIL",
meta_data: new Map(),
steps: [],
Expand Down
4 changes: 4 additions & 0 deletions tests/parser.junit.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,10 @@ describe('Parser - JUnit', () => {
assert.equal(result.errors, 0);
assert.equal(result.duration, 91024);
assert.equal(result.status, 'FAIL');
assert.equal(result.suites[0].cases[1].failure, `Error: element ("//button/span[text()='Continue']") still displayed after 20000ms`);
assert.match(result.suites[0].cases[1].stack_trace, /at file/);
assert.match(result.suites[0].cases[1].stack_trace, /async Element.wrapCommandFn/);
assert.match(result.suites[0].cases[1].stack_trace, /middlewares.js:18:32/);
});

});

0 comments on commit bb91b92

Please sign in to comment.