check for ws server every time
This commit is contained in:
+32
-24
@@ -83,7 +83,9 @@ const NO_TABS_ERROR = `No browser tabs are connected. Please install and enable
|
|||||||
|
|
||||||
async function isPortTaken(port: number): Promise<boolean> {
|
async function isPortTaken(port: number): Promise<boolean> {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`http://localhost:${port}/`)
|
const response = await fetch(`http://localhost:${port}/`, {
|
||||||
|
signal: AbortSignal.timeout(500)
|
||||||
|
})
|
||||||
return response.ok
|
return response.ok
|
||||||
} catch {
|
} catch {
|
||||||
return false
|
return false
|
||||||
@@ -94,11 +96,10 @@ async function ensureRelayServer(): Promise<void> {
|
|||||||
const portTaken = await isPortTaken(RELAY_PORT)
|
const portTaken = await isPortTaken(RELAY_PORT)
|
||||||
|
|
||||||
if (portTaken) {
|
if (portTaken) {
|
||||||
console.error('CDP relay server already running')
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
console.error('Starting CDP relay server...')
|
console.error('CDP relay server not running, starting it...')
|
||||||
|
|
||||||
const scriptPath = require.resolve('../dist/start-relay-server.js')
|
const scriptPath = require.resolve('../dist/start-relay-server.js')
|
||||||
|
|
||||||
@@ -109,10 +110,16 @@ async function ensureRelayServer(): Promise<void> {
|
|||||||
|
|
||||||
serverProcess.unref()
|
serverProcess.unref()
|
||||||
|
|
||||||
// wait for extension to connect
|
for (let i = 0; i < 10; i++) {
|
||||||
await new Promise((resolve) => setTimeout(resolve, 1000))
|
await new Promise((resolve) => setTimeout(resolve, 500))
|
||||||
|
const isRunning = await isPortTaken(RELAY_PORT)
|
||||||
|
if (isRunning) {
|
||||||
|
console.error('CDP relay server started successfully')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
console.error('CDP relay server started')
|
throw new Error('Failed to start CDP relay server after 5 seconds')
|
||||||
}
|
}
|
||||||
|
|
||||||
async function ensureConnection(): Promise<{ browser: Browser; page: Page }> {
|
async function ensureConnection(): Promise<{ browser: Browser; page: Page }> {
|
||||||
@@ -138,7 +145,7 @@ async function ensureConnection(): Promise<{ browser: Browser; page: Page }> {
|
|||||||
throw new Error(NO_TABS_ERROR)
|
throw new Error(NO_TABS_ERROR)
|
||||||
}
|
}
|
||||||
const page = pages[0]
|
const page = pages[0]
|
||||||
|
|
||||||
// Set up console listener for all existing pages
|
// Set up console listener for all existing pages
|
||||||
context.pages().forEach(p => setupPageConsoleListener(p))
|
context.pages().forEach(p => setupPageConsoleListener(p))
|
||||||
|
|
||||||
@@ -154,19 +161,19 @@ async function getPageTargetId(page: Page): Promise<string> {
|
|||||||
if (!page) {
|
if (!page) {
|
||||||
throw new Error('Page is null or undefined')
|
throw new Error('Page is null or undefined')
|
||||||
}
|
}
|
||||||
|
|
||||||
// Always use internal _guid for consistency and speed
|
// Always use internal _guid for consistency and speed
|
||||||
const guid = (page as any)._guid
|
const guid = (page as any)._guid
|
||||||
if (guid) {
|
if (guid) {
|
||||||
return guid
|
return guid
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Fallback to CDP if _guid is not available
|
// Fallback to CDP if _guid is not available
|
||||||
const client = await page.context().newCDPSession(page)
|
const client = await page.context().newCDPSession(page)
|
||||||
const { targetInfo } = await client.send('Target.getTargetInfo')
|
const { targetInfo } = await client.send('Target.getTargetInfo')
|
||||||
await client.detach()
|
await client.detach()
|
||||||
|
|
||||||
return targetInfo.targetId
|
return targetInfo.targetId
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw new Error(`Could not get page identifier: ${e}`)
|
throw new Error(`Could not get page identifier: ${e}`)
|
||||||
@@ -176,17 +183,17 @@ async function getPageTargetId(page: Page): Promise<string> {
|
|||||||
function setupPageConsoleListener(page: Page) {
|
function setupPageConsoleListener(page: Page) {
|
||||||
// Get targetId synchronously using _guid
|
// Get targetId synchronously using _guid
|
||||||
const targetId = (page as any)._guid as string | undefined
|
const targetId = (page as any)._guid as string | undefined
|
||||||
|
|
||||||
if (!targetId) {
|
if (!targetId) {
|
||||||
// If no _guid, silently fail - this shouldn't happen in normal operation
|
// If no _guid, silently fail - this shouldn't happen in normal operation
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize logs array for this page
|
// Initialize logs array for this page
|
||||||
if (!browserLogs.has(targetId)) {
|
if (!browserLogs.has(targetId)) {
|
||||||
browserLogs.set(targetId, [])
|
browserLogs.set(targetId, [])
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear logs on navigation/reload
|
// Clear logs on navigation/reload
|
||||||
page.on('framenavigated', (frame) => {
|
page.on('framenavigated', (frame) => {
|
||||||
// Only clear if it's the main frame navigating (page reload/navigation)
|
// Only clear if it's the main frame navigating (page reload/navigation)
|
||||||
@@ -194,21 +201,21 @@ function setupPageConsoleListener(page: Page) {
|
|||||||
browserLogs.set(targetId, [])
|
browserLogs.set(targetId, [])
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// Delete logs when page is closed
|
// Delete logs when page is closed
|
||||||
page.on('close', () => {
|
page.on('close', () => {
|
||||||
browserLogs.delete(targetId)
|
browserLogs.delete(targetId)
|
||||||
})
|
})
|
||||||
|
|
||||||
page.on('console', (msg) => {
|
page.on('console', (msg) => {
|
||||||
const logEntry = `[${msg.type()}] ${msg.text()}`
|
const logEntry = `[${msg.type()}] ${msg.text()}`
|
||||||
|
|
||||||
// Get or create logs array for this page targetId
|
// Get or create logs array for this page targetId
|
||||||
if (!browserLogs.has(targetId)) {
|
if (!browserLogs.has(targetId)) {
|
||||||
browserLogs.set(targetId, [])
|
browserLogs.set(targetId, [])
|
||||||
}
|
}
|
||||||
const pageLogs = browserLogs.get(targetId)!
|
const pageLogs = browserLogs.get(targetId)!
|
||||||
|
|
||||||
pageLogs.push(logEntry)
|
pageLogs.push(logEntry)
|
||||||
if (pageLogs.length > MAX_LOGS_PER_PAGE) {
|
if (pageLogs.length > MAX_LOGS_PER_PAGE) {
|
||||||
pageLogs.shift()
|
pageLogs.shift()
|
||||||
@@ -251,7 +258,7 @@ async function resetConnection(): Promise<{ browser: Browser; page: Page; contex
|
|||||||
state.page = null
|
state.page = null
|
||||||
state.context = null
|
state.context = null
|
||||||
state.isConnected = false
|
state.isConnected = false
|
||||||
|
|
||||||
// DO NOT clear browser logs on reset - logs should persist across reconnections
|
// DO NOT clear browser logs on reset - logs should persist across reconnections
|
||||||
// browserLogs.clear()
|
// browserLogs.clear()
|
||||||
|
|
||||||
@@ -273,7 +280,7 @@ async function resetConnection(): Promise<{ browser: Browser; page: Page; contex
|
|||||||
throw new Error(NO_TABS_ERROR)
|
throw new Error(NO_TABS_ERROR)
|
||||||
}
|
}
|
||||||
const page = pages[0]
|
const page = pages[0]
|
||||||
|
|
||||||
// Set up console listener for all existing pages
|
// Set up console listener for all existing pages
|
||||||
context.pages().forEach(p => setupPageConsoleListener(p))
|
context.pages().forEach(p => setupPageConsoleListener(p))
|
||||||
|
|
||||||
@@ -305,6 +312,7 @@ server.tool(
|
|||||||
timeout: z.number().default(5000).describe('Timeout in milliseconds for code execution (default: 5000ms)'),
|
timeout: z.number().default(5000).describe('Timeout in milliseconds for code execution (default: 5000ms)'),
|
||||||
},
|
},
|
||||||
async ({ code, timeout }) => {
|
async ({ code, timeout }) => {
|
||||||
|
await ensureRelayServer()
|
||||||
await ensureConnection()
|
await ensureConnection()
|
||||||
|
|
||||||
const page = await getCurrentPage(timeout)
|
const page = await getCurrentPage(timeout)
|
||||||
@@ -415,9 +423,9 @@ server.tool(
|
|||||||
searchFilter?: string | RegExp
|
searchFilter?: string | RegExp
|
||||||
}) => {
|
}) => {
|
||||||
const { page: filterPage, count, searchFilter } = options || {}
|
const { page: filterPage, count, searchFilter } = options || {}
|
||||||
|
|
||||||
let allLogs: string[] = []
|
let allLogs: string[] = []
|
||||||
|
|
||||||
// Get logs from specific page or all pages
|
// Get logs from specific page or all pages
|
||||||
if (filterPage) {
|
if (filterPage) {
|
||||||
const targetId = await getPageTargetId(filterPage)
|
const targetId = await getPageTargetId(filterPage)
|
||||||
@@ -429,7 +437,7 @@ server.tool(
|
|||||||
allLogs.push(...pageLogs)
|
allLogs.push(...pageLogs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filter by search string or regex
|
// Filter by search string or regex
|
||||||
if (searchFilter) {
|
if (searchFilter) {
|
||||||
allLogs = allLogs.filter(log => {
|
allLogs = allLogs.filter(log => {
|
||||||
@@ -441,11 +449,11 @@ server.tool(
|
|||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return all logs or limited count
|
// Return all logs or limited count
|
||||||
return count !== undefined ? allLogs.slice(-count) : allLogs
|
return count !== undefined ? allLogs.slice(-count) : allLogs
|
||||||
}
|
}
|
||||||
|
|
||||||
const clearAllLogs = () => {
|
const clearAllLogs = () => {
|
||||||
browserLogs.clear()
|
browserLogs.clear()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user