make icon green on new pages. add test for it.
This commit is contained in:
@@ -339,6 +339,17 @@ async function ensureConnection(): Promise<void> {
|
|||||||
}
|
}
|
||||||
logger.debug('Removed tab from _connectedTabs map')
|
logger.debug('Removed tab from _connectedTabs map')
|
||||||
},
|
},
|
||||||
|
onTabAttached: (tabId, targetId) => {
|
||||||
|
// logger.debug('=== Tab attached callback for tab:', tabId, '===')
|
||||||
|
useExtensionStore.setState((state) => {
|
||||||
|
const newTabs = new Map(state.connectedTabs)
|
||||||
|
newTabs.set(tabId, {
|
||||||
|
targetId,
|
||||||
|
state: 'connected',
|
||||||
|
})
|
||||||
|
return { connectedTabs: newTabs, connectionState: 'connected' }
|
||||||
|
})
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
useExtensionStore.setState({ connection: newConnection })
|
useExtensionStore.setState({ connection: newConnection })
|
||||||
|
|||||||
@@ -95,15 +95,18 @@ export class RelayConnection {
|
|||||||
private _closed = false;
|
private _closed = false;
|
||||||
private _onCloseCallback?: (reason: string, code: number) => void;
|
private _onCloseCallback?: (reason: string, code: number) => void;
|
||||||
private _onTabDetachedCallback?: (tabId: number, reason: `${chrome.debugger.DetachReason}`) => void
|
private _onTabDetachedCallback?: (tabId: number, reason: `${chrome.debugger.DetachReason}`) => void
|
||||||
|
private _onTabAttachedCallback?: (tabId: number, targetId: string) => void
|
||||||
|
|
||||||
constructor({ ws, onClose, onTabDetached }: {
|
constructor({ ws, onClose, onTabDetached, onTabAttached }: {
|
||||||
ws: WebSocket;
|
ws: WebSocket;
|
||||||
onClose?: (reason: string, code: number) => void;
|
onClose?: (reason: string, code: number) => void;
|
||||||
onTabDetached?: (tabId: number, reason: `${chrome.debugger.DetachReason}`) => void;
|
onTabDetached?: (tabId: number, reason: `${chrome.debugger.DetachReason}`) => void;
|
||||||
|
onTabAttached?: (tabId: number, targetId: string) => void;
|
||||||
}) {
|
}) {
|
||||||
this._ws = ws;
|
this._ws = ws;
|
||||||
this._onCloseCallback = onClose;
|
this._onCloseCallback = onClose;
|
||||||
this._onTabDetachedCallback = onTabDetached;
|
this._onTabDetachedCallback = onTabDetached;
|
||||||
|
this._onTabAttachedCallback = onTabAttached;
|
||||||
this._ws.onmessage = async (event: MessageEvent) => {
|
this._ws.onmessage = async (event: MessageEvent) => {
|
||||||
let message: ExtensionCommandMessage;
|
let message: ExtensionCommandMessage;
|
||||||
try {
|
try {
|
||||||
@@ -208,6 +211,7 @@ export class RelayConnection {
|
|||||||
});
|
});
|
||||||
|
|
||||||
logger.debug('Tab attached successfully:', tabId, 'sessionId:', sessionId, 'targetId:', targetInfo.targetId);
|
logger.debug('Tab attached successfully:', tabId, 'sessionId:', sessionId, 'targetId:', targetInfo.targetId);
|
||||||
|
this._onTabAttachedCallback?.(tabId, targetInfo.targetId);
|
||||||
return targetInfo;
|
return targetInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
"name": "root",
|
"name": "root",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "NODE_ENV=test vitest",
|
"test": "pnpm -r test",
|
||||||
"watch": "pnpm -r watch",
|
"watch": "pnpm -r watch",
|
||||||
"build": "pnpm -r build",
|
"build": "pnpm -r build",
|
||||||
"agents.md": "agentsdotmd ./PLAYWRITER_AGENTS.md core.md typescript.md pnpm.md vitest.md changelog.md docs-writing.md github.md playwright.md zod.md gitchamber.md",
|
"agents.md": "agentsdotmd ./PLAYWRITER_AGENTS.md core.md typescript.md pnpm.md vitest.md changelog.md docs-writing.md github.md playwright.md zod.md gitchamber.md",
|
||||||
|
|||||||
@@ -203,6 +203,55 @@ describe('MCP Server Tests', () => {
|
|||||||
expect(result.content).toBeDefined()
|
expect(result.content).toBeDefined()
|
||||||
}, 30000)
|
}, 30000)
|
||||||
|
|
||||||
|
it('should show extension as connected for pages created via newPage()', async () => {
|
||||||
|
if (!browserContext) throw new Error('Browser not initialized')
|
||||||
|
const serviceWorker = await getExtensionServiceWorker(browserContext)
|
||||||
|
|
||||||
|
// Create a page via MCP (which uses context.newPage())
|
||||||
|
await client.callTool({
|
||||||
|
name: 'execute',
|
||||||
|
arguments: {
|
||||||
|
code: js`
|
||||||
|
const newPage = await context.newPage();
|
||||||
|
state.testPage = newPage;
|
||||||
|
await newPage.goto('https://example.com/mcp-test');
|
||||||
|
return newPage.url();
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
// Get extension state to verify the page is marked as connected
|
||||||
|
const extensionState = await serviceWorker.evaluate(async () => {
|
||||||
|
const state = globalThis.getExtensionState()
|
||||||
|
const chrome = globalThis.chrome
|
||||||
|
const tabs = await chrome.tabs.query({})
|
||||||
|
const testTab = tabs.find((t: any) => t.url?.includes('mcp-test'))
|
||||||
|
return {
|
||||||
|
connected: !!testTab && state.connectedTabs.has(testTab.id),
|
||||||
|
tabId: testTab?.id,
|
||||||
|
tabInfo: testTab ? state.connectedTabs.get(testTab.id) : null,
|
||||||
|
connectionState: state.connectionState
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(extensionState.connected).toBe(true)
|
||||||
|
expect(extensionState.tabInfo?.state).toBe('connected')
|
||||||
|
expect(extensionState.connectionState).toBe('connected')
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
await client.callTool({
|
||||||
|
name: 'execute',
|
||||||
|
arguments: {
|
||||||
|
code: js`
|
||||||
|
if (state.testPage) {
|
||||||
|
await state.testPage.close();
|
||||||
|
delete state.testPage;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}, 30000)
|
||||||
|
|
||||||
it('should get accessibility snapshot of hacker news', async () => {
|
it('should get accessibility snapshot of hacker news', async () => {
|
||||||
await client.callTool({
|
await client.callTool({
|
||||||
name: 'execute',
|
name: 'execute',
|
||||||
|
|||||||
Reference in New Issue
Block a user