Skip to content

Commit

Permalink
feat: add env
Browse files Browse the repository at this point in the history
  • Loading branch information
Ma11hewThomas committed Feb 1, 2024
1 parent e977421 commit 5b509d2
Show file tree
Hide file tree
Showing 2 changed files with 161 additions and 21 deletions.
56 changes: 53 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
126 changes: 108 additions & 18 deletions src/generate-report.ts
Original file line number Diff line number Diff line change
@@ -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: {
Expand All @@ -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
Expand All @@ -75,7 +131,7 @@ class GenerateCtrfReport {
})
})
this.ctrfReport.results.summary.stop = Date.now()
this.writeToFile(this.filename, this.ctrfReport)
this.writeReportToFile(this.ctrfReport)
})
}

Expand All @@ -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)}`)
}
}
}
Expand Down

0 comments on commit 5b509d2

Please sign in to comment.