添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

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

I realize this is on the edge, but currently when running lighthouse-cli or using lighthouse-core in custom scripts, cri.js will throw an error and exit when running against the headless_shell built from the tip (as of Nov 17):

status Disconnecting from browser... +0ms
Runtime error encountered: Error: Unable to fetch webSocketDebuggerUrl, status: 500
    at IncomingMessage.response.on._ (/usr/local/lib/node_modules/lighthouse/lighthouse-core/gather/connections/cri.js:79:18)
    at emitNone (events.js:91:20)
    at IncomingMessage.emit (events.js:185:7)
    at endReadableNT (_stream_readable.js:974:12)
    at _combinedTickCallback (internal/process/next_tick.js:74:11)
    at process._tickCallback (internal/process/next_tick.js:98:9)

This is caused by CriConnection connect() method calling /json/new. In this case, headless_shell will return "Cannot create new page" as the /json/new API does not exist in headless_shell as per https://bugs.chromium.org/p/chromium/issues/detail?id=626847.

My question: leave the existing behavior and wait for 626847 to add the the backwards compatibility for /json/new or handle this in the new Browser.createTarget DevTools command?

Note: if anyone is reading this and you still want to run against headless_shell now, you can temporarily peg to 1.1.6 before the Connection refactor occurred.

@pavelfeldman if you have any advice.

@justinribeiro do you know how chrome-remote-interface does this that worked before? When I looked into it when Pavel changed to Connection in #800 it seemed like cri was doing the same http request to /json/new. I was just skimming the source, though, not stepping through it, so maybe I missed the actual execution path.

@brendankenny CriDriver in 1.1.6 used chromeRemoteInterface.New() and only warned on the inability to crete a new tab and re-used instead, which worked fine with headless_shell.

In terms of Browser.createTarget, I'm just coming up to speed on it based on the ticket (possibly @pavelfeldman or @paulirish can shine more light on that).

In the current build from the tip, if you call localhost:9222/json you can indeed see the webSocketDebuggerUrl, but localhost:9222/json/new will fail:

"description": "", "devtoolsFrontendUrl": "/devtools/inspector.html?ws=localhost:9222/devtools/page/ed48139f-429e-4f96-8412-bb0a49ebce7a", "id": "ed48139f-429e-4f96-8412-bb0a49ebce7a", "title": "about:blank", "type": "page", "url": "about:blank", "webSocketDebuggerUrl": "ws://localhost:9222/devtools/page/ed48139f-429e-4f96-8412-bb0a49ebce7a"

I suppose this could be worked around using this in the short term, but I'm not sure as to the utility (as it's likely not to be used much at this point given that you still have to build headless_shell from source).

We need to do something on chromium side to make you happy. Just filed this: https://bugs.chromium.org/p/chromium/issues/detail?id=666865. Once it is fixed, you can issue "Target.createTarget" while connected to the predefined "ws://localhost:9222/devtools/browser" endpoint. We might want to throw a secure GUID into that path to protect your clients from random pages attempting to connect to the endpoint. That way it does not require the flag, but you need to have a way of parsing the GUID out from the chrome stdout.

Was banging my head on this with chrome-remote-interface. This thread got me on a track. Thanks guys!

In case anyone is interested, I was able to achieve some results with the following code.

var cri = require('chrome-remote-interface');
var tabManagerP;
function getTabManager () {
  if (!tabManagerP) {
    tabManagerP = cri({ port: 9222 });
  return tabManagerP;
function executeInTab (workFn) {
  return getTabManager()
    .then(tabManager => {
      return tabManager.Target.createTarget({ url: 'about:blank' })
        .then(({ targetId }) => {
          return cri.List({ port: 9222 })
            .then(list => {
              var url = list.find(target => target.id === targetId).webSocketDebuggerUrl;
              return cri({ tab: url });
            .then(devtools => workFn(devtools))
            .then(result => {
              return tabManager.Target.closeTarget({ targetId })
                .then(() => result);
            }, error => {
              return tabManager.Target.closeTarget({ targetId })
                .then(() => {
                  throw error;
                });
            });
        });
    });
executeInTab(devtools => {
  return doSomethingWithDevtools(devtools);
}).then(result => {
  console.log(result);
});

@Janpot I'm trying to adapt your code (above and over at headless-dev group). It works as far as tab management is concerned, but after each task (executeInTab) finishes, there's an orphan Chrome process (unclosed target I suppose). It quickly results in 10s of orphan Chrome processes. Did you come across this issue, or would you know what could be causing it?

I tested a bare minimum code sample, pretty close to Lindsey's adaption of your code, on Ubuntu 16.04 LTS and Chrome 57 beta.

Update: Never mind. I figured out that the DevTools API needs parameter names, so the closeTarget method should include the targetId parameter name, like tabManager.Target.closeTarget({ targetId: targetId }), for it to correctly close a target (and end the chrome process).

BTW, it looks like /json/new is now implemented for headless (as of 4 days ago):
http://crbug.com/699392

It should be in a tip of tree build. m59, any build >= 455669.

Said ticket + merge was specific to headless shell (overrides CreateNewTarget in the HeadlessDevToolsManagerDelegate https://codereview.chromium.org/2735943005).

As I recall from either the tracker or mailing list (and Paul or someone else can correct me as I can't find said conversation), /devtools/browser was the way forward but due to the need for backwards comparability, /json/new was added.

We need to do something on chromium side to make you happy. Just filed this: https://bugs.chromium.org/p/chromium/issues/detail?id=666865. Once it is fixed, you can issue "Target.createTarget" while connected to the predefined "ws://localhost:9222/devtools/browser" endpoint.

FYI: A patch is up for this https://chromium-review.googlesource.com/c/596719