test.scripts/core/coordinators/snapshot.coordinator.test.ts
test.scripts/core/coordinators/snapshot.coordinator.test.ts is a file in Codebase Testing. 88 lines of code and 0 definitions.
import { afterEach, describe, expect, it, vi } from "vitest";
import { existsSync, mkdtempSync, readFileSync } from "node:fs";
import { SNAPSHOT_ARGV } from "@project/scripts/configuration/configs/snapshot.config.ts";
import type { SnapshotOptions } from "@project/scripts/types/snapshot.types.ts";
import { argvOf } from "@govlab/argv";
import { capturePage } from "@project/scripts/core/coordinators/snapshot.coordinator.ts";
import { join } from "node:path";
import { launchBrowser } from "@banes-lab/build-scripts/core/factories/browser.factory.ts";
import { logLines } from "@project/scripts/core/formatters/snapshot.formatter.ts";
import { readOptions } from "@project/scripts/core/converters/snapshot.converter.ts";
import { tmpdir } from "node:os";
import { writeArtifacts } from "@project/scripts/core/persistence/snapshot.persistence.ts";
vi.mock("@banes-lab/build-scripts/core/factories/browser.factory.ts", async (importOriginal) => ({
...(await importOriginal<Record<string, unknown>>()),
launchBrowser: vi.fn(() => ({ close: vi.fn<() => Promise<void>>().mockResolvedValue(), exitCode: () => null })),
}));
const scratch = function scratch(): string {
return mkdtempSync(join(tmpdir(), "snapshot-"));
};
const options = function options(overrides: Partial<SnapshotOptions>): SnapshotOptions {
return {
browser: null,
clickAfterMs: 0,
clickAt: null,
height: 1,
log: null,
out: null,
settleMs: 0,
software: true,
timeoutMs: 0,
url: "https://site.test",
width: 1,
...overrides,
};
};
describe("readOptions", () => {
it("refuses a call without a url or without any artifact", () => {
expect(readOptions(argvOf(SNAPSHOT_ARGV, ["--out", "a.png"]))).toBeNull();
expect(readOptions(argvOf(SNAPSHOT_ARGV, ["--url", "https://site.test"]))).toBeNull();
});
it("reads every flag with its default", () => {
const read = readOptions(
argvOf(SNAPSHOT_ARGV, ["--url", "https://site.test", "--log", "c.log", "--click", "3,4"]),
);
expect(read?.clickAt).toStrictEqual([3, 4]);
expect(read?.software).toBe(true);
expect(read?.width).toBe(1440);
});
it("drops a malformed click and honors the gpu flag", () => {
const read = readOptions(argvOf(SNAPSHOT_ARGV, ["--url", "u", "--out", "o.png", "--click", "x", "--gpu"]));
expect(read?.clickAt).toBeNull();
expect(read?.software).toBe(false);
});
});
describe("logLines", () => {
it("tallies repeated records and appends their source", () => {
const record = { level: "error", source: "a.js:1", text: "boom" };
expect(logLines([record, record, { level: "log", source: "", text: "hi" }])).toBe(
"error: boom [x2] (a.js:1)\nlog: hi\n",
);
});
});
describe("writeArtifacts", () => {
it("writes the log and the screenshot", () => {
const directory = scratch();
const out = join(directory, "shot.png");
const log = join(directory, "console.log");
const written = writeArtifacts(options({ log, out }), Buffer.from("png").toString("base64"), []);
expect(written).toBe(true);
expect(readFileSync(out, "utf8")).toBe("png");
expect(existsSync(log)).toBe(true);
});
it("refuses an empty frame when a screenshot was asked for", () => {
const out = join(scratch(), "shot.png");
expect(writeArtifacts(options({ out }), "", [])).toBe(false);
});
});
describe("capturePage", () => {
afterEach(() => {
vi.unstubAllGlobals();
});
it("kills the browser and reports failure when devtools never answers", async () => {
vi.stubGlobal("fetch", vi.fn<typeof fetch>().mockRejectedValue(new Error("refused")));
const out = join(scratch(), "shot.png");
await expect(capturePage("browser", options({ out }))).resolves.toBe(false);
expect(launchBrowser).toHaveBeenCalled();
});
});