delete cdp session from cache on page close
This commit is contained in:
@@ -610,12 +610,29 @@ export class PlaywrightExecutor {
|
||||
}
|
||||
|
||||
const getCDPSession = async (options: { page: Page }) => {
|
||||
if (options.page.isClosed()) {
|
||||
throw new Error('Cannot create CDP session for closed page')
|
||||
}
|
||||
|
||||
const cached = this.cdpSessionCache.get(options.page)
|
||||
if (cached) return cached
|
||||
if (cached) {
|
||||
return cached
|
||||
}
|
||||
|
||||
// Generate a fresh unique URL for each CDP session to avoid client ID conflicts
|
||||
const wsUrl = getCdpUrl(this.cdpConfig)
|
||||
const session = await getCDPSessionForPage({ page: options.page, wsUrl })
|
||||
this.cdpSessionCache.set(options.page, session)
|
||||
|
||||
options.page.on('close', () => {
|
||||
const cachedSession = this.cdpSessionCache.get(options.page)
|
||||
if (!cachedSession) {
|
||||
return
|
||||
}
|
||||
this.cdpSessionCache.delete(options.page)
|
||||
cachedSession.close()
|
||||
})
|
||||
|
||||
return session
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import { getCdpUrl } from './utils.js'
|
||||
import { getCDPSessionForPage } from './cdp-session.js'
|
||||
import { Debugger } from './debugger.js'
|
||||
import { Editor } from './editor.js'
|
||||
import { PlaywrightExecutor } from './executor.js'
|
||||
import { setupTestContext, cleanupTestContext, getExtensionServiceWorker, createSseServer, safeCloseCDPBrowser, type TestContext, withTimeout, js } from './test-utils.js'
|
||||
import './test-declarations.js'
|
||||
|
||||
@@ -106,6 +107,53 @@ describe('CDP Session Tests', () => {
|
||||
await page.close()
|
||||
}, 60000)
|
||||
|
||||
it('should reuse cached CDP session and close on page close', async () => {
|
||||
const browserContext = getBrowserContext()
|
||||
const serviceWorker = await getExtensionServiceWorker(browserContext)
|
||||
|
||||
const page = await browserContext.newPage()
|
||||
await page.goto('https://example.com/')
|
||||
await page.bringToFront()
|
||||
|
||||
await serviceWorker.evaluate(async () => {
|
||||
await globalThis.toggleExtensionForActiveTab()
|
||||
})
|
||||
await new Promise(r => setTimeout(r, 100))
|
||||
|
||||
const executor = new PlaywrightExecutor({
|
||||
cdpConfig: { port: TEST_PORT },
|
||||
logger: {
|
||||
log: () => {},
|
||||
error: () => {},
|
||||
},
|
||||
})
|
||||
|
||||
const result = await executor.execute(js`
|
||||
const sessionA = await getCDPSession({ page })
|
||||
const sessionB = await getCDPSession({ page })
|
||||
await sessionA.send('Runtime.evaluate', { expression: '1 + 1', returnByValue: true })
|
||||
const evalResult = await sessionB.send('Runtime.evaluate', { expression: '2 + 2', returnByValue: true })
|
||||
return evalResult.result.value
|
||||
`)
|
||||
|
||||
expect(result.isError).toBe(false)
|
||||
expect(result.text).toContain('[return value] 4')
|
||||
|
||||
await page.close()
|
||||
|
||||
const closeResult = await executor.execute(js`
|
||||
try {
|
||||
const session = await getCDPSession({ page })
|
||||
await session.send('Runtime.evaluate', { expression: '3 + 3', returnByValue: true })
|
||||
return 'unexpected'
|
||||
} catch (e) {
|
||||
return 'closed'
|
||||
}
|
||||
`)
|
||||
expect(closeResult.isError).toBe(false)
|
||||
expect(closeResult.text).toContain('[return value] closed')
|
||||
}, 60000)
|
||||
|
||||
it('should list scripts with Debugger class', async () => {
|
||||
const browserContext = getBrowserContext()
|
||||
const serviceWorker = await getExtensionServiceWorker(browserContext)
|
||||
|
||||
Reference in New Issue
Block a user