diff --git a/packages/playwright-core/src/server/trace/recorder/tracing.ts b/packages/playwright-core/src/server/trace/recorder/tracing.ts index 5b5273775f..a48c2974b9 100644 --- a/packages/playwright-core/src/server/trace/recorder/tracing.ts +++ b/packages/playwright-core/src/server/trace/recorder/tracing.ts @@ -367,8 +367,8 @@ export class Tracing extends SdkObject implements InstrumentationListener, Snaps onEntryFinished(entry: har.Entry) { const event: trace.ResourceSnapshotTraceEvent = { type: 'resource-snapshot', snapshot: entry }; this._appendTraceOperation(async () => { - visitSha1s(event, this._state!.networkSha1s); - await fs.promises.appendFile(this._state!.networkFile, JSON.stringify(event) + '\n'); + const visited = visitTraceEvent(event, this._state!.networkSha1s); + await fs.promises.appendFile(this._state!.networkFile, JSON.stringify(visited) + '\n'); }); } @@ -408,8 +408,8 @@ export class Tracing extends SdkObject implements InstrumentationListener, Snaps private _appendTraceEvent(event: trace.TraceEvent) { this._appendTraceOperation(async () => { - visitSha1s(event, this._state!.traceSha1s); - await fs.promises.appendFile(this._state!.traceFile, JSON.stringify(event) + '\n'); + const visited = visitTraceEvent(event, this._state!.traceSha1s); + await fs.promises.appendFile(this._state!.traceFile, JSON.stringify(visited) + '\n'); }); } @@ -452,22 +452,24 @@ export class Tracing extends SdkObject implements InstrumentationListener, Snaps } } -function visitSha1s(object: any, sha1s: Set) { - if (Array.isArray(object)) { - object.forEach(o => visitSha1s(o, sha1s)); - return; - } +function visitTraceEvent(object: any, sha1s: Set): any { + if (Array.isArray(object)) + return object.map(o => visitTraceEvent(o, sha1s)); + if (object instanceof Buffer) + return undefined; if (typeof object === 'object') { + const result: any = {}; for (const key in object) { if (key === 'sha1' || key === '_sha1' || key.endsWith('Sha1')) { const sha1 = object[key]; if (sha1) sha1s.add(sha1); } - visitSha1s(object[key], sha1s); + result[key] = visitTraceEvent(object[key], sha1s); } - return; + return result; } + return object; } export function shouldCaptureSnapshot(metadata: CallMetadata): boolean { diff --git a/tests/library/tracing.spec.ts b/tests/library/tracing.spec.ts index 8294cbeef6..163f3c8451 100644 --- a/tests/library/tracing.spec.ts +++ b/tests/library/tracing.spec.ts @@ -107,6 +107,17 @@ test('should not collect snapshots by default', async ({ context, page, server } expect(events.some(e => e.type === 'resource-snapshot')).toBeFalsy(); }); +test('should not include buffers in the trace', async ({ context, page, server }, testInfo) => { + await context.tracing.start({ snapshots: true }); + await page.goto(server.PREFIX + '/empty.html'); + await page.screenshot(); + await context.tracing.stop({ path: testInfo.outputPath('trace.zip') }); + const { events } = await parseTrace(testInfo.outputPath('trace.zip')); + const screenshotEvent = events.find(e => e.type === 'action' && e.metadata.apiName === 'page.screenshot'); + expect(screenshotEvent.metadata.snapshots.length).toBe(2); + expect(screenshotEvent.metadata.result).toEqual({}); +}); + test('should exclude internal pages', async ({ browserName, context, page, server }, testInfo) => { test.fixme(true, 'https://github.com/microsoft/playwright/issues/6743'); await page.goto(server.EMPTY_PAGE);