release: WRNexusJS 0.8.0
Quality / quality (ubuntu-latest) (push) Failing after 21s
Quality / quality (windows-latest) (push) Canceled after 0s

This commit is contained in:
2026-08-02 23:18:51 +05:30
parent 87507edf59
commit 586a6db8ff
625 changed files with 243608 additions and 11210 deletions
+157 -24
View File
@@ -1,26 +1,159 @@
/**
* `wrnexus test [app-dir] [--watch] [--profile=test]` — run the app's test files
* with `bun test`. Defaults to the `test` profile (config + .env.test). Extra
* args after `--` (or bun test flags) pass straight through.
*/
/** Level-aware `wrnexus test` runner with Bun and optional Playwright backends. */
import { existsSync, readdirSync, readFileSync } from "node:fs";
import { spawn, type ChildProcess } from "node:child_process";
import { join, relative, resolve } from "node:path";
import { spawn } from "node:child_process";
import { resolve } from "node:path";
export function runTests(appRoot: string, args: string[]): void {
const root = resolve(appRoot);
const watch = args.includes("--watch");
const passthrough = args.filter(
(a) => !a.startsWith("--profile=") && a !== "--watch" && a !== appRoot,
);
const child = spawn(
process.execPath, // the Bun binary
["test", ...(watch ? ["--watch"] : []), ...passthrough],
{ stdio: "inherit", cwd: root },
);
child.on("exit", (code, signal) => {
if (signal) return;
process.exit(code ?? 0);
});
export const TEST_LEVELS = [
"unit",
"component",
"api",
"browser",
"visual",
"accessibility",
"performance",
] as const;
export type TestLevel = (typeof TEST_LEVELS)[number];
export interface TestCommandPlan {
command: string;
args: string[];
cwd: string;
level?: TestLevel;
files: string[];
setup?: { command: string; args: string[] };
}
function shardFiles(files: string[], value?: string): string[] {
if (!value) return files;
const match = /^(\d+)\/(\d+)$/.exec(value);
if (!match) throw new Error("WRN-TEST-SHARD: expected --shard=<index>/<total>");
const index = Number(match[1]);
const total = Number(match[2]);
if (index < 1 || total < 1 || index > total)
throw new Error("WRN-TEST-SHARD: index must be between 1 and total");
return files.filter((_file, position) => position % total === index - 1);
}
function testFiles(root: string): string[] {
const files: string[] = [];
const walk = (directory: string): void => {
if (!existsSync(directory)) return;
for (const entry of readdirSync(directory, { withFileTypes: true })) {
if (["node_modules", "dist", ".wrnexus", "coverage"].includes(entry.name)) continue;
const path = join(directory, entry.name);
if (entry.isDirectory()) walk(path);
else if (/\.(?:test|spec)\.[cm]?[jt]sx?$/i.test(entry.name)) files.push(path);
}
};
for (const directory of ["app", "test", "tests"]) walk(join(root, directory));
return files.sort();
}
function hasPlaywright(root: string): boolean {
if (
["playwright.config.ts", "playwright.config.js", "playwright.config.mjs"].some((file) =>
existsSync(join(root, file)),
)
)
return true;
try {
const manifest = JSON.parse(readFileSync(join(root, "package.json"), "utf8"));
return Boolean(
manifest.dependencies?.["@playwright/test"] || manifest.devDependencies?.["@playwright/test"],
);
} catch {
return false;
}
}
export function createTestPlan(appRoot: string, args: string[]): TestCommandPlan {
const root = resolve(appRoot);
const level = args.find((value): value is TestLevel => TEST_LEVELS.includes(value as TestLevel));
const watch = args.includes("--watch");
const shard = args.find((value) => value.startsWith("--shard="))?.slice(8);
const browsers = (args.find((value) => value.startsWith("--browsers="))?.slice(11) ?? "chromium")
.split(",")
.filter(Boolean);
const passthrough = args.filter(
(value) =>
!value.startsWith("--profile=") &&
value !== "--watch" &&
value !== appRoot &&
value !== level &&
!value.startsWith("--browsers=") &&
!value.startsWith("--shard=") &&
value !== "--install-browsers",
);
if ((level === "browser" || level === "visual") && hasPlaywright(root)) {
return {
command: process.execPath,
args: [
"x",
"playwright",
"test",
...(level === "visual" ? ["--grep", "@visual"] : []),
...browsers.flatMap((browser) => ["--project", browser]),
...(shard ? [`--shard=${shard}`] : []),
"--reporter=line,html",
...passthrough,
],
cwd: root,
level,
files: [],
...(args.includes("--install-browsers")
? {
setup: { command: process.execPath, args: ["x", "playwright", "install", ...browsers] },
}
: {}),
};
}
const pattern =
level === "accessibility"
? /(?:accessibility|a11y)/i
: level === "performance"
? /(?:performance|benchmark)/i
: level
? new RegExp(level, "i")
: null;
const files = shardFiles(
pattern ? testFiles(root).filter((file) => pattern.test(relative(root, file))) : [],
shard,
);
return {
command: process.execPath,
args: ["test", ...(watch ? ["--watch"] : []), ...(pattern ? files : []), ...passthrough],
cwd: root,
level,
files,
};
}
export function runTests(appRoot: string, args: string[]): ChildProcess | null {
const plan = createTestPlan(appRoot, args);
if (plan.level && !plan.files.length && !plan.args.includes("playwright")) {
console.error(
`WRN-TEST-NO-FILES: no ${plan.level} tests found. Name a file or directory with '${plan.level}' under app/, test/, or tests/.`,
);
process.exitCode = 1;
return null;
}
const launch = () => spawn(plan.command, plan.args, { stdio: "inherit", cwd: plan.cwd });
if (plan.setup) {
const setup = spawn(plan.setup.command, plan.setup.args, { stdio: "inherit", cwd: plan.cwd });
setup.on("exit", (code, signal) => {
if (signal || code !== 0) {
process.exitCode = code ?? 1;
return;
}
const test = launch();
test.on("exit", (testCode, testSignal) => {
if (!testSignal) process.exitCode = testCode ?? 0;
});
});
return setup;
}
const child = launch();
child.on("exit", (code, signal) => {
if (!signal) process.exitCode = code ?? 0;
});
return child;
}