diff --git a/docs/src/api/class-browsercontext.md b/docs/src/api/class-browsercontext.md index ea7afa54fc259..806aaee33b283 100644 --- a/docs/src/api/class-browsercontext.md +++ b/docs/src/api/class-browsercontext.md @@ -1004,6 +1004,14 @@ named `page`, but it can be a `Page` or `Frame` type. Creates a new page in the browser context. +## method: BrowserContext.contextOptions +* since: v1.59 +* langs: js +- returns: <[Object]> + +Returns the context options that were used to create this browser context. The return type matches the options +accepted by [`method: Browser.newContext`]. + ## method: BrowserContext.pages * since: v1.8 - returns: <[Array]<[Page]>> diff --git a/packages/playwright-client/types/types.d.ts b/packages/playwright-client/types/types.d.ts index 2449c65b39211..6d34470f627ac 100644 --- a/packages/playwright-client/types/types.d.ts +++ b/packages/playwright-client/types/types.d.ts @@ -8324,6 +8324,12 @@ export interface BrowserContext { */ behavior?: 'wait'|'ignoreErrors'|'default' }): Promise; + + /** + * Returns the context options that were used to create this browser context. The return type matches the options + * accepted by [browser.newContext([options])](https://playwright.dev/docs/api/class-browser#browser-new-context). + */ + contextOptions(): BrowserContextOptions; /** * This event is not emitted. */ @@ -9751,6 +9757,12 @@ export interface Browser { */ behavior?: 'wait'|'ignoreErrors'|'default' }): Promise; + + /** + * Returns the launch options that were used to launch this browser. The return type matches the options accepted by + * [browserType.launch([options])](https://playwright.dev/docs/api/class-browsertype#browser-type-launch). + */ + launchOptions(): LaunchOptions; /** * Emitted when Browser gets disconnected from the browser application. This might happen because of one of the * following: @@ -9842,12 +9854,6 @@ export interface Browser { */ isConnected(): boolean; - /** - * Returns the launch options that were used to launch this browser. The return type matches the options accepted by - * [browserType.launch([options])](https://playwright.dev/docs/api/class-browsertype#browser-type-launch). - */ - launchOptions(): Object; - /** * **NOTE** CDP Sessions are only supported on Chromium-based browsers. * diff --git a/packages/playwright-core/src/client/browserContext.ts b/packages/playwright-core/src/client/browserContext.ts index 3a06890167776..7212dec579286 100644 --- a/packages/playwright-core/src/client/browserContext.ts +++ b/packages/playwright-core/src/client/browserContext.ts @@ -38,7 +38,7 @@ import { WebError } from './webError'; import { Worker } from './worker'; import { TimeoutSettings } from './timeoutSettings'; import { mkdirIfNeeded } from './fileUtils'; -import { headersObjectToArray } from '../utils/isomorphic/headers'; +import { headersArrayToObject, headersObjectToArray } from '../utils/isomorphic/headers'; import { urlMatchesEqual } from '../utils/isomorphic/urlMatch'; import { isRegExp, isString } from '../utils/isomorphic/rtti'; import { rewriteErrorMessage } from '../utils/isomorphic/stackTrace'; @@ -290,6 +290,10 @@ export class BrowserContext extends ChannelOwner return this._browser; } + contextOptions() { + return contextParamsToPublicOptions(this._options); + } + pages(): Page[] { return [...this._pages]; } @@ -603,6 +607,24 @@ export async function prepareBrowserContextParams(platform: Platform, options: B return contextParams; } +function contextParamsToPublicOptions(params: channels.BrowserNewContextParams): api.BrowserContextOptions { + const result = { + ...params, + viewport: params.noDefaultViewport ? null : params.viewport, + extraHTTPHeaders: params.extraHTTPHeaders ? headersArrayToObject(params.extraHTTPHeaders, false) : undefined, + colorScheme: params.colorScheme === 'no-override' ? null : params.colorScheme, + reducedMotion: params.reducedMotion === 'no-override' ? null : params.reducedMotion, + forcedColors: params.forcedColors === 'no-override' ? null : params.forcedColors, + contrast: params.contrast === 'no-override' ? null : params.contrast, + acceptDownloads: params.acceptDownloads === 'accept' ? true : params.acceptDownloads === 'deny' ? false : undefined, + storageState: undefined, + }; + delete result.clientCertificates; + delete result.noDefaultViewport; + delete result.selectorEngines; + return result; +} + function toAcceptDownloadsProtocol(acceptDownloads?: boolean) { if (acceptDownloads === undefined) return undefined; diff --git a/packages/playwright-core/src/client/selectors.ts b/packages/playwright-core/src/client/selectors.ts index 3a34cef5a96ff..3e6fc905c4802 100644 --- a/packages/playwright-core/src/client/selectors.ts +++ b/packages/playwright-core/src/client/selectors.ts @@ -47,8 +47,10 @@ export class Selectors implements api.Selectors { setTestIdAttribute(attributeName: string) { this._testIdAttributeName = attributeName; setTestIdAttribute(attributeName); - for (const context of this._contextsForSelectors) + for (const context of this._contextsForSelectors) { + context._options.testIdAttributeName = attributeName; context._channel.setTestIdAttributeName({ testIdAttributeName: attributeName }).catch(() => {}); + } } _withSelectorOptions(options: T) { diff --git a/packages/playwright-core/types/types.d.ts b/packages/playwright-core/types/types.d.ts index 2449c65b39211..6d34470f627ac 100644 --- a/packages/playwright-core/types/types.d.ts +++ b/packages/playwright-core/types/types.d.ts @@ -8324,6 +8324,12 @@ export interface BrowserContext { */ behavior?: 'wait'|'ignoreErrors'|'default' }): Promise; + + /** + * Returns the context options that were used to create this browser context. The return type matches the options + * accepted by [browser.newContext([options])](https://playwright.dev/docs/api/class-browser#browser-new-context). + */ + contextOptions(): BrowserContextOptions; /** * This event is not emitted. */ @@ -9751,6 +9757,12 @@ export interface Browser { */ behavior?: 'wait'|'ignoreErrors'|'default' }): Promise; + + /** + * Returns the launch options that were used to launch this browser. The return type matches the options accepted by + * [browserType.launch([options])](https://playwright.dev/docs/api/class-browsertype#browser-type-launch). + */ + launchOptions(): LaunchOptions; /** * Emitted when Browser gets disconnected from the browser application. This might happen because of one of the * following: @@ -9842,12 +9854,6 @@ export interface Browser { */ isConnected(): boolean; - /** - * Returns the launch options that were used to launch this browser. The return type matches the options accepted by - * [browserType.launch([options])](https://playwright.dev/docs/api/class-browsertype#browser-type-launch). - */ - launchOptions(): Object; - /** * **NOTE** CDP Sessions are only supported on Chromium-based browsers. * diff --git a/tests/library/browser.spec.ts b/tests/library/browser.spec.ts index 19d47f871a4ea..a2911f4ad65ef 100644 --- a/tests/library/browser.spec.ts +++ b/tests/library/browser.spec.ts @@ -51,6 +51,10 @@ test('version should work', async function({ browser, browserName }) { expect(version.match(/^\d+\.\d+/)).toBeTruthy(); }); +test('launchOptions() should work', async function({ browser, headless }) { + expect(!!browser.launchOptions().headless).toBe(!!headless); +}); + test('should dispatch page.on(close) upon browser.close and reject evaluate', async ({ browserType }) => { const browser = await browserType.launch(); const page = await browser.newPage(); diff --git a/tests/library/browsercontext-basic.spec.ts b/tests/library/browsercontext-basic.spec.ts index 795e8d1932dae..050d7c36ebcbc 100644 --- a/tests/library/browsercontext-basic.spec.ts +++ b/tests/library/browsercontext-basic.spec.ts @@ -33,6 +33,20 @@ it('should create new context @smoke', async function({ browser }) { await context2.close(); }); +it('should return context options', async function({ browser }) { + const context = await browser.newContext({ + userAgent: 'custom-ua', + locale: 'fr-FR', + extraHTTPHeaders: { 'foo': 'bar' }, + }); + const options = context.contextOptions(); + expect(options.userAgent).toBe('custom-ua'); + expect(options.locale).toBe('fr-FR'); + expect(options.extraHTTPHeaders).toEqual({ 'foo': 'bar' }); + expect((options as any).noDefaultViewport).toBeUndefined(); // internal option should not leak + await context.close(); +}); + it('should be able to click across browser contexts', async function({ browser }) { it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/29096' }); expect(browser.contexts().length).toBe(0); diff --git a/utils/generate_types/overrides.d.ts b/utils/generate_types/overrides.d.ts index 3a0c13eed56ea..35f10f96f5e8e 100644 --- a/utils/generate_types/overrides.d.ts +++ b/utils/generate_types/overrides.d.ts @@ -133,6 +133,8 @@ export interface BrowserContext { */ behavior?: 'wait'|'ignoreErrors'|'default' }): Promise; + + contextOptions(): BrowserContextOptions; } export interface Browser { @@ -146,6 +148,8 @@ export interface Browser { */ behavior?: 'wait'|'ignoreErrors'|'default' }): Promise; + + launchOptions(): LaunchOptions; } export interface Worker {