@@ -521,17 +521,56 @@ export class ExecutionDump implements IExecutionDump {
521521 *
522522 * @returns Serializable version of the execution dump
523523 */
524- async toSerializableFormat ( ) : Promise < IExecutionDump > {
524+ async toSerializableFormat ( options ?: { inlineScreenshots ?: boolean } ) : Promise < IExecutionDump > {
525+ const inlineScreenshots = options ?. inlineScreenshots ?? false ;
526+
525527 // Deep clone the data using JSON serialization with custom replacer
526- const replacer = ( key : string , value : any ) : any => {
527- // Convert ScreenshotItem to { $screenshot: id } format
528+ const replacer = async ( key : string , value : any ) : Promise < any > => {
529+ // Convert ScreenshotItem to { $screenshot: id } format or inline base64
528530 if ( value instanceof ScreenshotItem ) {
531+ if ( inlineScreenshots ) {
532+ return await value . getData ( ) ;
533+ }
529534 return value . toSerializable ( ) ;
530535 }
531536 return value ;
532537 } ;
533538
534- const jsonString = JSON . stringify ( this . toJSON ( ) , replacer ) ;
539+ // If inlineScreenshots is true, we need to await all screenshot getData() calls
540+ if ( inlineScreenshots ) {
541+ const collectScreenshotPromises = ( obj : any ) : Promise < any > => {
542+ if ( obj instanceof ScreenshotItem ) {
543+ return obj . getData ( ) ;
544+ }
545+ if ( Array . isArray ( obj ) ) {
546+ return Promise . all ( obj . map ( collectScreenshotPromises ) ) ;
547+ }
548+ if ( obj && typeof obj === 'object' ) {
549+ const promises : Record < string , Promise < any > > = { } ;
550+ for ( const [ key , value ] of Object . entries ( obj ) ) {
551+ promises [ key ] = collectScreenshotPromises ( value ) ;
552+ }
553+ return ( async ( ) => {
554+ const resolved : Record < string , any > = { } ;
555+ for ( const [ key , promise ] of Object . entries ( promises ) ) {
556+ resolved [ key ] = await promise ;
557+ }
558+ return resolved ;
559+ } ) ( ) ;
560+ }
561+ return Promise . resolve ( obj ) ;
562+ } ;
563+
564+ const resolvedData = await collectScreenshotPromises ( this . toJSON ( ) ) ;
565+ return resolvedData as IExecutionDump ;
566+ }
567+
568+ const jsonString = JSON . stringify ( this . toJSON ( ) , ( _key , value ) => {
569+ if ( value instanceof ScreenshotItem ) {
570+ return value . toSerializable ( ) ;
571+ }
572+ return value ;
573+ } ) ;
535574 return JSON . parse ( jsonString ) ;
536575 }
537576}
@@ -835,10 +874,10 @@ export class GroupedActionDump implements IGroupedActionDump {
835874 fs . writeFileSync ( filePath , buffer ) ;
836875 }
837876
838- // Serialize executions with relative paths
877+ // Serialize executions with inline base64 screenshots
839878 const serializedExecutions : any [ ] = [ ] ;
840879 for ( const execution of this . executions ) {
841- const serialized = await execution . toSerializableFormat ( ) ;
880+ const serialized = await execution . toSerializableFormat ( { inlineScreenshots : true } ) ;
842881 serializedExecutions . push ( serialized ) ;
843882 }
844883
@@ -850,23 +889,21 @@ export class GroupedActionDump implements IGroupedActionDump {
850889 executions : serializedExecutions ,
851890 } ;
852891
853- // Generate HTML with relative image paths
892+ // Generate HTML with embedded base64 image data
854893 const { generateDumpScriptTag, generateImageScriptTag } = require ( './dump' ) ;
855894 const { getReportTpl } = require ( './utils' ) ;
856895
857896 const dumpScript = generateDumpScriptTag ( JSON . stringify ( dumpData ) ) ;
858897
859- // Generate image reference scripts (pointing to separate files)
860- const imageScripts = screenshots
861- . map ( ( screenshot ) =>
862- generateImageScriptTag (
863- screenshot . id ,
864- `screenshots/${ screenshot . id } .png` ,
865- ) ,
866- )
867- . join ( '\n' ) ;
898+ // Generate image reference scripts with base64 data (not file paths)
899+ const imageScripts : string [ ] = [ ] ;
900+ for ( const screenshot of screenshots ) {
901+ const data = await screenshot . getData ( ) ;
902+ imageScripts . push ( generateImageScriptTag ( screenshot . id , data ) ) ;
903+ }
904+ const imageScriptsString = imageScripts . join ( '\n' ) ;
868905
869- const htmlContent = `${ getReportTpl ( ) } \n${ dumpScript } \n${ imageScripts } ` ;
906+ const htmlContent = `${ getReportTpl ( ) } \n${ dumpScript } \n${ imageScriptsString } ` ;
870907
871908 // Write index.html
872909 const indexPath = path . join ( outputDir , 'index.html' ) ;
0 commit comments