feat(connect): exposeNetwork option (#24436)

This commit is contained in:
Dmitry Gozman 2023-07-26 17:29:31 -07:00 committed by GitHub
parent ececb6d19e
commit ea6d127f28
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 78 additions and 12 deletions

View file

@ -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]>

View file

@ -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
});
@ -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,
};

View file

@ -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,

View file

@ -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.
*/

View file

@ -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,
};
}

View file

@ -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.
*/

View file

@ -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');
@ -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');
@ -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);
@ -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');
@ -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')
@ -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.
@ -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.

View file

@ -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>',
};
}

View file

@ -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.
*/