diff --git a/packages/playwright-core/src/protocol/validator.ts b/packages/playwright-core/src/protocol/validator.ts index 5788140676703..cca67f6407c9d 100644 --- a/packages/playwright-core/src/protocol/validator.ts +++ b/packages/playwright-core/src/protocol/validator.ts @@ -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), @@ -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), diff --git a/packages/playwright-core/src/server/android/android.ts b/packages/playwright-core/src/server/android/android.ts index 801ae85cfed3a..b1b57da6e6bec 100644 --- a/packages/playwright-core/src/server/android/android.ts +++ b/packages/playwright-core/src/server/android/android.ts @@ -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; diff --git a/packages/playwright-core/src/server/bidi/bidiChromium.ts b/packages/playwright-core/src/server/bidi/bidiChromium.ts index 9cdd1da833233..2e02b9295811e 100644 --- a/packages/playwright-core/src/server/bidi/bidiChromium.ts +++ b/packages/playwright-core/src/server/bidi/bidiChromium.ts @@ -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[] { @@ -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 diff --git a/packages/playwright-core/src/server/browser.ts b/packages/playwright-core/src/server/browser.ts index 1967a9549a066..bdd7dfe8e7aad 100644 --- a/packages/playwright-core/src/server/browser.ts +++ b/packages/playwright-core/src/server/browser.ts @@ -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; diff --git a/packages/playwright-core/src/server/browserType.ts b/packages/playwright-core/src/server/browserType.ts index c4787cb3f641f..f0503d245712b 100644 --- a/packages/playwright-core/src/server/browserType.ts +++ b/packages/playwright-core/src/server/browserType.ts @@ -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 { + async launchPersistentContext(progress: Progress, userDataDir: string, options: channels.BrowserTypeLaunchPersistentContextOptions & { internalIgnoreHTTPSErrors?: boolean, socksProxyPort?: number }): Promise { 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; @@ -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 { 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()); @@ -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, }; @@ -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, @@ -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; diff --git a/packages/playwright-core/src/server/chromium/chromium.ts b/packages/playwright-core/src/server/chromium/chromium.ts index 9c95feac19e56..daf7769b5d8d2 100644 --- a/packages/playwright-core/src/server/chromium/chromium.ts +++ b/packages/playwright-core/src/server/chromium/chromium.ts @@ -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 { + override async launchPersistentContext(progress: Progress, userDataDir: string, options: channels.BrowserTypeLaunchPersistentContextOptions & { internalIgnoreHTTPSErrors?: boolean, socksProxyPort?: number }): Promise { if (options.channel?.startsWith('bidi-')) return this._bidiChromium.launchPersistentContext(progress, userDataDir, options); return super.launchPersistentContext(progress, userDataDir, options); @@ -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 @@ -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'); @@ -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 }>(); diff --git a/packages/playwright-core/src/server/chromium/chromiumSwitches.ts b/packages/playwright-core/src/server/chromium/chromiumSwitches.ts index 946630f9accf1..af60e7c2b5b83 100644 --- a/packages/playwright-core/src/server/chromium/chromiumSwitches.ts +++ b/packages/playwright-core/src/server/chromium/chromiumSwitches.ts @@ -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 @@ -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', @@ -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', @@ -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); diff --git a/packages/playwright-core/src/server/firefox/firefox.ts b/packages/playwright-core/src/server/firefox/firefox.ts index d469a67c5fd17..14c43a327cfe5 100644 --- a/packages/playwright-core/src/server/firefox/firefox.ts +++ b/packages/playwright-core/src/server/firefox/firefox.ts @@ -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 { + override async launchPersistentContext(progress: Progress, userDataDir: string, options: channels.BrowserTypeLaunchPersistentContextOptions & { internalIgnoreHTTPSErrors?: boolean, socksProxyPort?: number }): Promise { if (options.channel?.startsWith('moz-')) return this._bidiFirefox.launchPersistentContext(progress, userDataDir, options); return super.launchPersistentContext(progress, userDataDir, options); diff --git a/packages/playwright-core/src/server/recorder/recorderApp.ts b/packages/playwright-core/src/server/recorder/recorderApp.ts index f5538450b5957..06d504dc8de20 100644 --- a/packages/playwright-core/src/server/recorder/recorderApp.ts +++ b/packages/playwright-core/src/server/recorder/recorderApp.ts @@ -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. diff --git a/packages/playwright-core/src/server/trace/viewer/traceViewer.ts b/packages/playwright-core/src/server/trace/viewer/traceViewer.ts index a7d1f70ee5739..e9fbf9f51ea54 100644 --- a/packages/playwright-core/src/server/trace/viewer/traceViewer.ts +++ b/packages/playwright-core/src/server/trace/viewer/traceViewer.ts @@ -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, }, diff --git a/packages/playwright-core/src/server/types.ts b/packages/playwright-core/src/server/types.ts index 8b663e51efe03..25c0f81206b75 100644 --- a/packages/playwright-core/src/server/types.ts +++ b/packages/playwright-core/src/server/types.ts @@ -155,9 +155,7 @@ export type NormalizedContinueOverrides = { export type EmulatedSize = { viewport: Size, screen: Size }; export type LaunchOptions = Omit & { - cdpPort?: number, proxyOverride?: ProxySettings, - assistantMode?: boolean, socksProxyPort?: number, }; diff --git a/packages/playwright-core/src/serverRegistry.ts b/packages/playwright-core/src/serverRegistry.ts index e6160c775dee6..d39fa8bc3c779 100644 --- a/packages/playwright-core/src/serverRegistry.ts +++ b/packages/playwright-core/src/serverRegistry.ts @@ -75,7 +75,7 @@ class ServerRegistry { const entries = await Promise.all(promises); const descriptors = []; for (const entry of entries) { - if (!entry.canConnect && !entry.browser.userDataDir) { + if (!entry.canConnect) { await fs.promises.unlink(entry.file).catch(() => {}); continue; } diff --git a/packages/playwright-core/src/tools/cli-client/session.ts b/packages/playwright-core/src/tools/cli-client/session.ts index 8ac4b92d0687f..28ecb5886bf0a 100644 --- a/packages/playwright-core/src/tools/cli-client/session.ts +++ b/packages/playwright-core/src/tools/cli-client/session.ts @@ -67,7 +67,7 @@ export class Session { } async deleteData() { - await this.stop(); + await this.stop(true); const dataDirs = await fs.promises.readdir(this._sessionFile.daemonDir).catch(() => []); const matchingEntries = dataDirs.filter(file => file === `${this.name}.session` || file.startsWith(`ud-${this.name}-`)); diff --git a/packages/playwright-core/src/tools/mcp/browserFactory.ts b/packages/playwright-core/src/tools/mcp/browserFactory.ts index cb2cb1e28a771..cc048c9bff46b 100644 --- a/packages/playwright-core/src/tools/mcp/browserFactory.ts +++ b/packages/playwright-core/src/tools/mcp/browserFactory.ts @@ -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 { diff --git a/packages/playwright-core/src/tools/mcp/cdpRelay.ts b/packages/playwright-core/src/tools/mcp/cdpRelay.ts index 623d1f5c4a59b..3b2f54597e7fd 100644 --- a/packages/playwright-core/src/tools/mcp/cdpRelay.ts +++ b/packages/playwright-core/src/tools/mcp/cdpRelay.ts @@ -22,8 +22,8 @@ * - /extension/guid - Extension connection * * Protocol version is controlled by PLAYWRIGHT_EXTENSION_PROTOCOL env variable: - * - v1: single-tab, extension manages debugger attachment - * - v2 (default): multi-tab, relay manages debugger via chrome.* APIs + * - v1 (default): single-tab, extension manages debugger attachment + * - v2: multi-tab, relay manages debugger via chrome.* APIs */ import { spawn } from 'child_process'; @@ -77,7 +77,7 @@ export class CDPRelayServer { this._browserChannel = browserChannel; this._userDataDir = userDataDir; this._executablePath = executablePath; - this._protocolVersion = parseInt(process.env.PLAYWRIGHT_EXTENSION_PROTOCOL ?? protocol.VERSION.toString(), 10); + this._protocolVersion = parseInt(process.env.PLAYWRIGHT_EXTENSION_PROTOCOL ?? protocol.DEFAULT_VERSION.toString(), 10); const sendCommand = (method: string, params: any): Promise => { if (!this._extensionConnection) diff --git a/packages/playwright-core/src/tools/mcp/config.ts b/packages/playwright-core/src/tools/mcp/config.ts index ae476a943aa0b..974c2fc5e24b6 100644 --- a/packages/playwright-core/src/tools/mcp/config.ts +++ b/packages/playwright-core/src/tools/mcp/config.ts @@ -163,17 +163,18 @@ export async function resolveCLIConfigForCLI(daemonProfilesDir: string, sessionN if (result.browser.isolated === undefined) result.browser.isolated = !options.profile && !options.persistent && !result.browser.userDataDir && !result.browser.remoteEndpoint && !result.browser.cdpEndpoint && !result.extension; - if (!result.extension && !result.browser.isolated && !result.browser.userDataDir && !result.browser.remoteEndpoint && !result.browser.cdpEndpoint) { - // No custom value provided, use the daemon data dir. - const browserToken = result.browser.launchOptions?.channel ?? result.browser?.browserName; - const userDataDir = path.resolve(daemonProfilesDir, `ud-${sessionName}-${browserToken}`); - result.browser.userDataDir = userDataDir; - } - if (result.browser.launchOptions.headless === undefined) result.browser.launchOptions.headless = true; const browser = await validateBrowserConfig(result.browser); + + if (!result.extension && !browser.isolated && !browser.userDataDir && !browser.remoteEndpoint && !browser.cdpEndpoint) { + // No custom value provided, use the daemon data dir. + const browserToken = browser.launchOptions?.channel ?? browser?.browserName; + const userDataDir = path.resolve(daemonProfilesDir, `ud-${sessionName}-${browserToken}`); + browser.userDataDir = userDataDir; + } + return { ...result, browser, configFile, skillMode: true }; } @@ -412,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), diff --git a/packages/playwright-core/src/tools/mcp/protocol.ts b/packages/playwright-core/src/tools/mcp/protocol.ts index c62f5a78c7699..b8f639a4914d3 100644 --- a/packages/playwright-core/src/tools/mcp/protocol.ts +++ b/packages/playwright-core/src/tools/mcp/protocol.ts @@ -14,9 +14,14 @@ * limitations under the License. */ -// Whenever the commands/events change, the version must be updated. The latest -// extension version should be compatible with the old MCP clients. -export const VERSION = 2; +// The latest protocol version defined in this file. Bumped whenever the +// commands/events change. The latest extension version should remain +// compatible with older MCP clients. +export const LATEST_VERSION = 2; + +// The protocol version used by default when PLAYWRIGHT_EXTENSION_PROTOCOL is +// not set. May lag behind LATEST_VERSION while a new version is rolling out. +export const DEFAULT_VERSION = 1; // Structural mirrors of @types/chrome shapes used over the wire. The extension // imports the real chrome.* types and they are structurally compatible. diff --git a/packages/protocol/src/channels.d.ts b/packages/protocol/src/channels.d.ts index 5f1e5bd31749e..8339636c0e221 100644 --- a/packages/protocol/src/channels.d.ts +++ b/packages/protocol/src/channels.d.ts @@ -902,7 +902,6 @@ export type BrowserTypeLaunchParams = { args?: string[], ignoreAllDefaultArgs?: boolean, ignoreDefaultArgs?: string[], - assistantMode?: boolean, handleSIGINT?: boolean, handleSIGTERM?: boolean, handleSIGHUP?: boolean, @@ -929,7 +928,6 @@ export type BrowserTypeLaunchOptions = { args?: string[], ignoreAllDefaultArgs?: boolean, ignoreDefaultArgs?: string[], - assistantMode?: boolean, handleSIGINT?: boolean, handleSIGTERM?: boolean, handleSIGHUP?: boolean, @@ -958,7 +956,6 @@ export type BrowserTypeLaunchPersistentContextParams = { args?: string[], ignoreAllDefaultArgs?: boolean, ignoreDefaultArgs?: string[], - assistantMode?: boolean, handleSIGINT?: boolean, handleSIGTERM?: boolean, handleSIGHUP?: boolean, @@ -1047,7 +1044,6 @@ export type BrowserTypeLaunchPersistentContextOptions = { args?: string[], ignoreAllDefaultArgs?: boolean, ignoreDefaultArgs?: string[], - assistantMode?: boolean, handleSIGINT?: boolean, handleSIGTERM?: boolean, handleSIGHUP?: boolean, diff --git a/packages/protocol/src/protocol.yml b/packages/protocol/src/protocol.yml index a2efffd896b64..abe1d504205bb 100644 --- a/packages/protocol/src/protocol.yml +++ b/packages/protocol/src/protocol.yml @@ -491,7 +491,6 @@ LaunchOptions: ignoreDefaultArgs: type: array? items: string - assistantMode: boolean? handleSIGINT: boolean? handleSIGTERM: boolean? handleSIGHUP: boolean? diff --git a/tests/library/chromium/chromium.spec.ts b/tests/library/chromium/chromium.spec.ts index 1433857ead3e2..3c0b2f0b1c4f0 100644 --- a/tests/library/chromium/chromium.spec.ts +++ b/tests/library/chromium/chromium.spec.ts @@ -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'], } 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 { diff --git a/tests/library/chromium/oopif.spec.ts b/tests/library/chromium/oopif.spec.ts index 058bce4a0c7b2..96149d6a881d0 100644 --- a/tests/library/chromium/oopif.spec.ts +++ b/tests/library/chromium/oopif.spec.ts @@ -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'); diff --git a/tests/mcp/config-resolve.spec.ts b/tests/mcp/config-resolve.spec.ts index cca192fb475af..5e85d48fb9d9c 100644 --- a/tests/mcp/config-resolve.spec.ts +++ b/tests/mcp/config-resolve.spec.ts @@ -17,7 +17,7 @@ import fs from 'fs'; import path from 'path'; -import { test, expect } from '@playwright/test'; +import { test, expect } from './fixtures'; import { tools } from '../../packages/playwright-core/lib/coreBundle'; import type { Config } from '../../packages/playwright-core/src/tools/mcp/config.d'; @@ -27,11 +27,7 @@ const { resolveCLIConfigForCLI, resolveCLIConfigForMCP } = tools; // Empty env to isolate tests from the host environment. const emptyEnv = {}; -// --------------------------------------------------------------------------- -// Shared behavior — browserName / channel resolution -// These are tested via resolveCLIConfigForMCP; the underlying configFromCLIOptions -// and validateBrowserConfig are shared with resolveCLIConfigForCLI. -// --------------------------------------------------------------------------- +test.skip(({ mcpBrowser }) => mcpBrowser !== 'chrome', 'Channel-agnostic tests.'); test.describe('browserName and channel', () => { test('no browser option defaults to chromium / chrome', async () => { @@ -376,7 +372,7 @@ test.describe('resolveCLIConfigForCLI - isolated and userDataDir', () => { test('auto userDataDir uses undefined token when no browser specified', async ({}, testInfo) => { const profilesDir = testInfo.outputPath('profiles'); const config = await resolveCLI(profilesDir, 'default', { persistent: true }); - expect(config.browser.userDataDir).toBe(path.resolve(profilesDir, 'ud-default-undefined')); + expect(config.browser.userDataDir).toBe(path.resolve(profilesDir, 'ud-default-chrome')); }); test('no auto userDataDir when isolated', async ({}, testInfo) => { diff --git a/tests/mcp/webdriver.spec.ts b/tests/mcp/webdriver.spec.ts deleted file mode 100644 index 99496cb187864..0000000000000 --- a/tests/mcp/webdriver.spec.ts +++ /dev/null @@ -1,40 +0,0 @@ -/** - * Copyright (c) Microsoft Corporation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { test, expect } from './fixtures'; - -test('do not falsely advertise user agent as a test driver', async ({ client, server, mcpBrowser }) => { - test.skip(mcpBrowser === 'firefox'); - test.skip(mcpBrowser === 'webkit'); - server.setRoute('/', (req, res) => { - res.writeHead(200, { 'Content-Type': 'text/html' }); - res.end(` - - - `); - }); - - expect(await client.callTool({ - name: 'browser_navigate', - arguments: { - url: server.PREFIX, - }, - })).toHaveResponse({ - snapshot: expect.stringContaining(`webdriver: false`), - }); -});