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 0000000000..c3f2b66b2b Binary files /dev/null and b/tests/library/trace-viewer.spec.ts-snapshots/should-show-canvas-webgl-works-with-preserveDrawingBuffer-1-chromium.png differ 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 0000000000..c3f2b66b2b Binary files /dev/null and b/tests/library/trace-viewer.spec.ts-snapshots/should-show-canvas-webgl-works-with-preserveDrawingBuffer-1-firefox.png differ 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 0000000000..7f89bc28d0 Binary files /dev/null and b/tests/library/trace-viewer.spec.ts-snapshots/should-show-canvas-webgl-works-with-preserveDrawingBuffer-1-webkit.png differ 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 0000000000..373594dac2 Binary files /dev/null and b/tests/library/trace-viewer.spec.ts-snapshots/should-show-canvas-works-for-2D-1-chromium.png differ diff --git a/tests/library/trace-viewer.spec.ts-snapshots/should-show-canvas-works-for-2D-1-firefox.png b/tests/library/trace-viewer.spec.ts-snapshots/should-show-canvas-works-for-2D-1-firefox.png new file mode 100644 index 0000000000..1cbe20828b Binary files /dev/null and b/tests/library/trace-viewer.spec.ts-snapshots/should-show-canvas-works-for-2D-1-firefox.png differ 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 0000000000..b0bb75e9b2 Binary files /dev/null and b/tests/library/trace-viewer.spec.ts-snapshots/should-show-canvas-works-for-2D-1-webkit.png differ