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

Puppeteer: resizeWindow() does not change window bounds #973

Closed
hubidu opened this issue Mar 1, 2018 · 5 comments
Closed

Puppeteer: resizeWindow() does not change window bounds #973

hubidu opened this issue Mar 1, 2018 · 5 comments

Comments

@hubidu
Copy link
Contributor

hubidu commented Mar 1, 2018

What are you trying to achieve?

I want to resize the browser window

What do you get instead?

I get a bigger viewport size, but the browser window size stays the same.

See also puppeteer/puppeteer#1183

Details

  • CodeceptJS version: 1.1.5
  • NodeJS Version: 8.9.4
  • Operating System: Windows
  • Puppeteer (1.0.0)

I would recommend considering the following code for the resizeWindow function which seems to work well

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

    // Window frame - probably OS and WM dependent.
    height += 85;
    
    // Any tab.
    const {targetInfos: [{targetId}]} = await this.browser._connection.send(
      'Target.getTargets'
    );
    
    // Tab window. 
    const {windowId} = await this.browser._connection.send(
      'Browser.getWindowForTarget',
      {targetId}
    );
    
    // Resize.
    await this.browser._connection.send('Browser.setWindowBounds', {
      bounds: {height, width},
      windowId
    });    
  }
@Mehuge
Copy link

Mehuge commented Apr 13, 2018

I just used the above code to implement browser window resizing, thanks

@pjaol
Copy link

pjaol commented Mar 6, 2020

I just tried this and got an error of TypeError: Cannot read property 'setViewport' of undefined
Where / How do you integrate this?

@jan-swiecki
Copy link

Modified version for puppeteer with slight code update (it works with chrome app mode):

async function resizeWindow(browser, page, width, height) {
  await page.setViewport({height, width})

  // Window frame - probably OS and WM dependent.
  height += 85
  
  // Any tab.
  const targets = await browser._connection.send(
    'Target.getTargets'
  )

  // modified code
  const target = targets.targetInfos.filter(t => t.attached === true && t.type === 'page')[0]
  
  // Tab window. 
  const {windowId} = await browser._connection.send(
    'Browser.getWindowForTarget',
    {targetId: target.targetId}
  )
  const {bounds} = await browser._connection.send(
    'Browser.getWindowBounds',
    {windowId}
  )
  
  const resize = async () => {
    await browser._connection.send('Browser.setWindowBounds', {
      bounds: {width: width, height: height},
      windowId
    })
  }

  if(bounds.windowState === 'normal') {
    await resize()
  } else {
    await browser._connection.send('Browser.setWindowBounds', {
      bounds: {windowState: 'minimized'},
      windowId
    })
    await resize()
  }
}

const browser = await puppeteer.launch({
  executablePath: '/path/to/chrome',
  args: ['--app=http://localhost:8080'],
  headless: false,
  defaultViewport: null
})

const page = (await browser.pages())[0]

setTimeout(() => {
  console.log('resize')
  resizeWindow(browser, page, 800, 600)
}, 1000)

@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)

@dvdvdmt
Copy link

dvdvdmt commented Dec 28, 2020

Here is a slightly improved version of @hubidu's snippet:

  async resizeWindow(width: number, height: number) {
    const page = await this.getActiveTab();
    const session = await page.target().createCDPSession();
    await page.setViewport({height, width});
    const {windowId} = await session.send('Browser.getWindowForTarget');
    await session.send('Browser.setWindowBounds', {
      bounds: {height, width},
      windowId,
    });
  }

I removed usages of private properties and call to 'Target.getTargets', because 'Browser.getWindowForTarget' returns the window with active CDP session (docs).

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

7 participants