feat(electrobun): PR1 foundation — package skeletons + native-types wiring#310
Conversation
…iring Bootstrap the Electrobun desktop testing service (ROADMAP Phase 5) as a CDP-attach archetype, cloned from the Electron service pair. This is the Foundation PR of a 4-PR stack (Foundation → MVP → Feature-complete → Ship) that merges into the feat/electrobun-service integration branch. - native-types: add src/electrobun.ts (ElectrobunServiceAPI, options, mock, capabilities as a plain interface, browser extension, window.__WDIO_ELECTROBUN__) and wire the WebdriverIO Browser / MultiRemoteBrowser / Capabilities / ServiceOption augmentation. - @wdio/electrobun-cdp-bridge: skeleton for the multi-target CDP client — constants (DEFAULT_PORT=9222 + the CEF 9222–9232 auto-select range), types (Debugger/Version + PageTarget/TargetClass/TargetRegistryEntry), barrel, README, export-shape test. Connection manager lands in MVP. - @wdio/electrobun-service: skeleton mirroring @wdio/dioxus-service — launcher extends BaseLauncher (handles browser mode; native-mode spawn + CEF port discovery land in MVP), worker service stub, errors (cefRendererRequired / deeplinkUnsupportedOnPlatform), constants, serviceConfig, session-free index, unit tests. - turbo.json: build-graph entries for both new packages. Decision baked in: CDP only works under Electrobun's CEF renderer, so the service requires apps built with defaultRenderer:'cef' on all three OSes; WebKit-default apps are a documented unsupported gap. Verification: typecheck + unit tests green for both packages (bridge 3/3 @100% cov, service 10/10), Biome clean, no regressions to native-types. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Capture the Phase 0 spike results in agent-os/specs (the tracked research-findings convention). A throwaway CEF Electrobun app was built and driven end-to-end on macOS, confirming the CDP-attach + Chromedriver debuggerAddress model is viable. Key results that refine PR2: - Port is PINNABLE — --remote-debugging-port overrides CEF's 9222-9232 scan. - CEF is single-instance per --user-data-dir → parallel workers need distinct user-data-dirs + pinned ports (biggest MVP item). - Each window/view = one CDP page target (no shell); mock seam is Page.addScriptToEvaluateOnNewDocument over window.__electrobun.*. - Chromedriver matches on major 147; deeplink works on macOS via open-url. - Still unverified: Linux CDP (remote_debugging_port commented out) + Windows. - Pin a known-good Electrobun release; 1.18.4-beta.3 ships two build defects. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Greptile SummaryThis PR bootstraps the
Confidence Score: 5/5Safe to merge — all changed code is new skeleton/stub that either returns early or logs a warning; no existing functionality is altered. The only findings are documentation inaccuracies and a mixed-mode mutation concern in new pre-release stub code. No existing packages or behaviour are touched beyond additive type augmentation in native-types. launcher.ts and the remoteDebuggingPort JSDoc in electrobun.ts should both be corrected before the MVP PR builds on them.
|
| Filename | Overview |
|---|---|
| packages/electrobun-service/src/launcher.ts | Browser-mode detection loops over all caps but mutates every cap's browserName regardless of per-cap mode; native mode is a no-op stub with correct port anchoring. |
| packages/native-types/src/electrobun.ts | New Electrobun type surface wired into native-types; remoteDebuggingPort JSDoc slightly mischaracterises the pinning mechanism vs. research findings. |
| packages/electrobun-cdp-bridge/src/constants.ts | Constants and error messages; JSDoc updated from previous review to accurately describe pinning strategy. |
| packages/electrobun-service/src/errors.ts | cefRendererRequired (SevereServiceError) and deeplinkUnsupportedOnPlatform helpers; error messages are clear and platform-aware. |
| packages/electrobun-service/src/serviceConfig.ts | Thin option-merge utility; shallow spread is appropriate since all fields are primitives. |
| packages/electrobun-service/src/constants.ts | Port constants correct — DEFAULT_DEBUG_PORT_BASE=9333 is safely outside CEF's 9222-9232 scan range; REMOTE_DEBUGGING_PORT_ENV comment says 'discovered' inconsistently with the pinning model. |
| packages/native-types/src/index.ts | Electrobun types wired into Browser/MultiRemoteBrowser/Capabilities/ServiceOption augmentation; follows existing Electron/Tauri/Dioxus pattern exactly. |
| turbo.json | Build-graph entries added for both packages; electrobun-service only declares cdp-bridge as a dependency, omitting the native-core/native-types/native-spy chain that service depends on. |
| packages/electrobun-service/src/service.ts | Worker stub; correctly resolves devServerUrl from capability options with global fallback. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[WDIO Runner] -->|onPrepare| B[ElectrobunLaunchService]
B --> C{mode?}
C -->|browser| D[Validate devServerUrl]
D --> E[Set browserName='chrome' on all caps]
E --> F[Return — skip binary/CDP setup]
C -->|native| G[warn: not yet implemented]
G --> H[Return]
A -->|before hook| I[ElectrobunWorkerService]
I --> J[Resolve devServerUrl from cap options or global]
B -.->|extends| L[BaseLauncher native-core]
L --> M[PortManager basePort=9333]
Reviews (3): Last reviewed commit: "docs(electrobun): clarify remoteDebuggin..." | Re-trigger Greptile
- launcher: anchor PortManager ports clear of CEF's [9222, 9232] auto-scan range (baseNativePort was 9223, inside the range). Electrobun is CDP-attach with no native driver, so baseNativePort is nominal — added DEFAULT_DEBUG_PORT_BASE (9333) as the allocation anchor. [P1] - launcher: drop the full JSON.stringify(config/capabilities) debug dumps — the testrunner config can carry reporter tokens / cloud credentials that shouldn't reach debug logs. [P2] - cdp-bridge + service constants: correct the misleading "discovers by scanning rather than dictating" port comments — the launcher pins the port per worker by writing build.json; the 9222-9232 scan is CEF's fallback only. [P1] Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Addressed the Greptile findings in
|
…ot discovered The remoteDebuggingPort JSDoc still described port auto-discovery (a stale model); the launcher allocates + pins a port per worker into the bundle's build.json. Reword so users configuring parallel/multiremote runs aren't misled — each worker gets a distinct auto-allocated, pinned port; this option only forces a fixed one. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…pare Greptile (PR #310 review summary, "mixed-mode mutation"): the launcher applies a single mode to all caps — browser mode forced browserName:'chrome' on every cap (even native ones) if ANY cap was browser-mode. Fail fast with a clear SevereServiceError on a mixed set instead of silently mis-handling a cap, and require a consistent mode. Fixed in the final (feature-complete) launcher. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…pare Greptile (PR #310 review summary, "mixed-mode mutation"): the launcher applies a single mode to all caps — browser mode forced browserName:'chrome' on every cap (even native ones) if ANY cap was browser-mode. Fail fast with a clear SevereServiceError on a mixed set instead of silently mis-handling a cap, and require a consistent mode. Fixed in the final (feature-complete) launcher. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- launcher: anchor PortManager ports clear of CEF's [9222, 9232] auto-scan range (baseNativePort was 9223, inside the range). Electrobun is CDP-attach with no native driver, so baseNativePort is nominal — added DEFAULT_DEBUG_PORT_BASE (9333) as the allocation anchor. [P1] - launcher: drop the full JSON.stringify(config/capabilities) debug dumps — the testrunner config can carry reporter tokens / cloud credentials that shouldn't reach debug logs. [P2] - cdp-bridge + service constants: correct the misleading "discovers by scanning rather than dictating" port comments — the launcher pins the port per worker by writing build.json; the 9222-9232 scan is CEF's fallback only. [P1] Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…pare Greptile (PR #310 review summary, "mixed-mode mutation"): the launcher applies a single mode to all caps — browser mode forced browserName:'chrome' on every cap (even native ones) if ANY cap was browser-mode. Fail fast with a clear SevereServiceError on a mixed set instead of silently mis-handling a cap, and require a consistent mode. Fixed in the final (feature-complete) launcher. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…pare Greptile (PR #310 review summary, "mixed-mode mutation"): the launcher applies a single mode to all caps — browser mode forced browserName:'chrome' on every cap (even native ones) if ANY cap was browser-mode. Fail fast with a clear SevereServiceError on a mixed set instead of silently mis-handling a cap, and require a consistent mode. Fixed in the final (feature-complete) launcher. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- launcher: anchor PortManager ports clear of CEF's [9222, 9232] auto-scan range (baseNativePort was 9223, inside the range). Electrobun is CDP-attach with no native driver, so baseNativePort is nominal — added DEFAULT_DEBUG_PORT_BASE (9333) as the allocation anchor. [P1] - launcher: drop the full JSON.stringify(config/capabilities) debug dumps — the testrunner config can carry reporter tokens / cloud credentials that shouldn't reach debug logs. [P2] - cdp-bridge + service constants: correct the misleading "discovers by scanning rather than dictating" port comments — the launcher pins the port per worker by writing build.json; the 9222-9232 scan is CEF's fallback only. [P1] Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…pare Greptile (PR #310 review summary, "mixed-mode mutation"): the launcher applies a single mode to all caps — browser mode forced browserName:'chrome' on every cap (even native ones) if ANY cap was browser-mode. Fail fast with a clear SevereServiceError on a mixed set instead of silently mis-handling a cap, and require a consistent mode. Fixed in the final (feature-complete) launcher. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
First of a 4-PR stack (Foundation → MVP → Feature-complete → Ship) bootstrapping
@wdio/electrobun-serviceper ROADMAP Phase 5. Targets thefeat/electrobun-serviceintegration branch; subsequent PRs stack on top.Electrobun is a CDP-attach archetype (like Electron, unlike Wry-based Tauri/Dioxus), so this clones the Electron service pair — no Rust, no driver process.
What's in this PR
@wdio/native-types— newsrc/electrobun.ts(ElectrobunServiceAPI, options, mock,ElectrobunCapabilitiesas a plain interface, browser extension,window.__WDIO_ELECTROBUN__); wired into theWebdriverIOBrowser/MultiRemoteBrowser/Capabilities/ServiceOptionaugmentation.@wdio/electrobun-cdp-bridge— skeleton for the multi-target CDP client: constants (DEFAULT_PORT=9222+ the CEF9222–9232range), types (Debugger/Version+PageTarget/TargetClass/TargetRegistryEntry), barrel, README, export-shape test. The connection manager lands in the MVP PR.@wdio/electrobun-service— skeleton mirroring@wdio/dioxus-service: launcher extendsBaseLauncher(handles browser mode; native-mode spawn lands in MVP), worker stub, errors (cefRendererRequired/deeplinkUnsupportedOnPlatform), constants,serviceConfig, unit tests.turbo.json— build-graph entries for both new packages.Key decision baked in
CDP is only available under Electrobun's CEF renderer (the default WebKit webviews on macOS/Linux don't speak CDP), so the service requires apps built with
defaultRenderer: 'cef'on all three OSes; WebKit-default apps are a documented unsupported gap.Phase 0 spike — ✅ GO (macOS validated)
A throwaway CEF app was driven end-to-end (
agent-os/specs/20260528-electrobun-service/RESEARCH_FINDINGS.md): Chromedriver attaches viadebuggerAddress, multiple windows enumerate as separate CDP page targets, attach is observation-only, macOS deeplinks reach the handler. The findings refine the MVP design (port is pinnable; CEF is single-instance per--user-data-dir; Linux CDP still to be validated in CI).Verification
typecheck+ unit tests green for both packages (cdp-bridge 3/3 @ 100% cov, service 10/10)@wdio/native-types🤖 Generated with Claude Code