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

Devtools resize viewport dimensions overlay included in screenshots #6819

Closed
marvinhagemeister opened this issue Feb 4, 2021 · 14 comments
Closed
Assignees

Comments

@marvinhagemeister
Copy link
Contributor

Steps to reproduce

Tell us about your environment:

  • Puppeteer version: 7.0.0
  • Platform / OS version: MacOS Big Sur
  • URLs (if applicable): -
  • Node.js version: 14.13.0

What steps will reproduce the problem?

const puppeteer = require('puppeteer');

(async () => {
    const browser = await puppeteer.launch({
        headless: false,
        devtools: true,
    });
    const page = await browser.newPage();
    await page.goto('https://example.com');

    await page.screenshot({ path: 'example.png', fullPage: true });

    await browser.close();
})();
  1. Run the above script
  2. open example.png

What is the expected result?

example

What happens instead?

Notice the viewport dimensions in the top right corner of the screenshot. I expect them not to be there. They are seemingly injected by the devtools somehow. They are not present when the devtools panel isn't open. Doesn't seem to be injected into the pages HTML either, otherwise I'd be able to hide it via CSS or something.

image

@mathiasbynens
Copy link
Member

Maksim, could you PTAL? Looks like the overlay (cc @OrKoN) shows up.

@OrKoN
Copy link
Collaborator

OrKoN commented Feb 5, 2021

The viewport size overlay is shown when you resize the window and have DevTools opened. So I wonder if it's a regression issue? Maybe the capturing of a screenshot causes the window to resize now.

@marvinhagemeister
Copy link
Contributor Author

marvinhagemeister commented Feb 5, 2021

Can confirm that this issue is not present in 5.x or 6.x. It starts to appear with version 7.0.0.

@OrKoN
Copy link
Collaborator

OrKoN commented Feb 5, 2021

@sadym-chromium PTAL then. Also, when a screenshot is taken via DevTools, DevTools disables all overlays so perhaps Puppeteers implementation should do the same?

@sadym-chromium
Copy link
Collaborator

On it

@sadym-chromium
Copy link
Collaborator

Confirmed. I was able to reproduce and to add an automated test for it. Looking into solving the issue.

@sadym-chromium
Copy link
Collaborator

It looks like the issue is with having 2 Overlay agents controlling Overlays. One from the DevTools session, another from the Puppeteer session. The question is should the Overlay be a global or should we stick to the current behaviour having an overlay manager per CDP session.

Having singleton Overlay Manager:

Pros:

  • No Overlay artefacts on the screenshots, doesn't matter who many sessions we have.

Cons:

  • Not precise result. Meaning e.g. if a node is highlighted by one session, the screenshot from the other session wouldn't have it.
  • Can be unwilling side-effects caused by the concurrent session.

I personally inclined to keep the Overlay per-session.

@jschfflr, @mathiasbynens, @OrKoN, @marvinhagemeister
WDYT?

@OrKoN
Copy link
Collaborator

OrKoN commented Feb 8, 2021

I think we should keep the overlay agents created per session unless it's the only solution.

@sadym-chromium
Copy link
Collaborator

@marvinhagemeister could you please clarify the business case why the screenshot with open DevTools is needed?

@marvinhagemeister
Copy link
Contributor Author

marvinhagemeister commented Feb 8, 2021

@sadym-chromium Sure!

We've build a complete test runner around puppeteer over at https://github.com/boxine/pentf/ . To make test inspection as easy as possible for our developers we have a -d, --debug flag that opens up the browser in headful mode with devtools already opened, with persistent logging enabled and a bunch of other stuff. They love it because it saves them quite a few clicks and makes test inspections easy. During testing we'll take various screenshots that is automatically included in test reports.

For most type of screenshots the additional overlay from devtools doesn't matter, but it get's very annoying when it comes to visual regression testing. It works by taking a screenshot of the current page and comparing it to a previous one and highlighting the differences. The devtools overlay causes a mismatch leading to test failures.

image

I'm happy with directly messaging with the devtools client like in the linked PR, if this issue is not seen as worthy enough to be fixed in puppeteer itself.

@sadym-chromium
Copy link
Collaborator

sadym-chromium commented Feb 10, 2021

A bit of implementation details explaining what is going on under the hood:

  1. Puppeteer opens Chrome with DevTools.
  2. Chrome is open with 2 parallel CDP connections: for Puppeteer and for DevTools.
  3. DevTools creates an OverlayAgent which can show a node highlighting and the size overlay in case of resizing.
  4. Puppeteer sends a request to make a page screenshot.
  5. PageHandler gets the screenshot request.
  6. PageHandler changes WebPreferences so that the whole page is rendered, not only the visible one.
    1. PageResized event is raised on the page.
    2. OverlayAgent created by the DevTools catches PageResized event and draws size overlay.
  7. PageHandler makes a screenshot.
  8. The Size overlay is on the screenshot.

As you see, the problem cannot be solved by the Puppeteer itself. There are few potential solutions:

  1. ❓ arguable: From the PageHandler access all the OverlayAgent for the page and call Overlay.setShowViewportSizeOnResize(show: false) on them.
  2. ❌ too radical approach: From the PageHandler try to prevent PageResized to be raised.
  3. ❓ quite radical, can have side effects with other Overlays: Implement page-singleton OverlayAgentPageSingleton and keep the state of the ShowViewportSizeOnResize there.
  4. ✅ less invasive: From the Puppeteer access DevTools, and send Overlay.setShowViewportSizeOnResize(show: false) message from there.

@calebeby
Copy link

calebeby commented Apr 2, 2021

@sadym-chromium I am still seeing the resize overlay in the screenshots after setting Overlay.setShowViewportSizeOnResize:

const session = await page.target().createCDPSession();
await session.send('Overlay.setShowViewportSizeOnResize', { show: false });

I didn't fully understand your comment explaining what is happening when the screenshot is taken, is there a different workaround that I could use to make the resize indicator go away?

@sadym-chromium
Copy link
Collaborator

sadym-chromium commented Apr 13, 2021

The issue can be solved by rolling back to previous behaviour. To do so, you should pass argument captureBeyondViewport: false to screenshot, implemented in the PR #7063

@sadym-chromium
Copy link
Collaborator

Feel free to reopen the issue if the approach doesn't work for you.

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

5 participants