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

window inner size not equal to viewport size #1183

Closed
0xtoorich opened this issue Oct 27, 2017 · 68 comments
Closed

window inner size not equal to viewport size #1183

0xtoorich opened this issue Oct 27, 2017 · 68 comments
Labels

Comments

@0xtoorich
Copy link

Tell us about your environment:

  • Puppeteer version: 0.13.0-alpha
  • Platform / OS version: macos high sierra 10.13
  • URLs (if applicable):

What steps will reproduce the problem?

Please include code that reproduces the issue.

// start.js

const puppeteer = require('puppeteer')

const run = async () => {
  const browser = await puppeteer.launch({
    headless: false,
    slowMo: 250,
    args: [
      '--disable-infobars',
    ],
  });

  const page = await browser.newPage();

  await page.goto('https://www.google.com/');

  await page.waitFor(60000)
  await browser.close();
}

run()
  1. node start.js

What is the expected result?

  1. window inner size and viewport should be equal, all the default 800px x 600px

What happens instead?

  1. window inner size is larger than the viewport size

google-puppeteer.png

@entrptaher
Copy link
Contributor

entrptaher commented Oct 28, 2017

To add more salt into it, opening devtools will make the viewport lose the predefined size. For example,
image

@zicongxie
Copy link

zicongxie commented Oct 29, 2017 via email

@0xtoorich
Copy link
Author

@zicongxie await page.setViewport({ width: 600, height: 400 }) only change the viewport size, but the window size will not changed to 600px x 400px too.

@0xtoorich
Copy link
Author

@entrptaher I noticed that too.

@aslushnikov
Copy link
Contributor

@chanjsq what's your usecase? Why would you need to change the window size?

@entrptaher
Copy link
Contributor

For me, say I will want to test responsiveness.

@0xtoorich
Copy link
Author

0xtoorich commented Nov 1, 2017

@aslushnikov When setting the viewport size larger than the default window size, we also need to set the window size with the same value to see the whole page width, it's convenient if the window size can change with viewport size accordingly.

@mike-aungsan
Copy link

Have the same issue on Windows 8.

@aslushnikov
Copy link
Contributor

@entrptaher isn't viewport enough for responsiveness?
@chanjsq so this is mostly for debugging purposes?

@0xtoorich
Copy link
Author

@aslushnikov yes, smart can be better

@z-vr
Copy link

z-vr commented Nov 15, 2017

can i make the viewport equal to the size of the window by default, and adjustable while resizing? i don't want the viewport which is not equal to the window size :( +1 on this one

@radekmie
Copy link

radekmie commented Dec 1, 2017

I'm using this code:

await page.setViewport({height, width});

// Window frame - probably OS and WM dependent.
height += 85;

// Any tab.
const {targetInfos: [{targetId}]} = await browser._connection.send(
  'Target.getTargets'
);

// Tab window. 
const {windowId} = await browser._connection.send(
  'Browser.getWindowForTarget',
  {targetId}
);

// Resize.
await browser._connection.send('Browser.setWindowBounds', {
  bounds: {height, width},
  windowId
});

I think that Tab window + Resize parts could be part browser API such as:

browser.resize({height, width})

@tnoetzel
Copy link

Definitely also need this, fwiw.

@ganfubin
Copy link

this function is very necessar

@leachimsumiri
Copy link

+1

@akylkb
Copy link

akylkb commented Feb 6, 2018

https://peter.sh/experiments/chromium-command-line-switches/#window-size

const puppeteer = require('puppeteer')

const run = async () => {

    // Viewport && Window size
    const width = 400
    const height = 600

    const browser = await puppeteer.launch({
        headless: false,
        args: [
            `--window-size=${ width },${ height }`
        ],
        defaultViewport: {
            width,
            height
        }
    });

    const page = await browser.newPage();
    await page.goto('https://www.google.com/')

    // await browser.close()
}

run()

@Mehuge
Copy link

Mehuge commented Feb 10, 2018

I am using the following to achieve the desired effect.

const chrome = { x: 0, y: 74 };   // comes from config in reality
args.push(`--window-size=${width+chrome.x},${height+chrome.y}`);
puppeteer.launch({ headless, sloMo, args });
// ...
page.setViewport({ width, height });

