Skip to content
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

Full page screenshot not rendering correctly #620

Closed
rightqa opened this issue Jan 24, 2020 · 10 comments
Closed

Full page screenshot not rendering correctly #620

rightqa opened this issue Jan 24, 2020 · 10 comments

Comments

@rightqa
Copy link

rightqa commented Jan 24, 2020

Here is my code

const pw = require('playwright');

(async () => {
  const browser = await pw.chromium.launch(); // or 'chromium', 'firefox'
  const context = await browser.newContext();
  const page = await context.newPage();

  await page.goto('https://www.waze.com/');
  await page.screenshot({ 
      path: 'example.png',
      fullPage : true });

  await browser.close();
})();

example

If you see the content at the bottom of the page is not properly captured in screenshot. Any help will be appreciated.

@arjunattam
Copy link
Contributor

Interesting example, thanks for sharing. On observing the page, I noticed that the bottom parts of the page load after scrolling. To replicate this behavior through Playwright, I've added a method scrollFullPage to your code snippet, executed right before taking a screenshot.

const pw = require('playwright');

(async () => {
  const browser = await pw.chromium.launch({ headless: false }); // or 'chromium', 'firefox'
  const context = await browser.newContext();
  const page = await context.newPage();
  
  await page.goto('https://www.waze.com/');
  await scrollFullPage(page);
  
  await page.screenshot({ 
    path: 'example.png',
    fullPage : true
  });
  
  await browser.close();
})();

async function scrollFullPage(page) {
  await page.evaluate(async () => {
    await new Promise(resolve => {
      let totalHeight = 0;
      const distance = 100;
      const timer = setInterval(() => {
        const scrollHeight = document.body.scrollHeight;
        window.scrollBy(0, distance);
        totalHeight += distance;
        
        if (totalHeight >= scrollHeight){
          clearInterval(timer);
          resolve();
        }
      }, 100);
    });
  });
}

@zac11
Copy link

zac11 commented Jan 24, 2020

Any chance this can be implemented as a method since there are many scenarios where we're in need of taking full page screenshots.
This was a limitation in Puppeteer and it would be a definite plus point for a lot of users imho.
Issue - GoogleChrome/rendertron#108 (Puppeteer doesn't support full page screenshot)

@arjunattam
Copy link
Contributor

arjunattam commented Jan 24, 2020

Thanks @zac11. Full page screenshots are supported with the fullPage: true flag. Can you share any examples where the flag does not work for you? Thanks!

@jcousins-ynap
Copy link

jcousins-ynap commented Jan 24, 2020

It's definitely due to the website animating in all images when inside the viewport. A fullpage screenshot scrolls too fast for the code to show the images. This isn't a puppeteer/playwright limitiation.

I wonder if turning off CSS transitions before taking the screenshot would help?

* {
  transition: unset !important;
}

@rightqa
Copy link
Author

rightqa commented Jan 24, 2020

Interesting example, thanks for sharing. On observing the page, I noticed that the bottom parts of the page load after scrolling. To replicate this behavior through Playwright, I've added a method scrollFullPage to your code snippet, executed right before taking a screenshot.

const pw = require('playwright');

(async () => {
  const browser = await pw.chromium.launch({ headless: false }); // or 'chromium', 'firefox'
  const context = await browser.newContext();
  const page = await context.newPage();
  
  await page.goto('https://www.waze.com/');
  await scrollFullPage(page);
  
  await page.screenshot({ 
    path: 'example.png',
    fullPage : true
  });
  
  await browser.close();
})();

async function scrollFullPage(page) {
  await page.evaluate(async () => {
    await new Promise(resolve => {
      let totalHeight = 0;
      const distance = 100;
      const timer = setInterval(() => {
        const scrollHeight = document.body.scrollHeight;
        window.scrollBy(0, distance);
        totalHeight += distance;
        
        if (totalHeight >= scrollHeight){
          clearInterval(timer);
          resolve();
        }
      }, 100);
    });
  });
}

Thanks @arjun27 , it worked for the given example. I appreciate your help. Will try with some other examples and let you know how I go.

This project looks interesting, anyway I can contribute to the project? Say some doco, tutorial etc?

@utkarshpaliwal9
Copy link

utkarshpaliwal9 commented Feb 17, 2021

Thanks @zac11. Full page screenshots are supported with the fullPage: true flag. Can you share any examples where the flag does not work for you? Thanks!

There's this page https://extrasalt.org/ where even with the fullPage flag enabled, playwright doesn't capture the entire page SS. Only a part of it. Attaching the screenshot captured.
https%3A%2F%2Fextrasalt org%2F1

@davidricardo1026
Copy link

davidricardo1026 commented Dec 2, 2022

Interesting example, thanks for sharing. On observing the page, I noticed that the bottom parts of the page load after scrolling. To replicate this behavior through Playwright, I've added a method scrollFullPage to your code snippet, executed right before taking a screenshot.

const pw = require('playwright');

(async () => {
  const browser = await pw.chromium.launch({ headless: false }); // or 'chromium', 'firefox'
  const context = await browser.newContext();
  const page = await context.newPage();
  
  await page.goto('https://www.waze.com/');
  await scrollFullPage(page);
  
  await page.screenshot({ 
    path: 'example.png',
    fullPage : true
  });
  
  await browser.close();
})();

async function scrollFullPage(page) {
  await page.evaluate(async () => {
    await new Promise(resolve => {
      let totalHeight = 0;
      const distance = 100;
      const timer = setInterval(() => {
        const scrollHeight = document.body.scrollHeight;
        window.scrollBy(0, distance);
        totalHeight += distance;
        
        if (totalHeight >= scrollHeight){
          clearInterval(timer);
          resolve();
        }
      }, 100);
    });
  });
}

Thanks @arjun27 , it worked for the given example. I appreciate your help. Will try with some other examples and let you know how I go.

This project looks interesting, anyway I can contribute to the project? Say some doco, tutorial etc?

overflow-y: initial !important;
the default overflow will affect the fullscreen args

sand4rt pushed a commit to sand4rt/playwright that referenced this issue Dec 21, 2022
@bryanjtc
Copy link

Can scrollFullPage() be implemented with a flag option? I use gsap animations that load the website content when the user scrolls. In my case fullPage: true is not enough.

@250king
Copy link

250king commented Aug 21, 2023

I have some problem about screenshot. I don't know why mine is a little fuzzy? Viewport size is 480×1080.
Cache_1a7696eb549ef62e.jpg

@slorber
Copy link

slorber commented Aug 24, 2023

Similar issue here, I couldn't understand why the bottom of my page gets cropped while running Argos (visual regression tests)

It turns out a widget on the page (the docs 👍 👎 rating widget) produces a layout shift when loading and it messes up with the fullPage screenshot. The bottom cropped part is exactly 109px which is the height this widget takes in practice.

CleanShot 2023-08-24 at 12 05 25@2x

Screenshotting code, using Playwright 1.30:

  await handle.screenshot({
    path: resolve(screenshotFolder, `${name}.png`),
    type: "png",
    fullPage: true,
    mask: [page.locator('[data-visual-test="blackout"]')],
    animations: "disabled",
    ...options,
  });

Considering the widget is visible on both screenshots, it looks to me that there might be some kind of race condition happening in the playwright screenshotting logic. My intuition is:

  • We call screenshot()
  • Screenshot computes the final height
  • The widget appears on the page
  • Playwright takes the screenshot

Example page I found this issue on: https://deploy-preview-3780--react-native.netlify.app/architecture/overview

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants