|
|
import { readFileSync } from "node:fs";
|
|
|
import { join } from "node:path";
|
|
|
import { describe, expect, it } from "vitest";
|
|
|
import {
|
|
|
parseRecordArgs,
|
|
|
resolveOutputBasename,
|
|
|
resolveStoragePath,
|
|
|
shouldEnforceGd15,
|
|
|
} from "@/scripts/record-mothership";
|
|
|
import { isForbiddenQuoteUrl } from "@/lib/rpa/env";
|
|
|
|
|
|
const SCRIPT_PATH = join(process.cwd(), "scripts", "record-mothership.sh");
|
|
|
|
|
|
describe("record-mothership.sh (task-121)", () => {
|
|
|
const content = readFileSync(SCRIPT_PATH, "utf8");
|
|
|
|
|
|
it("存在且包含 headed 与 codegen 启动", () => {
|
|
|
expect(content).toContain("RPA_HEADLESS=false");
|
|
|
expect(content).toContain("playwright");
|
|
|
expect(content).toContain("codegen");
|
|
|
});
|
|
|
|
|
|
it("禁止 GD-15 黑名单 URL", () => {
|
|
|
expect(content).toContain("dashboard.mothership.com");
|
|
|
expect(content).toContain("www.mothership.com/quote");
|
|
|
expect(content).toContain("check_url");
|
|
|
});
|
|
|
|
|
|
it("产出录制脚本与 storageState 路径", () => {
|
|
|
expect(content).toContain(".rpa/recordings");
|
|
|
expect(content).toContain("mothership-storage.json");
|
|
|
expect(content).toContain("--save-storage");
|
|
|
});
|
|
|
});
|
|
|
|
|
|
const TS_SCRIPT_PATH = join(process.cwd(), "scripts", "record-mothership.ts");
|
|
|
|
|
|
describe("record-mothership.ts (Windows 跨平台)", () => {
|
|
|
const content = readFileSync(TS_SCRIPT_PATH, "utf8");
|
|
|
|
|
|
it("存在且包含 headed codegen 与 GD-15 校验", () => {
|
|
|
expect(content).toContain('RPA_HEADLESS: "false"');
|
|
|
expect(content).toContain("playwright");
|
|
|
expect(content).toContain("codegen");
|
|
|
expect(content).toContain("isForbiddenQuoteUrl");
|
|
|
});
|
|
|
|
|
|
it("产出录制脚本与 storageState 路径", () => {
|
|
|
expect(content).toContain(".rpa/recordings");
|
|
|
expect(content).toContain("mothership-storage.json");
|
|
|
expect(content).toContain("--save-storage");
|
|
|
});
|
|
|
|
|
|
it("支持 --logged-in 独立产物前缀与 storage", () => {
|
|
|
expect(content).toContain("--logged-in");
|
|
|
expect(content).toContain("mothership-logged-in-");
|
|
|
expect(content).toContain("mothership-logged-in-storage.json");
|
|
|
});
|
|
|
});
|
|
|
|
|
|
describe("record-mothership parseRecordArgs / GD-15 分模式", () => {
|
|
|
it("默认匿名;--logged-in / --login 切换模式", () => {
|
|
|
expect(parseRecordArgs(["node", "record-mothership.ts"]).mode).toBe(
|
|
|
"anonymous",
|
|
|
);
|
|
|
expect(
|
|
|
parseRecordArgs(["node", "record-mothership.ts", "--logged-in"]).mode,
|
|
|
).toBe("logged-in");
|
|
|
expect(
|
|
|
parseRecordArgs(["node", "record-mothership.ts", "--login"]).mode,
|
|
|
).toBe("logged-in");
|
|
|
});
|
|
|
|
|
|
it("解析起始 URL 与 help", () => {
|
|
|
const withUrl = parseRecordArgs([
|
|
|
"node",
|
|
|
"x",
|
|
|
"--logged-in",
|
|
|
"https://dashboard.mothership.com/",
|
|
|
]);
|
|
|
expect(withUrl.mode).toBe("logged-in");
|
|
|
expect(withUrl.startUrl).toBe("https://dashboard.mothership.com/");
|
|
|
|
|
|
expect(parseRecordArgs(["node", "x", "--help"]).help).toBe(true);
|
|
|
});
|
|
|
|
|
|
it("登录后产物前缀与 storage 路径隔离", () => {
|
|
|
expect(resolveOutputBasename("logged-in", "20260715-120000")).toBe(
|
|
|
"mothership-logged-in-20260715-120000.js",
|
|
|
);
|
|
|
expect(resolveOutputBasename("anonymous", "20260715-120000")).toBe(
|
|
|
"mothership-20260715-120000.js",
|
|
|
);
|
|
|
expect(resolveStoragePath("logged-in").replace(/\\/g, "/")).toMatch(
|
|
|
/mothership-logged-in-storage\.json$/,
|
|
|
);
|
|
|
expect(resolveStoragePath("anonymous").replace(/\\/g, "/")).toMatch(
|
|
|
/mothership-storage\.json$/,
|
|
|
);
|
|
|
});
|
|
|
|
|
|
it("仅匿名模式强制 GD-15;登录后允许 dashboard URL", () => {
|
|
|
expect(shouldEnforceGd15("anonymous")).toBe(true);
|
|
|
expect(shouldEnforceGd15("logged-in")).toBe(false);
|
|
|
const dash = "https://dashboard.mothership.com/quotes/new";
|
|
|
expect(isForbiddenQuoteUrl(dash)).toBe(true);
|
|
|
// 登录模式不执行 GD-15 exit:逻辑门为 shouldEnforceGd15 && isForbidden
|
|
|
expect(shouldEnforceGd15("logged-in") && isForbiddenQuoteUrl(dash)).toBe(
|
|
|
false,
|
|
|
);
|
|
|
expect(shouldEnforceGd15("anonymous") && isForbiddenQuoteUrl(dash)).toBe(
|
|
|
true,
|
|
|
);
|
|
|
});
|
|
|
});
|