2.9 KiB
2.9 KiB
Plan: Add Deterministic Page Waiting to mcp.ts
Current Problem
In mcp.ts, both connect() and reconnect() functions:
const browser = await chromium.connectOverCDP(cdpEndpoint)
const context = contexts[0]
const pages = context.pages() // May be empty!
if (pages.length === 0) {
throw new Error(NO_TABS_ERROR)
}
This fails when:
- Extension has tabs connected, but...
- Playwright hasn't finished processing
Target.attachedToTarget+Runtime.executionContextCreatedevents
Solution
Use context.waitForEvent('page') with a timeout, similar to our test fix.
Implementation Plan
Step 1: Create a helper function
async function waitForPages(context: BrowserContext, options?: {
timeout?: number
minPages?: number
}): Promise<Page[]> {
const { timeout = 5000, minPages = 1 } = options || {}
// Check if pages already exist
let pages = context.pages()
if (pages.length >= minPages) {
return pages
}
// Wait for page events
const startTime = Date.now()
while (pages.length < minPages && Date.now() - startTime < timeout) {
try {
await context.waitForEvent('page', { timeout: timeout - (Date.now() - startTime) })
pages = context.pages()
} catch {
// Timeout - check one more time
pages = context.pages()
break
}
}
return pages
}
Step 2: Update connect() function (line ~305)
// Before:
const pages = context.pages()
if (pages.length === 0) {
throw new Error(NO_TABS_ERROR)
}
// After:
const pages = await waitForPages(context, { timeout: 5000 })
if (pages.length === 0) {
throw new Error(NO_TABS_ERROR)
}
Step 3: Update reconnect() function (line ~448)
Same change as above.
Step 4: Consider the "createInitialTab" flow
The relay server has a createInitialTab message for when no tabs exist. We should:
- First try
waitForPages()with a short timeout (1-2 seconds) - If still no pages, request
createInitialTab - Then
waitForPages()again for the new tab
let pages = await waitForPages(context, { timeout: 2000 })
if (pages.length === 0) {
// No tabs - request extension to create one
await requestCreateInitialTab()
pages = await waitForPages(context, { timeout: 5000 })
}
if (pages.length === 0) {
throw new Error(NO_TABS_ERROR)
}
Testing
- Run existing tests to ensure no regression
- Add a new test that:
- Connects immediately after extension toggle
- Verifies pages are available without sleep
Files to Modify
playwriter/src/mcp.ts:- Add
waitForPages()helper - Update
connect()function - Update
reconnect()function
- Add
Edge Cases
- All pages are
about:blank: May need to filter for real pages - Extension not connected: Existing timeout handling should work
- Very slow page load: 5 second timeout should be sufficient for CDP events (actual page content load is not required)