-
Notifications
You must be signed in to change notification settings - Fork 3.9k
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
feat: add support for using existing cdp websocket in launchServer #4344
Conversation
Urgh, seems like optional chaining is not supported in CI (or rather node |
@@ -17,7 +17,7 @@ | |||
|
|||
import { it, expect, describe } from './fixtures'; | |||
|
|||
describe('lauch server', (suite, { wire }) => { | |||
describe('launch server', (suite, { wire }) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thought I fix that while I'm there 😄
@@ -62,4 +62,17 @@ describe('lauch server', (suite, { wire }) => { | |||
expect(result['exitCode']).toBe(0); | |||
expect(result['signal']).toBe(null); | |||
}); | |||
|
|||
it('should allow using an existing cdp endpoint', async ({ browserType, server}) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test don't really prove that the cdp websocket works. @dgozman should we add another bot that runs all the tests via cdp?
Or we can just have a smoke test that.
- launches a browser server with
--remote-debugging-port
- launches a second browser server that connects to the first via cdpWebSocketEndpoint
- connect to that second browser server and create a page and eval 1+1=2 in there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, doing that was my first instinct :-) I had the impression the other tests were a bit shallow so I opted to just test the basics. Happy to change this to a more full-fledged test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just wondering about the best way to get the webSocketDebuggerUrl
from /json/version
(there doesn't seem to be an http client around)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can do await page.evaluate(() => fetch(url))
and use the browser 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@JoelEinbinder added an additional smoke test to ensure the cdp websocket works :-)
I think mapping |
src/client/browserType.ts
Outdated
|
||
export interface BrowserServerLauncher { | ||
launchServer(options?: LaunchServerOptions): Promise<BrowserServer>; | ||
} | ||
|
||
export interface BrowserServer { | ||
process(): ChildProcess; | ||
process(): ChildProcess | undefined; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please do not change this signature, it's not backwards-compatible. Instead, throw an error from process()
when running in "connect over cdp" mode.
@@ -93,11 +96,13 @@ export class BrowserServerImpl extends EventEmitter implements BrowserServer { | |||
} | |||
|
|||
async close(): Promise<void> { | |||
await this._browser._options.browserProcess.close(); | |||
if (this._browser._options.browserProcess) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the right way is to connect right here, in the BrowserServerImpl, instead of going all the way to _innerLaunch and back.
Now that I think about this more: when connecting over existing cdp, all other launch parameters are actually ignored. This hints at using a different method, something like chromium.connectServer
that only takes the websocket url. WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, when connecting to an existing cdp websocket virtually all of the launch code isn't needed. Also the flag feels a bit shoehorned into there, so it might be cleaner to keep it separate. If promoting this feature to it's own top-level API is fine then I'm happy to work on the changes 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a dedicated API implementation for comparison
@@ -62,4 +62,17 @@ describe('lauch server', (suite, { wire }) => { | |||
expect(result['exitCode']).toBe(0); | |||
expect(result['signal']).toBe(null); | |||
}); | |||
|
|||
it('should allow using an existing cdp endpoint', async ({ browserType, server}) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can do await page.evaluate(() => fetch(url))
and use the browser 😄
Thanks for all the valuable input and suggestions, will get back at it tomorrow. :-) |
@dgozman I added a dedicated Personally I think it's the better approach than cramping this into the existing Note: I placed the meaty stuff in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I definitely like the separate method more! Please give us some time to discuss the shape of this new API, and I'll get back to you with detailed PR review 😄
This is now obsolete and we have connectOverCDP, so closing! |
This PR:
cdpWebsocketEndpoint
option to.launchServer
.connect
&.launchServer
)CDP
As a side effect of switching to the new wire protocol we lost the ability to connect to existing CDP websockets. This is an issue for services that wish to make existing browsers (not created by Playwright) available to Playwright clients.
User-Agent
Adding a user-agent makes it much easier for services that wish to expose a single websocket to both Playwright and Puppeteer clients. In combination with
cdpWebsocketEndpoint
Playwright clients can then be piped through a wire protocol websocket created bylaunchServer
that in turn will communicate with an existing CDP websocket endpoint.I tried following the available naming pattern & style guide, kindly let me know if there are more preferred options. :-)