diff --git a/packages/trace-viewer/src/sw/snapshotRenderer.ts b/packages/trace-viewer/src/sw/snapshotRenderer.ts index 0d2f2af502..4166b1a65c 100644 --- a/packages/trace-viewer/src/sw/snapshotRenderer.ts +++ b/packages/trace-viewer/src/sw/snapshotRenderer.ts @@ -299,6 +299,28 @@ function snapshotScript(...targetIds: (string | undefined)[]) { } } + const canvases = root.querySelectorAll('canvas'); + if (canvases.length > 0) { + const sha1 = 'page@52b251b4d0b1412c19639922d9b22cb9-1728986751380.jpeg'; + fetch(`http://[::1]:58477/trace/sha1/${sha1}`).then(response => response.blob()).then(blob => { + const img = new Image(); + img.onload = () => { + for (const canvas of canvases) { + const context = canvas.getContext('2d')!; + + const boundingRect = canvas.getBoundingClientRect(); + const xStart = boundingRect.left / window.innerWidth; + const yStart = boundingRect.top / window.innerHeight; + const xEnd = boundingRect.right / window.innerWidth; + const yEnd = boundingRect.bottom / window.innerHeight; + + context.drawImage(img, xStart * img.width, yStart * img.height, (xEnd - xStart) * img.width, (yEnd - yStart) * img.height, 0, 0, canvas.width, canvas.height); + } + }; + img.src = URL.createObjectURL(blob); + }); + } + { const body = root.querySelector(`body[__playwright_custom_elements__]`); if (body && window.customElements) { diff --git a/tests/library/trace-viewer.spec.ts b/tests/library/trace-viewer.spec.ts index 0eda4b092a..d5df72d087 100644 --- a/tests/library/trace-viewer.spec.ts +++ b/tests/library/trace-viewer.spec.ts @@ -1439,6 +1439,15 @@ test.skip('should allow showing screenshots instead of snapshots', async ({ runA await expect(screenshot).toBeVisible(); }); +test('canvas clipping', async ({ runAndTrace, page, server }) => { + const traceViewer = await runAndTrace(async () => { + await page.goto(server.PREFIX + '/screenshots/canvas.html'); + await page.waitForTimeout(1000); // ensure we could take a screenshot + }); + + await traceViewer.page.pause(); +}); + test.skip('should handle case where neither snapshots nor screenshots exist', async ({ runAndTrace, page, server }) => { const traceViewer = await runAndTrace(async () => { await page.goto(server.PREFIX + '/one-style.html');