40 lines · 1.8 KB · JavaScript
RawDownload
import { mkdirSync, writeFileSync } from "node:fs";import { join, dirname } from "node:path";import { fileURLToPath } from "node:url";import { Recorder } from "./recorder.mjs";import { McpDriver } from "./driver.mjs";export { cookieConsentStrategy } from "../../vendor/mcporter/dist/index.js"; const RUNS = join(dirname(fileURLToPath(import.meta.url)), "..", "runs"); // A target = the per-host seam: which MCP server + how to consent (+ optional boot).export function mcpTarget(cfg) {  return { name: cfg.name ?? "target", server: cfg.server, consent: cfg.consent, boot: cfg.boot };} const tests = [];export function mcpTest(name, target, fn) { tests.push({ name, target, fn }); } const slug = (s) => s.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 60); export async function runTests({ outDir = RUNS } = {}) {  mkdirSync(outDir, { recursive: true });  const results = [];  for (const t of tests) {    // the test name IS the task / opening "user" turn — the MCP surface is a chat    const rec = new Recorder(t.name, { server: t.target.server, brain: "scripted" });    const mcp = new McpDriver(t.target, rec);    let ok = true, error;    try { await t.fn(mcp); }    catch (e) { ok = false; error = e; }    const run = rec.finish(ok, error);    const file = join(outDir, slug(t.name) + ".run.json");    writeFileSync(file, JSON.stringify(run, null, 2));    results.push({ name: t.name, ok: run.ok, file });    console.log(`${run.ok ? "\x1b[32m✓\x1b[0m" : "\x1b[31m✗\x1b[0m"} ${t.name}  →  ${file.replace(process.cwd() + "/", "")}`);    if (!run.ok && run.error) console.log(`    ${run.error}`);  }  const failed = results.filter((r) => !r.ok).length;  console.log(`\n${results.length - failed}/${results.length} passed`);  return { results, failed };}