import KSUID from 'ksuid' ; import { promisify } from 'util' ; import { writeFile } from 'fs' ; import { WorkRoot } from '../runtime-environment/types' ; import { NetworkTraceData , CompositeTraceData , Assertion } from '@flood/element-report' ; const writeFileAsync = promisify ( writeFile ) ; interface ErrorLike { message : string ; stack ? : string | string [ ] ; } export interface IObjectTrace { addError ( error ) : void ; addNetworkTrace ( trace ) : Promise < void > ; addScreenshot ( screenshotURL ) : void ; addAssertion ( assertion ) : void ; isEmpty : boolean ; toObject ( ) : CompositeTraceData ; } export const NullObjectTrace = { isEmpty : true , addError ( error ) { } , async addNetworkTrace ( trace ) { } , addScreenshot ( screenshotURL ) { } , addAssertion ( assertion ) { } , toObject ( ) { return { op : 'object' , label : '' , objects : [ ] , errors : [ ] , assertions : [ ] , objectTypes : [ ] , } ; } , } ; export class ObjectTrace { constructor ( private workRoot , public label , public errors = [ ] , public assertions = [ ] , public screenshots = [ ] , public networkTraces = [ ] ) { } public addError ( error ) { const { message , stack } = error ; this . errors . push ( { message , stack , } ) ; } public async addNetworkTrace ( trace ) { const fileId = await KSUID . random ( ) . then ( ( id ) => id . string ) ; const filePath = this . workRoot . join ( 'network' , `${ fileId }.json` ) ; this . networkTraces . push ( filePath ) ; return writeFileAsync ( filePath , JSON . stringify ( trace ) ) . catch ( ( err ) => { console . error ( `Object Trace writing ERROR: ${ err . message }` ) ; } ) ; } public addScreenshot ( screenshotURL ) { this . screenshots . push ( screenshotURL ) ; } public addAssertion ( assertion ) { this . assertions . push ( assertion ) ; } get isEmpty ( ) : boolean { const { screenshots , networkTraces , assertions , errors } = this ; return ( screenshots . length === 0 && networkTraces . length === 0 && assertions . length === 0 && errors . length === 0 ) ; } public toObject ( ) { const { label , screenshots , networkTraces , assertions , errors } = this ; const objectTypes = [ ] ; const objects = [ ] ; screenshots . forEach ( ( screenshot ) => { objects . push ( screenshot ) ; objectTypes . push ( 'screenshot' ) ; } ) ; networkTraces . forEach ( ( trace ) => { objects . push ( trace ) ; objectTypes . push ( 'trace' ) ; } ) ; return { op : 'object' , label , objects , errors , assertions , objectTypes , } ; } }