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:
+1
-1
Submodule playwright updated: 28c1be07cf...fc998ca899
@@ -46,7 +46,7 @@
|
|||||||
"@hono/node-ws": "^1.2.0",
|
"@hono/node-ws": "^1.2.0",
|
||||||
"@modelcontextprotocol/sdk": "^1.25.2",
|
"@modelcontextprotocol/sdk": "^1.25.2",
|
||||||
"@xmorse/cac": "^6.0.7",
|
"@xmorse/cac": "^6.0.7",
|
||||||
"@xmorse/playwright-core": "workspace:*",
|
"@xmorse/playwright-core": "workspace:^",
|
||||||
"acorn": "^8.15.0",
|
"acorn": "^8.15.0",
|
||||||
"async-sema": "^3.1.1",
|
"async-sema": "^3.1.1",
|
||||||
"diff": "^8.0.2",
|
"diff": "^8.0.2",
|
||||||
|
|||||||
@@ -288,16 +288,6 @@ export class PlaywrightExecutor {
|
|||||||
options.deviceScaleFactor = 2
|
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() {
|
private clearUserState() {
|
||||||
Object.keys(this.userState).forEach((key) => delete this.userState[key])
|
Object.keys(this.userState).forEach((key) => delete this.userState[key])
|
||||||
}
|
}
|
||||||
@@ -578,7 +568,6 @@ export class PlaywrightExecutor {
|
|||||||
context.pages().forEach((p) => this.setupPageListeners(p))
|
context.pages().forEach((p) => this.setupPageListeners(p))
|
||||||
const page = await this.ensurePageForContext({ context, timeout: 10000 })
|
const page = await this.ensurePageForContext({ context, timeout: 10000 })
|
||||||
|
|
||||||
await this.preserveSystemColorScheme(context)
|
|
||||||
await this.setDeviceScaleFactorForMacOS(context)
|
await this.setDeviceScaleFactorForMacOS(context)
|
||||||
|
|
||||||
this.browser = browser
|
this.browser = browser
|
||||||
@@ -656,7 +645,6 @@ export class PlaywrightExecutor {
|
|||||||
context.pages().forEach((p) => this.setupPageListeners(p))
|
context.pages().forEach((p) => this.setupPageListeners(p))
|
||||||
const page = await this.ensurePageForContext({ context, timeout: 10000 })
|
const page = await this.ensurePageForContext({ context, timeout: 10000 })
|
||||||
|
|
||||||
await this.preserveSystemColorScheme(context)
|
|
||||||
await this.setDeviceScaleFactorForMacOS(context)
|
await this.setDeviceScaleFactorForMacOS(context)
|
||||||
|
|
||||||
this.browser = browser
|
this.browser = browser
|
||||||
|
|||||||
@@ -691,8 +691,7 @@ describe('Relay Core Tests', () => {
|
|||||||
}
|
}
|
||||||
}, 60000)
|
}, 60000)
|
||||||
|
|
||||||
// right now our extension always forces light mode because of a playwright cdp bug
|
it(
|
||||||
it.todo(
|
|
||||||
'should preserve system color scheme instead of forcing light mode',
|
'should preserve system color scheme instead of forcing light mode',
|
||||||
async () => {
|
async () => {
|
||||||
const browserContext = getBrowserContext()
|
const browserContext = getBrowserContext()
|
||||||
@@ -702,15 +701,17 @@ describe('Relay Core Tests', () => {
|
|||||||
await page.goto('https://example.com')
|
await page.goto('https://example.com')
|
||||||
await page.bringToFront()
|
await page.bringToFront()
|
||||||
|
|
||||||
|
// test-utils launches with colorScheme: 'dark', so before MCP connection
|
||||||
|
// the browser should report dark mode
|
||||||
const colorSchemeBefore = await page.evaluate(() => {
|
const colorSchemeBefore = await page.evaluate(() => {
|
||||||
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
|
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 serviceWorker.evaluate(async () => {
|
||||||
await globalThis.toggleExtensionForActiveTab()
|
await globalThis.toggleExtensionForActiveTab()
|
||||||
})
|
})
|
||||||
await new Promise((r) => setTimeout(r, 100))
|
await new Promise((r) => setTimeout(r, 500))
|
||||||
|
|
||||||
const result = await client.callTool({
|
const result = await client.callTool({
|
||||||
name: 'execute',
|
name: 'execute',
|
||||||
@@ -731,14 +732,17 @@ describe('Relay Core Tests', () => {
|
|||||||
|
|
||||||
console.log('Color scheme after MCP connection:', result.content)
|
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(`
|
expect(result.content).toMatchInlineSnapshot(`
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"text": "[return value] { error: 'Page not found', urls: [ 'about:blank' ] }",
|
"text": "[return value] { matchesDark: true, matchesLight: false }",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
`)
|
`)
|
||||||
|
|
||||||
await page.close()
|
await page.close()
|
||||||
},
|
},
|
||||||
|
|||||||
Generated
+3
-3
@@ -324,7 +324,7 @@ importers:
|
|||||||
specifier: ^6.0.7
|
specifier: ^6.0.7
|
||||||
version: 6.0.7
|
version: 6.0.7
|
||||||
'@xmorse/playwright-core':
|
'@xmorse/playwright-core':
|
||||||
specifier: workspace:*
|
specifier: workspace:^
|
||||||
version: link:../playwright/packages/playwright-core
|
version: link:../playwright/packages/playwright-core
|
||||||
acorn:
|
acorn:
|
||||||
specifier: ^8.15.0
|
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))
|
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:
|
vitest:
|
||||||
specifier: ^4.0.16
|
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:
|
packages:
|
||||||
|
|
||||||
@@ -13537,7 +13537,7 @@ snapshots:
|
|||||||
tsx: 4.20.6
|
tsx: 4.20.6
|
||||||
yaml: 2.6.0
|
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:
|
dependencies:
|
||||||
'@vitest/expect': 4.0.16
|
'@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))
|
'@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))
|
||||||
|
|||||||
Reference in New Issue
Block a user