mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
feat(test runner): support connectOptions (#11919)
This allows to specify `connectOptions` in the config that switch built-in `browser` to be remotely connected.
This commit is contained in:
parent
5881a46ecf
commit
19368e93af
@ -110,6 +110,13 @@ Learn more about [various timeouts](./test-timeouts.md).
|
||||
|
||||
## property: TestOptions.colorScheme = %%-context-option-colorscheme-%%
|
||||
|
||||
## property: TestOptions.connectOptions
|
||||
- type: <[void]|[Object]>
|
||||
- `wsEndpoint` <[string]> A browser websocket endpoint to connect to.
|
||||
- `headers` <[void]|[Object]<[string], [string]>> Additional HTTP headers to be sent with web socket connect request. Optional.
|
||||
|
||||
When connect options are specified, default [`property: Fixtures.browser`], [`property: Fixtures.context`] and [`property: Fixtures.page`] use the remote browser instead of launching a browser locally, and any launch options like [`property: TestOptions.headless`] or [`property: TestOptions.channel`] are ignored.
|
||||
|
||||
## property: TestOptions.contextOptions
|
||||
- type: <[Object]>
|
||||
|
||||
|
||||
@ -63,6 +63,7 @@ export class BrowserTypeDispatcher extends Dispatcher<BrowserType, channels.Brow
|
||||
maxPayload: 256 * 1024 * 1024, // 256Mb,
|
||||
handshakeTimeout: params.timeout,
|
||||
headers: paramsHeaders,
|
||||
followRedirects: true,
|
||||
});
|
||||
const pipe = new JsonPipeDispatcher(this._scope);
|
||||
const openPromise = new ManualPromise<{ pipe: JsonPipeDispatcher }>();
|
||||
|
||||
@ -70,6 +70,7 @@ export const test = _baseTest.extend<TestFixtures, WorkerFixtures>({
|
||||
headless: [ undefined, { scope: 'worker', option: true } ],
|
||||
channel: [ undefined, { scope: 'worker', option: true } ],
|
||||
launchOptions: [ {}, { scope: 'worker', option: true } ],
|
||||
connectOptions: [ undefined, { scope: 'worker', option: true } ],
|
||||
screenshot: [ 'off', { scope: 'worker', option: true } ],
|
||||
video: [ 'off', { scope: 'worker', option: true } ],
|
||||
trace: [ 'off', { scope: 'worker', option: true } ],
|
||||
@ -100,9 +101,16 @@ export const test = _baseTest.extend<TestFixtures, WorkerFixtures>({
|
||||
await use(options);
|
||||
}, { scope: 'worker' }],
|
||||
|
||||
browser: [async ({ playwright, browserName }, use) => {
|
||||
browser: [async ({ playwright, browserName, connectOptions }, use) => {
|
||||
if (!['chromium', 'firefox', 'webkit'].includes(browserName))
|
||||
throw new Error(`Unexpected browserName "${browserName}", must be one of "chromium", "firefox" or "webkit"`);
|
||||
if (connectOptions) {
|
||||
const browser = await playwright[browserName].connect(connectOptions);
|
||||
await use(browser);
|
||||
await browser.close();
|
||||
return;
|
||||
}
|
||||
|
||||
const browser = await playwright[browserName].launch();
|
||||
await use(browser);
|
||||
await browser.close();
|
||||
|
||||
21
packages/playwright-test/types/test.d.ts
vendored
21
packages/playwright-test/types/test.d.ts
vendored
@ -2658,6 +2658,17 @@ type ColorScheme = Exclude<BrowserContextOptions['colorScheme'], undefined>;
|
||||
type ExtraHTTPHeaders = Exclude<BrowserContextOptions['extraHTTPHeaders'], undefined>;
|
||||
type Proxy = Exclude<BrowserContextOptions['proxy'], undefined>;
|
||||
type StorageState = Exclude<BrowserContextOptions['storageState'], undefined>;
|
||||
type ConnectOptions = {
|
||||
/**
|
||||
* A browser websocket endpoint to connect to.
|
||||
*/
|
||||
wsEndpoint: string;
|
||||
|
||||
/**
|
||||
* Additional HTTP headers to be sent with web socket connect request.
|
||||
*/
|
||||
headers?: { [key: string]: string; };
|
||||
};
|
||||
|
||||
/**
|
||||
* Playwright Test provides many options to configure test environment, [Browser], [BrowserContext] and more.
|
||||
@ -2735,6 +2746,16 @@ export interface PlaywrightWorkerOptions {
|
||||
* [testOptions.channel](https://playwright.dev/docs/api/class-testoptions#test-options-channel) take priority over this.
|
||||
*/
|
||||
launchOptions: LaunchOptions;
|
||||
/**
|
||||
* When connect options are specified, default
|
||||
* [fixtures.browser](https://playwright.dev/docs/api/class-fixtures#fixtures-browser),
|
||||
* [fixtures.context](https://playwright.dev/docs/api/class-fixtures#fixtures-context) and
|
||||
* [fixtures.page](https://playwright.dev/docs/api/class-fixtures#fixtures-page) use the remote browser instead of
|
||||
* launching a browser locally, and any launch options like
|
||||
* [testOptions.headless](https://playwright.dev/docs/api/class-testoptions#test-options-headless) or
|
||||
* [testOptions.channel](https://playwright.dev/docs/api/class-testoptions#test-options-channel) are ignored.
|
||||
*/
|
||||
connectOptions: ConnectOptions | undefined;
|
||||
/**
|
||||
* Whether to automatically capture a screenshot after each test. Defaults to `'off'`.
|
||||
* - `'off'`: Do not capture screenshots.
|
||||
|
||||
@ -546,3 +546,58 @@ test('should work with video.path() throwing', async ({ runInlineTest }, testInf
|
||||
const video = fs.readdirSync(dir).find(file => file.endsWith('webm'));
|
||||
expect(video).toBeTruthy();
|
||||
});
|
||||
|
||||
test('should work with connectOptions', async ({ runInlineTest }) => {
|
||||
const result = await runInlineTest({
|
||||
'playwright.config.js': `
|
||||
module.exports = {
|
||||
globalSetup: './global-setup',
|
||||
use: {
|
||||
connectOptions: {
|
||||
wsEndpoint: process.env.CONNECT_WS_ENDPOINT,
|
||||
},
|
||||
},
|
||||
};
|
||||
`,
|
||||
'global-setup.ts': `
|
||||
module.exports = async () => {
|
||||
const server = await pwt.chromium.launchServer();
|
||||
process.env.CONNECT_WS_ENDPOINT = server.wsEndpoint();
|
||||
return () => server.close();
|
||||
};
|
||||
`,
|
||||
'a.test.ts': `
|
||||
const { test } = pwt;
|
||||
test('pass', async ({ page }) => {
|
||||
await page.setContent('<div>PASS</div>');
|
||||
await expect(page.locator('div')).toHaveText('PASS');
|
||||
});
|
||||
`,
|
||||
});
|
||||
expect(result.exitCode).toBe(0);
|
||||
expect(result.passed).toBe(1);
|
||||
});
|
||||
|
||||
test('should throw with bad connectOptions', async ({ runInlineTest }) => {
|
||||
const result = await runInlineTest({
|
||||
'playwright.config.js': `
|
||||
module.exports = {
|
||||
use: {
|
||||
connectOptions: {
|
||||
wsEndpoint: 'http://does-not-exist-bad-domain.oh-no-should-not-work',
|
||||
},
|
||||
},
|
||||
};
|
||||
`,
|
||||
'a.test.ts': `
|
||||
const { test } = pwt;
|
||||
test('pass', async ({ page }) => {
|
||||
await page.setContent('<div>PASS</div>');
|
||||
await expect(page.locator('div')).toHaveText('PASS');
|
||||
});
|
||||
`,
|
||||
});
|
||||
expect(result.exitCode).toBe(1);
|
||||
expect(result.passed).toBe(0);
|
||||
expect(result.output).toContain('browserType.connect:');
|
||||
});
|
||||
|
||||
12
utils/generate_types/overrides-test.d.ts
vendored
12
utils/generate_types/overrides-test.d.ts
vendored
@ -297,6 +297,17 @@ type ColorScheme = Exclude<BrowserContextOptions['colorScheme'], undefined>;
|
||||
type ExtraHTTPHeaders = Exclude<BrowserContextOptions['extraHTTPHeaders'], undefined>;
|
||||
type Proxy = Exclude<BrowserContextOptions['proxy'], undefined>;
|
||||
type StorageState = Exclude<BrowserContextOptions['storageState'], undefined>;
|
||||
type ConnectOptions = {
|
||||
/**
|
||||
* A browser websocket endpoint to connect to.
|
||||
*/
|
||||
wsEndpoint: string;
|
||||
|
||||
/**
|
||||
* Additional HTTP headers to be sent with web socket connect request.
|
||||
*/
|
||||
headers?: { [key: string]: string; };
|
||||
};
|
||||
|
||||
export interface PlaywrightWorkerOptions {
|
||||
browserName: BrowserName;
|
||||
@ -304,6 +315,7 @@ export interface PlaywrightWorkerOptions {
|
||||
headless: boolean | undefined;
|
||||
channel: BrowserChannel | undefined;
|
||||
launchOptions: LaunchOptions;
|
||||
connectOptions: ConnectOptions | undefined;
|
||||
screenshot: 'off' | 'on' | 'only-on-failure';
|
||||
trace: TraceMode | /** deprecated */ 'retry-with-trace' | { mode: TraceMode, snapshots?: boolean, screenshots?: boolean, sources?: boolean };
|
||||
video: VideoMode | /** deprecated */ 'retry-with-video' | { mode: VideoMode, size?: ViewportSize };
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user