Fresh history cut from cynarAI/evoo antigravity-handoff/project-timeline (Voice First + project timeline). Brand docs/titles as evOo; keep @rakazo/* packages as tech debt. Excludes node_modules, caches, secrets, voice blobs.
316 lines
10 KiB
TypeScript
316 lines
10 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import {
|
|
buildPlaywrightPrScreenshotComment,
|
|
PLAYWRIGHT_PR_SCREENSHOT_COMMENT_MARKER,
|
|
type PlaywrightPrCommentScreenshot,
|
|
screenshotMatchesSpecStem,
|
|
selectPlaywrightPrFeatureFrames,
|
|
specStemsFromChangedPaths,
|
|
} from "./playwright-pr-screenshot-comment.js";
|
|
|
|
describe("specStemsFromChangedPaths", () => {
|
|
it("extracts Playwright spec stems from changed paths", () => {
|
|
expect(
|
|
specStemsFromChangedPaths([
|
|
"apps/web/e2e/tool-activity-shell.spec.ts",
|
|
"apps/web/src/components/ToolActivity.tsx",
|
|
"apps/web/e2e/tool-activity-disclosure.spec.ts",
|
|
"README.md",
|
|
]),
|
|
).toEqual(["tool-activity-disclosure", "tool-activity-shell"]);
|
|
});
|
|
});
|
|
|
|
describe("screenshotMatchesSpecStem", () => {
|
|
it("matches Playwright output directories that start with the spec stem", () => {
|
|
expect(
|
|
screenshotMatchesSpecStem(
|
|
"tool-activity-shell-produc-bb211-n-in-every-disclosure-state-chromium/shell.png",
|
|
"tool-activity-shell",
|
|
),
|
|
).toBe(true);
|
|
expect(
|
|
screenshotMatchesSpecStem(
|
|
"tool-activity-disclosure-t-f2d47-s-collapsed-until-disclosed-chromium/complete.png",
|
|
"tool-activity-disclosure",
|
|
),
|
|
).toBe(true);
|
|
expect(
|
|
screenshotMatchesSpecStem(
|
|
"onboarding-conversation-fo-bf02c-rves-a-completed-connection-chromium/01.png",
|
|
"tool-activity-shell",
|
|
),
|
|
).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe("selectPlaywrightPrFeatureFrames", () => {
|
|
it("prefers NEW checkpoints over everything else", () => {
|
|
const selection = selectPlaywrightPrFeatureFrames({
|
|
changedPaths: [],
|
|
screenshots: [
|
|
screenshot({
|
|
comparison: "changed",
|
|
fileName: "images/001-onboarding.png",
|
|
source: "onboarding-x/01.png",
|
|
title: "onboarding drift",
|
|
}),
|
|
screenshot({
|
|
comparison: "new",
|
|
fileName: "images/002-shell-live.png",
|
|
source: "tool-activity-shell-x/shell-live.png",
|
|
title: "shell live",
|
|
}),
|
|
],
|
|
});
|
|
|
|
expect(selection).toEqual({
|
|
frames: [
|
|
expect.objectContaining({
|
|
kind: "new",
|
|
title: "shell live",
|
|
}),
|
|
],
|
|
omittedCount: 0,
|
|
});
|
|
});
|
|
|
|
it("includes CHANGED checkpoints only when their spec is in the PR diff", () => {
|
|
const selection = selectPlaywrightPrFeatureFrames({
|
|
changedPaths: ["apps/web/e2e/tool-activity-disclosure.spec.ts"],
|
|
screenshots: [
|
|
screenshot({
|
|
comparison: "changed",
|
|
fileName: "images/001-complete.png",
|
|
source: "tool-activity-disclosure-t-f2d47-chromium/complete.png",
|
|
title: "complete collapsed",
|
|
}),
|
|
screenshot({
|
|
comparison: "changed",
|
|
fileName: "images/002-onboarding.png",
|
|
source: "onboarding-conversation-fo-bf02c-chromium/01.png",
|
|
title: "onboarding",
|
|
}),
|
|
screenshot({
|
|
comparison: "unchanged",
|
|
fileName: "images/003-other.png",
|
|
source: "tool-activity-disclosure-t-f2d47-chromium/other.png",
|
|
title: "other",
|
|
}),
|
|
],
|
|
});
|
|
|
|
expect(selection.frames).toEqual([
|
|
expect.objectContaining({
|
|
kind: "changed",
|
|
title: "complete collapsed",
|
|
}),
|
|
]);
|
|
expect(selection.omittedCount).toBe(0);
|
|
});
|
|
|
|
it("returns an empty selection for suite-vs-main drift only", () => {
|
|
const selection = selectPlaywrightPrFeatureFrames({
|
|
changedPaths: ["apps/web/src/components/ToolActivity.tsx"],
|
|
screenshots: [
|
|
screenshot({
|
|
comparison: "changed",
|
|
fileName: "images/001-onboarding.png",
|
|
source: "onboarding-x/01.png",
|
|
title: "onboarding",
|
|
}),
|
|
screenshot({
|
|
comparison: "changed",
|
|
fileName: "images/002-settings.png",
|
|
source: "settings-x/01.png",
|
|
title: "settings",
|
|
}),
|
|
],
|
|
});
|
|
|
|
expect(selection).toEqual({ frames: [], omittedCount: 0 });
|
|
});
|
|
|
|
it("caps the named list and reports how many were omitted", () => {
|
|
const screenshots = Array.from({ length: 10 }, (_, index) =>
|
|
screenshot({
|
|
comparison: "new",
|
|
fileName: `images/${String(index + 1).padStart(3, "0")}-frame.png`,
|
|
source: `tool-activity-shell-x/frame-${index}.png`,
|
|
title: `frame ${index + 1}`,
|
|
}),
|
|
);
|
|
|
|
const selection = selectPlaywrightPrFeatureFrames({
|
|
changedPaths: ["apps/web/e2e/tool-activity-shell.spec.ts"],
|
|
limit: 8,
|
|
screenshots,
|
|
});
|
|
|
|
expect(selection.frames).toHaveLength(8);
|
|
expect(selection.frames.map((frame) => frame.title)).toEqual([
|
|
"frame 1",
|
|
"frame 2",
|
|
"frame 3",
|
|
"frame 4",
|
|
"frame 5",
|
|
"frame 6",
|
|
"frame 7",
|
|
"frame 8",
|
|
]);
|
|
expect(selection.omittedCount).toBe(2);
|
|
});
|
|
});
|
|
|
|
describe("buildPlaywrightPrScreenshotComment", () => {
|
|
const urls = {
|
|
dashboardUrl: "https://example.com/playwright/index.html",
|
|
galleryUrl: "https://example.com/playwright/prs/452/index.html",
|
|
runUrl: "https://github.com/example/rakazo/actions/runs/1",
|
|
screenshotsUrl: "https://example.com/playwright/runs/1-1/screenshots/index.html",
|
|
sha: "abcdef1234567890",
|
|
};
|
|
|
|
it("names NEW frames with direct PNG links and keeps gallery links secondary", () => {
|
|
const body = buildPlaywrightPrScreenshotComment({
|
|
...urls,
|
|
changedPaths: ["apps/web/e2e/tool-activity-shell.spec.ts"],
|
|
screenshots: [
|
|
screenshot({
|
|
comparison: "new",
|
|
fileName: "images/010-shell-live-collapsed-desktop-1440x900.png",
|
|
source: "tool-activity-shell-x/shell-live-collapsed-desktop-1440x900.png",
|
|
title: "shell live collapsed desktop 1440x900",
|
|
}),
|
|
],
|
|
});
|
|
|
|
expect(body).toContain(PLAYWRIGHT_PR_SCREENSHOT_COMMENT_MARKER);
|
|
expect(body).toContain("### Playwright screenshots");
|
|
expect(body).toContain("Feature frames for this PR:");
|
|
expect(body).toContain(
|
|
"- [shell live collapsed desktop 1440x900](https://example.com/playwright/runs/1-1/screenshots/images/010-shell-live-collapsed-desktop-1440x900.png) (new)",
|
|
);
|
|
expect(body).toContain(
|
|
"[Open screenshot gallery](https://example.com/playwright/prs/452/index.html) · [Dashboard](https://example.com/playwright/index.html) · [CI run](https://github.com/example/rakazo/actions/runs/1)",
|
|
);
|
|
expect(body).toContain("Updated for commit `abcdef1`.");
|
|
expect(body).not.toContain("![");
|
|
expect(body).not.toContain("—");
|
|
});
|
|
|
|
it("includes spec-touched CHANGED frames after NEW frames", () => {
|
|
const body = buildPlaywrightPrScreenshotComment({
|
|
...urls,
|
|
changedPaths: ["apps/web/e2e/tool-activity-disclosure.spec.ts"],
|
|
screenshots: [
|
|
screenshot({
|
|
comparison: "changed",
|
|
fileName: "images/020-complete-collapsed-desktop-1440x900.png",
|
|
source:
|
|
"tool-activity-disclosure-t-f2d47-chromium/complete-collapsed-desktop-1440x900.png",
|
|
title: "complete collapsed desktop 1440x900",
|
|
}),
|
|
screenshot({
|
|
comparison: "new",
|
|
fileName: "images/010-shell-live.png",
|
|
source: "tool-activity-shell-x/shell-live.png",
|
|
title: "shell live",
|
|
}),
|
|
screenshot({
|
|
comparison: "changed",
|
|
fileName: "images/030-onboarding.png",
|
|
source: "onboarding-x/01.png",
|
|
title: "onboarding",
|
|
}),
|
|
],
|
|
});
|
|
|
|
expect(body).toContain(
|
|
"- [shell live](https://example.com/playwright/runs/1-1/screenshots/images/010-shell-live.png) (new)",
|
|
);
|
|
expect(body).toContain(
|
|
"- [complete collapsed desktop 1440x900](https://example.com/playwright/runs/1-1/screenshots/images/020-complete-collapsed-desktop-1440x900.png) (changed)",
|
|
);
|
|
expect(body).not.toContain("onboarding");
|
|
});
|
|
|
|
it("says so in one line when only suite drift remains", () => {
|
|
const body = buildPlaywrightPrScreenshotComment({
|
|
...urls,
|
|
changedPaths: ["apps/web/src/components/ToolActivity.tsx"],
|
|
screenshots: [
|
|
screenshot({
|
|
comparison: "changed",
|
|
fileName: "images/001-onboarding.png",
|
|
source: "onboarding-x/01.png",
|
|
title: "onboarding",
|
|
}),
|
|
],
|
|
});
|
|
|
|
expect(body).toContain("No new feature frames; gallery is suite-vs-main drift.");
|
|
expect(body).not.toContain("Feature frames for this PR:");
|
|
expect(body).not.toContain("onboarding");
|
|
expect(body).toContain("[Open screenshot gallery]");
|
|
});
|
|
|
|
it("caps named frames and points to the gallery for the rest", () => {
|
|
const screenshots = Array.from({ length: 10 }, (_, index) =>
|
|
screenshot({
|
|
comparison: "new",
|
|
fileName: `images/${String(index + 1).padStart(3, "0")}-frame.png`,
|
|
source: `tool-activity-shell-x/frame-${index}.png`,
|
|
title: `frame ${index + 1}`,
|
|
}),
|
|
);
|
|
|
|
const body = buildPlaywrightPrScreenshotComment({
|
|
...urls,
|
|
changedPaths: ["apps/web/e2e/tool-activity-shell.spec.ts"],
|
|
screenshots,
|
|
});
|
|
|
|
expect(body).toContain(
|
|
"- [frame 8](https://example.com/playwright/runs/1-1/screenshots/images/008-frame.png) (new)",
|
|
);
|
|
expect(body).not.toContain("frame 9");
|
|
expect(body).toContain("- +2 more in the gallery");
|
|
});
|
|
|
|
it("neutralizes Markdown and HTML syntax in contributor-controlled titles", () => {
|
|
const body = buildPlaywrightPrScreenshotComment({
|
|
...urls,
|
|
changedPaths: [],
|
|
screenshots: [
|
|
screenshot({
|
|
comparison: "new",
|
|
fileName: "images/010-crafted.png",
|
|
source: "tool-activity-shell-x/crafted.png",
|
|
title: "evil]\n**bold** `code` _em_ #heading [link] <details>&",
|
|
}),
|
|
],
|
|
});
|
|
|
|
expect(body).toContain(
|
|
"- [evil\\] \\*\\*bold\\*\\* \\`code\\` \\_em\\_ \\#heading \\[link\\] <details>&](https://example.com/playwright/runs/1-1/screenshots/images/010-crafted.png) (new)",
|
|
);
|
|
expect(body).not.toContain("\n**bold**");
|
|
expect(body).not.toContain("`code`");
|
|
expect(body).not.toContain("<details>");
|
|
});
|
|
});
|
|
|
|
function screenshot(
|
|
overrides: Partial<PlaywrightPrCommentScreenshot> = {},
|
|
): PlaywrightPrCommentScreenshot {
|
|
return {
|
|
captureType: "checkpoint",
|
|
comparison: "new",
|
|
fileName: "images/001-checkpoint.png",
|
|
source: "golden-chromium/checkpoint.png",
|
|
title: "checkpoint",
|
|
...overrides,
|
|
};
|
|
}
|