UNPKG

junit-converter

Version:

Test report files to JUnit XML converter

130 lines (110 loc) 4.79 kB
import * as fs from 'fs'; import * as path from 'path'; import * as _ from 'lodash'; import { ConverterOptions, TestSuites, TestSuite } from './interfaces.js'; import { CTRFReport, Test } from './ctrf.js'; export class CtrfConverter { private static suites: Record<string, TestSuite> = {}; private static getStdout(stdin: string[] | undefined): any[] | undefined { let stdout; if(stdin && stdin.length > 0){ stdout = []; stdout.push({ '$t': stdin.join('\n'), }); } return stdout; } private static parseTests(report: CTRFReport) { let suiteName: string = 'Root Suite'; report.results.tests.forEach((test: Test) => { if(test.suite && test.suite.length > 0){ if(typeof test.suite === 'string'){ suiteName = test.suite; } else if(Array.isArray(test.suite)){ suiteName = test.suite.join(' > '); } } if(!this.suites[suiteName]){ this.suites[suiteName] = { name: suiteName, tests: 0, failures: 0, skipped: 0, errors: 0, time: 0, testcase: [] }; } this.suites[suiteName].tests = Number(this.suites[suiteName].tests) + 1; this.suites[suiteName].time = Number(this.suites[suiteName].time) + Number(test.duration) / 1000; if(test.status.toLowerCase() === 'failed'){ this.suites[suiteName].failures = Number(this.suites[suiteName].failures) + 1; } else if(test.status.toLowerCase() === 'skipped'){ this.suites[suiteName].skipped = Number(this.suites[suiteName].skipped) + 1; } else if(test.status.toLowerCase() === 'pending'){ this.suites[suiteName].skipped = Number(this.suites[suiteName].skipped) + 1; } let stdout = this.getStdout(test.stdout); let stderr = this.getStdout(test.stderr); let failure; if(test.message || test.trace){ failure = []; failure.push({ message: test.message, '$t': test.trace, }); } let properties: any[] = []; if(test.parameters && Object.keys(test.parameters).length > 0){ properties.push({property: []}); Object.keys(test.parameters).forEach((key) => { properties[0].property.push({ name: key, value: String(test.parameters ? test.parameters[key] : ''), }); }); } this.suites[suiteName].testcase.push({ name: test.name.replace(`${suiteName}: `, ''), classname: suiteName, status: test.status.replace('pending', 'skipped'), time: String(Number(test.duration) / 1000), failure: failure, 'system-out': stdout, 'system-err': stderr, properties: properties, }); }); } static convert(options: ConverterOptions): TestSuites{ const report = JSON.parse(fs.readFileSync(options.testFile, 'utf8')) as CTRFReport; this.suites = {}; const duration = report.results.summary.duration ? Number(report.results.summary.duration) / 1000 : _.sumBy(report.results.tests, function (test: Test) { return (Number(test.duration) || 0) / 1000; }); this.parseTests(report); const converted = { testsuites: [ { name: report.results.environment?.reportName || 'CTRF Test Suite', tests: report.results.summary.tests, failures: report.results.summary.failed, skipped: report.results.summary.skipped + report.results.summary.pending, errors: 0, time: duration, testsuite: Object.values(this.suites), }, ], }; if(options.saveIntermediateFiles){ fs.writeFileSync(path.join(options.reportDir, `${path.parse(options.testFile).name}-converted.json`), JSON.stringify(converted, null, 2), 'utf8'); } return converted; } }