UNPKG

cucumber-html-report-generator

Version:

Generate beautiful cucumberjs html reports for multiple instances (browsers / devices)

128 lines (110 loc) 6.61 kB
import * as CommonFunctions from '../../common-functions/common-functions'; import * as Messages from '../../helpers/console-messages'; import * as Models from '../../models/models'; import * as messages from '@cucumber/messages'; import { FeatureFormatter } from './feature-formatter'; import { v4 as uuidv4 } from 'uuid'; import GherkinDocument = messages.GherkinDocument; import IFeature = messages.Feature; export class SuiteFactory { private readonly userProperties: Models.ReportGeneration; private readonly suite: Models.ExtendedReport; public constructor( userProperies: Models.ReportGeneration ) { this.userProperties = userProperies; this.suite = this.initializeSuite(); } public async parseJsons ( collectedJsons: Models.Feature[], providedFeatures: GherkinDocument[] | null ): Promise<Models.ExtendedReport> { const features = await Promise.all( collectedJsons.map( jsonFeature => { const gherkinFeature = this.getGherkinFeature( providedFeatures, jsonFeature.name ); const feature = new FeatureFormatter( gherkinFeature, jsonFeature ).parseFeature(); this.updateSuiteStadistics( feature ); if ( !feature.elements?.length ) { console.log( Messages.featureRemoved( feature.name ) ); return null; } return feature; } ) ); this.suite.features = features.flatMap( feature => feature ? [ feature ] : [] ); this.updateSuiteProperties(); this.suite.results.overview.result = [ ...new Map( this.suite.results.overview.result.map( item => [ item.status, item ] ) ).values() ]; this.suite.results.overview.resultStatusesJoined = this.suite.results.overview.result.map( ( value ) => value.status.toString() ).sort().join( ';' ); if ( this.suite.features.some( feature => feature.metadata?.length ) ) { this.suite.haveFeaturesMetadata = true; } if ( this.userProperties.saveEnrichedJSON ) { await this.saveEnrichedJson(); } return this.suite; } private updateSuiteProperties (): void { this.suite.features = this.suite.features.sort( ( firstFeature, secondFeature ) => ( firstFeature.id! > secondFeature.id! ? 1 : -1 ) ); this.addMissingMetadataToFeatures(); this.suite.results.overview.durationHHMMSS = CommonFunctions.convertTimeFromNanoSecondsToHHMMSS( this.suite.results.overview.duration ); this.suite.metadata = CommonFunctions.isMetadata( this.userProperties.reportMetadata ) ? this.userProperties.reportMetadata : <Models.Metadata[]>[]; this.suite.features = this.setUniqueIdForEachFeature( this.suite.features ); } private async saveEnrichedJson (): Promise<void> { await CommonFunctions.saveJsonFile( this.userProperties.reportPath, 'enriched-output.json', this.suite ); } private getGherkinFeature ( providedFeatures: GherkinDocument[] | null, jsonFeatureName: string ): IFeature | null | undefined { return providedFeatures?.length ? providedFeatures.filter( document => document.feature?.name === jsonFeatureName )[ 0 ]?.feature : null; } private updateSuiteStadistics ( feature: Models.Feature ): void { const overview = feature.results.overview; this.suite.results.overview.duration += overview.duration; this.suite.results.features.passed += overview.result.filter( result => result.status === Models.Status.passed ).length === overview.result.length && overview.result.length ? 1 : 0; this.suite.results.features.failed += overview.result.filter( result => result.status === Models.Status.failed ).length === overview.result.length && overview.result.length ? 1 : 0; this.suite.results.features.pending += overview.result.filter( result => result.status === Models.Status.pending ).length === overview.result.length && overview.result.length ? 1 : 0; this.suite.results.features.skipped += overview.result.filter( result => result.status === Models.Status.skipped ).length === overview.result.length && overview.result.length ? 1 : 0; this.suite.results.features.ambiguous += overview.result.filter( result => result.status === Models.Status.ambiguous ).length === overview.result.length && overview.result.length ? 1 : 0; this.suite.results.features.undefined += overview.result.filter( result => result.status === Models.Status.undefined ).length === overview.result.length && overview.result.length ? 1 : 0; this.suite.results.features.various += Number( [ ... new Set( overview.result ) ].length > 1 ); this.suite.results.features.total++; this.suite.results.scenarios = CommonFunctions.updateResultsAndPercentages( this.suite.results.scenarios, feature.results.scenarios ); this.suite.results.steps = CommonFunctions.updateResultsAndPercentages( this.suite.results.steps, feature.results.steps ); this.suite.results.features = <Models.FeatureModuleResults>CommonFunctions.updatePercentages( this.suite.results.features ); this.suite.results.overview.result.push( ...feature.results.overview.result ); } private initializeSuite (): Models.ExtendedReport { const suite = <Models.ExtendedReport>{}; suite.results = Models.reportResultsInitializer(); suite.metadata = <Models.Metadata[]>[]; suite.metadataTitle = this.userProperties.reportMetadataTitle; suite.reportTitle = this.userProperties.reportTitle; suite.haveFeaturesMetadata = false; return suite; } private setUniqueIdForEachFeature ( features: Models.Feature[] ): Models.Feature[] { const seen = new Set(); const modifiedFeatures = features.map( feature => { if ( seen.size === seen.add( feature.id ).size ) { feature.id += uuidv4(); } return feature; } ); return modifiedFeatures; } private addMissingMetadataToFeatures (): void { const allMetadata: Models.Metadata[] = []; this.suite.features.forEach( feature => { if ( feature.metadata?.length ) { feature.metadata.forEach( metadataElement => { if ( !allMetadata.filter( metadataObject => metadataObject.name === metadataElement.name ).length ) { allMetadata.push( metadataElement ); } } ); } } ); this.suite.results.overview.metadata = allMetadata; this.suite.features.forEach( feature => { allMetadata.forEach( metadataElement => { const featureMetadataName = feature.metadata?.filter( featureMetadataElement => featureMetadataElement.name === metadataElement.name ); if ( !featureMetadataName?.length ) { feature.metadata!.push( { name: metadataElement.name, value: '' } ); } } ); } ); } }