From 8eac1e96d3cff3faabe278e50b6d220d6c287da9 Mon Sep 17 00:00:00 2001 From: Pavel Feldman Date: Mon, 9 Aug 2021 16:36:24 -0700 Subject: [PATCH] chore: add extensions to the trace resources (#8105) --- src/server/snapshot/snapshotter.ts | 35 +++++++++++++++++++--- src/server/snapshot/snapshotterInjected.ts | 3 +- src/server/trace/recorder/tracing.ts | 7 +++-- 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/src/server/snapshot/snapshotter.ts b/src/server/snapshot/snapshotter.ts index f8cf5428de..85ea367593 100644 --- a/src/server/snapshot/snapshotter.ts +++ b/src/server/snapshot/snapshotter.ts @@ -137,10 +137,10 @@ export class Snapshotter { resourceOverrides: [], isMainFrame: page.mainFrame() === frame }; - for (const { url, content } of data.resourceOverrides) { + for (const { url, content, contentType } of data.resourceOverrides) { if (typeof content === 'string') { const buffer = Buffer.from(content); - const sha1 = calculateSha1(buffer); + const sha1 = calculateSha1(buffer) + mimeToExtension(contentType); this._delegate.onBlob({ sha1, buffer }); snapshot.resourceOverrides.push({ url, sha1 }); } else { @@ -184,7 +184,7 @@ export class Snapshotter { const method = original.method(); const status = response.status(); const requestBody = original.postDataBuffer(); - const requestSha1 = requestBody ? calculateSha1(requestBody) : ''; + const requestSha1 = requestBody ? calculateSha1(requestBody) + mimeToExtension(contentType) : ''; if (requestBody) this._delegate.onBlob({ sha1: requestSha1, buffer: requestBody }); const requestHeaders = original.headers(); @@ -197,7 +197,7 @@ export class Snapshotter { // Bail out after each async hop. if (!this._started) return; - responseSha1 = body ? calculateSha1(body) : ''; + responseSha1 = body ? calculateSha1(body) + mimeToExtension(contentType) : ''; if (body) this._delegate.onBlob({ sha1: responseSha1, buffer: body }); this._fetchedResponses.set(response, responseSha1); @@ -237,3 +237,30 @@ export class Snapshotter { } } } + +const kMimeToExtension: { [key: string]: string } = { + 'application/javascript': 'js', + 'application/json': 'json', + 'application/json5': 'json5', + 'application/pdf': 'pdf', + 'application/xhtml+xml': 'xhtml', + 'application/zip': 'zip', + 'font/otf': 'otf', + 'font/woff': 'woff', + 'font/woff2': 'woff2', + 'image/bmp': 'bmp', + 'image/gif': 'gif', + 'image/jpeg': 'jpeg', + 'image/png': 'png', + 'image/tiff': 'tiff', + 'text/css': 'css', + 'text/csv': 'csv', + 'text/html': 'html', + 'text/plain': 'text', + 'video/mp4': 'mp4', + 'video/mpeg': 'mpeg', +}; + +function mimeToExtension(contentType: string): string { + return '.' + (kMimeToExtension[contentType] || 'dat'); +} diff --git a/src/server/snapshot/snapshotterInjected.ts b/src/server/snapshot/snapshotterInjected.ts index 27db1ff823..21db023cbe 100644 --- a/src/server/snapshot/snapshotterInjected.ts +++ b/src/server/snapshot/snapshotterInjected.ts @@ -23,6 +23,7 @@ export type SnapshotData = { url: string, // String is the content. Number is "x snapshots ago", same url. content: string | number, + contentType: 'text/css' }[], viewport: { width: number, height: number }, url: string, @@ -461,7 +462,7 @@ export function frameSnapshotStreamer(snapshotStreamer: string) { } const base = this._getSheetBase(sheet); const url = removeHash(this._resolveUrl(base, sheet.href!)); - result.resourceOverrides.push({ url, content }); + result.resourceOverrides.push({ url, content, contentType: 'text/css' },); } result.collectionTime = performance.now() - result.timestamp; diff --git a/src/server/trace/recorder/tracing.ts b/src/server/trace/recorder/tracing.ts index bd63f2374c..e1c8efd2fd 100644 --- a/src/server/trace/recorder/tracing.ts +++ b/src/server/trace/recorder/tracing.ts @@ -19,7 +19,7 @@ import path from 'path'; import yazl from 'yazl'; import readline from 'readline'; import { EventEmitter } from 'events'; -import { calculateSha1, createGuid, mkdirIfNeeded, monotonicTime } from '../../../utils/utils'; +import { createGuid, mkdirIfNeeded, monotonicTime } from '../../../utils/utils'; import { Artifact } from '../../artifact'; import { BrowserContext } from '../../browserContext'; import { ElementHandle } from '../../dom'; @@ -287,9 +287,12 @@ export class Tracing implements InstrumentationListener { private _startScreencastInPage(page: Page) { page.setScreencastOptions(kScreencastOptions); + const prefix = page.guid; + let frameSeq = 0; this._screencastListeners.push( eventsHelper.addEventListener(page, Page.Events.ScreencastFrame, params => { - const sha1 = calculateSha1(createGuid()); // no need to compute sha1 for screenshots + const suffix = String(++frameSeq).padStart(10, '0'); + const sha1 = `${prefix}-${suffix}.jpeg`; const event: trace.ScreencastFrameTraceEvent = { type: 'screencast-frame', pageId: page.guid,