From 651f5a3ea49f357585fc78e66421a7c6dc3a51db Mon Sep 17 00:00:00 2001 From: Simon Knott Date: Tue, 6 Aug 2024 16:00:00 +0200 Subject: [PATCH] feat(tracing): record canvas screenshots --- .../src/server/trace/recorder/snapshotter.ts | 2 +- .../trace/recorder/snapshotterInjected.ts | 5 +++++ packages/trace-viewer/src/snapshotRenderer.ts | 10 ++++++++++ tests/assets/screenshots/webgl.html | 3 ++- tests/config/testserver/index.ts | 3 +++ tests/library/trace-viewer.spec.ts | 17 +++++++++++++++++ ...s-with-preserveDrawingBuffer-1-chromium.png | Bin 0 -> 4289 bytes ...ks-with-preserveDrawingBuffer-1-firefox.png | Bin 0 -> 4289 bytes ...rks-with-preserveDrawingBuffer-1-webkit.png | Bin 0 -> 4284 bytes ...uld-show-canvas-works-for-2D-1-chromium.png | Bin 0 -> 1450 bytes ...ould-show-canvas-works-for-2D-1-firefox.png | Bin 0 -> 1486 bytes ...hould-show-canvas-works-for-2D-1-webkit.png | Bin 0 -> 1486 bytes 12 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 tests/library/trace-viewer.spec.ts-snapshots/should-show-canvas-webgl-works-with-preserveDrawingBuffer-1-chromium.png create mode 100644 tests/library/trace-viewer.spec.ts-snapshots/should-show-canvas-webgl-works-with-preserveDrawingBuffer-1-firefox.png create mode 100644 tests/library/trace-viewer.spec.ts-snapshots/should-show-canvas-webgl-works-with-preserveDrawingBuffer-1-webkit.png create mode 100644 tests/library/trace-viewer.spec.ts-snapshots/should-show-canvas-works-for-2D-1-chromium.png create mode 100644 tests/library/trace-viewer.spec.ts-snapshots/should-show-canvas-works-for-2D-1-firefox.png create mode 100644 tests/library/trace-viewer.spec.ts-snapshots/should-show-canvas-works-for-2D-1-webkit.png diff --git a/packages/playwright-core/src/server/trace/recorder/snapshotter.ts b/packages/playwright-core/src/server/trace/recorder/snapshotter.ts index 48bfea7302..d3b7705a86 100644 --- a/packages/playwright-core/src/server/trace/recorder/snapshotter.ts +++ b/packages/playwright-core/src/server/trace/recorder/snapshotter.ts @@ -107,7 +107,7 @@ export class Snapshotter { async captureSnapshot(page: Page, callId: string, snapshotName: string, element?: ElementHandle): Promise { // Prepare expression synchronously. - const expression = `window["${this._snapshotStreamer}"].captureSnapshot(${JSON.stringify(snapshotName)})`; + const expression = `window["${this._snapshotStreamer}"].captureSnapshot()`; // In a best-effort manner, without waiting for it, mark target element. element?.callFunctionNoReply((element: Element, callId: string) => { diff --git a/packages/playwright-core/src/server/trace/recorder/snapshotterInjected.ts b/packages/playwright-core/src/server/trace/recorder/snapshotterInjected.ts index 14e34c8aee..0354a0394b 100644 --- a/packages/playwright-core/src/server/trace/recorder/snapshotterInjected.ts +++ b/packages/playwright-core/src/server/trace/recorder/snapshotterInjected.ts @@ -404,6 +404,11 @@ export function frameSnapshotStreamer(snapshotStreamer: string, removeNoScript: } }; + if (nodeName === 'CANVAS') { + const canvas = node as HTMLCanvasElement; + attrs['__playwright_canvas_'] = canvas.toDataURL('image/webp', 1); + } + if (nodeType === Node.DOCUMENT_FRAGMENT_NODE) attrs[kShadowAttribute] = 'open'; diff --git a/packages/trace-viewer/src/snapshotRenderer.ts b/packages/trace-viewer/src/snapshotRenderer.ts index 730cab4d19..87cb52b655 100644 --- a/packages/trace-viewer/src/snapshotRenderer.ts +++ b/packages/trace-viewer/src/snapshotRenderer.ts @@ -278,6 +278,16 @@ function snapshotScript(...targetIds: (string | undefined)[]) { } } + for (const element of root.querySelectorAll('canvas')) { + const canvas = element as HTMLCanvasElement; + const img = new Image(); + img.onload = () => { + const context = canvas.getContext('2d'); + context?.drawImage(img, 0, 0); + }; + img.src = canvas.getAttribute('__playwright_canvas_')!; + } + { const body = root.querySelector(`body[__playwright_custom_elements__]`); if (body && window.customElements) { diff --git a/tests/assets/screenshots/webgl.html b/tests/assets/screenshots/webgl.html index a5e3d4981a..5af82daedc 100644 --- a/tests/assets/screenshots/webgl.html +++ b/tests/assets/screenshots/webgl.html @@ -35,8 +35,9 @@ function attributeSetFloats(gl, prog, attr_name, rsize, arr) { gl.vertexAttribPointer(attr, rsize, gl.FLOAT, false, 0, 0); } +var preserveDrawingBuffer = new URLSearchParams(location.search).get('preserveDrawingBuffer') !== null var gl = document.getElementById("webgl") - .getContext("experimental-webgl"); + .getContext("webgl", { preserveDrawingBuffer }); gl.clearColor(0.8, 0.8, 0.8, 1); gl.clear(gl.COLOR_BUFFER_BIT); diff --git a/tests/config/testserver/index.ts b/tests/config/testserver/index.ts index 0596960f6b..e3d3c057b5 100644 --- a/tests/config/testserver/index.ts +++ b/tests/config/testserver/index.ts @@ -237,6 +237,9 @@ export class TestServer { filePath = path.join(this._dirPath, pathName.substring(1)); } + if (filePath.lastIndexOf('?') !== -1) + filePath = filePath.substring(0, filePath.lastIndexOf('?')); + if (this._cachedPathPrefix !== null && filePath.startsWith(this._cachedPathPrefix)) { if (request.headers['if-modified-since']) { response.statusCode = 304; // not modified diff --git a/tests/library/trace-viewer.spec.ts b/tests/library/trace-viewer.spec.ts index d8386d1684..e2f9ab4c9b 100644 --- a/tests/library/trace-viewer.spec.ts +++ b/tests/library/trace-viewer.spec.ts @@ -1378,3 +1378,20 @@ test('should show baseURL in metadata pane', { await traceViewer.showMetadataTab(); await expect(traceViewer.metadataTab).toContainText('baseURL:https://example.com'); }); + +test.describe('should show canvas', () => { + test('works for 2D', async ({ page, runAndTrace, server }) => { + const traceViewer = await runAndTrace(async () => { + await page.goto(server.PREFIX + '/screenshots/canvas.html'); + }); + + await expect(traceViewer.snapshotContainer).toHaveScreenshot(); + }); + + test('webgl works with preserveDrawingBuffer', async ({ runAndTrace, page, server }) => { + const traceViewer = await runAndTrace(async () => { + await page.goto(server.PREFIX + '/screenshots/webgl.html?preserveDrawingBuffer'); + }); + await expect(traceViewer.snapshotContainer).toHaveScreenshot(); + }); +}); diff --git a/tests/library/trace-viewer.spec.ts-snapshots/should-show-canvas-webgl-works-with-preserveDrawingBuffer-1-chromium.png b/tests/library/trace-viewer.spec.ts-snapshots/should-show-canvas-webgl-works-with-preserveDrawingBuffer-1-chromium.png new file mode 100644 index 0000000000000000000000000000000000000000..c3f2b66b2b5c870252a51af9a06b5f65808dd0b1 GIT binary patch literal 4289 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 AQvd(} literal 0 HcmV?d00001 diff --git a/tests/library/trace-viewer.spec.ts-snapshots/should-show-canvas-webgl-works-with-preserveDrawingBuffer-1-firefox.png b/tests/library/trace-viewer.spec.ts-snapshots/should-show-canvas-webgl-works-with-preserveDrawingBuffer-1-firefox.png new file mode 100644 index 0000000000000000000000000000000000000000..c3f2b66b2b5c870252a51af9a06b5f65808dd0b1 GIT binary patch literal 4289 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 AQvd(} literal 0 HcmV?d00001 diff --git a/tests/library/trace-viewer.spec.ts-snapshots/should-show-canvas-webgl-works-with-preserveDrawingBuffer-1-webkit.png b/tests/library/trace-viewer.spec.ts-snapshots/should-show-canvas-webgl-works-with-preserveDrawingBuffer-1-webkit.png new file mode 100644 index 0000000000000000000000000000000000000000..7f89bc28d008c758c96c006cc40fda887fc3f1c4 GIT binary patch literal 4284 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 MSFBB`mpvZ*6PrV0v;Y7A literal 0 HcmV?d00001 diff --git a/tests/library/trace-viewer.spec.ts-snapshots/should-show-canvas-works-for-2D-1-chromium.png b/tests/library/trace-viewer.spec.ts-snapshots/should-show-canvas-works-for-2D-1-chromium.png new file mode 100644 index 0000000000000000000000000000000000000000..373594dac2d530bda4263c71e0364f3ead98efd5 GIT binary patch literal 1450 zcmeAS@N?(olHy`uVBq!ia0y~yU`k+MU<~760*W{u+O`TvF%}28J29*~C-ahlfi=a` z#WAE}&fB|&S%)1290JvUC|&a`4cdJpTVje*=mTe^2-jnK!n+f9o!4{vbz|FGCWb#> zD!(x?eCT2kVrX(;auD!f;9%lpa8zJa;80;;X=G_on7|-_DH&64`?tpKxJ0||=G$+} ztgBfW?p@yJ&}TR;)iP)1-9Kl98k%<`vEtASG`VGF;~l<&{rA=LI2h`muy8UY-e3Og zUsCLKaT!*I-Dmipqz2u%BG@3j6Q3ctorlxy537z`D2?rx;AZ%rR;O@Pu)*BGctZd2 z76X5OiD`bZ{2fs+192HfFs==iqW^!E%5`o}p*3pt!lBN*nRItiu9 k(GVI9AtDMdijql-ewX(^-@gg`q~T5-KzPsySruM z{cpAZ85#b(e7>5Wq2axU0;2+l3Ij_cOM}7$1_2f!h9(Cl2LTTT4kk_pM-0hBzZd$~ z*VN?P{#vV+ zGd`GXQ literal 0 HcmV?d00001 diff --git a/tests/library/trace-viewer.spec.ts-snapshots/should-show-canvas-works-for-2D-1-webkit.png b/tests/library/trace-viewer.spec.ts-snapshots/should-show-canvas-works-for-2D-1-webkit.png new file mode 100644 index 0000000000000000000000000000000000000000..b0bb75e9b27aafe71e7c86ef9d14a5bf4b0f0111 GIT binary patch literal 1486 zcmeAS@N?(olHy`uVBq!ia0y~yU`k+MU<~760*W{u+O`TvF%}28J29*~C-ahlfwjZa z#WAE}&fB{OJ8uU_xLx#_;r6GhzmO&^-@gg`q~T5-KzPsySruM z{cpAZ85#b(e7>5Wq2axU0;2+l3Ij_cOM}7$1_2f!h9(Cl2LTTT4kk_pM-0hBzZd$~ z*VN?P{#vV+ zGd`GX