From 88f30d1ce2e67b569c7110e3ecd000319f92ea28 Mon Sep 17 00:00:00 2001 From: Dmitry Gozman Date: Fri, 27 Oct 2023 09:24:41 -0700 Subject: [PATCH] feat: support firefoxUserPrefs in launchPersistentContext (#27840) Fixes #27773. --- docs/src/api/class-browsertype.md | 6 ++++++ packages/playwright-core/src/client/types.ts | 12 +++++------- packages/playwright-core/src/protocol/validator.ts | 1 + .../playwright-core/src/server/firefox/ffBrowser.ts | 2 +- packages/playwright-core/types/types.d.ts | 6 ++++++ packages/protocol/src/channels.ts | 2 ++ packages/protocol/src/protocol.yml | 2 +- packages/trace-viewer/src/ui/logTab.tsx | 2 +- tests/library/firefox/launcher.spec.ts | 13 +++++++++++++ 9 files changed, 36 insertions(+), 10 deletions(-) diff --git a/docs/src/api/class-browsertype.md b/docs/src/api/class-browsertype.md index 02742b0c68578..6a776f1cee997 100644 --- a/docs/src/api/class-browsertype.md +++ b/docs/src/api/class-browsertype.md @@ -337,6 +337,12 @@ use a temporary directory instead. ### option: BrowserType.launchPersistentContext.-inline- = %%-shared-context-params-list-v1.8-%% * since: v1.8 +### option: BrowserType.launchPersistentContext.firefoxUserPrefs = %%-js-python-browser-option-firefoxuserprefs-%% +* since: v1.40 + +### option: BrowserType.launchPersistentContext.firefoxUserPrefs2 = %%-csharp-java-browser-option-firefoxuserprefs-%% +* since: v1.40 + ## async method: BrowserType.launchServer * since: v1.8 * langs: js diff --git a/packages/playwright-core/src/client/types.ts b/packages/playwright-core/src/client/types.ts index 4884d89cc2784..2fc2cea0d1873 100644 --- a/packages/playwright-core/src/client/types.ts +++ b/packages/playwright-core/src/client/types.ts @@ -76,14 +76,11 @@ type LaunchOverrides = { ignoreDefaultArgs?: boolean | string[]; env?: Env; logger?: Logger; + firefoxUserPrefs?: { [key: string]: string | number | boolean }; }; -type FirefoxUserPrefs = { - firefoxUserPrefs?: { [key: string]: string | number | boolean }, -}; -type LaunchOptionsBase = Omit & LaunchOverrides; -export type LaunchOptions = LaunchOptionsBase & FirefoxUserPrefs; -export type LaunchPersistentContextOptions = Omit; +export type LaunchOptions = Omit & LaunchOverrides; +export type LaunchPersistentContextOptions = Omit; export type ConnectOptions = { wsEndpoint: string, @@ -117,7 +114,8 @@ export type LaunchServerOptions = { port?: number, wsPath?: string, logger?: Logger, -} & FirefoxUserPrefs; + firefoxUserPrefs?: { [key: string]: string | number | boolean }; +}; export type LaunchAndroidServerOptions = { deviceSerialNumber?: string, diff --git a/packages/playwright-core/src/protocol/validator.ts b/packages/playwright-core/src/protocol/validator.ts index 8e8a25bb4bc71..0ea38e7f80241 100644 --- a/packages/playwright-core/src/protocol/validator.ts +++ b/packages/playwright-core/src/protocol/validator.ts @@ -521,6 +521,7 @@ scheme.BrowserTypeLaunchPersistentContextParams = tObject({ downloadsPath: tOptional(tString), tracesDir: tOptional(tString), chromiumSandbox: tOptional(tBoolean), + firefoxUserPrefs: tOptional(tAny), noDefaultViewport: tOptional(tBoolean), viewport: tOptional(tObject({ width: tNumber, diff --git a/packages/playwright-core/src/server/firefox/ffBrowser.ts b/packages/playwright-core/src/server/firefox/ffBrowser.ts index ab2f7f894ebc9..9b0e7113687d4 100644 --- a/packages/playwright-core/src/server/firefox/ffBrowser.ts +++ b/packages/playwright-core/src/server/firefox/ffBrowser.ts @@ -43,7 +43,7 @@ export class FFBrowser extends Browser { const browser = new FFBrowser(parent, connection, options); if ((options as any).__testHookOnConnectToBrowser) await (options as any).__testHookOnConnectToBrowser(); - let firefoxUserPrefs = options.persistent ? {} : options.originalLaunchOptions.firefoxUserPrefs ?? {}; + let firefoxUserPrefs = options.originalLaunchOptions.firefoxUserPrefs ?? {}; if (Object.keys(kBandaidFirefoxUserPrefs).length) firefoxUserPrefs = { ...kBandaidFirefoxUserPrefs, ...firefoxUserPrefs }; const promises: Promise[] = [ diff --git a/packages/playwright-core/types/types.d.ts b/packages/playwright-core/types/types.d.ts index 08644a856e80e..986846c9a6a1f 100644 --- a/packages/playwright-core/types/types.d.ts +++ b/packages/playwright-core/types/types.d.ts @@ -12841,6 +12841,12 @@ export interface BrowserType { */ extraHTTPHeaders?: { [key: string]: string; }; + /** + * Firefox user preferences. Learn more about the Firefox user preferences at + * [`about:config`](https://support.mozilla.org/en-US/kb/about-config-editor-firefox). + */ + firefoxUserPrefs?: { [key: string]: string|number|boolean; }; + /** * Emulates `'forced-colors'` media feature, supported values are `'active'`, `'none'`. See * [page.emulateMedia([options])](https://playwright.dev/docs/api/class-page#page-emulate-media) for more details. diff --git a/packages/protocol/src/channels.ts b/packages/protocol/src/channels.ts index a7aba4dd530c0..8b252040d5726 100644 --- a/packages/protocol/src/channels.ts +++ b/packages/protocol/src/channels.ts @@ -929,6 +929,7 @@ export type BrowserTypeLaunchPersistentContextParams = { downloadsPath?: string, tracesDir?: string, chromiumSandbox?: boolean, + firefoxUserPrefs?: any, noDefaultViewport?: boolean, viewport?: { width: number, @@ -1000,6 +1001,7 @@ export type BrowserTypeLaunchPersistentContextOptions = { downloadsPath?: string, tracesDir?: string, chromiumSandbox?: boolean, + firefoxUserPrefs?: any, noDefaultViewport?: boolean, viewport?: { width: number, diff --git a/packages/protocol/src/protocol.yml b/packages/protocol/src/protocol.yml index 262954ce7ee3d..0dd3c05e63e7f 100644 --- a/packages/protocol/src/protocol.yml +++ b/packages/protocol/src/protocol.yml @@ -411,6 +411,7 @@ LaunchOptions: downloadsPath: string? tracesDir: string? chromiumSandbox: boolean? + firefoxUserPrefs: json? ContextOptions: @@ -868,7 +869,6 @@ BrowserType: launch: parameters: $mixin: LaunchOptions - firefoxUserPrefs: json? slowMo: number? returns: browser: Browser diff --git a/packages/trace-viewer/src/ui/logTab.tsx b/packages/trace-viewer/src/ui/logTab.tsx index 45b7ebe989279..9e4995984f801 100644 --- a/packages/trace-viewer/src/ui/logTab.tsx +++ b/packages/trace-viewer/src/ui/logTab.tsx @@ -52,7 +52,7 @@ export const LogTab: React.FunctionComponent<{ }); } return entries; - }, [action]); + }, [action, isLive]); if (!entries.length) return ; diff --git a/tests/library/firefox/launcher.spec.ts b/tests/library/firefox/launcher.spec.ts index 1365026c53103..294d53643c0ef 100644 --- a/tests/library/firefox/launcher.spec.ts +++ b/tests/library/firefox/launcher.spec.ts @@ -30,3 +30,16 @@ it('should pass firefox user preferences', async ({ browserType, mode }) => { expect(error.message).toContain('NS_ERROR_PROXY_CONNECTION_REFUSED'); await browser.close(); }); + +it('should pass firefox user preferences in persistent', async ({ mode, launchPersistent }) => { + it.skip(mode.startsWith('service')); + const { page } = await launchPersistent({ + firefoxUserPrefs: { + 'network.proxy.type': 1, + 'network.proxy.http': '127.0.0.1', + 'network.proxy.http_port': 3333, + } + }); + const error = await page.goto('http://example.com').catch(e => e); + expect(error.message).toContain('NS_ERROR_PROXY_CONNECTION_REFUSED'); +});