Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions packages/playwright-core/src/protocol/validator.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -511,7 +511,6 @@ scheme.BrowserTypeLaunchParams = tObject({
args: tOptional(tArray(tString)),
ignoreAllDefaultArgs: tOptional(tBoolean),
ignoreDefaultArgs: tOptional(tArray(tString)),
assistantMode: tOptional(tBoolean),
handleSIGINT: tOptional(tBoolean),
handleSIGTERM: tOptional(tBoolean),
handleSIGHUP: tOptional(tBoolean),
Expand DownExpand Up@@ -541,7 +540,6 @@ scheme.BrowserTypeLaunchPersistentContextParams = tObject({
args: tOptional(tArray(tString)),
ignoreAllDefaultArgs: tOptional(tBoolean),
ignoreDefaultArgs: tOptional(tArray(tString)),
assistantMode: tOptional(tBoolean),
handleSIGINT: tOptional(tBoolean),
handleSIGTERM: tOptional(tBoolean),
handleSIGHUP: tOptional(tBoolean),
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/server/android/android.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -299,7 +299,7 @@ export class AndroidDevice extends SdkObject {
'--disable-fre',
'--no-default-browser-check',
`--remote-debugging-socket-name=${socketName}`,
...chromiumSwitches(undefined, undefined, true),
...chromiumSwitches({ android: true }),
...this._innerDefaultArgs(options)
];
return chromeArguments;
Expand Down
4 changes: 2 additions & 2 deletions packages/playwright-core/src/server/bidi/bidiChromium.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -102,7 +102,7 @@ export class BidiChromium extends BrowserType {
}

override async waitForReadyState(options: types.LaunchOptions, browserLogsCollector: RecentLogsCollector): Promise<{ wsEndpoint?: string }> {
return waitForReadyState({ ...options, cdpPort: 0 }, browserLogsCollector);
return waitForReadyState({ ...options, args: ['--remote-debugging-port=0'] }, browserLogsCollector);
}

private _innerDefaultArgs(options: types.LaunchOptions): string[] {
Expand All@@ -114,7 +114,7 @@ export class BidiChromium extends BrowserType {
throw new Error('Playwright manages remote debugging connection itself.');
if (args.find(arg => !arg.startsWith('-')))
throw new Error('Arguments can not specify page to be opened');
const chromeArguments = [...chromiumSwitches(options.assistantMode)];
const chromeArguments = [...chromiumSwitches()];

if (os.platform() === 'darwin') {
// See https://issues.chromium.org/issues/40277080
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/server/browser.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -59,7 +59,7 @@ export type BrowserOptions = {
protocolLogger: types.ProtocolLogger,
browserLogsCollector: RecentLogsCollector,
slowMo?: number;
wsEndpoint?: string; // Only there when connected over web socket.
wsEndpoint?: string;
sdkLanguage?: Language;
originalLaunchOptions: types.LaunchOptions;
userDataDir?: string;
Expand Down
12 changes: 6 additions & 6 deletions packages/playwright-core/src/server/browserType.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -72,7 +72,7 @@ export abstract class BrowserType extends SdkObject {
return this._innerLaunchWithRetries(progress, options, undefined, helper.debugProtocolLogger(protocolLogger)).catch(e => { throw this._rewriteStartupLog(e); });
}

async launchPersistentContext(progress: Progress, userDataDir: string, options: channels.BrowserTypeLaunchPersistentContextOptions & { cdpPort?: number, internalIgnoreHTTPSErrors?: boolean, socksProxyPort?: number }): Promise<BrowserContext> {
async launchPersistentContext(progress: Progress, userDataDir: string, options: channels.BrowserTypeLaunchPersistentContextOptions & { internalIgnoreHTTPSErrors?: boolean, socksProxyPort?: number }): Promise<BrowserContext> {
const launchOptions = this._validateLaunchOptions(options);
// Note: Any initial TLS requests will fail since we rely on the Page/Frames initialize which sets ignoreHTTPSErrors.
let clientCertificatesProxy: ClientCertificatesProxy | undefined;
Expand DownExpand Up@@ -109,7 +109,7 @@ export abstract class BrowserType extends SdkObject {
private async _innerLaunch(progress: Progress, options: types.LaunchOptions, persistent: types.BrowserContextOptions | undefined, protocolLogger: types.ProtocolLogger, maybeUserDataDir?: string): Promise<Browser> {
options.proxy = options.proxy ? normalizeProxySettings(options.proxy) : undefined;
const browserLogsCollector = new RecentLogsCollector();
const { browserProcess, userDataDir, artifactsDir, transport } = await this._launchProcess(progress, options, !!persistent, browserLogsCollector, maybeUserDataDir);
const { browserProcess, userDataDir, artifactsDir, transport, wsEndpoint } = await this._launchProcess(progress, options, !!persistent, browserLogsCollector, maybeUserDataDir);
try {
if ((options as any).__testHookBeforeCreateBrowser)
await progress.race((options as any).__testHookBeforeCreateBrowser());
Expand All@@ -128,7 +128,7 @@ export abstract class BrowserType extends SdkObject {
proxy: options.proxy,
protocolLogger,
browserLogsCollector,
wsEndpoint: transport instanceof WebSocketTransport ? transport.wsEndpoint : undefined,
wsEndpoint,
originalLaunchOptions: options,
userDataDir: persistent ? userDataDir : undefined,
};
Expand DownExpand Up@@ -198,7 +198,7 @@ export abstract class BrowserType extends SdkObject {
return { executable, browserArguments, userDataDir, artifactsDir, tempDirectories };
}

private async _launchProcess(progress: Progress, options: types.LaunchOptions, isPersistent: boolean, browserLogsCollector: RecentLogsCollector, userDataDir?: string): Promise<{ browserProcess: BrowserProcess, artifactsDir: string, userDataDir: string, transport: ConnectionTransport }> {
private async _launchProcess(progress: Progress, options: types.LaunchOptions, isPersistent: boolean, browserLogsCollector: RecentLogsCollector, userDataDir?: string): Promise<{ browserProcess: BrowserProcess, artifactsDir: string, userDataDir: string, transport: ConnectionTransport, wsEndpoint?: string }> {
const {
handleSIGINT = true,
handleSIGTERM = true,
Expand DownExpand Up@@ -273,13 +273,13 @@ export abstract class BrowserType extends SdkObject {
const updatedLog = this.doRewriteStartupLog(log);
throw new Error(`Failed to launch the browser process.\nBrowser logs:\n${updatedLog}`);
}
if (options.cdpPort !== undefined || !this.supportsPipeTransport()) {
if (!this.supportsPipeTransport()) {
transport = await WebSocketTransport.connect(progress, wsEndpoint!);
} else {
const stdio = launchedProcess.stdio as unknown as [NodeJS.ReadableStream, NodeJS.WritableStream, NodeJS.WritableStream, NodeJS.WritableStream, NodeJS.ReadableStream];
transport = new PipeTransport(stdio[3], stdio[4]);
}
return { browserProcess, artifactsDir: prepared.artifactsDir, userDataDir: prepared.userDataDir, transport };
return { browserProcess, artifactsDir: prepared.artifactsDir, userDataDir: prepared.userDataDir, transport, wsEndpoint };
} catch (error) {
await progress.race(closeOrKill(DEFAULT_PLAYWRIGHT_TIMEOUT).catch(() => {}));
throw error;
Expand Down
11 changes: 4 additions & 7 deletions packages/playwright-core/src/server/chromium/chromium.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -74,7 +74,7 @@ export class Chromium extends BrowserType {
return super.launch(progress, options, protocolLogger);
}

override async launchPersistentContext(progress: Progress, userDataDir: string, options: channels.BrowserTypeLaunchPersistentContextOptions & { cdpPort?: number, internalIgnoreHTTPSErrors?: boolean, socksProxyPort?: number }): Promise<BrowserContext> {
override async launchPersistentContext(progress: Progress, userDataDir: string, options: channels.BrowserTypeLaunchPersistentContextOptions & { internalIgnoreHTTPSErrors?: boolean, socksProxyPort?: number }): Promise<BrowserContext> {
if (options.channel?.startsWith('bidi-'))
return this._bidiChromium.launchPersistentContext(progress, userDataDir, options);
return super.launchPersistentContext(progress, userDataDir, options);
Expand DownExpand Up@@ -343,10 +343,7 @@ export class Chromium extends BrowserType {
override async defaultArgs(options: types.LaunchOptions, isPersistent: boolean, userDataDir: string) {
const chromeArguments = this._innerDefaultArgs(options);
chromeArguments.push(`--user-data-dir=${userDataDir}`);
if (options.cdpPort !== undefined)
chromeArguments.push(`--remote-debugging-port=${options.cdpPort}`);
else
chromeArguments.push('--remote-debugging-pipe');
chromeArguments.push('--remote-debugging-pipe');
if (isPersistent)
chromeArguments.push('about:blank');
else
Expand All@@ -363,7 +360,7 @@ export class Chromium extends BrowserType {
throw new Error('Playwright manages remote debugging connection itself.');
if (args.find(arg => !arg.startsWith('-')))
throw new Error('Arguments can not specify page to be opened');
const chromeArguments = [...chromiumSwitches(options.assistantMode, options.channel)];
const chromeArguments = [...chromiumSwitches()];

// See https://issues.chromium.org/issues/40277080
chromeArguments.push('--enable-unsafe-swiftshader');
Expand DownExpand Up@@ -418,7 +415,7 @@ export class Chromium extends BrowserType {
}

export async function waitForReadyState(options: types.LaunchOptions, browserLogsCollector: RecentLogsCollector): Promise<{ wsEndpoint?: string }> {
if (options.cdpPort === undefined && !options.args?.some(a => a.startsWith('--remote-debugging-port')))
if (!options.args?.some(a => a.startsWith('--remote-debugging-port')))
return {};

const result = new ManualPromise<{ wsEndpoint?: string }>();
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,7 +17,7 @@

// No dependencies as it is used from the Electron loader.

const disabledFeatures = (assistantMode?: boolean) => [
const disabledFeatures = [
// See https://github.com/microsoft/playwright/issues/14047
'AvoidUnnecessaryBeforeUnloadCheckSync',
// See https://github.com/microsoft/playwright/issues/38568
Expand All@@ -44,14 +44,13 @@ const disabledFeatures = (assistantMode?: boolean) => [
'RenderDocument',
// Prevents downloading optimization hints on startup.
'OptimizationHints',
assistantMode ? 'AutomationControlled' : '',
// Disables forced sign-in in Edge.
'msForceBrowserSignIn',
// Disables updating the preferred version in LaunchServices preferences on mac.
'msEdgeUpdateLaunchServicesPreferredVersion',
].filter(Boolean);

export const chromiumSwitches = (assistantMode?: boolean, channel?: string, android?: boolean) => [
export const chromiumSwitches = (options?: { android?: boolean }) => [
'--disable-field-trial-config', // https://source.chromium.org/chromium/chromium/src/+/main:testing/variations/README.md
'--disable-background-networking',
'--disable-background-timer-throttling',
Expand All@@ -66,7 +65,7 @@ export const chromiumSwitches = (assistantMode?: boolean, channel?: string, andr
'--disable-dev-shm-usage',
'--disable-edgeupdater', // Disables Edge-specific updater on mac.
'--disable-extensions',
'--disable-features=' + disabledFeatures(assistantMode).join(','),
'--disable-features=' + disabledFeatures.join(','),
process.env.PLAYWRIGHT_LEGACY_SCREENSHOT ? '' : '--enable-features=CDPScreenshotNewSurface',
'--allow-pre-commit-input',
'--disable-hang-monitor',
Expand All@@ -88,12 +87,11 @@ export const chromiumSwitches = (assistantMode?: boolean, channel?: string, andr
'--unsafely-disable-devtools-self-xss-warnings',
// Edge can potentially restart on Windows (msRelaunchNoCompatLayer) which looses its file descriptors (stdout/stderr) and CDP (3/4). Disable until fixed upstream.
'--edge-skip-compat-layer-relaunch',
assistantMode ? '' : '--enable-automation',
// This disables Chrome for Testing infobar that is visible in the persistent context.
// The switch is ignored everywhere else, including Chromium/Chrome/Edge.
'--disable-infobars',
// Less annoying popups.
'--disable-search-engine-choice-screen',
// Prevents the "three dots" menu crash in IdentityManager::HasPrimaryAccount for ephemeral contexts.
android ? '' : '--disable-sync',
options?.android ? '' : '--disable-sync',
].filter(Boolean);
2 changes: 1 addition & 1 deletion packages/playwright-core/src/server/firefox/firefox.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -47,7 +47,7 @@ export class Firefox extends BrowserType {
return super.launch(progress, options, protocolLogger);
}

override async launchPersistentContext(progress: Progress, userDataDir: string, options: channels.BrowserTypeLaunchPersistentContextOptions & { cdpPort?: number, internalIgnoreHTTPSErrors?: boolean, socksProxyPort?: number }): Promise<BrowserContext> {
override async launchPersistentContext(progress: Progress, userDataDir: string, options: channels.BrowserTypeLaunchPersistentContextOptions & { internalIgnoreHTTPSErrors?: boolean, socksProxyPort?: number }): Promise<BrowserContext> {
if (options.channel?.startsWith('moz-'))
return this._bidiFirefox.launchPersistentContext(progress, userDataDir, options);
return super.launchPersistentContext(progress, userDataDir, options);
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -214,7 +214,7 @@ export class RecorderApp {
persistentContextOptions: {
noDefaultViewport: true,
headless: !!process.env.PWTEST_CLI_HEADLESS || (isUnderTest() && !headed),
cdpPort: isUnderTest() ? 0 : undefined,
args: isUnderTest() ? ['--remote-debugging-port=0'] : undefined,
handleSIGINT: params.handleSIGINT,
executablePath: isChromium ? inspectedContext._browser.options.customExecutablePath : undefined,
// Use the same channel as the inspected context to guarantee that the browser is installed.
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -178,7 +178,7 @@ export async function openTraceViewerApp(url: string, browserName: string, optio
windowSize: { width: 1280, height: 800 },
persistentContextOptions: {
...options?.persistentContextOptions,
cdpPort: isUnderTest() ? 0 : undefined,
args: isUnderTest() ? ['--remote-debugging-port=0'] : undefined,
headless: !!options?.headless,
colorScheme: isUnderTest() ? 'light' : undefined,
},
Expand Down
2 changes: 0 additions & 2 deletions packages/playwright-core/src/server/types.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -155,9 +155,7 @@ export type NormalizedContinueOverrides = {
export type EmulatedSize = { viewport: Size, screen: Size };

export type LaunchOptions = Omit<channels.BrowserTypeLaunchParams, 'timeout'> & {
cdpPort?: number,
proxyOverride?: ProxySettings,
assistantMode?: boolean,
socksProxyPort?: number,
};

Expand Down
7 changes: 4 additions & 3 deletions packages/playwright-core/src/tools/mcp/browserFactory.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -195,9 +195,10 @@ async function createUserDataDir(config: FullConfig, clientInfo: ClientInfo) {
}

async function injectCdpPort(browserConfig: FullConfig['browser']) {
if (browserConfig.browserName === 'chromium')
// eslint-disable-next-line no-restricted-syntax
(browserConfig.launchOptions as any).cdpPort = await findFreePort();
if (browserConfig.browserName === 'chromium') {
browserConfig.launchOptions.args = browserConfig.launchOptions.args ?? [];
browserConfig.launchOptions.args?.push(`--remote-debugging-port=${await findFreePort()}`);
}
}

async function findFreePort(): Promise<number> {
Expand Down
2 changes: 0 additions & 2 deletions packages/playwright-core/src/tools/mcp/config.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -413,8 +413,6 @@ function mergeConfig(base: MergedConfig, overrides: Config): MergedConfig {
launchOptions: {
...pickDefined(base.browser?.launchOptions),
...pickDefined(overrides.browser?.launchOptions),
// Assistant mode is not a part of the public API.
...{ assistantMode: true },
},
contextOptions: {
...pickDefined(base.browser?.contextOptions),
Expand Down
4 changes: 0 additions & 4 deletions packages/protocol/src/channels.d.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -902,7 +902,6 @@ export type BrowserTypeLaunchParams = {
args?: string[],
ignoreAllDefaultArgs?: boolean,
ignoreDefaultArgs?: string[],
assistantMode?: boolean,
handleSIGINT?: boolean,
handleSIGTERM?: boolean,
handleSIGHUP?: boolean,
Expand All@@ -929,7 +928,6 @@ export type BrowserTypeLaunchOptions = {
args?: string[],
ignoreAllDefaultArgs?: boolean,
ignoreDefaultArgs?: string[],
assistantMode?: boolean,
handleSIGINT?: boolean,
handleSIGTERM?: boolean,
handleSIGHUP?: boolean,
Expand DownExpand Up@@ -958,7 +956,6 @@ export type BrowserTypeLaunchPersistentContextParams = {
args?: string[],
ignoreAllDefaultArgs?: boolean,
ignoreDefaultArgs?: string[],
assistantMode?: boolean,
handleSIGINT?: boolean,
handleSIGTERM?: boolean,
handleSIGHUP?: boolean,
Expand DownExpand Up@@ -1047,7 +1044,6 @@ export type BrowserTypeLaunchPersistentContextOptions = {
args?: string[],
ignoreAllDefaultArgs?: boolean,
ignoreDefaultArgs?: string[],
assistantMode?: boolean,
handleSIGINT?: boolean,
handleSIGTERM?: boolean,
handleSIGHUP?: boolean,
Expand Down
1 change: 0 additions & 1 deletion packages/protocol/src/protocol.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -491,7 +491,6 @@ LaunchOptions:
ignoreDefaultArgs:
type: array?
items: string
assistantMode: boolean?
handleSIGINT: boolean?
handleSIGTERM: boolean?
handleSIGHUP: boolean?
Expand Down
4 changes: 2 additions & 2 deletions tests/library/chromium/chromium.spec.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -631,11 +631,11 @@ test('should throw when connecting twice to an already running persistent contex
test.skip(!!channel?.startsWith('msedge'), 'Edge does not print the ProcessSingleton line');
const userDataDir = await createUserDataDir();
const browser = await browserType.launchPersistentContext(userDataDir, {
cdpPort: 9222,
args: ['--remote-debugging-port=9222'],

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use freePort() instead?

} as any);
try {
const error = await browserType.launchPersistentContext(userDataDir, {
cdpPort: 9223,
args: ['--remote-debugging-port=9223'],
} as any).catch(e => e);
expect(error.message).toContain('This usually means that the profile is already in use by another instance of Chromium.');
} finally {
Expand Down
6 changes: 3 additions & 3 deletions tests/library/chromium/oopif.spec.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -371,13 +371,13 @@ it('should intercept response body from oopif', async function({ page, browser,
expect(await response.text()).toBeTruthy();
});

it('should allow to re-connect to OOPIFs with CDP when iframes were there already', async ({ browserType, server, browserMajorVersion }) => {
it('should allow to re-connect to OOPIFs with CDP when iframes were there already', async ({ browserType, server }) => {
it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/36095' });
it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/17656' });
it.skip(browserMajorVersion < 141, 'old chromium does not have TargetInfo.parentFrameId');
it.skip(!!process.env.PWTEST_CHANNEL, 'Test default channel only');

const cdpPort = 10123 + it.info().parallelIndex * 4;
const hostBrowser = await browserType.launch({ cdpPort } as any);
const hostBrowser = await browserType.launch({ channel: 'chromium', args: ['--remote-debugging-port=' + cdpPort] });
const hostPage = await hostBrowser.newPage();
await hostPage.goto(server.PREFIX + '/dynamic-oopif.html');

Expand Down
40 changes: 0 additions & 40 deletions tests/mcp/webdriver.spec.ts

This file was deleted.

Loading