-
Notifications
You must be signed in to change notification settings - Fork 9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Puppeteer in headless mode takes empty screenshot of Canvas element, working fine in headfull mode #5352
Comments
Same problem, I solved this by replace all await page.evaluate(() => {
function canvasToImage(element: HTMLCanvasElement) {
const dataUrl = element.toDataURL();
const image = document.createElement('img');
image.src = dataUrl;
const properties = ['width', 'height', 'position', 'left', 'top'] as const;
properties.forEach(key => image.style[key] = element.style[key])
image.className = element.className;
element.parentNode?.insertBefore(image, element);
element.parentNode?.removeChild(element);
}
[].forEach.call(document.getElementsByTagName('canvas'), canvasToImage)
})
await page.screenshot({
path: path.resolve(__dirname, './temp/dashboardPage.png'),
type: 'png',
}); |
@Demonly Thanks, bro!!! You save me 🎉 |
I tried this workaround and didn't work for me. First of all I got some simple js errors from node:
SyntaxError: Unexpected token ':'
SyntaxError: Unexpected identifier I'm not familiar with js nor node, maybe just some version issue. I commented out the problematic parts, run it and still it did not capture image from site https://www.kathabineider.de/. |
@yxiong20 I'm using typescript in the above excample, you can try this instead. await page.evaluate(() => {
function canvasToImage(element) {
const dataUrl = element.toDataURL();
const image = document.createElement('img');
image.src = dataUrl;
const properties = ['width', 'height', 'position', 'left', 'top'];
properties.forEach(key => image.style[key] = element.style[key])
image.className = element.className;
element.parentNode && element.parentNode.insertBefore(image, element);
element.parentNode && element.parentNode.removeChild(element);
}
[].forEach.call(document.getElementsByTagName('canvas'), canvasToImage)
})
await page.screenshot({
path: path.resolve(__dirname, './temp/dashboardPage.png'),
type: 'png',
}); |
Thanks @Demonly. In my case I solved the problem by adding "--use-gl=egl" to the args pass to Chrome which seems to work in headless mode. |
We're marking this issue as unconfirmed because it has not had recent activity and we weren't able to confirm it yet. It will be closed if no further activity occurs within the next 30 days. |
We are closing this issue. If the issue still persists in the latest version of Puppeteer, please reopen the issue and update the description. We will try our best to accomodate it! |
1 similar comment
We are closing this issue. If the issue still persists in the latest version of Puppeteer, please reopen the issue and update the description. We will try our best to accomodate it! |
A clear and concise description of what the bug is.
Puppeteer in headless mode is not able to take the screenshot of a canvas element in my test app. Though while using puppeteer in non-headless mode, it's working perfectly fine.
This is my test scenario,
Press some button, it will invoke WebGL rendering on the canvas element.
(As soon as the rendering is finished source code update a div element value on the web page.)
Test code wait for the div element value to get changed
Take the screenshot of canvas element.
Repeat step 1-3 for some 'n' number of times (each time code will render something on the canvas)
On taking the screenshot, I see that sometimes the first screenshot if blank other times second. It's showing intermittent behavior. It's working fine with headful mode though.
To Reproduce
// My function to take a screenshot
async function captureScreenshotAndCompare(element: ElementHandle, fileName: string, shouldCompare: boolean = true) {
const testFile = Path.resolve(testFolder, ${fileName}.png);
// capture screenshot
const image = await element.screenshot({ path: testFile });
// compare with baseline
if(!shouldCompare) return;
expect(image).toMatchImageSnapshot({
failureThreshold: 0.1,
failureThresholdType: 'percent',
customSnapshotsDir: baselineFolder,
customDiffConfig: { threshold: 0.1 },
customSnapshotIdentifier: () => {
return fileName;
},
});
}
const canvas = await page.$('canvas[id="webgl-canvas"]');
expect(canvas).not.toBeNull();
if(!canvas) return;
await captureScreenshotAndCompare(canvas, 'Image_1', true);
let index: number = 2;
while (index <= maxCount) {
// move to next step
await nextBtn.click();
await page.waitFor(() => document.querySelector('#eventName')!.innerHTML === "rendered" );
await captureScreenshotAndCompare(canvas, Image_${index});
index += 1;
}
Steps to reproduce the behavior:
Expected behavior
The screenshot should be correct both in headless and headful mode.
A clear and concise description of what you expected to happen.
These are all the versions exist in my package.json file.
"puppeteer": "^2.0.0",
"jest-puppeteer": "4.3.0",
"jest-image-snapshot": "2.11.0"
"@types/puppeteer": "^1.19.1",
"@types/jest-environment-puppeteer": "4.3.1",
"@types/expect-puppeteer": "3.3.1",
The text was updated successfully, but these errors were encountered: