fix: stop forcing light mode on connectOverCDP pages

Removed the preserveSystemColorScheme() workaround from executor.ts that was
mutating private Playwright internals via (context as any)._options to patch
around the forced light mode.

The root cause is now fixed in @xmorse/playwright-core@1.59.4: the default
colorScheme fallback in page.emulatedMedia() changed from 'light' to
'no-override', so Chrome respects the user's system color scheme.

Activated the previously-todo test that validates dark mode is preserved
after MCP connection (matchesDark: true, matchesLight: false).
This commit is contained in:
Tommy D. Rossi
2026-02-24 15:31:14 +01:00
parent 9c376b7637
commit 0d3ec43da3
5 changed files with 20 additions and 28 deletions
+1 -1
View File
@@ -46,7 +46,7 @@
"@hono/node-ws": "^1.2.0",
"@modelcontextprotocol/sdk": "^1.25.2",
"@xmorse/cac": "^6.0.7",
"@xmorse/playwright-core": "workspace:*",
"@xmorse/playwright-core": "workspace:^",
"acorn": "^8.15.0",
"async-sema": "^3.1.1",
"diff": "^8.0.2",
-12
View File
@@ -288,16 +288,6 @@ export class PlaywrightExecutor {
options.deviceScaleFactor = 2
}
private async preserveSystemColorScheme(context: BrowserContext): Promise<void> {
const options = (context as any)._options
if (!options) {
return
}
options.colorScheme = 'no-override'
options.reducedMotion = 'no-override'
options.forcedColors = 'no-override'
}
private clearUserState() {
Object.keys(this.userState).forEach((key) => delete this.userState[key])
}
@@ -578,7 +568,6 @@ export class PlaywrightExecutor {
context.pages().forEach((p) => this.setupPageListeners(p))
const page = await this.ensurePageForContext({ context, timeout: 10000 })
await this.preserveSystemColorScheme(context)
await this.setDeviceScaleFactorForMacOS(context)
this.browser = browser
@@ -656,7 +645,6 @@ export class PlaywrightExecutor {
context.pages().forEach((p) => this.setupPageListeners(p))
const page = await this.ensurePageForContext({ context, timeout: 10000 })
await this.preserveSystemColorScheme(context)
await this.setDeviceScaleFactorForMacOS(context)
this.browser = browser
+15 -11
View File
@@ -691,8 +691,7 @@ describe('Relay Core Tests', () => {
}
}, 60000)
// right now our extension always forces light mode because of a playwright cdp bug
it.todo(
it(
'should preserve system color scheme instead of forcing light mode',
async () => {
const browserContext = getBrowserContext()
@@ -702,15 +701,17 @@ describe('Relay Core Tests', () => {
await page.goto('https://example.com')
await page.bringToFront()
// test-utils launches with colorScheme: 'dark', so before MCP connection
// the browser should report dark mode
const colorSchemeBefore = await page.evaluate(() => {
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
})
console.log('Color scheme before MCP connection:', colorSchemeBefore)
expect(colorSchemeBefore).toBe('dark')
await serviceWorker.evaluate(async () => {
await globalThis.toggleExtensionForActiveTab()
})
await new Promise((r) => setTimeout(r, 100))
await new Promise((r) => setTimeout(r, 500))
const result = await client.callTool({
name: 'execute',
@@ -731,14 +732,17 @@ describe('Relay Core Tests', () => {
console.log('Color scheme after MCP connection:', result.content)
// After MCP connection, color scheme should NOT be forced to light.
// The page.ts default is now 'no-override', so the browser's actual
// color scheme (dark, from test-utils launch config) should be preserved.
expect(result.content).toMatchInlineSnapshot(`
[
{
"text": "[return value] { error: 'Page not found', urls: [ 'about:blank' ] }",
"type": "text",
},
]
`)
[
{
"text": "[return value] { matchesDark: true, matchesLight: false }",
"type": "text",
},
]
`)
await page.close()
},
+3 -3
View File
@@ -324,7 +324,7 @@ importers:
specifier: ^6.0.7
version: 6.0.7
'@xmorse/playwright-core':
specifier: workspace:*
specifier: workspace:^
version: link:../playwright/packages/playwright-core
acorn:
specifier: ^8.15.0
@@ -511,7 +511,7 @@ importers:
version: 6.0.3(typescript@5.9.3)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(tsx@4.20.6)(yaml@2.6.0))
vitest:
specifier: ^4.0.16
version: 4.0.16(@opentelemetry/api@1.9.0)(@types/node@25.0.3)(@vitest/ui@4.0.8)(jiti@2.6.1)(jsdom@27.2.0(bufferutil@4.0.9))(lightningcss@1.31.1)(tsx@4.20.6)(yaml@2.6.0)
version: 4.0.16(@opentelemetry/api@1.9.0)(@types/node@25.0.3)(@vitest/ui@4.0.8(vitest@4.0.8))(jiti@2.6.1)(jsdom@27.2.0(bufferutil@4.0.9))(lightningcss@1.31.1)(tsx@4.20.6)(yaml@2.6.0)
packages:
@@ -13537,7 +13537,7 @@ snapshots:
tsx: 4.20.6
yaml: 2.6.0
vitest@4.0.16(@opentelemetry/api@1.9.0)(@types/node@25.0.3)(@vitest/ui@4.0.8)(jiti@2.6.1)(jsdom@27.2.0(bufferutil@4.0.9))(lightningcss@1.31.1)(tsx@4.20.6)(yaml@2.6.0):
vitest@4.0.16(@opentelemetry/api@1.9.0)(@types/node@25.0.3)(@vitest/ui@4.0.8(vitest@4.0.8))(jiti@2.6.1)(jsdom@27.2.0(bufferutil@4.0.9))(lightningcss@1.31.1)(tsx@4.20.6)(yaml@2.6.0):
dependencies:
'@vitest/expect': 4.0.16
'@vitest/mocker': 4.0.16(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(tsx@4.20.6)(yaml@2.6.0))