Files

141 lines
4.0 KiB
JavaScript

import { spawnSync } from 'node:child_process';
import fs from 'node:fs';
import path from 'node:path';
function parsePositiveInt(value, label) {
const parsed = Number.parseInt(value, 10);
if (!Number.isInteger(parsed) || parsed < 1) {
throw new Error(`${label} must be a positive integer, got '${value}'`);
}
return parsed;
}
function isWSL() {
return process.platform === 'linux' && !!process.env.WSL_DISTRO_NAME;
}
function isDrvFsCwd() {
const cwd = process.cwd();
return cwd.startsWith('/mnt/');
}
function ensureDir(p) {
fs.mkdirSync(p, { recursive: true });
}
function resolvePlaywrightCli() {
const candidates = [
path.join(process.cwd(), 'node_modules', 'playwright', 'cli.js'),
path.join(process.cwd(), 'node_modules', '@playwright', 'test', 'cli.js'),
];
for (const p of candidates) {
if (fs.existsSync(p)) return p;
}
return null;
}
function runPlaywright(args, { label }) {
const cli = resolvePlaywrightCli();
if (!cli) {
console.error(
`[OpenClaw] Failed to run ${label}: Playwright CLI not found. Did you run 'npm ci'?`,
);
process.exit(1);
}
return spawnSync(process.execPath, [cli, ...args], { stdio: 'inherit', env });
}
function ensurePlaywrightBrowsersIfNeeded() {
// In CI, ensure Playwright browsers are installed; otherwise tests fail with exit code 1.
if (!process.env.CI && process.env.OPENCLAW_PLAYWRIGHT_INSTALL !== '1') {
return;
}
// Default to Chromium only (fast + matches CI workflow); allow override.
const browsers = (process.env.OPENCLAW_PLAYWRIGHT_BROWSERS || 'chromium')
.split(',')
.map((s) => s.trim())
.filter(Boolean);
const args = ['install', ...browsers];
if (process.platform === 'linux' && process.env.OPENCLAW_PLAYWRIGHT_WITH_DEPS === '1') {
args.push('--with-deps');
}
const res = runPlaywright(args, { label: 'Playwright install' });
if (res.error) {
console.error('[OpenClaw] Failed to run Playwright install:', res.error);
process.exit(1);
}
if (res.status !== 0) {
console.error(`[OpenClaw] Playwright install failed with exit code ${res.status}`);
process.exit(res.status === undefined || res.status === null ? 1 : res.status);
}
}
const env = { ...process.env };
const rawArgs = process.argv.slice(2);
function hasArg(args, name) {
return args.some((arg) => arg === name || arg.startsWith(`${name}=`));
}
function resolveStressMode(args) {
return args.includes('--stress') || env.OPENCLAW_PLAYWRIGHT_STRESS === '1';
}
function resolveRepeatEach() {
if (!env.OPENCLAW_PLAYWRIGHT_REPEAT_EACH) {
return 5;
}
return parsePositiveInt(env.OPENCLAW_PLAYWRIGHT_REPEAT_EACH, 'OPENCLAW_PLAYWRIGHT_REPEAT_EACH');
}
function resolveStressWorkers() {
if (env.OPENCLAW_PLAYWRIGHT_STRESS_WORKERS) {
return parsePositiveInt(
env.OPENCLAW_PLAYWRIGHT_STRESS_WORKERS,
'OPENCLAW_PLAYWRIGHT_STRESS_WORKERS',
);
}
if (isWSL() && isDrvFsCwd()) {
return 1;
}
return 2;
}
function buildPlaywrightArgs(args) {
const scriptArgs = args.filter((arg) => arg !== '--stress');
const playwrightArgs = ['test'];
const stressMode = resolveStressMode(args);
if (stressMode) {
if (!hasArg(scriptArgs, '--repeat-each')) {
playwrightArgs.push('--repeat-each', String(resolveRepeatEach()));
}
if (!hasArg(scriptArgs, '--workers')) {
playwrightArgs.push('--workers', String(resolveStressWorkers()));
}
if (!hasArg(scriptArgs, '--reporter')) {
playwrightArgs.push('--reporter', env.OPENCLAW_PLAYWRIGHT_STRESS_REPORTER || 'line');
}
}
return [...playwrightArgs, ...scriptArgs];
}
if (isWSL() && isDrvFsCwd()) {
const tmpDir = path.join(process.cwd(), '.tmp', 'playwright');
ensureDir(tmpDir);
env.TMPDIR = tmpDir;
env.TMP = tmpDir;
env.TEMP = tmpDir;
}
ensurePlaywrightBrowsersIfNeeded();
let res = runPlaywright(buildPlaywrightArgs(rawArgs), { label: 'Playwright' });
if (res.error) {
console.error('[OpenClaw] Failed to run Playwright:', res.error);
process.exit(1);
}
process.exit((res.status === undefined || res.status === null) ? 1 : res.status);