@tomholub
Copy link

Based on https://github.com/GoogleChrome/puppeteer/blob/v0.13.0/docs/api.md#pagefocusselector and @Mehuge asnwer

const chrome = { x: 0, y: 74 };   // comes from config in reality
args.push(`--window-size=${width+chrome.x},${height+chrome.y}`);
puppeteer.launch({ headless, sloMo, args });
// ...
page.setViewport({ width, height });

(correcting typo in setViewport above)

@I-keep-trying
Copy link

Thanks, guys!!! I combined @akylkb with @Mehuge and got the perfect solution!

And fwiw, for people who didn't understand why viewport size is important. It was stopping me dead in my tracks, because a common practice in many websites is to change the layout from pc / laptop to mobile based on viewport size, and the default size was causing it to go to the mobile layout, which did not have the login button available without an extra menu, involving two extra clicks. The entire DOM and navigation path can be completely different depending on how many different responsive designs the website designers have in place; they could have several, from smart watches to mobile, to ipads and tablets, touch screens and kiosks as well. The world includes much, much more than just laptops and pcs, and each and every layout will have a completely different DOM structure.

So, again, THANK YOU, @akylkb and @Mehuge, your solutions deserve a lot more attention imo!!

@grantstephens
Copy link

Think this is actually a bug when connecting over a websocket as I can't find a way to set the window size when on web socket. This means that some sites render incorrectly as they seem to look at the window size and not that set viewport, i.e:
Launch the browser
Connect to it via websocket
Set the viewport to be bigger than the window size of the websocket browser
Screenshot is based on window size.

I'm not 100% sure of this, but would seem to be the case and would appreciate anybody who could confirm.

@PayteR
Copy link

PayteR commented Mar 19, 2018

Hi, thx guys for solutions, but screen.width and screen.height are in headless: true always 800x600 and for headless: false is always resolution of actual screen. Any suggestions to solve this other than manually do it so in evaluate() method? Code:

await Page.evaluateOnNewDocument((screenWidth, screenHeight) => {
    screen.__defineGetter__('width', function () {
        return screenWidth;
    });
    screen.__defineGetter__('height', function () {
        return screenHeight;
    });
}, width, height);

gavoja added a commit to gavoja/CodeceptJS that referenced this issue Mar 29, 2018
DavertMik pushed a commit to codeceptjs/CodeceptJS that referenced this issue Mar 30, 2018
* Workaround for puppeteer/puppeteer#1183

* Formatting.

* Formatting.
@winterli
Copy link

This might be related issue,

When saving as PDF (have to use headless mode), the window size triggers the incorrect media query. For example, if page.setViewport(1200,960), then load below HTML page and save to PDF. Will expect the DIV has a gray background. But it actually shows a yellow background.

<body>
	<script>
		document.write("Window width: "+window.innerWidth);
	</script>
	<style>
		div{
			background: gray;
		}
		@media (max-width: 767px) {
			div{
				background: yellow;
			}
		}
	</style>
	<div>gray indicates window > 767px, yellow indicates window <=767px</div>
</body>

1523341516653 pdf 2018-04-09 23-25-38

aslushnikov added a commit to aslushnikov/puppeteer that referenced this issue Apr 12, 2018
This patch:
- teaches page.setViewpot() to accept `null` to disable
viewport emulation.
- allows passing `0` as deviceScaleFactor to use machine-defined
deviceScaleFactor.

References puppeteer#1183.
Fixes puppeteer#2358.
@Mehuge
Copy link

Mehuge commented Apr 13, 2018

I am now using @radekmie's solution, as well as the --window-size argument.

In my test environment, the browser size may be specified before the browser window is open, and may be altered afterwards. So in the case where it is specified before the browser window is open, I remember the size and use --window-size when launching the browser. If the test scripts later specify a new size, I then use the resize code provided by @radekmie.

@junguchina
Copy link

junguchina commented Sep 17, 2018

@DanielRuf Thanks, my version of puppeteer is the latest version(1.8.0).
It still has this problem.I use codeceptjs with puppeteer.
The viewport size of chromium is 800x600,but inner homepage size is 1920x1080.
jietu20180917-175801-hd

@fergardi
Copy link

