diff --git a/packages/playwright-core/src/protocol/channels.ts b/packages/playwright-core/src/protocol/channels.ts index 09def4da7e..c11c1000d4 100644 --- a/packages/playwright-core/src/protocol/channels.ts +++ b/packages/playwright-core/src/protocol/channels.ts @@ -3843,7 +3843,15 @@ export type AndroidDeviceInputDragOptions = { }; export type AndroidDeviceInputDragResult = void; export type AndroidDeviceLaunchBrowserParams = { - pkg?: string, + noDefaultViewport?: boolean, + viewport?: { + width: number, + height: number, + }, + screen?: { + width: number, + height: number, + }, ignoreHTTPSErrors?: boolean, javaScriptEnabled?: boolean, bypassCSP?: boolean, @@ -3869,6 +3877,7 @@ export type AndroidDeviceLaunchBrowserParams = { reducedMotion?: 'reduce' | 'no-preference', forcedColors?: 'active' | 'none', acceptDownloads?: boolean, + baseURL?: string, recordVideo?: { dir: string, size?: { @@ -3881,6 +3890,7 @@ export type AndroidDeviceLaunchBrowserParams = { path: string, }, strictSelectors?: boolean, + pkg?: string, proxy?: { server: string, bypass?: string, @@ -3889,7 +3899,15 @@ export type AndroidDeviceLaunchBrowserParams = { }, }; export type AndroidDeviceLaunchBrowserOptions = { - pkg?: string, + noDefaultViewport?: boolean, + viewport?: { + width: number, + height: number, + }, + screen?: { + width: number, + height: number, + }, ignoreHTTPSErrors?: boolean, javaScriptEnabled?: boolean, bypassCSP?: boolean, @@ -3915,6 +3933,7 @@ export type AndroidDeviceLaunchBrowserOptions = { reducedMotion?: 'reduce' | 'no-preference', forcedColors?: 'active' | 'none', acceptDownloads?: boolean, + baseURL?: string, recordVideo?: { dir: string, size?: { @@ -3927,6 +3946,7 @@ export type AndroidDeviceLaunchBrowserOptions = { path: string, }, strictSelectors?: boolean, + pkg?: string, proxy?: { server: string, bypass?: string, diff --git a/packages/playwright-core/src/protocol/protocol.yml b/packages/playwright-core/src/protocol/protocol.yml index 3ccf0c99f6..ae104fce39 100644 --- a/packages/playwright-core/src/protocol/protocol.yml +++ b/packages/playwright-core/src/protocol/protocol.yml @@ -2944,66 +2944,8 @@ AndroidDevice: launchBrowser: parameters: + $mixin: ContextOptions pkg: string? - ignoreHTTPSErrors: boolean? - javaScriptEnabled: boolean? - bypassCSP: boolean? - userAgent: string? - locale: string? - timezoneId: string? - geolocation: - type: object? - properties: - longitude: number - latitude: number - accuracy: number? - permissions: - type: array? - items: string - extraHTTPHeaders: - type: array? - items: NameValue - offline: boolean? - httpCredentials: - type: object? - properties: - username: string - password: string - deviceScaleFactor: number? - isMobile: boolean? - hasTouch: boolean? - colorScheme: - type: enum? - literals: - - dark - - light - - no-preference - reducedMotion: - type: enum? - literals: - - reduce - - no-preference - forcedColors: - type: enum? - literals: - - active - - none - acceptDownloads: boolean? - recordVideo: - type: object? - properties: - dir: string - size: - type: object? - properties: - width: number - height: number - recordHar: - type: object? - properties: - omitContent: boolean? - path: string - strictSelectors: boolean? proxy: type: object? properties: diff --git a/packages/playwright-core/src/protocol/validator.ts b/packages/playwright-core/src/protocol/validator.ts index da3ace8ae4..4af2d3c350 100644 --- a/packages/playwright-core/src/protocol/validator.ts +++ b/packages/playwright-core/src/protocol/validator.ts @@ -1359,7 +1359,15 @@ export function createScheme(tChannel: (name: string) => Validator): Scheme { steps: tNumber, }); scheme.AndroidDeviceLaunchBrowserParams = tObject({ - pkg: tOptional(tString), + noDefaultViewport: tOptional(tBoolean), + viewport: tOptional(tObject({ + width: tNumber, + height: tNumber, + })), + screen: tOptional(tObject({ + width: tNumber, + height: tNumber, + })), ignoreHTTPSErrors: tOptional(tBoolean), javaScriptEnabled: tOptional(tBoolean), bypassCSP: tOptional(tBoolean), @@ -1385,6 +1393,7 @@ export function createScheme(tChannel: (name: string) => Validator): Scheme { reducedMotion: tOptional(tEnum(['reduce', 'no-preference'])), forcedColors: tOptional(tEnum(['active', 'none'])), acceptDownloads: tOptional(tBoolean), + baseURL: tOptional(tString), recordVideo: tOptional(tObject({ dir: tString, size: tOptional(tObject({ @@ -1397,6 +1406,7 @@ export function createScheme(tChannel: (name: string) => Validator): Scheme { path: tString, })), strictSelectors: tOptional(tBoolean), + pkg: tOptional(tString), proxy: tOptional(tObject({ server: tString, bypass: tOptional(tString), diff --git a/packages/playwright-core/src/server/chromium/crPage.ts b/packages/playwright-core/src/server/chromium/crPage.ts index 50e52d9a56..2309075cf4 100644 --- a/packages/playwright-core/src/server/chromium/crPage.ts +++ b/packages/playwright-core/src/server/chromium/crPage.ts @@ -1005,8 +1005,6 @@ class FrameSession { } async _updateEmulateMedia(initial: boolean): Promise { - if (this._crPage._browserContext._browser.isClank()) - return; const colorScheme = this._page._state.colorScheme === null ? '' : this._page._state.colorScheme; const reducedMotion = this._page._state.reducedMotion === null ? '' : this._page._state.reducedMotion; const forcedColors = this._page._state.forcedColors === null ? '' : this._page._state.forcedColors; diff --git a/tests/android/browser.spec.ts b/tests/android/browser.spec.ts index 11e6317c91..4618fe9015 100644 --- a/tests/android/browser.spec.ts +++ b/tests/android/browser.spec.ts @@ -55,3 +55,24 @@ test('should be able to send CDP messages', async ({ androidDevice }) => { const evalResponse = await client.send('Runtime.evaluate', { expression: '1 + 2', returnByValue: true }); expect(evalResponse.result.value).toBe(3); }); + +test('should be able to pass context options', async ({ androidDevice, httpsServer }) => { + const context = await androidDevice.launchBrowser({ + colorScheme: 'dark', + geolocation: { longitude: 10, latitude: 10 }, + permissions: ['geolocation'], + ignoreHTTPSErrors: true, + baseURL: httpsServer.PREFIX, + }); + const [page] = context.pages(); + + await page.goto('./empty.html'); + expect(page.url()).toBe(httpsServer.PREFIX + '/empty.html'); + + expect(await page.evaluate(() => new Promise(resolve => navigator.geolocation.getCurrentPosition(position => { + resolve({ latitude: position.coords.latitude, longitude: position.coords.longitude }); + })))).toEqual({ latitude: 10, longitude: 10 }); + + expect(await page.evaluate(() => matchMedia('(prefers-color-scheme: dark)').matches)).toBe(true); + expect(await page.evaluate(() => matchMedia('(prefers-color-scheme: light)').matches)).toBe(false); +});