repositories / pi-ext
pi-ext
bugabingas pi extensions
owned by admin
extensions/chrome-cdp/__tests__/settings.test.ts
Rawimport { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import path from "node:path";
import { afterEach, describe, expect, it } from "vitest";
import { createTestSession, type TestSession } from "../../../test/harness";
const extensionPath = path.resolve(import.meta.dirname, "../index.ts");
type Case = {
user?: Record<string, unknown>;
project?: Record<string, unknown>;
flag?: boolean;
untrusted?: boolean;
};
describe("chrome-cdp settings resolution", () => {
let t: TestSession | undefined;
let root: string | undefined;
afterEach(() => {
t?.dispose();
t = undefined;
if (root) rmSync(root, { recursive: true, force: true });
root = undefined;
});
async function start(input: Case) {
root = mkdtempSync(path.join(tmpdir(), "pi-ext-chrome-cdp-settings-"));
const write = (dir: string, value: Record<string, unknown>) => {
mkdirSync(dir, { recursive: true });
writeFileSync(
path.join(dir, "settings.json"),
JSON.stringify({ "chrome-cdp": value }),
);
};
if (input.user) write(path.join(root, ".test-home/.pi/agent"), input.user);
if (input.project) write(path.join(root, ".pi"), input.project);
t = await createTestSession({ cwd: root, extensions: [extensionPath] });
if (input.untrusted) t.session.settingsManager.setProjectTrusted(false);
const runner = t.session.extensionRunner;
if (input.flag !== undefined) runner.setFlagValue("chrome", input.flag);
await runner.emit({ type: "session_start", reason: "startup" });
return t;
}
const warnings = (session: TestSession) => [
...new Set(
session.events
.uiCallsFor("notify")
.filter((call) => call.args[1] === "warning")
.map((call) => String(call.args[0])),
),
];
const active = (session: TestSession) =>
session.session.getActiveToolNames().includes("chrome_cdp");
it("registers --chrome without a default so omission stays distinct", async () => {
const session = await start({});
const runner = session.session.extensionRunner;
expect(active(session)).toBe(false);
expect(runner.getFlags().get("chrome")?.default).toBe(undefined);
expect(runner.getFlagValues().has("chrome")).toBe(false);
});
it.each([
["user true", { user: { enable: true } }, true],
[
"project false over user true",
{ user: { enable: true }, project: { enable: false } },
false,
],
[
"project true over user false",
{ user: { enable: false }, project: { enable: true } },
true,
],
[
"flag over project false",
{ project: { enable: false }, flag: true },
true,
],
[
"untrusted project ignored",
{ user: { enable: true }, project: { enable: false }, untrusted: true },
true,
],
] satisfies [string, Case, boolean][])(
"enable: %s",
async (_name, input, expected) => {
const session = await start(input);
expect(active(session)).toBe(expected);
expect(warnings(session)).toEqual([]);
},
);
it.each([
[
"string project",
{ user: { enable: true }, project: { enable: "true" } },
"project settings",
],
["numeric user", { user: { enable: 1 } }, "user settings"],
] satisfies [string, Case, string][])(
"enable: rejects %s without falling through",
async (_name, input, source) => {
const session = await start(input);
expect(active(session)).toBe(false);
expect(warnings(session)).toEqual([
`Invalid chrome-cdp.enable from ${source}; chrome_cdp off`,
]);
},
);
// findExecutable names the configured path in its warning, exposing the resolved value.
async function toggle(input: Case) {
const session = await start(input);
const runner = session.session.extensionRunner;
await runner.getCommand("chrome")?.handler("", {
...runner.createCommandContext(),
mode: "print" as const,
hasUI: false,
});
return warnings(session);
}
it.each([
[
"user only",
{ user: { executablePath: "/missing/user" } },
"/missing/user",
],
[
"project over user",
{
user: { executablePath: "/missing/user" },
project: { executablePath: "/missing/project" },
},
"/missing/project",
],
[
"untrusted project ignored",
{
user: { executablePath: "/missing/user" },
project: { executablePath: "/missing/project" },
untrusted: true,
},
"/missing/user",
],
] satisfies [string, Case, string][])(
"executablePath: %s",
async (_name, input, expected) => {
expect(await toggle(input)).toEqual([
`Chrome unavailable: Chrome not found; set chrome-cdp.executablePath (checked: ${expected})`,
]);
},
);
it("executablePath: rejects invalid project value without falling through", async () => {
expect(
await toggle({
user: { executablePath: "/missing/user" },
project: { executablePath: 1 },
}),
).toEqual([
"Chrome unavailable: Invalid chrome-cdp.executablePath from project settings",
]);
});
it.each([
["flags", { flags: ["--ok", 1] }],
["profile", { profile: 1 }],
["artifactDir", { artifactDir: [] }],
] satisfies [string, Record<string, unknown>][])(
"%s: invalid value fails the tool before launch",
async (key, project) => {
const session = await start({ project });
const runner = session.session.extensionRunner;
const tool = runner.extensions[0]?.tools.get("chrome_cdp")?.definition;
await expect(
tool?.execute(
"id",
{ operations: [{ kind: "status" }] } as never,
undefined,
undefined,
runner.createCommandContext(),
),
).rejects.toThrow(`Invalid chrome-cdp.${key} from project settings`);
},
);
});