fix: remove connectInsteadOfLaunching (#26828)
This commit is contained in:
parent
b387249e45
commit
6d85ba1494
|
|
@ -23,7 +23,7 @@ import { Connection } from './connection';
|
||||||
import { Events } from './events';
|
import { Events } from './events';
|
||||||
import type { ChildProcess } from 'child_process';
|
import type { ChildProcess } from 'child_process';
|
||||||
import { envObjectToArray } from './clientHelper';
|
import { envObjectToArray } from './clientHelper';
|
||||||
import { jsonStringifyForceASCII, assert, headersObjectToArray, monotonicTime } from '../utils';
|
import { assert, headersObjectToArray, monotonicTime } from '../utils';
|
||||||
import type * as api from '../../types/types';
|
import type * as api from '../../types/types';
|
||||||
import { kBrowserClosedError } from '../common/errors';
|
import { kBrowserClosedError } from '../common/errors';
|
||||||
import { raceAgainstDeadline } from '../utils/timeoutRunner';
|
import { raceAgainstDeadline } from '../utils/timeoutRunner';
|
||||||
|
|
@ -51,7 +51,6 @@ export class BrowserType extends ChannelOwner<channels.BrowserTypeChannel> imple
|
||||||
_defaultContextTimeout?: number;
|
_defaultContextTimeout?: number;
|
||||||
_defaultContextNavigationTimeout?: number;
|
_defaultContextNavigationTimeout?: number;
|
||||||
private _defaultLaunchOptions?: LaunchOptions;
|
private _defaultLaunchOptions?: LaunchOptions;
|
||||||
private _defaultConnectOptions?: ConnectOptions;
|
|
||||||
|
|
||||||
static from(browserType: channels.BrowserTypeChannel): BrowserType {
|
static from(browserType: channels.BrowserTypeChannel): BrowserType {
|
||||||
return (browserType as any)._object;
|
return (browserType as any)._object;
|
||||||
|
|
@ -71,9 +70,6 @@ export class BrowserType extends ChannelOwner<channels.BrowserTypeChannel> imple
|
||||||
assert(!(options as any).userDataDir, 'userDataDir option is not supported in `browserType.launch`. Use `browserType.launchPersistentContext` instead');
|
assert(!(options as any).userDataDir, 'userDataDir option is not supported in `browserType.launch`. Use `browserType.launchPersistentContext` instead');
|
||||||
assert(!(options as any).port, 'Cannot specify a port without launching as a server.');
|
assert(!(options as any).port, 'Cannot specify a port without launching as a server.');
|
||||||
|
|
||||||
if (this._defaultConnectOptions)
|
|
||||||
return await this._connectInsteadOfLaunching(this._defaultConnectOptions, options);
|
|
||||||
|
|
||||||
const logger = options.logger || this._defaultLaunchOptions?.logger;
|
const logger = options.logger || this._defaultLaunchOptions?.logger;
|
||||||
options = { ...this._defaultLaunchOptions, ...options };
|
options = { ...this._defaultLaunchOptions, ...options };
|
||||||
const launchOptions: channels.BrowserTypeLaunchParams = {
|
const launchOptions: channels.BrowserTypeLaunchParams = {
|
||||||
|
|
@ -89,20 +85,6 @@ export class BrowserType extends ChannelOwner<channels.BrowserTypeChannel> imple
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _connectInsteadOfLaunching(connectOptions: ConnectOptions, launchOptions: LaunchOptions): Promise<Browser> {
|
|
||||||
return this._connect({
|
|
||||||
wsEndpoint: connectOptions.wsEndpoint,
|
|
||||||
headers: {
|
|
||||||
// HTTP headers are ASCII only (not UTF-8).
|
|
||||||
'x-playwright-launch-options': jsonStringifyForceASCII({ ...this._defaultLaunchOptions, ...launchOptions }),
|
|
||||||
...connectOptions.headers,
|
|
||||||
},
|
|
||||||
exposeNetwork: connectOptions.exposeNetwork ?? connectOptions._exposeNetwork,
|
|
||||||
slowMo: connectOptions.slowMo,
|
|
||||||
timeout: connectOptions.timeout ?? 3 * 60 * 1000, // 3 minutes
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async launchServer(options: LaunchServerOptions = {}): Promise<api.BrowserServer> {
|
async launchServer(options: LaunchServerOptions = {}): Promise<api.BrowserServer> {
|
||||||
if (!this._serverLauncher)
|
if (!this._serverLauncher)
|
||||||
throw new Error('Launching server is not supported');
|
throw new Error('Launching server is not supported');
|
||||||
|
|
|
||||||
|
|
@ -67,11 +67,7 @@ const playwrightFixtures: Fixtures<TestFixtures, WorkerFixtures> = ({
|
||||||
channel: [({ launchOptions }, use) => use(launchOptions.channel), { scope: 'worker', option: true }],
|
channel: [({ launchOptions }, use) => use(launchOptions.channel), { scope: 'worker', option: true }],
|
||||||
launchOptions: [{}, { scope: 'worker', option: true }],
|
launchOptions: [{}, { scope: 'worker', option: true }],
|
||||||
connectOptions: [async ({}, use) => {
|
connectOptions: [async ({}, use) => {
|
||||||
// Usually, when connect options are specified (e.g, in the config or in the environment),
|
await use(connectOptionsFromEnv());
|
||||||
// all launch() calls are turned into connect() calls.
|
|
||||||
// However, when running in "reuse browser" mode and connecting to the reusable server,
|
|
||||||
// only the default "browser" fixture should turn into reused browser.
|
|
||||||
await use(process.env.PW_TEST_REUSE_CONTEXT ? undefined : connectOptionsFromEnv());
|
|
||||||
}, { scope: 'worker', option: true }],
|
}, { scope: 'worker', option: true }],
|
||||||
screenshot: ['off', { scope: 'worker', option: true }],
|
screenshot: ['off', { scope: 'worker', option: true }],
|
||||||
video: ['off', { scope: 'worker', option: true }],
|
video: ['off', { scope: 'worker', option: true }],
|
||||||
|
|
@ -81,7 +77,7 @@ const playwrightFixtures: Fixtures<TestFixtures, WorkerFixtures> = ({
|
||||||
await use(process.env.TEST_ARTIFACTS_DIR!);
|
await use(process.env.TEST_ARTIFACTS_DIR!);
|
||||||
}, { scope: 'worker', _title: 'playwright configuration' } as any],
|
}, { scope: 'worker', _title: 'playwright configuration' } as any],
|
||||||
|
|
||||||
_browserOptions: [async ({ playwright, headless, channel, launchOptions, connectOptions, _artifactsDir }, use) => {
|
_browserOptions: [async ({ playwright, headless, channel, launchOptions, _artifactsDir }, use) => {
|
||||||
const options: LaunchOptions = {
|
const options: LaunchOptions = {
|
||||||
handleSIGINT: false,
|
handleSIGINT: false,
|
||||||
...launchOptions,
|
...launchOptions,
|
||||||
|
|
@ -92,28 +88,23 @@ const playwrightFixtures: Fixtures<TestFixtures, WorkerFixtures> = ({
|
||||||
options.channel = channel;
|
options.channel = channel;
|
||||||
options.tracesDir = path.join(_artifactsDir, 'traces');
|
options.tracesDir = path.join(_artifactsDir, 'traces');
|
||||||
|
|
||||||
for (const browserType of [playwright.chromium, playwright.firefox, playwright.webkit]) {
|
for (const browserType of [playwright.chromium, playwright.firefox, playwright.webkit])
|
||||||
(browserType as any)._defaultLaunchOptions = options;
|
(browserType as any)._defaultLaunchOptions = options;
|
||||||
(browserType as any)._defaultConnectOptions = connectOptions;
|
|
||||||
}
|
|
||||||
await use(options);
|
await use(options);
|
||||||
for (const browserType of [playwright.chromium, playwright.firefox, playwright.webkit]) {
|
for (const browserType of [playwright.chromium, playwright.firefox, playwright.webkit])
|
||||||
(browserType as any)._defaultLaunchOptions = undefined;
|
(browserType as any)._defaultLaunchOptions = undefined;
|
||||||
(browserType as any)._defaultConnectOptions = undefined;
|
|
||||||
}
|
|
||||||
}, { scope: 'worker', auto: true }],
|
}, { scope: 'worker', auto: true }],
|
||||||
|
|
||||||
browser: [async ({ playwright, browserName, _browserOptions }, use, testInfo) => {
|
browser: [async ({ playwright, browserName, _browserOptions, connectOptions }, use, testInfo) => {
|
||||||
if (!['chromium', 'firefox', 'webkit'].includes(browserName))
|
if (!['chromium', 'firefox', 'webkit'].includes(browserName))
|
||||||
throw new Error(`Unexpected browserName "${browserName}", must be one of "chromium", "firefox" or "webkit"`);
|
throw new Error(`Unexpected browserName "${browserName}", must be one of "chromium", "firefox" or "webkit"`);
|
||||||
|
|
||||||
// Support for "reuse browser" mode.
|
if (connectOptions) {
|
||||||
const connectOptions = connectOptionsFromEnv();
|
|
||||||
if (connectOptions && process.env.PW_TEST_REUSE_CONTEXT) {
|
|
||||||
const browser = await playwright[browserName].connect({
|
const browser = await playwright[browserName].connect({
|
||||||
...connectOptions,
|
...connectOptions,
|
||||||
|
exposeNetwork: connectOptions.exposeNetwork ?? (connectOptions as any)._exposeNetwork,
|
||||||
headers: {
|
headers: {
|
||||||
'x-playwright-reuse-context': '1',
|
...(process.env.PW_TEST_REUSE_CONTEXT ? { 'x-playwright-reuse-context': '1' } : {}),
|
||||||
// HTTP headers are ASCII only (not UTF-8).
|
// HTTP headers are ASCII only (not UTF-8).
|
||||||
'x-playwright-launch-options': jsonStringifyForceASCII(_browserOptions),
|
'x-playwright-launch-options': jsonStringifyForceASCII(_browserOptions),
|
||||||
...connectOptions.headers,
|
...connectOptions.headers,
|
||||||
|
|
|
||||||
|
|
@ -698,22 +698,6 @@ for (const kind of ['launchServer', 'run-server'] as const) {
|
||||||
await Promise.all([uploadFile, file1.filepath].map(fs.promises.unlink));
|
await Promise.all([uploadFile, file1.filepath].map(fs.promises.unlink));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should connect when launching', async ({ browserType, startRemoteServer }) => {
|
|
||||||
const remoteServer = await startRemoteServer(kind);
|
|
||||||
(browserType as any)._defaultConnectOptions = {
|
|
||||||
wsEndpoint: remoteServer.wsEndpoint()
|
|
||||||
};
|
|
||||||
|
|
||||||
const browser = await browserType.launch();
|
|
||||||
|
|
||||||
await Promise.all([
|
|
||||||
new Promise(f => browser.on('disconnected', f)),
|
|
||||||
remoteServer.close(),
|
|
||||||
]);
|
|
||||||
|
|
||||||
(browserType as any)._defaultConnectOptions = undefined;
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should connect over http', async ({ connect, startRemoteServer, mode }) => {
|
test('should connect over http', async ({ connect, startRemoteServer, mode }) => {
|
||||||
test.skip(mode !== 'default');
|
test.skip(mode !== 'default');
|
||||||
const remoteServer = await startRemoteServer(kind);
|
const remoteServer = await startRemoteServer(kind);
|
||||||
|
|
|
||||||
|
|
@ -46,13 +46,12 @@ const test = baseTest.extend<Fixtures>({
|
||||||
connectedBrowserFactory: async ({ wsEndpoint, browserType }, use) => {
|
connectedBrowserFactory: async ({ wsEndpoint, browserType }, use) => {
|
||||||
const browsers: BrowserWithReuse [] = [];
|
const browsers: BrowserWithReuse [] = [];
|
||||||
await use(async () => {
|
await use(async () => {
|
||||||
const oldValue = (browserType as any)._defaultConnectOptions;
|
const browser = await browserType.connect(wsEndpoint, {
|
||||||
(browserType as any)._defaultConnectOptions = {
|
headers: {
|
||||||
wsEndpoint,
|
'x-playwright-launch-options': JSON.stringify((browserType as any)._defaultLaunchOptions),
|
||||||
headers: { 'x-playwright-reuse-context': '1', },
|
'x-playwright-reuse-context': '1',
|
||||||
};
|
},
|
||||||
const browser = await browserType.launch() as BrowserWithReuse;
|
}) as BrowserWithReuse;
|
||||||
(browserType as any)._defaultConnectOptions = oldValue;
|
|
||||||
browsers.push(browser);
|
browsers.push(browser);
|
||||||
return browser;
|
return browser;
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,7 @@ test('should throw with bad connectOptions', async ({ runInlineTest }) => {
|
||||||
});
|
});
|
||||||
expect(result.exitCode).toBe(1);
|
expect(result.exitCode).toBe(1);
|
||||||
expect(result.passed).toBe(0);
|
expect(result.passed).toBe(0);
|
||||||
expect(result.output).toContain('browserType.launch:');
|
expect(result.output).toContain('browserType.connect:');
|
||||||
expect(result.output).toContain('does-not-exist-bad-domain');
|
expect(result.output).toContain('does-not-exist-bad-domain');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -124,7 +124,7 @@ test('should respect connectOptions.timeout', async ({ runInlineTest }) => {
|
||||||
});
|
});
|
||||||
expect(result.exitCode).toBe(1);
|
expect(result.exitCode).toBe(1);
|
||||||
expect(result.passed).toBe(0);
|
expect(result.passed).toBe(0);
|
||||||
expect(result.output).toContain('browserType.launch: Timeout 1ms exceeded.');
|
expect(result.output).toContain('browserType.connect: Timeout 1ms exceeded.');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should print debug log when failed to connect', async ({ runInlineTest }) => {
|
test('should print debug log when failed to connect', async ({ runInlineTest }) => {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue