UNPKG

junit-converter

Version:

Test report files to JUnit XML converter

115 lines (92 loc) 3.9 kB
const fs = require('fs'); const path = require('path'); const parser = require('p3x-xml2json'); const xmlFormat = require('xml-formatter'); const _ = require('lodash'); /** * @param {ConverterOptions} options * @param {any} json * @returns {any} */ function sortByClassname(options, json){ json.testsuites[0].testsuite[0].testcase = _.sortBy(json.testsuites[0].testsuite[0].testcase, ['classname' ,'name']); let classnames = _.map(json.testsuites[0].testsuite[0].testcase, 'classname') .filter((value, index, array) => array.indexOf(value) === index); classnames = _.sortBy(classnames, [function(o) { return o; }]); let time = _.sumBy(json.testsuites[0].testsuite, suite => _.sumBy(suite.testcase, function(testCase) { return Number(testCase.time); })); json.testsuites[0].time = time; json.testsuites[0].testsuite[0].time = time; if(classnames.length > 1){ let testSuites = []; classnames.forEach((classname) => { let testcases = _.filter(json.testsuites[0].testsuite[0].testcase, { 'classname': classname}); let time = _.sumBy(testcases, function(testCase) { return Number(testCase.time); }); const failures = testcases.filter((testCase) => testCase.status === 'Failed').length; const skipped = testcases.filter((testCase) => testCase.status === 'Skipped').length; testSuites.push( { name: classname, tests: `${testcases.length}`, failures: `${failures}`, skipped: `${skipped}`, time: `${time}`, testcase: testcases, } ); }); json.testsuites[0].testsuite = testSuites; } else{ json.testsuites[0].testsuite[0].time = time; json.testsuites[0].testsuite[0].name = json.testsuites[0].testsuite[0].testcase[0].classname; } return json; } /** * @param {ConverterOptions} options * @param {string} xml * @returns {string} */ function processXml(options, xml){ let xmlParserOptions = { object: true, arrayNotation: true, sanitize: false, reversible: true, } let json; try{ json = parser.toJson(xml, xmlParserOptions); } catch (e){ throw `Could not parse JSON from converted XML ${options.testFile}.\n ${e.message}`; } if((json && json.testsuites && json.testsuites.length && json.testsuites.length === 0) || (!json || !json.testsuites || !json.testsuites.length || !json.testsuites[0].testsuite || !json.testsuites[0].testsuite.length || json.testsuites[0].testsuite.length === 0) ){ console.warn('No test suites found, skipping JUnit file creation.'); return null; } if(options.saveIntermediateFiles){ let fileName = `${path.parse(options.testFile).name}-converted.json`; fs.writeFileSync(path.join(options.reportDir, fileName), JSON.stringify(json, null, 2), 'utf8'); } // sort test suites if(json.testsuites[0].testsuite[0].file && json.testsuites[0].testsuite[0].name){ json.testsuites[0].testsuite = _.sortBy(json.testsuites[0].testsuite, ['file', 'name']) } else if(json.testsuites[0].testsuite[0].name){ json.testsuites[0].testsuite = _.sortBy(json.testsuites[0].testsuite, ['name']) } json = sortByClassname(options, json); xmlParserOptions.sanitize = true; return options.minify ? xmlFormat.minify(parser.toXml(json, xmlParserOptions), {forceSelfClosingEmptyTag: true}) : xmlFormat(parser.toXml(json, xmlParserOptions), {forceSelfClosingEmptyTag: true}) } module.exports = { processXml };