question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

page.pdf() captures application before end of resize animation

See original GitHub issue

Steps to reproduce

Tell us about your environment:

  • Puppeteer version: 1.0.0
  • Platform / OS version: Fedora 27
  • URLs (if applicable):
  • Node.js version: 6.5.0

What steps will reproduce the problem?

'use strict';

const puppeteer = require('puppeteer');

const inIsolatedSession = ({action, dimensions, url}) =>
  puppeteer.launch().then(browser =>
    browser
      .newPage()
      .then(page =>
        Promise.resolve()
          .then(() => page.setViewport(dimensions))
          .then(() => page.goto(url, {waitUntil: ['networkidle0']}))
          .then(() => action(page))
      )
      .then(result => browser.close().then(() => result))
  );

const dimensions = {height: 800, width: 800};
const url = 'https://youtube.com';

[
  page =>
    page.pdf(
      Object.assign(
        {
          pageRanges: '1',
          path: 'test.pdf',
          printBackground: true,
        },
        dimensions
      )
    ),
  page => page.screenshot({path: 'test.png'}),
].forEach(action => {
  inIsolatedSession({
    action,
    dimensions,
    url,
  });
});

What is the expected result?

The PDF and PNG file content should look the same.

What happens instead?

Here is the PNG:

PNG

And here is the PDF that looks like this:

PDF

The PNG is what I expect: the application is centered in the middle of the screen. In the PDF however, the application was captured in the middle of a resize animation, leading to a shifted content.

When enabling the debug output, I can see this:

puppeteer:session SEND ► {"id":13,"method":"Page.printToPDF","params":{"landscape":false,"displayHeaderFooter":false,"headerTemplate":"","footerTemplate":"","printBackground":true,"scale":1,"paperWidth":8.333333333333334,"paperHeight":8.333333333333334,"marginTop":0,"marginBottom":0,"marginLeft":0,"marginRight":0,"pageRanges":"1"}} +3ms
puppeteer:session ◀ RECV {"method":"Page.frameResized","params":{}} +319ms
puppeteer:session ◀ RECV {"method":"Page.frameResized","params":{}} +0ms
puppeteer:session ◀ RECV {"id":13,"result":{"data": ... PDF content ...

So, even though the viewport was already the right one (see call to page.setViewport(dimensions) above), the Page.frameResized event was still fired just before triggering the PDF export, probably not letting enough time to the application to finish its resize animation.

Is this a problem upstream in Chromium or can it be fixed in Puppeteer?

Thanks for your help!

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:9

github_iconTop GitHub Comments

7reactions
tibdexcommented, Jan 17, 2018

This issue is different than #1751 because here, even if I wait several seconds for the application to settle before calling page.pdf(), the method call will trigger a Page.frameResized event and grab a PDF quickly after it. I have no control on the delay between this resize event and the PDF generation. Thus, I cannot use requestAnimationFrame or requestIdleCallback as suggested in the other issue.

2reactions
tibdexcommented, Dec 10, 2018

Not a good workaround but I hardcode the width and height of <body> so that the layout doesn’t change when calling page.pdf().

Read more comments on GitHub >

github_iconTop Results From Across the Web

Animation resources - Android Developers
An animation resource can define one of two types of animations: Property Animation: Creates an animation by modifying an object's property ...
Read more >
How To Process Images in Node.js With Sharp - DigitalOcean
In this tutorial, you'll use sharp to read an image and extract its metadata, resize, change an image format, and compress an image....
Read more >
How to wait for the 'end' of 'resize' event and only then perform ...
The way this function works is by saving data into a specific scope, so you could call it into different scopes, other than...
Read more >
Adobe Animate CC Help
You can use frame level filters to apply them for all the objects at a time in a frame. Apply filters directly on...
Read more >
Safari Technology Preview Release Notes - Apple Developer
commitStyles() not changing the style attribute for individual CSS ... to not set the initial selection at the end of the text content...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found