microsoft / playwright

Playwright is a framework for Web Testing and Automation. It allows testing Chromium, Firefox and WebKit with a single API.
https://playwright.dev
Apache License 2.0
64.93k stars 3.53k forks source link

[BUG] Screenshot: Reduce flicker in headful mode. #2576

Closed kblok closed 4 years ago

kblok commented 4 years ago

Context:

Code Snippet

const playwright = require('playwright');

async function init (){
  const browser = await playwright['chromium'].launch({headless: false});
  const context = await browser.newContext();
  const page = await context.newPage();
  await page.goto('https://example.com');
  screenshot(page)
};

async function screenshot(page){
  let buffer = await page.screenshot();
  let imageBuffer = buffer.toString('base64');
  // save imageBuffer to database
  setTimeout(screenshot, 3000, page)
}

init();

Describe the bug

Bringing this here from this question on StackOverflow.

Do you think we can/want to remove this flicker?

pavelfeldman commented 4 years ago

tl/dr

Do this on all platforms:

const context = await browser.newContext({ viewport: null });

or this on a Mac only:

const context = await browser.newContext({ deviceScaleFactor: 2 });

Details

The reason things jump is that by default Playwright will set fixed viewport size 1280x720 with the deviceScaleFactor set to 1 to emulate low DPI consistently on all platforms. Device scale factor is the ratio between the physical pixel size (your screen) and logical pixel size (DIP or CSS w/o scale). Your Mac has a Retina screen, it is high DPI, the device scale factor for Mac Retina is 2.

When emulating device scale factor on a Mac, Chromium will zoom the image 2x for it to not be tiny while you are using your headful browser. But when you are taking a screenshot, it needs to make image 1:1 with the physical pixels to read screenshot back from the GPU memory. Hence the flickering.

Related

We are working on capturing video from the test runs as a part of the Playwright API. Would that work for your scenario? That would be less resource-consuming since it won't generate frames when nothing happens on the screen, also it'll capture interesting frames even if they are between your 3 second snapshots.

pavelfeldman commented 4 years ago

As pointed out in the stackoverflow, we are bringing window to front before capturing. @dgozman do you remember why this could be necessary?

dgozman commented 4 years ago

This is due to background tabs in Chromium not producing frames. With our new "foreground" emulation, we should double check whether this is still needed.

ghost commented 4 years ago

Thank you so much for your precious help and support ! I have an ongoing project that really needs the browser to not be focused on screenshot, in how much time do you think this will be fixed ?

mehul-warhousing1 commented 8 months ago

Can you post the video again. I also recorded a test video in github CI and the page was flickering from it's position to the left and coming back to the position. This was happening in a loop like GIF for 20 secs. But I am unsure if this was ever reported before, in local trace viewer or browser emulator it never happens. Even I not sure if this particular thread relates to my issue, so if I could see the video once and confirm it.