Skip to content

Commit

Permalink
feat(connect): exposeNetwork option (#24436)
Browse files Browse the repository at this point in the history
  • Loading branch information
dgozman authored Jul 27, 2023
1 parent ececb6d commit ea6d127
Show file tree
Hide file tree
Showing 9 changed files with 78 additions and 12 deletions.
16 changes: 16 additions & 0 deletions docs/src/api/class-browsertype.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,22 @@ Logger sink for Playwright logging. Optional.
Maximum time in milliseconds to wait for the connection to be established. Defaults to
`0` (no timeout).

### option: BrowserType.connect.exposeNetwork
* since: v1.37
- `exposeNetwork` <[string]>

This option exposes network available on the connecting client to the browser being connected to. Consists of a list of rules separated by comma.

Available rules:
1. Hostname pattern, for example: `example.com`, `*.org:99`, `x.*.y.com`, `*foo.org`.
1. IP literal, for example: `127.0.0.1`, `0.0.0.0:99`, `[::1]`, `[0:0::1]:99`.
1. `<loopback>` that matches local loopback interfaces: `localhost`, `*.localhost`, `127.0.0.1`, `[::1]`.

Some common examples:
1. `"*"` to expose all network.
1. `"<loopback>"` to expose localhost network.
1. `"*.test.internal-domain,*.staging.internal-domain,<loopback>"` to expose test/staging deployments and localhost.

## async method: BrowserType.connectOverCDP
* since: v1.9
- returns: <[Browser]>
Expand Down
4 changes: 2 additions & 2 deletions packages/playwright-core/src/client/browserType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ export class BrowserType extends ChannelOwner<channels.BrowserTypeChannel> imple
'x-playwright-launch-options': jsonStringifyForceASCII({ ...this._defaultLaunchOptions, ...launchOptions }),
...connectOptions.headers,
},
_exposeNetwork: connectOptions._exposeNetwork,
exposeNetwork: connectOptions.exposeNetwork ?? connectOptions._exposeNetwork,
slowMo: connectOptions.slowMo,
timeout: connectOptions.timeout ?? 3 * 60 * 1000, // 3 minutes
});
Expand Down Expand Up @@ -149,7 +149,7 @@ export class BrowserType extends ChannelOwner<channels.BrowserTypeChannel> imple
const connectParams: channels.LocalUtilsConnectParams = {
wsEndpoint: params.wsEndpoint,
headers,
exposeNetwork: params._exposeNetwork,
exposeNetwork: params.exposeNetwork ?? params._exposeNetwork,
slowMo: params.slowMo,
timeout: params.timeout,
};
Expand Down
1 change: 1 addition & 0 deletions packages/playwright-core/src/client/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ export type LaunchPersistentContextOptions = Omit<LaunchOptionsBase & BrowserCon
export type ConnectOptions = {
wsEndpoint: string,
headers?: { [key: string]: string; };
exposeNetwork?: string,
_exposeNetwork?: string,
slowMo?: number,
timeout?: number,
Expand Down
17 changes: 17 additions & 0 deletions packages/playwright-core/types/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19640,6 +19640,23 @@ export interface ConnectOverCDPOptions {
}

export interface ConnectOptions {
/**
* This option exposes network available on the connecting client to the browser being connected to. Consists of a
* list of rules separated by comma.
*
* Available rules:
* 1. Hostname pattern, for example: `example.com`, `*.org:99`, `x.*.y.com`, `*foo.org`.
* 1. IP literal, for example: `127.0.0.1`, `0.0.0.0:99`, `[::1]`, `[0:0::1]:99`.
* 1. `<loopback>` that matches local loopback interfaces: `localhost`, `*.localhost`, `127.0.0.1`, `[::1]`.
*
* Some common examples:
* 1. `"*"` to expose all network.
* 1. `"<loopback>"` to expose localhost network.
* 1. `"*.test.internal-domain,*.staging.internal-domain,<loopback>"` to expose test/staging deployments and
* localhost.
*/
exposeNetwork?: string;

/**
* Additional HTTP headers to be sent with web socket connect request. Optional.
*/
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-test/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,7 @@ function connectOptionsFromEnv() {
return {
wsEndpoint,
headers,
_exposeNetwork: process.env.PW_TEST_CONNECT_EXPOSE_NETWORK,
exposeNetwork: process.env.PW_TEST_CONNECT_EXPOSE_NETWORK,
};
}

Expand Down
16 changes: 16 additions & 0 deletions packages/playwright-test/types/test.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3392,6 +3392,22 @@ type ConnectOptions = {
*/
headers?: { [key: string]: string; };

/**
* This option exposes network available on the connecting client to the browser being connected to.
* Consists of a list of rules separated by comma.
*
* Available rules:
* - Hostname pattern, for example: `example.com`, `*.org:99`, `x.*.y.com`, `*foo.org`.
* - IP literal, for example: `127.0.0.1`, `0.0.0.0:99`, `[::1]`, `[0:0::1]:99`.
* - `<loopback>` that matches local loopback interfaces: `localhost`, `*.localhost`, `127.0.0.1`, `[::1]`.
* Some common examples:
* - `"*"` to expose all network.
* - `"<loopback>"` to expose localhost network.
* - `"*.test.internal-domain,*.staging.internal-domain,<loopback>"` to expose test/staging deployments and localhost.
*/
exposeNetwork?: string;

/**
* Timeout in milliseconds for the connection to be established. Optional, defaults to no timeout.
*/
Expand Down
16 changes: 8 additions & 8 deletions tests/library/browsertype-connect.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -736,7 +736,7 @@ for (const kind of ['launchServer', 'run-server'] as const) {
res.end('<html><body>original-target</body></html>');
});
const remoteServer = await startRemoteServer(kind);
const browser = await connect(remoteServer.wsEndpoint(), { _exposeNetwork: '*' } as any);
const browser = await connect(remoteServer.wsEndpoint(), { exposeNetwork: '*' });
const page = await browser.newPage();
await page.goto(server.PREFIX + '/foo.html');
expect(await page.content()).toContain('original-target');
Expand Down Expand Up @@ -770,7 +770,7 @@ for (const kind of ['launchServer', 'run-server'] as const) {
});
const examplePort = 20_000 + testInfo.workerIndex * 3;
const remoteServer = await startRemoteServer(kind);
const browser = await connect(remoteServer.wsEndpoint(), { _exposeNetwork: '*' } as any, ipV6ServerPort);
const browser = await connect(remoteServer.wsEndpoint(), { exposeNetwork: '*' }, ipV6ServerPort);
const page = await browser.newPage();
await page.goto(`http://[::1]:${examplePort}/foo.html`);
expect(await page.content()).toContain('from-ipv6-server');
Expand All @@ -790,7 +790,7 @@ for (const kind of ['launchServer', 'run-server'] as const) {
});
const examplePort = 20_000 + workerInfo.workerIndex * 3;
const remoteServer = await startRemoteServer(kind);
const browser = await connect(remoteServer.wsEndpoint(), { _exposeNetwork: '*' } as any, dummyServerPort);
const browser = await connect(remoteServer.wsEndpoint(), { exposeNetwork: '*' }, dummyServerPort);
const page = await browser.newPage();
const response = await page.request.get(`http://127.0.0.1:${examplePort}/foo.html`);
expect(response.status()).toBe(200);
Expand All @@ -806,7 +806,7 @@ for (const kind of ['launchServer', 'run-server'] as const) {
});
const examplePort = 20_000 + workerInfo.workerIndex * 3;
const remoteServer = await startRemoteServer(kind);
const browser = await connect(remoteServer.wsEndpoint(), { _exposeNetwork: '*' } as any, dummyServerPort);
const browser = await connect(remoteServer.wsEndpoint(), { exposeNetwork: '*' }, dummyServerPort);
const page = await browser.newPage();
await page.goto(`http://local.playwright:${examplePort}/foo.html`);
expect(await page.content()).toContain('from-dummy-server');
Expand All @@ -816,7 +816,7 @@ for (const kind of ['launchServer', 'run-server'] as const) {
test('should lead to the error page for forwarded requests when the connection is refused', async ({ connect, startRemoteServer, browserName }, workerInfo) => {
const examplePort = 20_000 + workerInfo.workerIndex * 3;
const remoteServer = await startRemoteServer(kind);
const browser = await connect(remoteServer.wsEndpoint(), { _exposeNetwork: '*' } as any);
const browser = await connect(remoteServer.wsEndpoint(), { exposeNetwork: '*' });
const page = await browser.newPage();
const error = await page.goto(`http://127.0.0.1:${examplePort}`).catch(e => e);
if (browserName === 'chromium')
Expand All @@ -837,7 +837,7 @@ for (const kind of ['launchServer', 'run-server'] as const) {
});
const examplePort = 20_000 + workerInfo.workerIndex * 3;
const remoteServer = await startRemoteServer(kind);
const browser = await connect(remoteServer.wsEndpoint(), { _exposeNetwork: 'localhost' } as any, dummyServerPort);
const browser = await connect(remoteServer.wsEndpoint(), { exposeNetwork: 'localhost' }, dummyServerPort);
const page = await browser.newPage();

// localhost should be proxied.
Expand Down Expand Up @@ -866,11 +866,11 @@ for (const kind of ['launchServer', 'run-server'] as const) {
});
const remoteServer = await startRemoteServer(kind);
const browser = await connect(remoteServer.wsEndpoint(), {
_exposeNetwork: '127.0.0.1',
exposeNetwork: '127.0.0.1',
headers: {
'x-playwright-proxy': '*',
},
} as any, dummyServerPort);
}, dummyServerPort);
const page = await browser.newPage();