I'm facing the same issue as above.

@DanielRuf
Copy link

Mh weird, it seems this was not resolved as I am still getting the narrow / small viewport even if I resize. Is there some regression?

@fergardi
Copy link

I want to share my personal experience. This will be a long trip.

I'm using puppeteer@1.8.0 and Google Chrome V69.0.3497.100 in a Windows10 environment.

Let's say I am new to Headless Chrome, and I want to print a dashboard in PDF. I searched for a typical responsive template dashboard and found this one I will be using as an example, credits to the original author: https://demos.creative-tim.com/bs3/paper-dashboard/dashboard.html

Then I create a new fresh script to work with:

const puppeteer = require('puppeteer');
(async () => {
  const browser = await puppeteer.launch({headless: false}) // debug
  const page = await browser.newPage()
  await page.setViewport({width: 768, height: 1024, deviceScaleFactor: 2})
  await page.goto('https://demos.creative-tim.com/bs3/paper-dashboard/dashboard.html', {waitUntil: 'networkidle0'})
  await page.waitFor(1000)
  await page.click('button.close') // remove notification
  await page.click('a.navbar-brand') // click on page to close advertisement
  await page.emulateMedia('screen') // force screen CSS
  await page.waitFor(1000) // wait for every modal to dissapear
  await page.pdf({path: `${Date.now()}.pdf`, format: 'A4', printBackground: true})
  await browser.close()
})()

After that, I prove that in headful mode, and it gives me this result:

image

Firstly, why that blank space? Is that the difference between the default 800px width viewport minus my 768px viewport? I don't think so. However, this does not show in the final PDF, only in headful mode, but it stills bugs me a lot. In headless mode, it shows at follows:

image

Secondly, why the media CSS flex is not triggering as showed in the intial picture? There should be two columned layout, not the single one. As I inspect them, they show as classic '@media' queries. Maybe the 'screen' forced mode instead of 'print' is causing this? I do not know.

Thirdly, why my pixel resolution is not being respected? If, in headful mode, I show the DevTools and extract them from the page (which seems, by the way, to re-render the page to the expected behaviour), I can see the pixel resolution is not at all the one I setted of in the initial step.

image

In fact, I could even increase the pixel resolution to have no results on the output:

image

Ah, that seems the old 800x600 viewport issue we were talking about. So I started to test every solution in this post, with these results:

  1. Force puppeteer to launch to a nulled defaultViewport? No changes either in headless or headful.
  2. Force puppeteer to launch to a defaultViewport with exactly the same resolution as I wanted? No changes either in headless or headful.
  3. Force puppeteer to launch to a defined --window-size arg commands? That seems indeed to change the headful result and fix the strange blank space, leaving me with my desired initial resolution (to test responsiveness, for example). That leads me to the next issue. If I'm visiting this website with 768px width, which effectively triggers the corresponding @media query, why in headful I see one result and in headless I see another different result?

image

Maybe the float is affecting the behaviour? But again, why am I not achieveing the exact same result being in headful or in headless, as this is the whole point? I do not know. That will be an entirely different issue.

@paynecodes
Copy link

paynecodes commented Apr 9, 2019

Is there any way we can get this opened? It's still an issue, and @fergardi's comment describes the issue nicely.

cc @aslushnikov

@samburgers
Copy link

samburgers commented Apr 10, 2019

I was knocking my head over this for some time, until i realised (at least for my particular use case) is that this is all i needed to do to break out of the default 800 x 600 size:

const puppeteer = require("puppeteer");

(async () => {

  const browser = await puppeteer.launch();

  const page = await browser.newPage();

  await page.emulateMedia("screen"); // <- optional but super useful

  await page.goto("http://localhost:3000", {
    waitUntil: "networkidle2"
  });

  await page.pdf({
    path: "filename.pdf",
    pageRanges: "1",
    width: 1600, // <- set width
    height: 1240, // <- set height
    printBackground: true
  });
})();

@redochka
Copy link

why is this issue closed, while the problem is still there?

@shawnnaquin
Copy link

tested, still an issue.

@aslushnikov
Copy link
Contributor

aslushnikov commented Jun 7, 2019

Everybody: the reason this issue is closed is because you can actually disable viewport emulation with defaultViewport: null option.

