fix(screenshot): use innerW/H instead of offsetW/H to determine viewport size (#2229)

When capturing a screenshot with null viewport, we determine the screenshot size
based on body.offsetHeight. This is a very large number for long pages. We should
use window.innerHeight instead.
This commit is contained in:
Dmitry Gozman 2020-05-13 20:53:11 -07:00 committed by GitHub
parent dbef7de42a
commit 76e106605f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 8 additions and 11 deletions

View File

@ -43,16 +43,7 @@ export class Screenshotter {
let viewportSize = originalViewportSize;
if (!viewportSize) {
const context = await this._page.mainFrame()._utilityContext();
viewportSize = await context.evaluateInternal(() => {
if (!document.body || !document.documentElement)
return null;
return {
width: Math.max(document.body.offsetWidth, document.documentElement.offsetWidth),
height: Math.max(document.body.offsetHeight, document.documentElement.offsetHeight),
};
});
if (!viewportSize)
throw new Error(kScreenshotDuringNavigationError);
viewportSize = await context.evaluateInternal(() => ({ width: window.innerWidth, height: window.innerHeight }));
}
return { viewportSize, originalViewportSize };
}

View File

@ -16,6 +16,7 @@
*/
const {FFOX, CHROMIUM, WEBKIT} = require('./utils').testOptions(browserType);
const {PNG} = require('pngjs');
// Firefox headful produces a different image.
const ffheadful = FFOX && !HEADLESS;
@ -410,10 +411,15 @@ describe.skip(ffheadful)('ElementHandle.screenshot', function() {
it('should take screenshots when default viewport is null', async({server, browser}) => {
const context = await browser.newContext({ viewport: null });
const page = await context.newPage();
await page.goto(server.PREFIX + '/grid.html');
await page.setContent(`<div style='height: 10000px; background: red'></div>`);
const windowSize = await page.evaluate(() => ({ width: window.innerWidth * window.devicePixelRatio, height: window.innerHeight * window.devicePixelRatio }));
const sizeBefore = await page.evaluate(() => ({ width: document.body.offsetWidth, height: document.body.offsetHeight }));
const screenshot = await page.screenshot();
expect(screenshot).toBeInstanceOf(Buffer);
const decoded = PNG.sync.read(screenshot);
expect(decoded.width).toBe(windowSize.width);
expect(decoded.height).toBe(windowSize.height);
const sizeAfter = await page.evaluate(() => ({ width: document.body.offsetWidth, height: document.body.offsetHeight }));
expect(sizeBefore.width).toBe(sizeAfter.width);