From 44af7a55a3a0ab37c250a80dbde3ab61a3867ee5 Mon Sep 17 00:00:00 2001 From: Kevin Lakotko Date: Wed, 8 Nov 2023 16:40:51 -0500 Subject: [PATCH] feat(formatters): junit formatter extensibility --- src/formatter/junit_formatter.ts | 79 ++++++++++++++++++++++---------- 1 file changed, 56 insertions(+), 23 deletions(-) diff --git a/src/formatter/junit_formatter.ts b/src/formatter/junit_formatter.ts index 03722198d..b8a8ff7ff 100644 --- a/src/formatter/junit_formatter.ts +++ b/src/formatter/junit_formatter.ts @@ -20,7 +20,7 @@ import { import { getPickleStepMap, getStepKeyword } from './helpers/pickle_parser' import Formatter, { IFormatterOptions } from './' -interface IJUnitTestSuite { +export interface IJUnitTestSuite { name: string failures: number skipped: number @@ -28,7 +28,7 @@ interface IJUnitTestSuite { tests: IJUnitTestCase[] } -interface IJUnitTestCase { +export interface IJUnitTestCase { classname: string name: string time: number @@ -258,32 +258,65 @@ export default class JunitFormatter extends Formatter { this.log(this.buildXmlReport(testSuite)) } + buildTestSuite(testSuite: IJUnitTestSuite): Record { + return { + testsuite: { + '@failures': testSuite.failures, + '@skipped': testSuite.skipped, + '@name': testSuite.name, + '@time': testSuite.time, + '@tests': testSuite.tests.length, + }, + } + } + + buildTestCase(test: IJUnitTestCase): Record { + return { + testcase: { + '@classname': test.classname, + '@name': test.name, + '@time': test.time, + }, + } + } + + buildSkippedCase(_test: IJUnitTestCase): Record { + return { + skipped: {}, + } + } + + buildFailedCase(test: IJUnitTestCase): Record { + return { + failure: { + '@type': test.result.failure?.type, + '@message': test.result.failure?.message, + '#cdata': test.result.failure?.detail, + }, + } + } + + buildSystemOutput(test: IJUnitTestCase): Record { + return { + 'system-out': { + '#cdata': test.systemOutput, + }, + } + } + private buildXmlReport(testSuite: IJUnitTestSuite): string { - const xmlReport = xmlbuilder - .create('testsuite', { invalidCharReplacement: '' }) - .att('failures', testSuite.failures) - .att('skipped', testSuite.skipped) - .att('name', testSuite.name) - .att('time', testSuite.time) - .att('tests', testSuite.tests.length) + const xmlReport = xmlbuilder.create(this.buildTestSuite(testSuite), { + invalidCharReplacement: '', + }) + testSuite.tests.forEach((test) => { - const xmlTestCase = xmlReport.ele('testcase', { - classname: test.classname, - name: test.name, - time: test.time, - }) + const xmlTestCase = xmlReport.ele(this.buildTestCase(test)) if (test.result.status === TestStepResultStatus.SKIPPED) { - xmlTestCase.ele('skipped') + xmlTestCase.ele(this.buildSkippedCase(test)) } else if (test.result.status !== TestStepResultStatus.PASSED) { - const xmlFailure = xmlTestCase.ele('failure', { - type: test.result.failure?.type, - message: test.result.failure?.message, - }) - if (test.result?.failure) { - xmlFailure.cdata(test.result.failure.detail) - } + xmlTestCase.ele(this.buildFailedCase(test)) } - xmlTestCase.ele('system-out', {}).cdata(test.systemOutput) + xmlTestCase.ele(this.buildSystemOutput(test)) }) return xmlReport.end({ pretty: true })