fix(canvas snapshots): fix position mismatch with headless screenshots

This commit is contained in:
Simon Knott 2024-11-13 12:40:30 +01:00
parent d1ae5f6ac4
commit 868a95eadc
No known key found for this signature in database
GPG key ID: 8CEDC00028084AEC
5 changed files with 60 additions and 6 deletions

View file

@ -429,12 +429,12 @@ function snapshotScript(...targetIds: (string | undefined)[]) {
const boundingRect = canvas.getBoundingClientRect();
const xStart = boundingRect.left / window.innerWidth;
const yStart = boundingRect.top / window.innerHeight;
const yStart = boundingRect.top / window.innerWidth;
const xEnd = boundingRect.right / window.innerWidth;
const yEnd = boundingRect.bottom / window.innerHeight;
const yEnd = boundingRect.bottom / window.innerWidth;
const partiallyUncaptured = xEnd > 1 || yEnd > 1;
const fullyUncaptured = xStart > 1 || yStart > 1;
const partiallyUncaptured = boundingRect.right > window.innerWidth || boundingRect.bottom > window.innerHeight;
const fullyUncaptured = boundingRect.left > window.innerWidth || boundingRect.top > window.innerHeight;
if (fullyUncaptured) {
canvas.title = `Playwright couldn't capture canvas contents because it's located outside the viewport.`;
continue;
@ -442,7 +442,7 @@ function snapshotScript(...targetIds: (string | undefined)[]) {
drawCheckerboard(context, canvas);
context.drawImage(img, xStart * img.width, yStart * img.height, (xEnd - xStart) * img.width, (yEnd - yStart) * img.height, 0, 0, canvas.width, canvas.height);
context.drawImage(img, xStart * img.width, yStart * img.width, (xEnd - xStart) * img.width, (yEnd - yStart) * img.width, 0, 0, canvas.width, canvas.height);
if (isUnderTest)
// eslint-disable-next-line no-console
console.log(`canvas drawn:`, JSON.stringify([xStart, yStart, xEnd, yEnd].map(v => Math.floor(v * 100))));

View file

@ -0,0 +1,42 @@
<style>
/* Style for the canvas */
#myCanvas {
border: 2px solid #000000;
}
/* Style for the overlay div */
#overlay {
position: absolute;
top: 150px;
/* Adjust position as needed */
left: 150px;
/* Adjust position as needed */
width: 150px;
height: 150px;
background-color: red;
opacity: 0.7;
/* Optional: make it semi-transparent */
display: flex;
align-items: center;
justify-content: center;
color: white;
}
/* Container for positioning */
.container {
position: relative;
width: 500px;
height: 500px;
}
</style>
<div class="container">
<canvas id="myCanvas" width="500" height="500"></canvas>
<div id="overlay"><span>An HTML element</span></div>
</div>
<script>
const ctx = document.getElementById('myCanvas').getContext('2d');
ctx.fillStyle = 'blue';
ctx.fillRect(50, 50, 200, 200);
</script>

View file

@ -1510,7 +1510,7 @@ test('canvas clipping', async ({ runAndTrace, page, server }) => {
});
const msg = await traceViewer.page.waitForEvent('console', { predicate: msg => msg.text().startsWith('canvas drawn:') });
expect(msg.text()).toEqual('canvas drawn: [0,91,12,111]');
expect(msg.text()).toEqual('canvas drawn: [0,51,12,62]');
const snapshot = await traceViewer.snapshotFrame('page.goto');
await expect(snapshot.locator('canvas')).toHaveAttribute('title', `Playwright couldn't capture full canvas contents because it's located partially outside the viewport.`);
@ -1529,6 +1529,18 @@ test('canvas clipping in iframe', async ({ runAndTrace, page, server }) => {
await expect(canvas).toHaveAttribute('title', `Playwright displays canvas contents on a best-effort basis. It doesn't support canvas elements inside an iframe yet. If this impacts your workflow, please open an issue so we can prioritize.`);
});
test('canvas clipping with overlaying element', { annotation: [{ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/33562' }] }, async ({ runAndTrace, page, server, browserName }) => {
test.fixme(browserName === 'firefox', 'firefox doesnt handle the screenshot test well');
const traceViewer = await runAndTrace(async () => {
await page.goto(server.PREFIX + '/screenshots/canvas-with-overlay.html');
await rafraf(page, 5);
});
const snapshot = await traceViewer.snapshotFrame('page.evaluate');
await expect(snapshot.owner()).toHaveScreenshot();
});
test('should show only one pointer with multilevel iframes', async ({ page, runAndTrace, server, browserName }) => {
test.fixme(browserName === 'firefox', 'Elements in iframe are not marked');

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB