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

--remote-debugging-pipe support #381

Closed
gregmartyn opened this issue Dec 7, 2018 · 23 comments · May be fixed by #440
Closed

--remote-debugging-pipe support #381

gregmartyn opened this issue Dec 7, 2018 · 23 comments · May be fixed by #440

Comments

@gregmartyn
Copy link

--remote-debugging-pipe would let us use CDP without having to worry about finding an available listening port, and the possible race condition between finding an open port and Chrome starting up on that port

It's not very well documented other than in the code, with a short discussion here:
https://groups.google.com/a/chromium.org/forum/#!msg/devtools-reviews/wnCpqPbWqiU/1T95Os2sBAAJ

--remote-debugging-pipe tells Chrome to listen on file descriptor 3 for CDP input and FD 4 for output.

@gregmartyn
Copy link
Author

@cyrus-and
Copy link
Owner

Hm and how should I use this? It looks like something that concerns an application that starts Chrome itself.

@cyrus-and
Copy link
Owner

version support (v67)

It only works for Chrome >= 72; segfaults in 71:

$ google-chrome --version
Google Chrome 71.0.3578.80
$ google-chrome --headless --remote-debugging-pipe
Fontconfig warning: "/etc/fonts/fonts.conf", line 100: unknown element "blank"
[1207/170032.369584:ERROR:gpu_process_transport_factory.cc(967)] Lost UI shared context.
Segmentation fault

@cyrus-and
Copy link
Owner

This doesn't work as expected.

Terminal 1:

$ mkfifo input
$ echo '{"id": 0, "method": "Target.getTargets"}' >input

Terminal 2:

$ mkfifo output
$ cat output

Terminal 3:

$ google-chrome-unstable --headless --remote-debugging-pipe 3<input 4>output
Fontconfig warning: "/etc/fonts/fonts.conf", line 100: unknown element "blank"
[1207/172020.059236:ERROR:devtools_pipe_handler.cc(143)] Connection terminated while reading from pipe

And nothing appears on terminal 2.

@gregmartyn
Copy link
Author

gregmartyn commented Dec 7, 2018 via email

@cyrus-and
Copy link
Owner

The trick seems to be the null character.

Nice that does it!

Anyway I'm struggling to see how this can be incorporated with this library as it's only meaningful (unless some ugly hacks) if you start Chrome with those FDs set up.

@cyrus-and
Copy link
Owner

I could theoretically require two paths (input and output pipe) to be specified by the user and use that in place of the WebSocket, but the user would then need to start Chrome with the proper redirection (like above example).

But what's the real advantage? We're trading the "finding and available port" with "finding an available path" (well actually two of them). Which, besides, if you're in charge of starting Chrome it's something that you can specify.

The only thing could be avoiding the need of polling but it can be trivially achieved with a couple of lines of Bash or JavaScript.

@gregmartyn
Copy link
Author

When using ports, when you're starting Chrome there's a race between when you check for an open port and when the Chrome process opens it. There's no way to hand the open port to the Chrome process. Ports are also a finite global resource, so it's much easier to run out or have a collision than with files.

When using fds and spawning Chrome, you can create a pipe and access it through subprocess.stdio[fd]. https://nodejs.org/api/child_process.html#child_process_options_stdio There's no risk of collision with other processes that way.

And yeah no polling is a win too

@cyrus-and
Copy link
Owner

When using ports, when you're starting Chrome there's a race between when you check for an open port and when the Chrome process opens it. There's no way to hand the open port to the Chrome process.

That's the wrong approach IMHO, you shouldn't check for open ports then use it, you just use it then handle the failure, this is an universal issue. (Or you can let the OS pick one for you with --remote-debugging-port=0.)

Ports are also a finite global resource, so it's much easier to run out or have a collision than with files.

Do you really need 60k+ Chrome instances listening (or whatever active long-running connections) on a single IP address?

I suspect your use case is a bit exceptional, otherwise those are not really concerns; care to explain?

@gregmartyn
Copy link
Author

Thanks for the feedback! I didn't know about the --remote-debugging-port=0 approach. That will work.

--remote-debugging-pipe would simplify things, (no loop for chrome start failure) but I'm all set.

@cyrus-and
Copy link
Owner

Good! So I'm closing this, at least for the time being.

@paambaati
Copy link
Contributor

@cyrus-and It might be worthwhile reopening this, as the future puppeteer v2.0 release plans to default to pipe mode.

@cyrus-and
Copy link
Owner

@paambaati as long as the WebSocket approach is supported by Chrome I don't see why this library should support pipe mode. It makes more sense for Puppeteer that starts its own Chrome instance by default. But there's no easy way to start Chrome manually then use pipes to interact with it.

I'd put this on hold, al least until the feature has been established, I don't want to do a major rewrite of the lib just to discover that things have changed again. Also because – pure speculation here – the current implementation of pipes seems quite crude to me, I wouldn't be surprised if it would change again...

@kensoh
Copy link

kensoh commented Dec 28, 2019

Adding on to this conversation.. Hi @cyrus-and ! I have an automation project TagUI which connects to Chrome directly through --remote-debugging-port=9222 and controls it with the DevTools protocol using that websocket connection.

Last week, a user raised an issue that Gmail now blocks logging in and that it shows an error message detecting the browser is automated and unsupported. It looks like there is a recent change in current Chrome release that somehow blocks Google account login with a browser that is launched with --remote-debugging-port=9222. Seems like many users and apps are impacted, from this Google support issue - https://support.google.com/accounts/thread/22873505

There's an open issue at my project now aisingapore/TagUI#660, I'm adding a comment here fyi, and that it may be something that will impact this project as well. If somehow Puppeteer now defaults to only accepting --remote-debugging-pipe for Google account logins. Also, following this thread, and the Google support issue, to see if there are new developments. Copying my friend @siowyisheng for info.

@cyrus-and
Copy link
Owner

Thank you @kensoh for the heads up. The problem isn't how you do the automation, is the mere fact that the browser is instrumented, in fact the same sign in error happens if you use --remote-debugging-pipe instead of --remote-debugging-port=9222. And it does make sense, the former isn't more secure than the latter.

@kensoh
Copy link

kensoh commented Dec 29, 2019

Thanks @cyrus-and got it! My friend @siowyisheng and I were digging around but did not seem to find other automation tools like Selenium running into this issue. But it seems to be something that happened recently and replicable. Will watch out for new developments at that Google support issue and other automation tools.

@cyrus-and
Copy link
Owner

@kensoh AFAIK this happens since Chrome 79 and any automation tool is affected provided that Chrome is started with one of those options, in fact you can simply start Chrome that way and try to sign in manually, i.e., without any automation tool, you'll see you won't be able to.

@kensoh
Copy link

kensoh commented Dec 30, 2019

Thanks @cyrus-and you are very helpful, I appreciate it!

Though I can't seem to find issues being raised at Selenium, it seems like Selenium is affected, from one of the users Dumont Reporting at https://support.google.com/accounts/thread/22873505

I'm very upset about this. Has Google blocked all automation scripts? I use a lot of these at work and that would be devastating to my work flow if they have blocked these type of useful bots. My team and I rely on Selenium automation for a lot of our work. Please help!

Another user from above thread Shannon Davis 625 also confirmed issue in Chrome v79 -

I figured out how to fix my "This browser or app may not be secure" can't log in issue!!!!
I deleted Chrome app and installed Chrome 78.
I was not able to log into my Google accounts at from any browser including Chrome! Once I deleted Chrome 79 app and went back to the 78 I can log into all my accounts!!!

I'll be curious to know how Puppeteer handles it, or if Puppeteer is also blocked from automated logging in to Google accounts. No other leads for now, pending more developments in other tools or user inputs. Copying @siowyisheng fyi.

@cyrus-and
Copy link
Owner

@kensoh I didn't try Puppeteer but I can't see how that can be different, it's not that Google is blocking specific automation scripts, it merely blocks any login from Chrome instances started with --remote-debugging-pipe or --remote-debugging-port, which AFAIK are the only way to enable the debugging features apart from writing an extension, that I'm pretty sure will lead to the same outcome.

Besides, why does automating the login to Google services is so important for you? Usually people automate testing for their own application, if you need to automate something on the Google side the proper way is to use the API of the service you're trying to automate.

@kensoh
Copy link

kensoh commented Dec 31, 2019

I see, that will be really funny that Google ends up blocking Puppeteer from automated login to Google accounts such as Gmail. Got it thanks @cyrus-and !

Oh for the tool that I'm maintaining, the intended purpose is automation from the UI layer instead of through APIs. The other more commonly known term is RPA (robotic process automation). Though access through API can be done, I'll still hope to find a solution where it can be done via the user interface, which is the primary use case for users of these tools.

At the moment the tools already a workaround using computer vision and OCR to literally control a real Chrome browser with real user accounts on Gmail etc. But I'll prefer if that can be done also through web element identifiers so that users can write a more robust automation workflows.

https://github.com/kelaberetiv/TagUI
https://github.com/tebelorg/TagUI-Python

@icodeforlove
Copy link

@cyrus-and any idea how they are detecting those flags? Are they accessing something through the javascript environment on the client-side to determine this?

Is there an easy way to know the local changes when enabling those debugging flags.

@cyrus-and
Copy link
Owner

@icodeforlove I spent some time trying to figure this out and I found the navigator.webdriver variable which is true when the browser is instrumented and undefined otherwise. It might be this...

The Google sing-in is just a web application so the check must be performed somewhere in the JavaScript code, but reversing that sign-in process would require me too much time (and I don't really have motivation to do that apart from mere curiosity) so I gave up.

@Kle0s
Copy link

Kle0s commented May 5, 2024

@cyrus-and
IMO the use case for that is to install extensions in runtime. This requires using the command line flag --enable-unsafe-extension-debugging which only works if the protocol client is connected over --remote-debugging-pipe.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants