Skip to content

Commit 5667123

Browse files
committed
fix(core): inline screenshots in directory report mode
- Add inlineScreenshots option to toSerializableFormat - In directory report mode, embed base64 directly in dump data - Generate image script tags with base64 for fallback - Fixes 'MemoryStorage: Data not found' error in reports
1 parent 79c5138 commit 5667123

File tree

1 file changed

+54
-17
lines changed

1 file changed

+54
-17
lines changed

packages/core/src/types.ts

Lines changed: 54 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)