Search code examples
javascriptnode.jsgoogle-chromegoogle-chrome-devtoolsgoogle-chrome-headless

Headless chrome launcher --window-size causing error


I need to be able to take screenshot given a certain window size. I read this blog post on How to run Headless Chrome in Codeception and this page on Getting Started with Headless Chrome but could not figure out how to resize the window at init.

I have tried to pass --window-size in all options below and none work:

--window-size=1280,1696
--window-size=1280x1696
--window-size 1280,1696
--window-size 1280x1696

Worst of all, now my screenshot is blank after doing this for awhile. Is there some kind of memory retained in the headless browser causing this? I have not tried to reboot my Mac yet which is probably next.

So what is a way to take full page screenshot given window size? In phantom.js, this is a very trivial thing.

My code is below

const chromeLauncher = require('chrome-launcher');
const CDP = require('chrome-remote-interface');
const file = require('fs');

(async function() {
  async function launchChrome() {
    return await chromeLauncher.launch({
      chromeFlags: [
        '--window-size=1280,1696',
        '--disable-gpu',
        '--headless'
      ]
    });
  }
  const chrome = await launchChrome();
  const protocol = await CDP({
    port: chrome.port
  });

  const {
    DOM,
    Network,
    Page,
    Emulation,
    Runtime
  } = protocol;
  await Promise.all([Network.enable(), Page.enable(), Runtime.enable(), DOM.enable()]);

  Page.navigate({
    url: 'https://www.yahoo.com/'
  });

  Page.loadEventFired(async() => {

    console.log('Start Page.loadEventFired');
    const script1 = "document.querySelector('p').textContent"
    const result = await Runtime.evaluate({
      expression: script1
    });
    console.log(result.result.value);

    const ss = await Page.captureScreenshot({format: 'png', fromSurface: false});
    file.writeFile('output.png', ss.data, 'base64', function(err) {
      if (err) {
        console.log(err);
      }
    });

    protocol.close();
    chrome.kill(); 
  });

})();

If I do this in command line, it works fine:

alias chrome-canary="/Applications/Google\ Chrome\ Canary.app/Contents/MacOS/Google\ Chrome\ Canary"

chrome-canary --headless --disable-gpu --screenshot --window-size=300,1696 https://www.yahoo.com/

UPDATE

I realized headless Chrome Canary is very unstable on the Mac at least. If I close down the Terminal and start it fresh, sometime it works. But then after running exactly the same script, it just hung up forever (I left overnight). I just updated everything (Chrome Canary, chrome-launcher, chrome-remote-interface) today and continue to debug. Maybe it's not its prime time yet.


Solution

  • OK I just learnt that using --window-size won't work. Below works:

    Added:

      Page.setDeviceMetricsOverride({
        'width': 735,
        'height': 2200,
        'deviceScaleFactor': 1,
        'mobile': false
      });
    

    Removed (caused Headless Chrome to freeze):

    const script1 = "document.querySelector('p').textContent"
    const result = await Runtime.evaluate({
      expression: script1
    });
    console.log(result.result.value);