Files
jackwener__opencli/tests/e2e/helpers.ts
AlexYue 6d1fb6d219 feat(runtime): add Bun runtime compatibility (#459)
* feat(runtime): add runtime detection utility for Bun/Node.js

Add runtime-detect.ts module that detects whether opencli is running
under Bun or Node.js via globalThis.Bun check. Includes helper
functions for version string and label formatting.

Add corresponding unit tests that work correctly under both runtimes.

* feat(runtime): integrate Bun runtime support into CLI tooling

- doctor: show runtime label (e.g. 'node v22.13.0') in diagnostic output
- package.json: add dev:bun, start:bun, test:bun convenience scripts
- E2E helpers: support OPENCLI_TEST_RUNTIME env var for runtime selection

* ci: add Bun compatibility test job and document runtime support

- ci.yml: add bun-test job using oven-sh/setup-bun@v2
- README.md: update Prerequisites to mention Bun, add Runtime Support
  section with usage examples for dev:bun, start:bun, test:bun

* ci: pin Bun version in compatibility job

---------

Co-authored-by: jackwener <jakevingoo@gmail.com>
2026-03-26 19:10:31 +08:00

65 lines
1.7 KiB
TypeScript

/**
* Shared helpers for E2E tests.
* Runs the built opencli binary as a subprocess.
*/
import { execFile } from 'node:child_process';
import { promisify } from 'node:util';
import * as path from 'node:path';
import { fileURLToPath } from 'node:url';
const exec = promisify(execFile);
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const ROOT = path.resolve(__dirname, '../..');
const MAIN = path.join(ROOT, 'dist', 'main.js');
export interface CliResult {
stdout: string;
stderr: string;
code: number;
}
/**
* Run `opencli` as a child process with the given arguments.
* Without PLAYWRIGHT_MCP_EXTENSION_TOKEN, opencli auto-launches its own browser.
*/
export async function runCli(
args: string[],
opts: { timeout?: number; env?: Record<string, string> } = {},
): Promise<CliResult> {
const timeout = opts.timeout ?? 30_000;
try {
const runtime = process.env.OPENCLI_TEST_RUNTIME || 'node';
const { stdout, stderr } = await exec(runtime, [MAIN, ...args], {
cwd: ROOT,
timeout,
env: {
...process.env,
// Prevent chalk colors from polluting test assertions
FORCE_COLOR: '0',
NO_COLOR: '1',
...opts.env,
},
});
return { stdout, stderr, code: 0 };
} catch (err: any) {
return {
stdout: err.stdout ?? '',
stderr: err.stderr ?? '',
code: err.code ?? 1,
};
}
}
/**
* Parse JSON output from a CLI command.
* Throws a descriptive error if parsing fails.
*/
export function parseJsonOutput(stdout: string): any {
try {
return JSON.parse(stdout.trim());
} catch {
throw new Error(`Failed to parse CLI JSON output:\n${stdout.slice(0, 500)}`);
}
}