add disconnectEverything function. add new test where playwright sees
existing page tab
This commit is contained in:
@@ -68,6 +68,30 @@ async function toggleExtensionForActiveTab(): Promise<{ isConnected: boolean; st
|
|||||||
return { isConnected, state }
|
return { isConnected, state }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
globalThis.disconnectEverything = disconnectEverything
|
||||||
|
|
||||||
|
async function disconnectEverything() {
|
||||||
|
const { connectedTabs, connection } = useExtensionStore.getState()
|
||||||
|
|
||||||
|
// Disconnect all tabs
|
||||||
|
for (const tabId of connectedTabs.keys()) {
|
||||||
|
await disconnectTab(tabId)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force close connection if it still exists
|
||||||
|
const state = useExtensionStore.getState()
|
||||||
|
if (state.connection) {
|
||||||
|
state.connection.close('Manual full disconnect')
|
||||||
|
useExtensionStore.setState({
|
||||||
|
connection: undefined,
|
||||||
|
connectionState: 'disconnected',
|
||||||
|
connectedTabs: new Map(),
|
||||||
|
errorText: undefined
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
globalThis.getExtensionState = () => useExtensionStore.getState()
|
globalThis.getExtensionState = () => useExtensionStore.getState()
|
||||||
|
|
||||||
@@ -75,6 +99,7 @@ declare global {
|
|||||||
var state: typeof useExtensionStore
|
var state: typeof useExtensionStore
|
||||||
var toggleExtensionForActiveTab: () => Promise<{ isConnected: boolean; state: ExtensionState }>
|
var toggleExtensionForActiveTab: () => Promise<{ isConnected: boolean; state: ExtensionState }>
|
||||||
var getExtensionState: () => ExtensionState
|
var getExtensionState: () => ExtensionState
|
||||||
|
var disconnectEverything: () => Promise<void>
|
||||||
}
|
}
|
||||||
|
|
||||||
async function resetDebugger() {
|
async function resetDebugger() {
|
||||||
|
|||||||
@@ -39,11 +39,11 @@ function js(strings: TemplateStringsArray, ...values: any[]): string {
|
|||||||
async function killProcessOnPort(port: number): Promise<void> {
|
async function killProcessOnPort(port: number): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const { stdout } = await execAsync(`lsof -ti:${port}`)
|
const { stdout } = await execAsync(`lsof -ti:${port}`)
|
||||||
const pid = stdout.trim()
|
const pids = stdout.trim().split('\n').filter(Boolean)
|
||||||
if (pid) {
|
if (pids.length > 0) {
|
||||||
await execAsync(`kill -9 ${pid}`)
|
await execAsync(`kill -9 ${pids.join(' ')}`)
|
||||||
console.log(`Killed process ${pid} on port ${port}`)
|
console.log(`Killed processes ${pids.join(', ')} on port ${port}`)
|
||||||
await new Promise((resolve) => setTimeout(resolve, 500))
|
await new Promise((resolve) => setTimeout(resolve, 1000))
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// No process running on port or already killed
|
// No process running on port or already killed
|
||||||
@@ -53,6 +53,7 @@ async function killProcessOnPort(port: number): Promise<void> {
|
|||||||
declare global {
|
declare global {
|
||||||
var toggleExtensionForActiveTab: () => Promise<{ isConnected: boolean; state: any }>;
|
var toggleExtensionForActiveTab: () => Promise<{ isConnected: boolean; state: any }>;
|
||||||
var getExtensionState: () => { connectedTabs: Map<number, { targetId: string }> };
|
var getExtensionState: () => { connectedTabs: Map<number, { targetId: string }> };
|
||||||
|
var disconnectEverything: () => Promise<void>;
|
||||||
var chrome: any;
|
var chrome: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,6 +117,16 @@ describe('MCP Server Tests', () => {
|
|||||||
// Wait for service worker and connect
|
// Wait for service worker and connect
|
||||||
const serviceWorker = await getExtensionServiceWorker(browserContext)
|
const serviceWorker = await getExtensionServiceWorker(browserContext)
|
||||||
|
|
||||||
|
// Wait for extension to initialize global functions
|
||||||
|
for (let i = 0; i < 50; i++) {
|
||||||
|
const isReady = await serviceWorker.evaluate(() => {
|
||||||
|
// @ts-ignore
|
||||||
|
return typeof globalThis.toggleExtensionForActiveTab === 'function'
|
||||||
|
})
|
||||||
|
if (isReady) break
|
||||||
|
await new Promise(r => setTimeout(r, 100))
|
||||||
|
}
|
||||||
|
|
||||||
// Create a page to attach to
|
// Create a page to attach to
|
||||||
const page = await browserContext.newPage()
|
const page = await browserContext.newPage()
|
||||||
await page.goto('about:blank')
|
await page.goto('about:blank')
|
||||||
@@ -662,6 +673,43 @@ describe('MCP Server Tests', () => {
|
|||||||
await pageB.close()
|
await pageB.close()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should show correct url when enabling extension after navigation', async () => {
|
||||||
|
if (!browserContext) throw new Error('Browser not initialized')
|
||||||
|
const serviceWorker = await getExtensionServiceWorker(browserContext)
|
||||||
|
|
||||||
|
// 1. Ensure clean state (disconnected)
|
||||||
|
await serviceWorker.evaluate(async () => {
|
||||||
|
await globalThis.disconnectEverything()
|
||||||
|
})
|
||||||
|
|
||||||
|
// 2. Open page and navigate
|
||||||
|
const page = await browserContext.newPage()
|
||||||
|
const targetUrl = 'https://example.com/late-enable'
|
||||||
|
await page.goto(targetUrl)
|
||||||
|
await page.bringToFront()
|
||||||
|
|
||||||
|
// Wait for load
|
||||||
|
await page.waitForLoadState('networkidle')
|
||||||
|
|
||||||
|
// 3. Enable extension
|
||||||
|
await serviceWorker.evaluate(async () => {
|
||||||
|
await globalThis.toggleExtensionForActiveTab()
|
||||||
|
})
|
||||||
|
|
||||||
|
// 4. Verify via CDP
|
||||||
|
const browser = await chromium.connectOverCDP(getCdpUrl())
|
||||||
|
// Wait for sync
|
||||||
|
await new Promise(r => setTimeout(r, 1000))
|
||||||
|
|
||||||
|
const cdpPage = browser.contexts()[0].pages().find(p => p.url() === targetUrl)
|
||||||
|
|
||||||
|
expect(cdpPage).toBeDefined()
|
||||||
|
expect(cdpPage?.url()).toBe(targetUrl)
|
||||||
|
|
||||||
|
await browser.close()
|
||||||
|
await page.close()
|
||||||
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user