Here's an example:

const browser = puppeteer.launch({
  defaultViewport: null, // <= set this to have viewport emulation off
});
const page = await browser.newPage();
// ... 

@meeple142
Copy link

thanks for the tip @aslushnikov

@KotieSmit
Copy link

KotieSmit commented Jul 15, 2019

FWIW

My workaround was to add:

_beforeSuite() {
this.helpers.Puppeteer.resizeWindow(1200, 960)
}

This way the view port is always set the size I want. You can go a step further and read out the values from the config file.

https://codecept.io/helpers/Puppeteer#resizewindow

@deqline
Copy link

deqline commented May 29, 2020

As of today @aslushnikov method still works for anyone having this problem.

const browser = puppeteer.launch({
  defaultViewport: null, // <= set this to have viewport emulation off
});

@destroyer22719
Copy link

Everybody: the reason this issue is closed is because you can actually disable viewport emulation with defaultViewport: null option.

Here's an example:

const browser = puppeteer.launch({
  defaultViewport: null, // <= set this to have viewport emulation off
});
const page = await browser.newPage();
// ... 

THANK YOU SO MUCH YOU ARE AN ANGEL

@jonwilliams-bluescape
Copy link

having fought with this for a few days, none of the googled solutions worked for me.
Although some of what's been posted will result in the window size being set, the values won't be readable from window.outerWidth after a page navigation.

However...

function setWindowDimensions ({width, height}) {
  window.outerWidth = width;
  window.outerHeight = height;
}

(async () => {
  const dimensions = await page.evaluateOnNewDocument(setWindowDimensions, {width, height});
})();

Executing this before navigating to the target URL will allow a script on that page to properly read the window size.
Tested in both headless and non-headless mode (Chromium)

@siva349
Copy link

siva349 commented Oct 8, 2021

Started working with puppeteer since few days, struggled with this problem. But this solution worked like a magic. Thanks @aslushnikov

const browser = puppeteer.launch({
  defaultViewport: null, // <= set this to have viewport emulation off
});

@f-g-s
Copy link

f-g-s commented Oct 18, 2021

I´m using Puppeteer and Jest and this jest-puppeteer.config.js works for me. :)

module.exports = {
    launch: {
        args: ['--start-maximized'], // get full screen browser window 
        defaultViewport: null, // get default (full size) viewport 
    },
}

@danangponorogo
Copy link

danangponorogo commented Nov 15, 2021

a little addition

(async () => {
    const browser = await puppeteer.launch({
        headless: false,
        ignoreHTTPSErrors: true,
        defaultViewport: null,
        args: [`--start-maximized`]
    });
    const page = await browser.newPage();
    await page.goto('https://domain.com');
    await browser.close();
})();

@mystic-poet
Copy link

#> this.helpers.Puppeteer.resizeWindow(1200, 960)

const browser = puppeteer.launch(

Started working with puppeteer since few days, struggled with this problem. But this solution worked like a magic. Thanks @aslushnikov

const browser = puppeteer.launch({
  defaultViewport: null, // <= set this to have viewport emulation off
});

Where did you add these lines?

@ganfubin
Copy link

ganfubin commented Jan 8, 2022 via email

@vigneshwaran-chandrasekaran
 const browser = await puppeteer.launch({
        headless: false,
        defaultViewport: null,
        args: ['--start-maximized'], // we can use '--start-fullscreen' || --start-maximized
    });

@ganfubin
Copy link

ganfubin commented Feb 11, 2022 via email

@augustoaraujoo
Copy link

const browser = await puppeteer.launch({
    /* headless: false */,
    defaultViewport: null,
    args: ['--start-maximized']
  });

@ganfubin
Copy link

ganfubin commented Aug 26, 2022 via email

@nickfthedev
Copy link

As of today @aslushnikov method still works for anyone having this problem.

const browser = puppeteer.launch({
  defaultViewport: null, // <= set this to have viewport emulation off
});

4 years later, you made my day sir! Thanks!

@ganfubin
Copy link

ganfubin commented Oct 24, 2024 via email

@TheGP
Copy link

TheGP commented Oct 25, 2024

That Chinese guy is on vacation for 2 years already

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

No branches or pull requests