Skip to content

Commit 2ce91c7

Browse files
authored
feat(api): expose browser.isRemote() (#39613)
1 parent 52e5df7 commit 2ce91c7

11 files changed

Lines changed: 49 additions & 9 deletions

File tree

docs/src/api/class-browser.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,12 @@ System.Console.WriteLine(browser.Contexts.Count); // prints "1"
158158

159159
Indicates that the browser is connected.
160160

161+
## method: Browser.isRemote
162+
* since: v1.59
163+
- returns: <[boolean]>
164+
165+
Indicates that the browser is remote, i.e. connected over a WebSocket.
166+
161167
## async method: Browser.newBrowserCDPSession
162168
* since: v1.11
163169
- returns: <[CDPSession]>

packages/playwright-client/types/types.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10109,6 +10109,11 @@ export interface Browser {
1010910109
*/
1011010110
isConnected(): boolean;
1011110111

10112+
/**
10113+
* Indicates that the browser is remote, i.e. connected over a WebSocket.
10114+
*/
10115+
isRemote(): boolean;
10116+
1011210117
/**
1011310118
* **NOTE** CDP Sessions are only supported on Chromium-based browsers.
1011410119
*

packages/playwright-core/src/cli/daemon/program.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,10 @@ export function decorateCLICommand(command: Command, version: string) {
5353
const socketPath = await startCliDaemonServer(sessionName, browserContext, mcpConfig, clientInfo, { persistent, exitOnClose: true });
5454
console.log(`### Success\nDaemon listening on ${socketPath}`);
5555
console.log('<EOF>');
56-
try {
56+
57+
if (!browser.isRemote()) {
5758
await (browser as any)._startServer(sessionName, { workspaceDir: clientInfo.workspaceDir });
5859
browserContext.on('close', () => (browser as any)._stopServer().catch(() => {}));
59-
} catch (error) {
60-
if (!error.message.includes('Server is already running'))
61-
throw error;
6260
}
6361
} catch (error) {
6462
const message = process.env.PWDEBUGIMPL ? (error as Error).stack || (error as Error).message : (error as Error).message;

packages/playwright-core/src/client/browser.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import { mkdirIfNeeded } from './fileUtils';
2424

2525
import type { BrowserType } from './browserType';
2626
import type { Page } from './page';
27-
import type { BrowserContextOptions, LaunchOptions, Logger } from './types';
27+
import type { BrowserContextOptions, LaunchOptions, Logger, StartServerOptions } from './types';
2828
import type * as api from '../../types/types';
2929
import type * as channels from '@protocol/channels';
3030

@@ -54,6 +54,10 @@ export class Browser extends ChannelOwner<channels.BrowserChannel> implements ap
5454
this._closedPromise = new Promise(f => this.once(Events.Browser.Disconnected, f));
5555
}
5656

57+
isRemote() {
58+
return this._connection.isRemote();
59+
}
60+
5761
browserType(): BrowserType {
5862
return this._browserType;
5963
}
@@ -130,7 +134,7 @@ export class Browser extends ChannelOwner<channels.BrowserChannel> implements ap
130134
return this._initializer.version;
131135
}
132136

133-
async _startServer(title: string, options: { wsPath?: string, workspaceDir?: string } = {}): Promise<{ wsEndpoint?: string, pipeName?: string }> {
137+
async _startServer(title: string, options: StartServerOptions = {}): Promise<{ wsEndpoint?: string, pipeName?: string }> {
134138
return await this._channel.startServer({ title, ...options });
135139
}
136140

packages/playwright-core/src/client/types.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,14 @@ export type LaunchAndroidServerOptions = {
120120
wsPath?: string,
121121
};
122122

123+
export type StartServerOptions = {
124+
host?: string,
125+
port?: number,
126+
wsPath?: string,
127+
workspaceDir?: string,
128+
metadata?: Record<string, any>,
129+
};
130+
123131
export type SelectorEngine = {
124132
/**
125133
* Returns the first element matching given selector in the root's subtree.

packages/playwright-core/src/protocol/validator.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,8 +651,11 @@ scheme.BrowserContextEvent = tObject({
651651
scheme.BrowserCloseEvent = tOptional(tObject({}));
652652
scheme.BrowserStartServerParams = tObject({
653653
title: tString,
654+
host: tOptional(tString),
655+
port: tOptional(tInt),
654656
wsPath: tOptional(tString),
655657
workspaceDir: tOptional(tString),
658+
metadata: tOptional(tAny),
656659
});
657660
scheme.BrowserStartServerResult = tObject({
658661
wsEndpoint: tOptional(tString),

packages/playwright-core/src/server/browser.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ export abstract class Browser extends SdkObject {
174174
return video?.artifact;
175175
}
176176

177-
async startServer(title: string, options: { workspaceDir?: string, wsPath?: string, pipeName?: string }): Promise<{ wsEndpoint?: string, pipeName?: string }> {
177+
async startServer(title: string, options: channels.BrowserStartServerOptions): Promise<{ wsEndpoint?: string, pipeName?: string }> {
178178
return await this._server.start(title, options);
179179
}
180180

@@ -219,7 +219,7 @@ export class BrowserServer {
219219
this._browser = browser;
220220
}
221221

222-
async start(title: string, options: { workspaceDir?: string, wsPath?: string }): Promise<{ wsEndpoint?: string, pipeName?: string }> {
222+
async start(title: string, options: channels.BrowserStartServerOptions): Promise<{ wsEndpoint?: string, pipeName?: string }> {
223223
if (this._isStarted)
224224
throw new Error(`Server is already started.`);
225225
this._isStarted = true;
@@ -233,7 +233,7 @@ export class BrowserServer {
233233
if (options.wsPath) {
234234
const path = options.wsPath.startsWith('/') ? options.wsPath : `/${options.wsPath}`;
235235
this._wsServer = new PlaywrightWebSocketServer(this._browser, path);
236-
result.wsEndpoint = await this._wsServer.listen(0, 'localhost', path);
236+
result.wsEndpoint = await this._wsServer.listen(options.port ?? 0, options.host ?? 'localhost', path);
237237
}
238238

239239
const browserInfo: BrowserInfo = {
@@ -247,6 +247,7 @@ export class BrowserServer {
247247
wsEndpoint: result.wsEndpoint,
248248
pipeName: result.pipeName,
249249
workspaceDir: options.workspaceDir,
250+
metadata: options.metadata,
250251
});
251252
return result;
252253
}

packages/playwright-core/src/serverRegistry.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ export type EndpointInfo = {
3636
wsEndpoint?: string;
3737
pipeName?: string;
3838
workspaceDir?: string;
39+
metadata?: Record<string, any>;
3940
};
4041

4142
export type BrowserDescriptor = EndpointInfo & {

packages/playwright-core/types/types.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10109,6 +10109,11 @@ export interface Browser {
1010910109
*/
1011010110
isConnected(): boolean;
1011110111

10112+
/**
10113+
* Indicates that the browser is remote, i.e. connected over a WebSocket.
10114+
*/
10115+
isRemote(): boolean;
10116+
1011210117
/**
1011310118
* **NOTE** CDP Sessions are only supported on Chromium-based browsers.
1011410119
*

packages/protocol/src/channels.d.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1180,12 +1180,18 @@ export type BrowserContextEvent = {
11801180
export type BrowserCloseEvent = {};
11811181
export type BrowserStartServerParams = {
11821182
title: string,
1183+
host?: string,
1184+
port?: number,
11831185
wsPath?: string,
11841186
workspaceDir?: string,
1187+
metadata?: any,
11851188
};
11861189
export type BrowserStartServerOptions = {
1190+
host?: string,
1191+
port?: number,
11871192
wsPath?: string,
11881193
workspaceDir?: string,
1194+
metadata?: any,
11891195
};
11901196
export type BrowserStartServerResult = {
11911197
wsEndpoint?: string,

0 commit comments

Comments
 (0)