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