adding docs
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
# Plan: Add Deterministic Page Waiting to mcp.ts
|
||||
|
||||
## Current Problem
|
||||
|
||||
In `mcp.ts`, both `connect()` and `reconnect()` functions:
|
||||
|
||||
```typescript
|
||||
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:
|
||||
1. Extension has tabs connected, but...
|
||||
2. Playwright hasn't finished processing `Target.attachedToTarget` + `Runtime.executionContextCreated` events
|
||||
|
||||
## Solution
|
||||
|
||||
Use `context.waitForEvent('page')` with a timeout, similar to our test fix.
|
||||
|
||||
## Implementation Plan
|
||||
|
||||
### Step 1: Create a helper function
|
||||
|
||||
```typescript
|
||||
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)
|
||||
|
||||
```typescript
|
||||
// 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:
|
||||
1. First try `waitForPages()` with a short timeout (1-2 seconds)
|
||||
2. If still no pages, request `createInitialTab`
|
||||
3. Then `waitForPages()` again for the new tab
|
||||
|
||||
```typescript
|
||||
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
|
||||
|
||||
1. Run existing tests to ensure no regression
|
||||
2. Add a new test that:
|
||||
- Connects immediately after extension toggle
|
||||
- Verifies pages are available without sleep
|
||||
|
||||
## Files to Modify
|
||||
|
||||
1. `playwriter/src/mcp.ts`:
|
||||
- Add `waitForPages()` helper
|
||||
- Update `connect()` function
|
||||
- Update `reconnect()` function
|
||||
|
||||
## Edge Cases
|
||||
|
||||
1. **All pages are `about:blank`**: May need to filter for real pages
|
||||
2. **Extension not connected**: Existing timeout handling should work
|
||||
3. **Very slow page load**: 5 second timeout should be sufficient for CDP events (actual page content load is not required)
|
||||
Reference in New Issue
Block a user