mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
fix(canvas snapshots): position mismatch in headless mode (#33575)
This commit is contained in:
parent
80ce205d81
commit
25c039401d
@ -47,6 +47,7 @@ export function frameSnapshotStreamer(snapshotStreamer: string, removeNoScript:
|
|||||||
const kTargetAttribute = '__playwright_target__';
|
const kTargetAttribute = '__playwright_target__';
|
||||||
const kCustomElementsAttribute = '__playwright_custom_elements__';
|
const kCustomElementsAttribute = '__playwright_custom_elements__';
|
||||||
const kCurrentSrcAttribute = '__playwright_current_src__';
|
const kCurrentSrcAttribute = '__playwright_current_src__';
|
||||||
|
const kBoundingRectAttribute = '__playwright_bounding_rect__';
|
||||||
|
|
||||||
// Symbols for our own info on Nodes/StyleSheets.
|
// Symbols for our own info on Nodes/StyleSheets.
|
||||||
const kSnapshotFrameId = Symbol('__playwright_snapshot_frameid_');
|
const kSnapshotFrameId = Symbol('__playwright_snapshot_frameid_');
|
||||||
@ -436,6 +437,18 @@ export function frameSnapshotStreamer(snapshotStreamer: string, removeNoScript:
|
|||||||
expectValue(value);
|
expectValue(value);
|
||||||
attrs[kSelectedAttribute] = value;
|
attrs[kSelectedAttribute] = value;
|
||||||
}
|
}
|
||||||
|
if (nodeName === 'CANVAS') {
|
||||||
|
const boundingRect = (element as HTMLCanvasElement).getBoundingClientRect();
|
||||||
|
const value = JSON.stringify({
|
||||||
|
left: boundingRect.left / window.innerWidth,
|
||||||
|
top: boundingRect.top / window.innerHeight,
|
||||||
|
right: boundingRect.right / window.innerWidth,
|
||||||
|
bottom: boundingRect.bottom / window.innerHeight
|
||||||
|
});
|
||||||
|
expectValue(kBoundingRectAttribute);
|
||||||
|
expectValue(value);
|
||||||
|
attrs[kBoundingRectAttribute] = value;
|
||||||
|
}
|
||||||
if (element.scrollTop) {
|
if (element.scrollTop) {
|
||||||
expectValue(kScrollTopAttribute);
|
expectValue(kScrollTopAttribute);
|
||||||
expectValue(element.scrollTop);
|
expectValue(element.scrollTop);
|
||||||
|
|||||||
@ -427,14 +427,20 @@ function snapshotScript(...targetIds: (string | undefined)[]) {
|
|||||||
for (const canvas of canvasElements) {
|
for (const canvas of canvasElements) {
|
||||||
const context = canvas.getContext('2d')!;
|
const context = canvas.getContext('2d')!;
|
||||||
|
|
||||||
const boundingRect = canvas.getBoundingClientRect();
|
const boundingRectAttribute = canvas.getAttribute('__playwright_bounding_rect__');
|
||||||
const xStart = boundingRect.left / window.innerWidth;
|
canvas.removeAttribute('__playwright_bounding_rect__');
|
||||||
const yStart = boundingRect.top / window.innerHeight;
|
if (!boundingRectAttribute)
|
||||||
const xEnd = boundingRect.right / window.innerWidth;
|
continue;
|
||||||
const yEnd = boundingRect.bottom / window.innerHeight;
|
|
||||||
|
|
||||||
const partiallyUncaptured = xEnd > 1 || yEnd > 1;
|
let boundingRect: { left: number, top: number, right: number, bottom: number };
|
||||||
const fullyUncaptured = xStart > 1 || yStart > 1;
|
try {
|
||||||
|
boundingRect = JSON.parse(boundingRectAttribute);
|
||||||
|
} catch (e) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const partiallyUncaptured = boundingRect.right > 1 || boundingRect.bottom > 1;
|
||||||
|
const fullyUncaptured = boundingRect.left > 1 || boundingRect.top > 1;
|
||||||
if (fullyUncaptured) {
|
if (fullyUncaptured) {
|
||||||
canvas.title = `Playwright couldn't capture canvas contents because it's located outside the viewport.`;
|
canvas.title = `Playwright couldn't capture canvas contents because it's located outside the viewport.`;
|
||||||
continue;
|
continue;
|
||||||
@ -442,10 +448,10 @@ function snapshotScript(...targetIds: (string | undefined)[]) {
|
|||||||
|
|
||||||
drawCheckerboard(context, canvas);
|
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, boundingRect.left * img.width, boundingRect.top * img.height, (boundingRect.right - boundingRect.left) * img.width, (boundingRect.bottom - boundingRect.top) * img.height, 0, 0, canvas.width, canvas.height);
|
||||||
if (isUnderTest)
|
if (isUnderTest)
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.log(`canvas drawn:`, JSON.stringify([xStart, yStart, xEnd, yEnd].map(v => Math.floor(v * 100))));
|
console.log(`canvas drawn:`, JSON.stringify([boundingRect.left, boundingRect.top, (boundingRect.right - boundingRect.left), (boundingRect.bottom - boundingRect.top)].map(v => Math.floor(v * 100))));
|
||||||
|
|
||||||
if (partiallyUncaptured)
|
if (partiallyUncaptured)
|
||||||
canvas.title = `Playwright couldn't capture full canvas contents because it's located partially outside the viewport.`;
|
canvas.title = `Playwright couldn't capture full canvas contents because it's located partially outside the viewport.`;
|
||||||
|
|||||||
@ -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:') });
|
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,91,11,20]');
|
||||||
|
|
||||||
const snapshot = await traceViewer.snapshotFrame('page.goto');
|
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.`);
|
await expect(snapshot.locator('canvas')).toHaveAttribute('title', `Playwright couldn't capture full canvas contents because it's located partially outside the viewport.`);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user