UNPKG

junit-converter

Version:

Test report files to JUnit XML converter

120 lines (105 loc) 4.3 kB
import * as fs from 'fs'; import * as path from 'path'; import xmlFormat from 'xml-formatter'; import { XmlConverter } from './xmlConverter.js'; import { ConfigService } from './config.js'; import { TestReportConverterOptions, XmlParserOptions, TestSuites, ConverterOptions } from './interfaces.js'; import { CtrfConverter } from './ctrfConverter.js'; import {toJson as xmlToJson, toXml as jsonToXml} from 'p3x-xml2json'; /** * Main converter service for test reports to JUnit XML */ export class Converter { private xmlParserOptions: XmlParserOptions = { object: true, arrayNotation: true, sanitize: false, reversible: true, }; private xmlFormatterOptions = { forceSelfClosingEmptyTag: true }; private formatXml(options: ConverterOptions, xml: string): string { return options.minify ? xmlFormat.minify(xml, this.xmlFormatterOptions) : xmlFormat(xml, this.xmlFormatterOptions); } /** * Convert test report to JUnit XML and write to file async * @param options Converter configuration * @throws {Error} If conversion or file writing fails */ async toFile(options: TestReportConverterOptions): Promise<void> { const config = ConfigService.config(options); let result; if(config.testType === 'ctrf'){ this.xmlParserOptions.sanitize = true; let xml = jsonToXml(CtrfConverter.convert(config), this.xmlParserOptions); result = this.formatXml(config, xml); } else{ result = await XmlConverter.convert(config); } fs.writeFileSync(path.join(config.reportDir, config.reportFile), result, 'utf8'); } /** * Convert test report to JUnit XML string * @param options Converter configuration * @returns {Promise<string>} Async formatted JUnit XML string * @throws {Error} If conversion fails */ async toString(options: TestReportConverterOptions): Promise<string> { const config = ConfigService.config(options); let result; if(config.testType === 'ctrf'){ this.xmlParserOptions.sanitize = true; let xml = jsonToXml(CtrfConverter.convert(config), this.xmlParserOptions); result = this.formatXml(config, xml); } else{ result = await XmlConverter.convert(config); } return result; } /** * Convert test report to JUnit and parse as JSON object * @param {TestReportConverterOptions} options Converter configuration * @returns {Promise<TestSuites>} Async parsed JSON object * @throws {Error} If conversion or JSON parsing fails */ async toJson(options: TestReportConverterOptions): Promise<TestSuites> { const xmlParserOptions: XmlParserOptions = { object: true, arrayNotation: true, sanitize: false, reversible: true, }; if (options.testType === 'ctrf') { const config = ConfigService.config(options); return CtrfConverter.convert(config); } else{ const str = await this.toString(options); try { return xmlToJson(str, xmlParserOptions) as TestSuites; } catch (e) { throw new Error( `Could not parse JSON from converted XML ${options.testFile}.\n ${ e instanceof Error ? e.message : String(e) }` ); } } } } // Create singleton instance for backward compatibility const converter = new Converter(); // Export instance methods for backward compatibility export const toFile = (options: TestReportConverterOptions): Promise<void> => converter.toFile(options); export const toString = (options: TestReportConverterOptions): Promise<string> => converter.toString(options); export const toJson = (options: TestReportConverterOptions): Promise<TestSuites> => converter.toJson(options); // Default export for CommonJS consumers export default { toFile, toString, toJson, Converter: Converter, };