From 5b509d25be40b5cefce82e27f272a8c47b78e91c Mon Sep 17 00:00:00 2001 From: Matthew Thomas Date: Thu, 1 Feb 2024 23:09:28 +0000 Subject: [PATCH] feat: add env --- README.md | 56 +++++++++++++++++- src/generate-report.ts | 126 +++++++++++++++++++++++++++++++++++------ 2 files changed, 161 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index cbbf9c2..d8163de 100644 --- a/README.md +++ b/README.md @@ -13,19 +13,69 @@ A Postman newman test reporter to generate JSON test reports that are [CTRF](htt A JSON test report schema that is the same structure, no matter which testing tool is used. It's created to provide consistent test reporting agnostic of specific programming languages or testing frameworks. Where many testing frameworks exist, each generating JSON reports in their own way, CTRF provides a standardised schema helping you generate the same report anywhere. +``` json +{ + "results": { + "tool": { + "name": "newman" + }, + "summary": { + "tests": 4, + "passed": 3, + "failed": 1, + "pending": 0, + "skipped": 0, + "other": 0, + "start": 1706828654274, + "stop": 1706828655782 + }, + "tests": [ + { + "name": "API Status code is 200", + "status": "passed", + "duration": 801 + }, + ... + ], + "environment": { + "appName": "MyApp", + "buildName": "MyApp", + "buildNumber": "100" + } + } +} +``` + ## Installation ```bash -npm install --save-dev newman-reporter-ctrf-json +npm install newman-reporter-ctrf-json ``` Run your tests with the reporter argument: ```bash -newman run ./postman_collection.json -r newman-reporter-ctrf-json +newman run ./postman_collection.json -r ctrf-json ``` -You'll find a JSON file named `ctrf-report.json` in the root directory. +You'll find a JSON file named `ctrf-report.json` in the `ctrf` directory. + +## Reporter Options + +The reporter supports several configuration options passed via the command line: + +```bash +newman run ./postman_collection.json -r ctrf-json \ +--reporter-ctrf-json-output-file custom-name.json \ +--reporter-ctrf-json-output-dir custom-directory \ +--reporter-ctrf-json-app-name MyApp \ +--reporter-ctrf-json-app-version 1.0.0 \ +--reporter-ctrf-json-os-platform linux \ +--reporter-ctrf-json-os-release 18.04 \ +--reporter-ctrf-json-os-version 5.4.0 \ +--reporter-ctrf-json-build-name MyApp \ +--reporter-ctrf-json-build-number 100 +``` ## Test Object Properties diff --git a/src/generate-report.ts b/src/generate-report.ts index b69be57..da507fc 100644 --- a/src/generate-report.ts +++ b/src/generate-report.ts @@ -1,24 +1,57 @@ import * as fs from 'fs' import { type EventEmitter } from 'events' -import { type CtrfReport, type CtrfTestState } from '../types/ctrf' +import { + type CtrfEnvironment, + type CtrfReport, + type CtrfTestState, +} from '../types/ctrf' import { type NewmanRunOptions, type NewmanRunSummary } from 'newman' +import path = require('path') -interface ReporterOptions { - filename?: string +interface ReporterConfigOptions { + ctrfJsonOutputFile?: string + ctrfJsonOutputDir?: string + ctrfJsonMinimal?: boolean + ctrfJsonTestType?: string + ctrfJsonAppName?: string + ctrfJsonAppVersion?: string + ctrfJsonOsPlatform?: string + ctrfJsonOsRelease?: string + ctrfJsonOsVersion?: string + ctrfJsonBuildName?: string + ctrfJsonBuildNumber?: string } class GenerateCtrfReport { - private readonly ctrfReport: CtrfReport - private readonly reporterName = 'ctrf-json-reporter' - private readonly defaultFilename = 'ctrf-report.json' - private filename = this.defaultFilename + readonly ctrfReport: CtrfReport + readonly ctrfEnvironment: CtrfEnvironment + readonly reporterConfigOptions: ReporterConfigOptions + readonly reporterName = 'jest-ctrf-json-reporter' + readonly defaultOutputFile = 'ctrf-report.json' + readonly defaultOutputDir = 'ctrf' + filename = this.defaultOutputFile constructor( private readonly emitter: EventEmitter, - private readonly reporterOptions: ReporterOptions | undefined = undefined, + reporterOptions: ReporterConfigOptions, private readonly collectionRunOptions: NewmanRunOptions ) { this.registerEvents() + + this.reporterConfigOptions = { + ctrfJsonOutputFile: + reporterOptions?.ctrfJsonOutputFile ?? this.defaultOutputFile, + ctrfJsonOutputDir: + reporterOptions?.ctrfJsonOutputDir ?? this.defaultOutputDir, + ctrfJsonAppName: reporterOptions?.ctrfJsonAppName ?? undefined, + ctrfJsonAppVersion: reporterOptions?.ctrfJsonAppVersion ?? undefined, + ctrfJsonOsPlatform: reporterOptions?.ctrfJsonOsPlatform ?? undefined, + ctrfJsonOsRelease: reporterOptions?.ctrfJsonOsRelease ?? undefined, + ctrfJsonOsVersion: reporterOptions?.ctrfJsonOsVersion ?? undefined, + ctrfJsonBuildName: reporterOptions?.ctrfJsonBuildName ?? undefined, + ctrfJsonBuildNumber: reporterOptions?.ctrfJsonBuildNumber ?? undefined, + } + this.ctrfReport = { results: { tool: { @@ -37,21 +70,44 @@ class GenerateCtrfReport { tests: [], }, } + + this.ctrfEnvironment = {} + + if (this.reporterConfigOptions?.ctrfJsonOutputFile !== undefined) + this.setFilename(this.reporterConfigOptions.ctrfJsonOutputFile) + + if ( + !fs.existsSync( + this.reporterConfigOptions.ctrfJsonOutputDir ?? this.defaultOutputDir + ) + ) { + fs.mkdirSync( + this.reporterConfigOptions.ctrfJsonOutputDir ?? this.defaultOutputDir, + { recursive: true } + ) + } } private registerEvents(): void { + this.emitter.on('start', () => { + this.ctrfReport.results.summary.start = Date.now() + this.setEnvironmentDetails(this.reporterConfigOptions ?? {}) + if (this.hasEnvironmentDetails(this.ctrfEnvironment)) { + this.ctrfReport.results.environment = this.ctrfEnvironment + } + }) + this.emitter.on('done', (err, summary: NewmanRunSummary) => { if (err !== null || typeof summary === 'undefined') { return } if ( - this.reporterOptions?.filename !== undefined && - this.reporterOptions.filename !== '' + this.reporterConfigOptions?.ctrfJsonOutputFile !== undefined && + this.reporterConfigOptions.ctrfJsonOutputFile !== '' ) { - this.setFilename(this.reporterOptions.filename) + this.setFilename(this.reporterConfigOptions.ctrfJsonOutputFile) } - this.ctrfReport.results.summary.start = Date.now() summary.run.executions.forEach((execution) => { execution.assertions.forEach((assertion) => { this.ctrfReport.results.summary.tests += 1 @@ -75,7 +131,7 @@ class GenerateCtrfReport { }) }) this.ctrfReport.results.summary.stop = Date.now() - this.writeToFile(this.filename, this.ctrfReport) + this.writeReportToFile(this.ctrfReport) }) } @@ -87,16 +143,50 @@ class GenerateCtrfReport { } } - private writeToFile(filename: string, data: CtrfReport): void { + setEnvironmentDetails(reporterConfigOptions: ReporterConfigOptions): void { + if (reporterConfigOptions.ctrfJsonAppName !== undefined) { + this.ctrfEnvironment.appName = reporterConfigOptions.ctrfJsonAppName + } + if (reporterConfigOptions.ctrfJsonAppVersion !== undefined) { + this.ctrfEnvironment.appVersion = reporterConfigOptions.ctrfJsonAppVersion + } + if (reporterConfigOptions.ctrfJsonOsPlatform !== undefined) { + this.ctrfEnvironment.osPlatform = reporterConfigOptions.ctrfJsonOsPlatform + } + if (reporterConfigOptions.ctrfJsonOsRelease !== undefined) { + this.ctrfEnvironment.osRelease = reporterConfigOptions.ctrfJsonOsRelease + } + if (reporterConfigOptions.ctrfJsonOsVersion !== undefined) { + this.ctrfEnvironment.osVersion = reporterConfigOptions.ctrfJsonOsVersion + } + if (reporterConfigOptions.ctrfJsonBuildName !== undefined) { + this.ctrfEnvironment.buildName = reporterConfigOptions.ctrfJsonBuildName + } + if (reporterConfigOptions.ctrfJsonBuildNumber !== undefined) { + this.ctrfEnvironment.buildNumber = + reporterConfigOptions.ctrfJsonBuildNumber + } + } + + hasEnvironmentDetails(environment: CtrfEnvironment): boolean { + return Object.keys(environment).length > 0 + } + + private writeReportToFile(data: CtrfReport): void { + const filePath = path.join( + this.reporterConfigOptions.ctrfJsonOutputDir ?? this.defaultOutputDir, + this.filename + ) const str = JSON.stringify(data, null, 2) try { - fs.writeFileSync(filename, str + '\n') + fs.writeFileSync(filePath, str + '\n') console.log( - `${this.reporterName}: successfully written ctrf json to %s`, - filename + `${this.reporterName}: successfully written ctrf json to %s/%s`, + this.reporterConfigOptions.ctrfJsonOutputDir, + this.filename ) } catch (error) { - console.error(`Error writing ctrf json report: ${String(error)}`) + console.error(`Error writing ctrf json report:, ${String(error)}`) } } }