Custom Vitest pool that runs tests inside CDP-connected runtimes (Chrome, Photoshop UXP, Electron, and similar environments).
@bubblydoo/vitest-pool-cdp runs Vitest tests in a remote JavaScript runtime by:
Supported by design:
allowOnly / testNamePattern propagationpnpm add -D @bubblydoo/vitest-pool-cdp vitest
// vitest.config.ts
import { defineConfig } from 'vitest/config';
import { cdpPool } from '@bubblydoo/vitest-pool-cdp';
export default defineConfig({
test: {
pool: cdpPool({
cdp: 'ws://localhost:9222/devtools/page/ABC123',
}),
},
});
cdp (required)cdp is the connection source. It supports:
string){ url, teardown }cdp: async () => ({ url: await getUrl(), teardown: async () => stopTarget() })
By default the pool enables auto-attach and runs in the attached target session.
Use executionContextOrSession if you need to explicitly choose:
{ sessionId: string }{ uniqueId: string } (execution context unique id){ id: number } (execution context id)executionContextOrSession: async (cdp) => {
const desc = await waitForExecutionContextCreated(cdp);
return { uniqueId: desc.uniqueId };
}
| Option | Type | Default | Description |
|---|---|---|---|
cdp |
string | (() => Promise<string>) | (() => Promise<{ url: string; teardown: () => Promise<void> }>) |
required | CDP target source |
executionContextOrSession |
(cdp) => Promise<{ sessionId } | { uniqueId } | { id }> |
auto-attach session | Select execution context/session |
debug |
boolean |
false |
Verbose pool logging |
connectionTimeout |
number |
5000 |
CDP connection timeout (ms) |
rpcTimeout |
number |
30000 |
RPC call timeout (ms) |
esbuildOptions |
{ define?, external?, alias?, plugins? } |
undefined |
Extra esbuild config for test bundling |
embedSourcemap |
boolean |
false |
Expose bundled sourcemap as a EVAL_SOURCEMAP variable in target |
enableErrorSourcemapping |
boolean |
true |
Remap stacks/task locations/error frames to original sources |
showBundledStackTrace |
boolean |
false |
Preserve raw bundled stack as error.bundledStack (with remapped stack still shown) |
runBeforeTests |
(cdp) => Promise<void> |
undefined |
Hook run after CDP connection and before test execution |
hotkeys |
{ enabled?: boolean; openDevtools?: (connection) => Promise<void> } |
{ enabled: true, openDevtools: openDevtoolsSessionInChrome } |
Configure terminal hotkeys (d opens the current CDP devtools session in Chrome) |
import { defineConfig } from 'vitest/config';
import { cdpPool } from '@bubblydoo/vitest-pool-cdp';
import { setupDevtoolsUrl } from '@bubblydoo/uxp-devtools-common';
export default defineConfig({
test: {
pool: cdpPool({
cdp: () => setupDevtoolsUrl('./plugin', 'com.example.plugin'),
debug: true,
}),
},
});
┌──────────────────────────────┐ ┌──────────────────────────────┐
│ Vitest process (Node.js) │ │ CDP target runtime │
│ │ │ (Browser / UXP / Electron) │
├──────────────────────────────┤ ├──────────────────────────────┤
│ CdpPoolWorker │ │ Injected worker runtime │
│ │ │ │
│ ┌───────────────┐ │ │ ┌───────────────┐ │
│ │ send() │───────────┼─────────────────►│ │ receive() │ │
│ └───────────────┘ │ Runtime.evaluate │ └───────────────┘ │
│ │ │ │
│ ┌───────────────┐ │ │ ┌───────────────┐ │
│ │ on('msg') │◄──────────┼───────────────── │ │ post() │ │
│ └───────────────┘ │ bindingCalled │ └───────────────┘ │
└──────────────────────────────┘ └──────────────────────────────┘
send() -> receive() uses Runtime.evaluate.
post() -> on('msg') uses Runtime.addBinding / Runtime.bindingCalled.
Runtime.addBinding (not console transport), which avoids conflicts with extra debugger clients.devalue.The worker runtime includes a Chai snapshot plugin built on @vitest/snapshot:
toMatchSnapshottoMatchInlineSnapshottoThrowErrorMatchingSnapshottoThrowErrorMatchingInlineSnapshotexpect.addSnapshotSerializer(...)For packages/vitest-pool-cdp/test development, the Puppeteer launcher opens a local viewer page:
test-viewer/index.htmlWhen running:
pnpm --filter @bubblydoo/vitest-pool-cdp test:chrome
the browser navigates to that page and shows live test results from __vitestUiUpdate / __vitestUiState (summary + per-test status, duration, and file path).
test.setupFiles is currently not implemented for this pool and throws an explicit error.MIT