// local.playwright should fail on the client side.
Expand Down
2 changes: 1 addition & 1 deletion tests/library/playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ if (mode === 'service2') {
connectOptions = {
wsEndpoint: `${process.env.PLAYWRIGHT_SERVICE_URL}?accessKey=${process.env.PLAYWRIGHT_SERVICE_ACCESS_KEY}&cap=${JSON.stringify({ os, runId })}`,
timeout: 3 * 60 * 1000,
_exposeNetwork: '<loopback>',
exposeNetwork: '<loopback>',
};
}

Expand Down
16 changes: 16 additions & 0 deletions utils/generate_types/overrides-test.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,22 @@ type ConnectOptions = {
*/
headers?: { [key: string]: string; };

/**
* This option exposes network available on the connecting client to the browser being connected to.
* Consists of a list of rules separated by comma.
*
* Available rules:
* - Hostname pattern, for example: `example.com`, `*.org:99`, `x.*.y.com`, `*foo.org`.
* - IP literal, for example: `127.0.0.1`, `0.0.0.0:99`, `[::1]`, `[0:0::1]:99`.
* - `<loopback>` that matches local loopback interfaces: `localhost`, `*.localhost`, `127.0.0.1`, `[::1]`.
* Some common examples:
* - `"*"` to expose all network.
* - `"<loopback>"` to expose localhost network.
* - `"*.test.internal-domain,*.staging.internal-domain,<loopback>"` to expose test/staging deployments and localhost.
*/
exposeNetwork?: string;

/**
* Timeout in milliseconds for the connection to be established. Optional, defaults to no timeout.
*/
Expand Down

0 comments on commit ea6d127

Please sign in to comment.