From 735169a3c98873143cf13204d19270c655c2a6d4 Mon Sep 17 00:00:00 2001 From: Kartik Sahu Date: Sun, 20 Sep 2026 03:01:41 +0530 Subject: [PATCH] fix: add screen option to test runner fixtures Fixes #42679 The test runner was silently dropping the 'screen' key when using device descriptors (e.g., devices['iPhone 13']) via test.use(). This caused window.screen dimensions to collapse to viewport size, breaking device emulation. Changes: - Added 'screen' fixture to TestOptions in index.ts - Added 'screen' to _combinedContextOptions destructure and if-chain - Updated PlaywrightTestOptions interface to include screen property - Added regression tests for device descriptor and explicit screen usage The fix ensures screen emulation works consistently in both library mode (browser.newContext) and test runner mode (test.use). --- packages/playwright/src/index.ts | 4 ++ .../playwright-test/playwright.config.spec.ts | 64 +++++++++++++++++++ utils/generate_types/overrides-test.d.ts | 1 + 3 files changed, 69 insertions(+) diff --git a/packages/playwright/src/index.ts b/packages/playwright/src/index.ts index b1e14b7810c68..0d4332109d7b1 100644 --- a/packages/playwright/src/index.ts +++ b/packages/playwright/src/index.ts @@ -284,6 +284,7 @@ const playwrightFixtures: Fixtures use(contextOptions.timezoneId), { option: true, box: true }], userAgent: [({ contextOptions }, use) => use(contextOptions.userAgent), { option: true, box: true }], viewport: [({ contextOptions }, use) => use(contextOptions.viewport === undefined ? { width: 1280, height: 720 } : contextOptions.viewport), { option: true, box: true }], + screen: [({ contextOptions }, use) => use(contextOptions.screen), { option: true, box: true }], actionTimeout: [0, { option: true, box: true }], navigationTimeout: [0, { option: true, box: true }], baseURL: [async ({ }, use) => { @@ -311,6 +312,7 @@ const playwrightFixtures: Fixtures { + const result = await runInlineTest({ + 'playwright.config.ts': ` + import { defineConfig, devices } from '@playwright/test'; + export default defineConfig({ + projects: [ + { + name: 'chromium', + use: { ...devices['iPhone 13'] }, + }, + ], + }); + `, + 'a.test.ts': ` + import { test, expect } from '@playwright/test'; + test('screen should match device descriptor', async ({ page }) => { + const screen = await page.evaluate(() => ({ + width: window.screen.width, + height: window.screen.height + })); + // iPhone 13 has screen dimensions of 390x844 + expect(screen.width).toBe(390); + expect(screen.height).toBe(844); + }); + `, + }, { workers: 1 }); + + expect(result.exitCode).toBe(0); + expect(result.passed).toBe(1); +}); + +test('should support explicit screen option', async ({ runInlineTest }) => { + const result = await runInlineTest({ + 'playwright.config.ts': ` + export default { + use: { + screen: { width: 1920, height: 1080 }, + viewport: { width: 800, height: 600 } + } + }; + `, + 'a.test.ts': ` + import { test, expect } from '@playwright/test'; + test('screen should differ from viewport', async ({ page }) => { + const viewport = page.viewportSize(); + const screen = await page.evaluate(() => ({ + width: window.screen.width, + height: window.screen.height + })); + // Viewport is 800x600 + expect(viewport.width).toBe(800); + expect(viewport.height).toBe(600); + // But screen is 1920x1080 + expect(screen.width).toBe(1920); + expect(screen.height).toBe(1080); + }); + `, + }, { workers: 1 }); + + expect(result.exitCode).toBe(0); + expect(result.passed).toBe(1); +}); diff --git a/utils/generate_types/overrides-test.d.ts b/utils/generate_types/overrides-test.d.ts index b95c661759778..3f6f556804eff 100644 --- a/utils/generate_types/overrides-test.d.ts +++ b/utils/generate_types/overrides-test.d.ts @@ -299,6 +299,7 @@ export interface PlaywrightTestOptions { permissions: string[] | undefined; proxy: Proxy | undefined; reducedMotion: ReducedMotion; + screen: ViewportSize | undefined; storageState: StorageState | undefined; timezoneId: string | undefined; userAgent: string | undefined;