From 76e106605fb1733cc7e6b705642a9a41556e2d6b Mon Sep 17 00:00:00 2001 From: Dmitry Gozman Date: Wed, 13 May 2020 20:53:11 -0700 Subject: [PATCH] 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. --- src/screenshotter.ts | 11 +---------- test/screenshot.spec.js | 8 +++++++- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/screenshotter.ts b/src/screenshotter.ts index 8e3738688a..997e66368a 100644 --- a/src/screenshotter.ts +++ b/src/screenshotter.ts @@ -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 }; } diff --git a/test/screenshot.spec.js b/test/screenshot.spec.js index 36801caf58..506cd122e8 100644 --- a/test/screenshot.spec.js +++ b/test/screenshot.spec.js @@ -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(`
`); + 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);