concurrent tabs test works

This commit is contained in:
Tommy D. Rossi
2025-11-22 12:43:52 +01:00
parent c658c153b2
commit 27172cf7ca
4 changed files with 57 additions and 259 deletions
+12
View File
@@ -37,3 +37,15 @@ curl -sL https://raw.githubusercontent.com/ChromeDevTools/devtools-protocol/mast
```
you can list other files in that folder on github to read more if you need to control things like DOM, performance, etc
## testing
run `cd playwriter && pnpm test` to test the extension and mcp and CDP directly in a chrome instance automated. with the extension loaded too.
the test script will also pass -u to update some inline snapshots used
you can run singular tests with `-t "testname"`
each test() block should reset the extension connection to make sure tests are independent.
NEVER call browser.close() in the tests
-225
View File
@@ -1,225 +0,0 @@
CDP relay server started
Host: 127.0.0.1
Port: 19988
Extension endpoint: ws://127.0.0.1:19988/extension
CDP endpoint: ws://127.0.0.1:19988/cdp
Extension connected with clean state
← Extension: Target.attachedToTarget targetId=37BE179F93AF8207BD1E2372B9C515BA, sessionId=pw-tab-1
→ Playwright [ALL]: Target.attachedToTarget targetId=37BE179F93AF8207BD1E2372B9C515BA, sessionId=pw-tab-1
← Extension: Target.attachedToTarget targetId=E3E15D82C13B4A15D3CF71E44B260036, sessionId=pw-tab-2
→ Playwright [ALL]: Target.attachedToTarget targetId=E3E15D82C13B4A15D3CF71E44B260036, sessionId=pw-tab-2
← Extension: Target.attachedToTarget targetId=16E435409CFBF47529751B04E9F9021D, sessionId=pw-tab-3
→ Playwright [ALL]: Target.attachedToTarget targetId=16E435409CFBF47529751B04E9F9021D, sessionId=pw-tab-3
Playwright client connected: E3E15D82C13B4A15D3CF71E44B260036 (1 total)
← Playwright [E3E15D82C13B4A15D3CF71E44B260036]: Browser.getVersion id=1
← Playwright [E3E15D82C13B4A15D3CF71E44B260036]: Target.setAutoAttach id=2
→ Playwright [E3E15D82C13B4A15D3CF71E44B260036]: Target.attachedToTarget targetId=37BE179F93AF8207BD1E2372B9C515BA, sessionId=pw-tab-1 (server-generated)
→ Playwright [E3E15D82C13B4A15D3CF71E44B260036]: Target.attachedToTarget targetId=E3E15D82C13B4A15D3CF71E44B260036, sessionId=pw-tab-2 (server-generated)
→ Playwright [E3E15D82C13B4A15D3CF71E44B260036]: Target.attachedToTarget targetId=16E435409CFBF47529751B04E9F9021D, sessionId=pw-tab-3 (server-generated)
← Playwright [E3E15D82C13B4A15D3CF71E44B260036]: Browser.setDownloadBehavior id=3
← Playwright [E3E15D82C13B4A15D3CF71E44B260036]: Page.enable id=4, sessionId=pw-tab-1
← Playwright [E3E15D82C13B4A15D3CF71E44B260036]: Page.getFrameTree id=5, sessionId=pw-tab-1
← Playwright [E3E15D82C13B4A15D3CF71E44B260036]: Log.enable id=6, sessionId=pw-tab-1
← Playwright [E3E15D82C13B4A15D3CF71E44B260036]: Page.setLifecycleEventsEnabled id=7, sessionId=pw-tab-1
← Playwright [E3E15D82C13B4A15D3CF71E44B260036]: Runtime.enable id=8, sessionId=pw-tab-1
← Playwright [E3E15D82C13B4A15D3CF71E44B260036]: Page.addScriptToEvaluateOnNewDocument id=9, sessionId=pw-tab-1
← Playwright [E3E15D82C13B4A15D3CF71E44B260036]: Network.enable id=10, sessionId=pw-tab-1
← Playwright [E3E15D82C13B4A15D3CF71E44B260036]: Target.setAutoAttach id=11, sessionId=pw-tab-1
← Playwright [E3E15D82C13B4A15D3CF71E44B260036]: Emulation.setFocusEmulationEnabled id=12, sessionId=pw-tab-1
← Playwright [E3E15D82C13B4A15D3CF71E44B260036]: Emulation.setEmulatedMedia id=13, sessionId=pw-tab-1
← Playwright [E3E15D82C13B4A15D3CF71E44B260036]: Runtime.runIfWaitingForDebugger id=14, sessionId=pw-tab-1
← Playwright [E3E15D82C13B4A15D3CF71E44B260036]: Page.enable id=15, sessionId=pw-tab-2
← Playwright [E3E15D82C13B4A15D3CF71E44B260036]: Page.getFrameTree id=16, sessionId=pw-tab-2
← Playwright [E3E15D82C13B4A15D3CF71E44B260036]: Log.enable id=17, sessionId=pw-tab-2
← Playwright [E3E15D82C13B4A15D3CF71E44B260036]: Page.setLifecycleEventsEnabled id=18, sessionId=pw-tab-2
← Playwright [E3E15D82C13B4A15D3CF71E44B260036]: Runtime.enable id=19, sessionId=pw-tab-2
← Playwright [E3E15D82C13B4A15D3CF71E44B260036]: Page.addScriptToEvaluateOnNewDocument id=20, sessionId=pw-tab-2
← Playwright [E3E15D82C13B4A15D3CF71E44B260036]: Network.enable id=21, sessionId=pw-tab-2
← Playwright [E3E15D82C13B4A15D3CF71E44B260036]: Target.setAutoAttach id=22, sessionId=pw-tab-2
← Playwright [E3E15D82C13B4A15D3CF71E44B260036]: Emulation.setFocusEmulationEnabled id=23, sessionId=pw-tab-2
← Playwright [E3E15D82C13B4A15D3CF71E44B260036]: Emulation.setEmulatedMedia id=24, sessionId=pw-tab-2
← Playwright [E3E15D82C13B4A15D3CF71E44B260036]: Runtime.runIfWaitingForDebugger id=25, sessionId=pw-tab-2
← Playwright [E3E15D82C13B4A15D3CF71E44B260036]: Page.enable id=26, sessionId=pw-tab-3
← Playwright [E3E15D82C13B4A15D3CF71E44B260036]: Page.getFrameTree id=27, sessionId=pw-tab-3
← Playwright [E3E15D82C13B4A15D3CF71E44B260036]: Log.enable id=28, sessionId=pw-tab-3
← Playwright [E3E15D82C13B4A15D3CF71E44B260036]: Page.setLifecycleEventsEnabled id=29, sessionId=pw-tab-3
← Playwright [E3E15D82C13B4A15D3CF71E44B260036]: Runtime.enable id=30, sessionId=pw-tab-3
← Playwright [E3E15D82C13B4A15D3CF71E44B260036]: Page.addScriptToEvaluateOnNewDocument id=31, sessionId=pw-tab-3
← Playwright [E3E15D82C13B4A15D3CF71E44B260036]: Network.enable id=32, sessionId=pw-tab-3
← Playwright [E3E15D82C13B4A15D3CF71E44B260036]: Target.setAutoAttach id=33, sessionId=pw-tab-3
← Playwright [E3E15D82C13B4A15D3CF71E44B260036]: Emulation.setFocusEmulationEnabled id=34, sessionId=pw-tab-3
← Playwright [E3E15D82C13B4A15D3CF71E44B260036]: Emulation.setEmulatedMedia id=35, sessionId=pw-tab-3
← Playwright [E3E15D82C13B4A15D3CF71E44B260036]: Runtime.runIfWaitingForDebugger id=36, sessionId=pw-tab-3
← Playwright [E3E15D82C13B4A15D3CF71E44B260036]: Target.getTargetInfo id=37
← Extension: Page.lifecycleEvent sessionId=pw-tab-1
→ Playwright [ALL]: Page.lifecycleEvent sessionId=pw-tab-1
← Extension: Page.lifecycleEvent sessionId=pw-tab-1
→ Playwright [ALL]: Page.lifecycleEvent sessionId=pw-tab-1
← Extension: Page.lifecycleEvent sessionId=pw-tab-1
→ Playwright [ALL]: Page.lifecycleEvent sessionId=pw-tab-1
← Extension: Page.lifecycleEvent sessionId=pw-tab-1
→ Playwright [ALL]: Page.lifecycleEvent sessionId=pw-tab-1
← Extension: Page.lifecycleEvent sessionId=pw-tab-1
→ Playwright [ALL]: Page.lifecycleEvent sessionId=pw-tab-1
← Extension: Runtime.executionContextCreated sessionId=pw-tab-1
→ Playwright [ALL]: Runtime.executionContextCreated sessionId=pw-tab-1
← Extension: Runtime.executionContextCreated sessionId=pw-tab-1
→ Playwright [ALL]: Runtime.executionContextCreated sessionId=pw-tab-1
← Extension: Log.entryAdded sessionId=pw-tab-2
→ Playwright [ALL]: Log.entryAdded sessionId=pw-tab-2
← Extension: Page.lifecycleEvent sessionId=pw-tab-2
→ Playwright [ALL]: Page.lifecycleEvent sessionId=pw-tab-2
← Extension: Page.lifecycleEvent sessionId=pw-tab-2
→ Playwright [ALL]: Page.lifecycleEvent sessionId=pw-tab-2
← Extension: Page.lifecycleEvent sessionId=pw-tab-2
→ Playwright [ALL]: Page.lifecycleEvent sessionId=pw-tab-2
← Extension: Page.lifecycleEvent sessionId=pw-tab-2
→ Playwright [ALL]: Page.lifecycleEvent sessionId=pw-tab-2
← Extension: Page.lifecycleEvent sessionId=pw-tab-2
→ Playwright [ALL]: Page.lifecycleEvent sessionId=pw-tab-2
← Extension: Runtime.executionContextCreated sessionId=pw-tab-2
→ Playwright [ALL]: Runtime.executionContextCreated sessionId=pw-tab-2
← Extension: Runtime.executionContextCreated sessionId=pw-tab-2
→ Playwright [ALL]: Runtime.executionContextCreated sessionId=pw-tab-2
← Extension: Runtime.executionContextCreated sessionId=pw-tab-2
→ Playwright [ALL]: Runtime.executionContextCreated sessionId=pw-tab-2
← Extension: Page.lifecycleEvent sessionId=pw-tab-3
→ Playwright [ALL]: Page.lifecycleEvent sessionId=pw-tab-3
← Extension: Page.lifecycleEvent sessionId=pw-tab-3
→ Playwright [ALL]: Page.lifecycleEvent sessionId=pw-tab-3
← Extension: Page.lifecycleEvent sessionId=pw-tab-3
→ Playwright [ALL]: Page.lifecycleEvent sessionId=pw-tab-3
← Extension: Page.lifecycleEvent sessionId=pw-tab-3
→ Playwright [ALL]: Page.lifecycleEvent sessionId=pw-tab-3
← Extension: Page.lifecycleEvent sessionId=pw-tab-3
→ Playwright [ALL]: Page.lifecycleEvent sessionId=pw-tab-3
← Extension: Runtime.executionContextCreated sessionId=pw-tab-3
→ Playwright [ALL]: Runtime.executionContextCreated sessionId=pw-tab-3
← Extension: Runtime.executionContextCreated sessionId=pw-tab-3
→ Playwright [ALL]: Runtime.executionContextCreated sessionId=pw-tab-3
← Playwright [E3E15D82C13B4A15D3CF71E44B260036]: Page.createIsolatedWorld id=38, sessionId=pw-tab-1
← Playwright [E3E15D82C13B4A15D3CF71E44B260036]: Page.createIsolatedWorld id=39, sessionId=pw-tab-2
← Playwright [E3E15D82C13B4A15D3CF71E44B260036]: Page.createIsolatedWorld id=40, sessionId=pw-tab-3
Playwright client connected: 16E435409CFBF47529751B04E9F9021D (2 total)
← Extension: Runtime.executionContextCreated sessionId=pw-tab-1
→ Playwright [ALL]: Runtime.executionContextCreated sessionId=pw-tab-1
← Extension: Runtime.executionContextCreated sessionId=pw-tab-2
→ Playwright [ALL]: Runtime.executionContextCreated sessionId=pw-tab-2
← Extension: Runtime.executionContextCreated sessionId=pw-tab-3
→ Playwright [ALL]: Runtime.executionContextCreated sessionId=pw-tab-3
← Playwright [16E435409CFBF47529751B04E9F9021D]: Browser.getVersion id=1
← Playwright [16E435409CFBF47529751B04E9F9021D]: Target.setAutoAttach id=2
→ Playwright [16E435409CFBF47529751B04E9F9021D]: Target.attachedToTarget targetId=37BE179F93AF8207BD1E2372B9C515BA, sessionId=pw-tab-1 (server-generated)
→ Playwright [16E435409CFBF47529751B04E9F9021D]: Target.attachedToTarget targetId=E3E15D82C13B4A15D3CF71E44B260036, sessionId=pw-tab-2 (server-generated)
→ Playwright [16E435409CFBF47529751B04E9F9021D]: Target.attachedToTarget targetId=16E435409CFBF47529751B04E9F9021D, sessionId=pw-tab-3 (server-generated)
← Playwright [16E435409CFBF47529751B04E9F9021D]: Browser.setDownloadBehavior id=3
← Playwright [16E435409CFBF47529751B04E9F9021D]: Page.enable id=4, sessionId=pw-tab-1
← Playwright [16E435409CFBF47529751B04E9F9021D]: Page.getFrameTree id=5, sessionId=pw-tab-1
← Playwright [16E435409CFBF47529751B04E9F9021D]: Log.enable id=6, sessionId=pw-tab-1
← Playwright [16E435409CFBF47529751B04E9F9021D]: Page.setLifecycleEventsEnabled id=7, sessionId=pw-tab-1
← Playwright [16E435409CFBF47529751B04E9F9021D]: Runtime.enable id=8, sessionId=pw-tab-1
← Playwright [16E435409CFBF47529751B04E9F9021D]: Page.addScriptToEvaluateOnNewDocument id=9, sessionId=pw-tab-1
← Playwright [16E435409CFBF47529751B04E9F9021D]: Network.enable id=10, sessionId=pw-tab-1
← Playwright [16E435409CFBF47529751B04E9F9021D]: Target.setAutoAttach id=11, sessionId=pw-tab-1
← Playwright [16E435409CFBF47529751B04E9F9021D]: Emulation.setFocusEmulationEnabled id=12, sessionId=pw-tab-1
← Playwright [16E435409CFBF47529751B04E9F9021D]: Emulation.setEmulatedMedia id=13, sessionId=pw-tab-1
← Playwright [16E435409CFBF47529751B04E9F9021D]: Runtime.runIfWaitingForDebugger id=14, sessionId=pw-tab-1
← Playwright [16E435409CFBF47529751B04E9F9021D]: Page.enable id=15, sessionId=pw-tab-2
← Playwright [16E435409CFBF47529751B04E9F9021D]: Page.getFrameTree id=16, sessionId=pw-tab-2
← Playwright [16E435409CFBF47529751B04E9F9021D]: Log.enable id=17, sessionId=pw-tab-2
← Playwright [16E435409CFBF47529751B04E9F9021D]: Page.setLifecycleEventsEnabled id=18, sessionId=pw-tab-2
← Extension: Page.lifecycleEvent sessionId=pw-tab-1
→ Playwright [ALL]: Page.lifecycleEvent sessionId=pw-tab-1
← Extension: Page.lifecycleEvent sessionId=pw-tab-1
→ Playwright [ALL]: Page.lifecycleEvent sessionId=pw-tab-1
← Playwright [16E435409CFBF47529751B04E9F9021D]: Runtime.enable id=19, sessionId=pw-tab-2
← Playwright [16E435409CFBF47529751B04E9F9021D]: Page.addScriptToEvaluateOnNewDocument id=20, sessionId=pw-tab-2
← Playwright [16E435409CFBF47529751B04E9F9021D]: Network.enable id=21, sessionId=pw-tab-2
← Playwright [16E435409CFBF47529751B04E9F9021D]: Target.setAutoAttach id=22, sessionId=pw-tab-2
← Playwright [16E435409CFBF47529751B04E9F9021D]: Emulation.setFocusEmulationEnabled id=23, sessionId=pw-tab-2
← Playwright [16E435409CFBF47529751B04E9F9021D]: Emulation.setEmulatedMedia id=24, sessionId=pw-tab-2
← Playwright [16E435409CFBF47529751B04E9F9021D]: Runtime.runIfWaitingForDebugger id=25, sessionId=pw-tab-2
← Playwright [16E435409CFBF47529751B04E9F9021D]: Page.enable id=26, sessionId=pw-tab-3
← Playwright [16E435409CFBF47529751B04E9F9021D]: Page.getFrameTree id=27, sessionId=pw-tab-3
← Playwright [16E435409CFBF47529751B04E9F9021D]: Log.enable id=28, sessionId=pw-tab-3
← Playwright [16E435409CFBF47529751B04E9F9021D]: Page.setLifecycleEventsEnabled id=29, sessionId=pw-tab-3
← Playwright [16E435409CFBF47529751B04E9F9021D]: Runtime.enable id=30, sessionId=pw-tab-3
← Playwright [16E435409CFBF47529751B04E9F9021D]: Page.addScriptToEvaluateOnNewDocument id=31, sessionId=pw-tab-3
← Playwright [16E435409CFBF47529751B04E9F9021D]: Network.enable id=32, sessionId=pw-tab-3
← Playwright [16E435409CFBF47529751B04E9F9021D]: Target.setAutoAttach id=33, sessionId=pw-tab-3
← Playwright [16E435409CFBF47529751B04E9F9021D]: Emulation.setFocusEmulationEnabled id=34, sessionId=pw-tab-3
← Extension: Page.lifecycleEvent sessionId=pw-tab-1
→ Playwright [ALL]: Page.lifecycleEvent sessionId=pw-tab-1
← Extension: Page.lifecycleEvent sessionId=pw-tab-1
→ Playwright [ALL]: Page.lifecycleEvent sessionId=pw-tab-1
← Extension: Runtime.executionContextCreated sessionId=pw-tab-1
→ Playwright [ALL]: Runtime.executionContextCreated sessionId=pw-tab-1
← Extension: Runtime.executionContextCreated sessionId=pw-tab-1
→ Playwright [ALL]: Runtime.executionContextCreated sessionId=pw-tab-1
← Extension: Runtime.executionContextCreated sessionId=pw-tab-1
→ Playwright [ALL]: Runtime.executionContextCreated sessionId=pw-tab-1
← Extension: Page.lifecycleEvent sessionId=pw-tab-1
→ Playwright [ALL]: Page.lifecycleEvent sessionId=pw-tab-1
← Extension: Page.lifecycleEvent sessionId=pw-tab-2
→ Playwright [ALL]: Page.lifecycleEvent sessionId=pw-tab-2
← Extension: Page.lifecycleEvent sessionId=pw-tab-2
→ Playwright [ALL]: Page.lifecycleEvent sessionId=pw-tab-2
← Extension: Page.lifecycleEvent sessionId=pw-tab-2
→ Playwright [ALL]: Page.lifecycleEvent sessionId=pw-tab-2
← Extension: Page.lifecycleEvent sessionId=pw-tab-2
→ Playwright [ALL]: Page.lifecycleEvent sessionId=pw-tab-2
← Playwright [16E435409CFBF47529751B04E9F9021D]: Emulation.setEmulatedMedia id=35, sessionId=pw-tab-3
← Playwright [16E435409CFBF47529751B04E9F9021D]: Runtime.runIfWaitingForDebugger id=36, sessionId=pw-tab-3
← Playwright [16E435409CFBF47529751B04E9F9021D]: Target.getTargetInfo id=37
← Playwright [16E435409CFBF47529751B04E9F9021D]: Page.createIsolatedWorld id=38, sessionId=pw-tab-1
← Extension: Page.lifecycleEvent sessionId=pw-tab-2
→ Playwright [ALL]: Page.lifecycleEvent sessionId=pw-tab-2
← Extension: Runtime.executionContextCreated sessionId=pw-tab-2
→ Playwright [ALL]: Runtime.executionContextCreated sessionId=pw-tab-2
← Extension: Runtime.executionContextCreated sessionId=pw-tab-2
→ Playwright [ALL]: Runtime.executionContextCreated sessionId=pw-tab-2
← Extension: Runtime.executionContextCreated sessionId=pw-tab-2
→ Playwright [ALL]: Runtime.executionContextCreated sessionId=pw-tab-2
← Extension: Page.lifecycleEvent sessionId=pw-tab-3
→ Playwright [ALL]: Page.lifecycleEvent sessionId=pw-tab-3
← Extension: Runtime.executionContextCreated sessionId=pw-tab-3
→ Playwright [ALL]: Runtime.executionContextCreated sessionId=pw-tab-3
← Extension: Runtime.executionContextCreated sessionId=pw-tab-3
→ Playwright [ALL]: Runtime.executionContextCreated sessionId=pw-tab-3
← Extension: Runtime.executionContextCreated sessionId=pw-tab-3
→ Playwright [ALL]: Runtime.executionContextCreated sessionId=pw-tab-3
← Playwright [16E435409CFBF47529751B04E9F9021D]: Page.createIsolatedWorld id=39, sessionId=pw-tab-2
← Extension: Page.lifecycleEvent sessionId=pw-tab-3
→ Playwright [ALL]: Page.lifecycleEvent sessionId=pw-tab-3
← Extension: Page.lifecycleEvent sessionId=pw-tab-3
→ Playwright [ALL]: Page.lifecycleEvent sessionId=pw-tab-3
← Extension: Page.lifecycleEvent sessionId=pw-tab-3
→ Playwright [ALL]: Page.lifecycleEvent sessionId=pw-tab-3
← Extension: Page.lifecycleEvent sessionId=pw-tab-3
→ Playwright [ALL]: Page.lifecycleEvent sessionId=pw-tab-3
← Extension: Runtime.executionContextCreated sessionId=pw-tab-1
→ Playwright [ALL]: Runtime.executionContextCreated sessionId=pw-tab-1
← Playwright [16E435409CFBF47529751B04E9F9021D]: Page.createIsolatedWorld id=40, sessionId=pw-tab-3
← Extension: Runtime.executionContextCreated sessionId=pw-tab-2
→ Playwright [ALL]: Runtime.executionContextCreated sessionId=pw-tab-2
← Extension: Runtime.executionContextCreated sessionId=pw-tab-3
→ Playwright [ALL]: Runtime.executionContextCreated sessionId=pw-tab-3
← Playwright [E3E15D82C13B4A15D3CF71E44B260036]: Runtime.evaluate id=41, sessionId=pw-tab-1
← Playwright [E3E15D82C13B4A15D3CF71E44B260036]: Runtime.callFunctionOn id=42, sessionId=pw-tab-1
← Playwright [16E435409CFBF47529751B04E9F9021D]: Runtime.evaluate id=41, sessionId=pw-tab-1
← Playwright [16E435409CFBF47529751B04E9F9021D]: Runtime.callFunctionOn id=42, sessionId=pw-tab-1
← Extension: Inspector.detached sessionId=pw-tab-3
→ Playwright [ALL]: Inspector.detached sessionId=pw-tab-3
← Extension: Inspector.detached sessionId=pw-tab-2
→ Playwright [ALL]: Inspector.detached sessionId=pw-tab-2
← Extension: Inspector.detached sessionId=pw-tab-1
→ Playwright [ALL]: Inspector.detached sessionId=pw-tab-1
← Extension: Target.detachedFromTarget targetId=16E435409CFBF47529751B04E9F9021D, sessionId=pw-tab-3
→ Playwright [ALL]: Target.detachedFromTarget targetId=16E435409CFBF47529751B04E9F9021D, sessionId=pw-tab-3
← Extension: Target.detachedFromTarget targetId=E3E15D82C13B4A15D3CF71E44B260036, sessionId=pw-tab-2
→ Playwright [ALL]: Target.detachedFromTarget targetId=E3E15D82C13B4A15D3CF71E44B260036, sessionId=pw-tab-2
← Extension: Target.detachedFromTarget targetId=37BE179F93AF8207BD1E2372B9C515BA, sessionId=pw-tab-1
→ Playwright [ALL]: Target.detachedFromTarget targetId=37BE179F93AF8207BD1E2372B9C515BA, sessionId=pw-tab-1
Extension disconnected
Playwright client disconnected: E3E15D82C13B4A15D3CF71E44B260036 (0 remaining)
Playwright client disconnected: 16E435409CFBF47529751B04E9F9021D (0 remaining)
+44 -33
View File
@@ -45,6 +45,12 @@ async function killProcessOnPort(port: number): Promise<void> {
}
}
declare global {
var toggleExtensionForActiveTab: () => Promise<{ isConnected: boolean; state: any }>;
var getExtensionState: () => { connectedTabs: Map<number, { targetId: string }> };
var chrome: any;
}
describe('MCP Server Tests', () => {
let client: Awaited<ReturnType<typeof createMCPClient>>['client']
let cleanup: (() => Promise<void>) | null = null
@@ -114,7 +120,6 @@ describe('MCP Server Tests', () => {
// Connect the tab
await serviceWorker.evaluate(async () => {
// @ts-ignore
await globalThis.toggleExtensionForActiveTab()
})
@@ -289,7 +294,6 @@ describe('MCP Server Tests', () => {
// 2. Enable extension on this new tab
// Since it's a new page, extension is not connected yet
const result = await serviceWorker.evaluate(async () => {
// @ts-ignore
return await globalThis.toggleExtensionForActiveTab()
})
expect(result.isConnected).toBe(true)
@@ -305,11 +309,10 @@ describe('MCP Server Tests', () => {
expect(foundPage).toBeDefined()
expect(foundPage?.url()).toBe(testUrl)
await directBrowser.close()
// 4. Disable extension on this tab
const resultDisabled = await serviceWorker.evaluate(async () => {
// @ts-ignore
return await globalThis.toggleExtensionForActiveTab()
})
expect(resultDisabled.isConnected).toBe(false)
@@ -325,11 +328,10 @@ describe('MCP Server Tests', () => {
foundPage = pages.find(p => p.url() === testUrl)
expect(foundPage).toBeUndefined()
await directBrowser.close()
// 6. Re-enable extension
const resultEnabled = await serviceWorker.evaluate(async () => {
// @ts-ignore
return await globalThis.toggleExtensionForActiveTab()
})
expect(resultEnabled.isConnected).toBe(true)
@@ -351,7 +353,7 @@ describe('MCP Server Tests', () => {
expect(foundPage).toBeDefined()
expect(foundPage?.url()).toBe(testUrl)
await directBrowser.close()
await page.close()
})
it('should maintain connection across reloads and navigation', async () => {
@@ -366,7 +368,6 @@ describe('MCP Server Tests', () => {
// 2. Enable extension
await serviceWorker.evaluate(async () => {
// @ts-ignore
await globalThis.toggleExtensionForActiveTab()
})
@@ -391,7 +392,7 @@ describe('MCP Server Tests', () => {
expect(connectedPage?.url()).toBe(newUrl)
expect(await connectedPage?.title()).toContain('Hacker News')
await directBrowser.close()
await page.close()
})
@@ -406,7 +407,6 @@ describe('MCP Server Tests', () => {
await pageA.bringToFront()
await new Promise(resolve => setTimeout(resolve, 500))
await serviceWorker.evaluate(async () => {
// @ts-ignore
await globalThis.toggleExtensionForActiveTab()
})
@@ -416,49 +416,60 @@ describe('MCP Server Tests', () => {
await pageB.bringToFront()
await new Promise(resolve => setTimeout(resolve, 500))
await serviceWorker.evaluate(async () => {
// @ts-ignore
await globalThis.toggleExtensionForActiveTab()
})
// Get target IDs for both
const targetIds = await serviceWorker.evaluate(async () => {
// @ts-ignore
const state = globalThis.getExtensionState()
// @ts-ignore
const chrome = globalThis.chrome
const tabs = await chrome.tabs.query({})
const tabA = tabs.find(t => t.url?.includes('tab-a'))
const tabB = tabs.find(t => t.url?.includes('tab-b'))
const tabA = tabs.find((t: any) => t.url?.includes('tab-a'))
const tabB = tabs.find((t: any) => t.url?.includes('tab-b'))
return {
// @ts-ignore
idA: state.connectedTabs.get(tabA?.id)?.targetId,
// @ts-ignore
idB: state.connectedTabs.get(tabB?.id)?.targetId
}
})
expect(targetIds.idA).toBeTruthy()
expect(targetIds.idB).toBeTruthy()
expect(targetIds).toMatchInlineSnapshot({
idA: expect.any(String),
idB: expect.any(String)
}, `
{
"idA": Any<String>,
"idB": Any<String>,
}
`)
expect(targetIds.idA).not.toBe(targetIds.idB)
// Verify independent connections
const browserA = await chromium.connectOverCDP(getCdpUrl({ clientId: targetIds.idA }))
const browserB = await chromium.connectOverCDP(getCdpUrl({ clientId: targetIds.idB }))
const browser = await chromium.connectOverCDP(getCdpUrl())
const titleA = await browserA.contexts()[0].pages()[0].title()
const titleB = await browserB.contexts()[0].pages()[0].title()
const pages = browser.contexts()[0].pages()
// Both are "Example Domain" but we verified they are distinct pages via target ID
expect(titleA).toBe('Example Domain')
expect(titleB).toBe('Example Domain')
const results = await Promise.all(pages.map(async (p) => ({
url: p.url(),
title: await p.title()
})))
// Verify URL to be sure
const urlA = browserA.contexts()[0].pages()[0].url()
const urlB = browserB.contexts()[0].pages()[0].url()
expect(urlA).toContain('tab-a')
expect(urlB).toContain('tab-b')
expect(results).toMatchInlineSnapshot(`
[
{
"title": "",
"url": "about:blank",
},
{
"title": "Example Domain",
"url": "https://example.com/tab-a",
},
{
"title": "Example Domain",
"url": "https://example.com/tab-b",
},
]
`)
await browserA.close()
await browserB.close()
await pageA.close()
await pageB.close()
})
+1 -1
View File
@@ -1,4 +1,4 @@
export function getCdpUrl({ port = 19988, host = '127.0.0.1', clientId }: { port?: number; host?: string; clientId?: string } = {}) {
const id = clientId || Date.now().toString()
const id = clientId || Math.random().toString(36).substring(2, 15)
return `ws://${host}:${port}/cdp/${id}`
}