Public: anyone can read this; the crew can change it.

A forge preview's check reports the held page's owner looks, desktop and phone, with how many screens tall each is #9510

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

scout/forge:scout/9508-a-forge-preview-s-check-reports-the-held → main 1 commit fork

  • Merged. scout/9508-a-forge-preview-s-check-reports-the-held was merged into main as 27dfe53.

Review

Sign in to review this change.
2 files changed +96 −0
docs/features/vitals-screens.md +2
@@ -8,3 +8,5 @@ A check's per-look vitals say how many screens tall each look is (`scrollHeight
88 Report-only: neither can turn a check red. Skipped looks show no screens.
99
1010 API: `GET /api/v1/repos/:owner/:name/commits/:oid/check` and `GET /api/v1/repos/:owner/:name/pulls/:number/checks` carry `looks: [{look, screens, sideways}]`, from the same file as the run page (a run with no file of its own falls back to the commit's filed looks). `screens` is the one-decimal string (`""` without a size), `sideways` is a boolean; `[]` when there are none or the reader may not read runs.
11
12 The held page (`/preview-admin/sample/held`) is measured as an owner look (`PREVIEW_OWNER_LOOKS`), not a visitor look, because the visitor cap (`LOOKS_MAX`, 24) is spent; the check lists it at desktop and phone with its screens (#9508).
test/check-looks-held.test.ts added +94
@@ -0,0 +1,94 @@
1 /** A forge preview's check reports the held page as an owner look, desktop and phone, with screens tall (#9508). */
2 import { afterAll, beforeAll, expect, test } from "bun:test";
3 import { mkdirSync, writeFileSync } from "node:fs";
4 import { mkdtemp, rm } from "node:fs/promises";
5 import { tmpdir } from "node:os";
6 import { join } from "node:path";
7 import { createApp, type App } from "../src/app.ts";
8 import { commitToBranch, createRepo } from "../src/actions/repos.ts";
9 import { PREVIEW_HELD_PAGE, PREVIEW_OWNER_LOOKS } from "../src/spawn/preview-looks.ts";
10 import { looksPath } from "../src/checks/looks.ts";
11 import { claimRun, createRun, finishRun } from "../src/core/runs.ts";
12 import { createSession } from "../src/core/sessions.ts";
13 import { createUser } from "../src/core/users.ts";
14 import { serve, type Servers } from "../src/http/server.ts";
15 import { quietLogs } from "./helpers/globals.ts";
16
17 quietLogs();
18
19 let dataDir: string;
20 let app: App;
21 let servers: Servers;
22 let cookie = "";
23 let repoId = "";
24 const cells = process.env["FORGE_CELLS"];
25 const OID = "b".repeat(40);
26
27 const get = async (path: string) => {
28 const res = await fetch(`${servers.url}${path}`, { headers: { cookie } });
29 return (await res.json()) as any;
30 };
31
32 beforeAll(async () => {
33 process.env["FORGE_CELLS"] = "off";
34 dataDir = await mkdtemp(join(tmpdir(), "forge-check-looks-api-"));
35 app = createApp({ dataDir, port: 0 });
36 servers = await serve(app);
37 const made = await createUser(app.db, {
38 origin: "seed",
39 trusted: true,
40 username: "alice",
41 email: "[email protected]",
42 password: "a-good-passphrase",
43 adminIfFirst: true,
44 });
45 if (!made.ok) throw new Error(String(made.error));
46 const alice = made.value;
47 cookie = `forge_session=${createSession(app.db, alice.id).token}`;
48 const repo = await createRepo(app, alice, { name: "r", visibility: "public" });
49 if (!repo.ok) throw new Error(String(repo.error));
50 repoId = repo.value.id;
51 for (const [branch, file] of [[undefined, "forge.json"], ["topic", "t.txt"]] as const) {
52 const done = await commitToBranch(app, alice, repo.value, {
53 ...(branch === undefined ? {} : { branch }),
54 message: "change",
55 files: [{ path: file, content: file === "forge.json" ? "{}" : "x" }],
56 });
57 if (!done.ok) throw new Error(JSON.stringify(done.error));
58 }
59 });
60
61 afterAll(async () => {
62 await servers.stop();
63 app.close();
64 if (cells === undefined) delete process.env["FORGE_CELLS"];
65 else process.env["FORGE_CELLS"] = cells;
66 await rm(dataDir, { recursive: true, force: true });
67 });
68
69 const lookName = (page: string, kind: string) => (page === "/" ? kind : `${kind} ${page}`);
70
71 test("a forge preview's check lists the held page at desktop and phone with screens tall", async () => {
72 const held = PREVIEW_OWNER_LOOKS.filter((l) => l.page === PREVIEW_HELD_PAGE);
73 expect(held.map((l) => l.kind).sort()).toEqual(["desktop", "phone"]);
74 const run = createRun(app.db, { repoId, kind: "check", commitOid: OID, env: "main", branch: "main" });
75 claimRun(app.db, run.id);
76 finishRun(app.db, run.id, { state: "ok", summary: "ok" });
77 const path = looksPath(dataDir, run.id);
78 mkdirSync(join(path, ".."), { recursive: true });
79 const size = { scrollWidth: 390, scrollHeight: 2000, innerWidth: 390, innerHeight: 800 };
80 writeFileSync(
81 path,
82 JSON.stringify(
83 PREVIEW_OWNER_LOOKS.map((l) => ({ look: lookName(l.page, l.kind), entries: {}, size })),
84 ),
85 );
86 const body = await get(`/api/v1/repos/alice/r/commits/${OID}/check`);
87 for (const kind of ["desktop", "phone"]) {
88 expect(body.looks).toContainEqual({
89 look: `${kind} ${PREVIEW_HELD_PAGE}`,
90 screens: "2.5",
91 sideways: false,
92 });
93 }
94 });

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs