| name | electrobun-kitchen-sink |
| description | This skill should be used when the user asks about the "electrobun kitchen sink", "defineTest", "AUTO_RUN mode", "kitchen sink tests", "electrobun test runner", navigating playground windows, or wants to add new electrobun Kitchen Sink test coverage. |
| version | 1.0.0 |
Electrobun Kitchen Sink
The Kitchen Sink is Electrobun's integration test app. It contains automated and interactive tests for every Electrobun API, plus standalone playground windows for manual exploration.
Project Layout
kitchen/
├── scripts/
│ ├── generate-manifest.ts # static parser → feature-manifest.json
│ └── validate-manifest.ts # consistency checks
├── src/
│ ├── bun/index.ts # Electrobun bun-side entrypoint
│ ├── generated/
│ │ ├── manifest-types.ts # TypeScript types for the manifest
│ │ └── feature-manifest.json # generated feature index
│ ├── test-framework/ # test executor & result types
│ ├── test-runner/ # test runner UI (views://test-runner/)
│ ├── test-harness/ # webview used by automated tests
│ ├── tests/
│ │ ├── index.ts # aggregates all suites
│ │ ├── *.test.ts # automated test suites
│ │ └── interactive/ # interactive test suites
│ └── playgrounds/ # standalone feature demo windows
└── electrobun.config.ts
Running the Kitchen Sink
cd kitchen && bun install
electrobun dev
electrobun dev --watch
AUTO_RUN=1 electrobun dev
AUTO_RUN_TEST_NAME="Window creation with URL" electrobun dev
Exit codes: 0 = all pass, 1 = any failure.
Feature Manifest
Generated at kitchen/src/generated/feature-manifest.json. Each entry:
{
"id": "window-creation-with-url",
"title": "Window creation with URL",
"category": "BrowserWindow",
"description": "Test creating a window with a URL",
"interactive": false,
"testFile": "src/tests/window.test.ts",
"playgroundRoute": null,
"apiSurface": ["BrowserWindow"],
"uiSelectors": [],
"platformCaveats": []
}
Regenerate / Validate
cd kitchen
npx tsx scripts/generate-manifest.ts
npx tsx scripts/validate-manifest.ts
Generator does static analysis only — no Electrobun runtime required.
Test Suites
Automated (run unattended)
| Suite | Key APIs |
|---|
| RPC | BrowserView.defineRPC, Electroview.defineRPC |
| BrowserWindow | new BrowserWindow, all lifecycle methods |
| Navigation | setNavigationRules, will-navigate, did-navigate |
| Utils | clipboard, paths, openFileDialog, showNotification |
| Screen | getPrimaryDisplay, getAllDisplays, getCursorScreenPoint |
| Session | Session.fromPartition, cookies |
| Events | Electrobun.events.on (all global events) |
| Preload | preload script injection |
| Updater | checkForUpdate, downloadUpdate, applyUpdate |
| Sandbox | sandbox: true isolation |
| Tray | new Tray, setMenu, tray-clicked |
| WGPU FFI | WGPUBridge low-level FFI |
| WGPU Adapter | GpuWindow, WGPUView adapter layer |
| Babylon Adapter | BabylonJS WebGPU integration |
| WGPU Adapter Extended | extended WGPU surface coverage |
Interactive (require human)
| Suite | Feature area |
|---|
| Dialogs | openFileDialog, showMessageBox |
| Tray | Tray visibility, icon, menu |
| Shortcuts | GlobalShortcut register/unregister |
| Webview Tag | <electrobun-webview> masks, passthrough, navigation |
| Clipboard | clipboardRead/WriteText/Image |
| Menus | ApplicationMenu, ContextMenu |
| Window Events | move, resize, blur, focus events |
| Chromeless | titleBarStyle: hidden, draggable regions |
| Multiwindow CEF | CEF renderer multi-window |
| Quit test | before-quit lifecycle |
| Webview settings | renderer options, sandbox |
| Webview cleanup | view lifecycle and removal |
| WGPU View | WGPUView interactive |
| WGPU Tag | <wgpu-view> HTML tag |
| Fullsize frame repro | window frame edge cases |
Test Runner UI — CSS Selectors
Main window: views://test-runner/index.html
Controls
| Selector | Action |
|---|
#btn-run-all | runAllAutomated() — runs all non-interactive tests |
#btn-run-interactive | runInteractiveTests() |
.run-btn[data-test-id] | runTest({ testId }) — run one test |
#test-search | Fuzzy filter by name/category/description |
#update-btn | applyUpdate() |
#update-history-toggle | Toggle update status history panel |
#update-history-clear | clearUpdateStatusHistory() |
Status elements
| Selector | Shows |
|---|
#total-count | Total test count |
#passed-count | Passed |
#failed-count | Failed |
#pending-count | Pending/not-run |
#test-list | Category groups + test cards |
#search-meta | Total or filtered count |
Interactive modal
| Selector | Purpose |
|---|
#interactive-modal | Modal container |
#modal-title | Test name |
#modal-instructions | Instructions text |
#btn-start | submitReady({ testId }) |
#btn-pass | submitVerification({ testId, action: 'pass' }) |
#btn-fail | submitVerification({ testId, action: 'fail' }) |
#btn-retest | submitVerification({ testId, action: 'retest' }) |
#notes-input | Optional notes |
Bun↔UI RPC Contract
Requests (bun exposes to UI)
getTests() → test list
runTest({ testId }) → run one test
runAllAutomated() → run all automated
runInteractiveTests() → start interactive sequence
submitInteractiveResult({ testId, passed, notes }) → submit result
submitReady({ testId }) → signal ready for interactive step
submitVerification({ testId, action, notes }) → pass/fail/retest
applyUpdate() → apply downloaded update
getUpdateStatusHistory() / clearUpdateStatusHistory()
getTestRunnerPreferences() / setTestRunnerPreferences({ searchQuery })
Messages (bun sends to UI)
testStarted — test execution began
testCompleted — result with pass/fail/duration
testLog — log line
allCompleted — all tests done
interactiveWaiting — waiting for user to click Start
interactiveReady — user ready, perform the action
interactiveVerify — show pass/fail/retest controls
buildConfig — app metadata
updateStatus / updateStatusEntry — updater state
Interactive Test Flow (Two-Step)
1. User clicks Open on an interactive test
2. Runner shows modal: instructions + #btn-start
3. User reads instructions, clicks Start → submitReady()
4. A secondary playground window opens (bun-side)
5. User performs the described action in that window
6. Modal shows: #btn-pass, #btn-fail, #btn-retest
7. User marks result → submitVerification()
8. Modal closes, result recorded
Consuming the Manifest (agent usage)
cat kitchen/src/generated/feature-manifest.json
jq '[.[] | select(.interactive == false)]' feature-manifest.json
jq '[.[] | select(.apiSurface | contains(["BrowserWindow"]))]' feature-manifest.json
jq '.[] | select(.id == "window-creation-with-url") | .testFile' feature-manifest.json
Playground Windows
Each interactive suite opens a dedicated playground window. Key ones:
| Playground | URL | Key Controls |
|---|
| File dialog | views://playgrounds/file-dialog/ | #openDialogBtn, #result, #history |
| App menu | views://playgrounds/application-menu/ | Sets app menu via RPC |
| Context menu | views://playgrounds/context-menu/ | Shows context menu via RPC |
| Webview tag | views://playgrounds/webviewtag/ | masks, passthrough, navigation |
| Session/partition | views://playgrounds/session/ | Compares cross-partition localStorage |
| Window events | views://playgrounds/window-events-*/ | move/resize/blur/focus detection |
| Clipboard | views://playgrounds/clipboard/ | read/write text and image |
| Tray | views://playgrounds/tray/ | tray icon and menu |
Platform Caveats in Tests
- Zoom: exact zoom level only verified on macOS; defaults to
1.0 on other platforms
- Minimize/unminimize: marked unreliable on some Linux window managers
- Session cookies: some tests commented out due to ARM Windows VM crashes
- Application menus: intentionally skipped on Linux in interactive tests
- Context menus: marked macOS-only in interactive tests
- CEF devtools: only available in
dev builds, at http://localhost:9222