Fixes#22
CDP's Network.enable buffers response bodies by default, which breaks
SSE/streaming - data arrives at Chrome but ReadableStream never receives it.
Changes:
- Intercept Network.enable in relay, default maxTotalBufferSize: 0
- Agents can re-enable buffering via Network.disable + Network.enable
with explicit buffer sizes when they need response.body()
- Added test and documentation for reading response bodies
Service workers, web workers, and iframes are now filtered out at the
server level, preventing Playwright from trying to initialize these
targets which caused timeouts and errors.
Standard Chrome DevTools Protocol HTTP discovery endpoints that allow
tools like Playwright to connect using just the HTTP URL without needing
to call getCdpUrl() first.
- /json/version returns browser info and webSocketDebuggerUrl
- /json/list returns array of connected targets
- Supports GET/PUT methods and trailing slashes for compatibility
- getAriaSnapshot() discovers aria refs and caches ElementHandles
- showAriaRefLabels() overlays yellow badges on interactive elements
- hideAriaRefLabels() removes labels from page
- test captures screenshots from HN, Google, GitHub
Move auto-create logic from onOpen to Target.setAutoAttach handler so it runs
synchronously in the CDP command flow. Add skipAttachedEvent option to extension's
attachTab to prevent sending Target.attachedToTarget when the relay will send it
via the Target.setAutoAttach response handler.
- Connect WS at extension startup via maintainConnection() loop
- Auto-retry every 5 seconds silently (no connecting badge)
- Never disconnect WS based on tab count
- Rename ConnectionState 'disconnected' to 'idle', remove global 'connecting'
- Fix race condition with tabGroupQueue for syncTabGroup/disconnectEverything/onTabUpdated
- Add auto-create initial tab when Playwright connects (PLAYWRITER_AUTO_ENABLE env var)
- Add test for auto-create feature
- Add bippy library for React fiber introspection
- Create build-bippy.ts and build-selector-generator.ts using Bun.build
- Use CDP Runtime.evaluate instead of addScriptTag to bypass CSP
- Add getReactSource utility function exposed in MCP VMContext
- Works on local React dev servers with JSX transform (not production builds)
Replace arbitrary sleep(200ms) with proper wait for Runtime.executionContextCreated
event in the relay server. This ensures pages are fully ready before Runtime.enable
returns to Playwright, fixing intermittent 'page not found' errors.
## Debugger Tests Summary
### 1. should use Debugger class to set breakpoints and inspect variables
Tests the core debugging workflow when paused at a debugger statement:
- Creates a Debugger instance with a CDP session
- Verifies isPaused() returns false initially
- Executes code with a debugger statement that pauses execution
- Verifies isPaused() returns true when paused
- Calls getLocation() and verifies:
- callstack[0].functionName is 'testFunction'
- sourceContext contains the debugger keyword
- Calls inspectVariables({ scope: 'local' }) and verifies local variables:
{ localVar: "hello", numberVar: 42 }
- Calls evaluate({ expression }) in paused context and verifies it can access local variables
- Calls resume() and verifies isPaused() returns false
### 2. should list scripts with Debugger class
Tests script discovery after page load:
- Navigates to news.ycombinator.com (has external JS files)
- Enables debugger, reloads page to trigger Debugger.scriptParsed events
- Calls listScripts() and verifies:
- Returns array with scriptId and url properties
- At least one script exists
- Calls listScripts({ search: 'hn' }) and verifies filtering works
### 3. should manage breakpoints with Debugger class
Tests breakpoint CRUD operations:
- Verifies listBreakpoints() returns empty array initially
- Calls setBreakpoint({ file, line }) and verifies:
- Returns a breakpoint ID string
- listBreakpoints() now has 1 entry with correct id, file, line
- Calls deleteBreakpoint({ breakpointId }) and verifies:
- listBreakpoints() returns empty array again
### 4. should step through code with Debugger class
Tests stepping methods and call stack navigation:
- Executes nested functions (outer calls inner) with debugger in inner
- When paused, verifies getLocation().callstack:
- Has at least 2 frames
- Frame 0 is inner, frame 1 is outer
- Calls stepOver() and verifies line number advances
- Calls stepOut() and verifies:
- Now in outer function (stepped out of inner)
- Calls resume() to finish