import { ContentType , Severity , Allure } from 'allure-js-commons' ; const defaultTrackerAddress = 'http://localhost' ; let pmsUrl = defaultTrackerAddress ; let tmsUrl = defaultTrackerAddress ; let allure ; /**
 * This code was partially cloned from testdeck/core package and improved to support missing features.
 */ const nodeSymbol = ( key ) : string => '__testdeck_' + key ; const testNameSymbol = nodeSymbol ( 'name' ) ; const parametersSymbol = nodeSymbol ( 'parametersSymbol' ) ; const nameForParametersSymbol = nodeSymbol ( 'nameForParameters' ) ; type Params = any | ( ( arg ? : any ) => any ) ; type Execution = undefined | 'pending' | 'only' | 'skip' | 'execution' ; type TestDecorator = ( target : object , property : string , descriptor : PropertyDescriptor ) => PropertyDescriptor ; type ParamsDecorator = ( params : Params , name ? : string ) => TestDecorator ; interface ParameterizedPropertyDescriptor extends PropertyDescriptor { ( params , name ? ) : MethodDecorator ; skip ( params , name ? ) : MethodDecorator ; only ( params , name ? ) : MethodDecorator ; pending ( params , name ? ) : MethodDecorator ; naming ( nameForParameters ) : MethodDecorator ; } const enum LinkType { issue = 'issue' , tms = 'tms' } export const data = makeParamsObject ( ) ; export function step < T > ( nameFn ) { return ( target , propertyKey , descriptor ) => { const original = descriptor . value ; let callable = ( ) => { } ; if ( typeof original === 'function' ) { descriptor . value = function ( ... args ) { try { const value = typeof nameFn === 'function' ? nameFn . apply ( this , args ) : nameFn ; callable = ( ) => getAllure ( ) . step ( value , ( ) => original . apply ( this , args ) ) ; } catch ( e ) { console . error ( `[ERROR] Failed to apply decorator: ${ e }` ) ; } return callable . apply ( this , args ) ; } ; } return descriptor ; } ; } export function attachment < T > ( name , type ) { return ( target , propertyKey , descriptor ) => { const original = descriptor . value ; let callable = ( ) => { } ; if ( typeof original === 'function' ) { descriptor . value = function ( ... args ) { try { const content = original . apply ( this , args ) ; callable = ( ) => getAllure ( ) . attachment ( name , content , type ) ; } catch ( e ) { console . error ( `[ERROR] Failed to apply decorator: ${ e }` ) ; } return callable . apply ( this , args ) ; } ; } return descriptor ; } ; } export function testCaseId < T > ( idFn ) { return processDecorator ( idFn , ( id ) => getAllure ( ) . link ( `${ tmsUrl }/${ id }` , id , LinkType . tms ) ) ; } export function issue < T > ( idFn ) { return processDecorator ( idFn , ( id ) => getAllure ( ) . link ( `${ pmsUrl }/${ id }` , id , LinkType . issue ) ) ; } export function feature < T > ( featureFn ) { return processDecorator ( featureFn , ( name ) => getAllure ( ) . feature ( name ) ) ; } export function story < T > ( storyFn ) { return processDecorator ( storyFn , ( name ) => getAllure ( ) . story ( name ) ) ; } export function severity < T > ( severityFn ) { return processDecorator ( severityFn , ( name ) => getAllure ( ) . severity ( name ) ) ; } export function tag < T > ( tagFn ) { return processDecorator ( tagFn , ( name ) => getAllure ( ) . tag ( name ) ) ; } export function owner < T > ( ownerFn ) { return processDecorator ( ownerFn , ( name ) => getAllure ( ) . owner ( name ) ) ; } export function epic < T > ( epicFn ) { return processDecorator ( epicFn , ( name ) => getAllure ( ) . epic ( name ) ) ; } export function description < T > ( descriptionFn ) { return processDecorator ( descriptionFn , ( text ) => getAllure ( ) . description ( text ) ) ; } export function assignTmsUrl ( url ) { tmsUrl = url ; } export function assignPmsUrl ( url ) { pmsUrl = url ; } export function decorate < T extends Allure > ( allureInstance ) { allure = allureInstance ; } function getAllure < T extends Allure > ( ) { if ( ! allure ) { throw new Error ( 'Unable to find Allure implementation' ) ; } return allure as T ; } function processDescriptor < T > ( parameterFn , reporterFn , descriptor ) { const original = descriptor . value ; if ( typeof original === 'function' ) { descriptor . value = function ( ... args ) { try { const value = typeof parameterFn === 'function' ? parameterFn . apply ( this , args ) : parameterFn ; reporterFn ( value ) ; } catch ( e ) { console . error ( `[ERROR] Failed to apply decorator: ${ e }` ) ; } return original . apply ( this , args ) ; } ; } for ( const prop of Object . keys ( original ) ) { if ( original . hasOwnProperty ( prop ) && prop . startsWith ( '__testdeck_' ) ) { descriptor . value [ prop ] = original [ prop ] ; } } return descriptor ; } function makeParamsFunction < T > ( execution ? ) { return ( params , name ? ) => { return ( target , propertyKey , descriptor ) => { const adjustedParams = typeof params === 'function' ? params ( ) : params ; target [ propertyKey ] [ testNameSymbol ] = propertyKey . toString ( ) ; target [ propertyKey ] [ parametersSymbol ] = target [ propertyKey ] [ parametersSymbol ] || [ ] ; [ ] . concat ( adjustedParams || [ ] ) . forEach ( ( param ) => { target [ propertyKey ] [ parametersSymbol ] . push ( { execution , name , params : param } ) ; } ) ; return processDescriptor < T > ( ( args ) => JSON . stringify ( args ) , ( arg ) => getAllure ( ) . parameter ( 'inputs' , arg ) , descriptor ) ; } ; } ; } function makeParamsNameFunction ( ) { return ( nameForParameters ) => { return ( target , propertyKey , descriptor ) => { target [ propertyKey ] [ nameForParametersSymbol ] = nameForParameters ; return descriptor ; } ; } ; } function makeParamsObject ( ) { return Object . assign ( makeParamsFunction ( ) , { only : makeParamsFunction ( 'only' ) , pending : makeParamsFunction ( 'pending' ) , skip : makeParamsFunction ( 'skip' ) , naming : makeParamsNameFunction ( ) , } ) ; } function processDecorator < T > ( parameterFn , reporterFn ) { return ( target , property , descriptor ) => { return processDescriptor ( parameterFn , reporterFn , descriptor ) ; } ; }