Lighthouse: Make the ChromeLauncher API into a real thing.

Created on 28 Apr 2017  Â·  9Comments  Â·  Source: GoogleChrome/lighthouse



Here's a few incarnations I'm seeing of people using the ChromeLauncher API:

image
image
image
image
image
image
image

and this dude who's just like "wtf is autoselect?": https://github.com/siddharthkp/lighthouse-ci/blob/c3938a2523434f26ea7963b0546fb241d4f21d36/index.js

_(click above)_

and not to mention the example in lighthouse's readme which is like whaaaaa..

There's a lot of variety and nothing I'm seeing in those snippets actually _looks correct._

Feels like we could use chrome-launcher module that has a real first-class API.

Something with a very clear API surface to handle launch, getting the port number (if set with 0), ability to kill..

It'd also be nice to have sigint kill the process automatically as well. (our poor manual-chrome-launcher doesn't have this currently).

wdyt?

  • @samccone @ebidel

Most helpful comment

This is now fixed. chrome-launcher is published on NPM and available:

const chromeLauncher = require('chrome-launcher');

chromeLauncher.launch({
  chromeFlags: ['--show-paint-rects']
}).then(chrome => {
  console.log(`Chrome debugging port running on: ${chrome.port}`);
});

There is still some work remaining but please feel free to put it to use and report bugs. Thanks!

All 9 comments

In!

getting the port number (if set with 0), ability to kill

more on this: it's really handy to be able to run with --port 0 to listen on a random available port, but Lighthouse needs to connect to the same port, so it needs to be able to get that information non-awkwardly...

maybe we should make a checklist of requirements :)

That'd be great!

The Calibre Chrome launcher is really similar to the Lighthouse one, with a couple of exceptions:

  • It loads a couple of custom extensions (one for auth, one experimental one… and I've often thought about adding 'adblock' in certain circumstances — although, if chrome natively does this, that'd be even better)
  • It returns a connected CRI instance with the browser (Essentially, you're not requesting a browser, but a means to talk to a browser)
  • Set the start url as run.calibreapp.com (this resolves to localhost) — this is great because then custom extensions can be executed (although, this is probably not appropriate for LH)

Another reason this might be great to have in a module is that downstream --headless clients could use ChromeLauncher as a means to loading a testing environment… or a tonne of other things. Setting custom flags would be pretty great.

I'm very much in support of this.

Seems useful.

Mind putting together a requirements doc, more than happy to take care of this now that we have an idea about the use cases.

usecase

launch for Lighthouse or Headless (via cri)

features

feature: port (auto-)selection:

  • if port provided as non-zero will attempt to use that port and fails if the port is unavailable
  • port as 0 will get available

feature: kill() method
feature: optional sigint-> kill ability
feature: use explicit path for chrome (otherwise we'll pick one we like)
feature: hopefully kill autoSelectChrome
feature: WaitTillDebuggerReady (-ish) can be used separately (on already launched Chrome)
feature: chrome-debug binary here too
feature: pass extra chrome flags
feature (2.0?): modify default chrome flags

return and resolve

launchAndConnect() resolves ONLY when protocol is ready. (can have retry stuff built in for this)
return object - port, (pid?), (profilePath?)

logistics

keep in repo, but publish as standalone module.


API got sketched out more: https://public.etherpad-mozilla.org/p/chromelauncherapi

const opts = {
    chromeFlags: string, // e.g. '--show-paint-rects --disable-web-security'
    port: number, // defaults to 0 aka auto, which finds an open port.
    chromePath: string // we pick one automatically if you dont pass the filepath of the chrome/chromium binary
    handleSIGINT: boolean // defaults totrue. iffalse we wouldn't bind to process.on("SIGINT")
};

const instance = await launcher.launch(opts);  
// launch() resolves when chrome is launched and debugger protocol is ready

instance.port
instance.profilePath

instance.kill();

Some prior discussion: https://github.com/GoogleChrome/lighthouse/issues/1176

For now I'v stepped away from lighthouse as a means to launch Chrome. I've used it for a while but solved this problem better with my container orchestrator. Also I didn't like pulling in the whole lighthouse package, just for launching a process. One feature I'd liked to have seen was pluggable logging.

The features described by @paulirish would be perfect for Speed Racer.

I would clarify a multiple Chrome installation use case. In my use case I need to prioritize Canary for the headless support (I think that's what Lighthouse already does right?). But others might want to prioritize mainstream Chrome.

I would prioritize Canary by default but let the user opt-out with something like this:

const launcher = new ChromeLauncher({ canary: false })

I've been using lighthouse as a module and ham-fistedly added some of these (1, 2, 3, 4, 7 above) out of necessity to our very much in-development tool. I'd be happy to help with this, discuss our use cases, and/or add to the documentation @samccone @paulirish!

This is now fixed. chrome-launcher is published on NPM and available:

const chromeLauncher = require('chrome-launcher');

chromeLauncher.launch({
  chromeFlags: ['--show-paint-rects']
}).then(chrome => {
  console.log(`Chrome debugging port running on: ${chrome.port}`);
});

There is still some work remaining but please feel free to put it to use and report bugs. Thanks!

Was this page helpful?
0 / 5 - 0 ratings