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

The forge toolbar names the environment in one word (production, preview of pull N) and links to the pull #11438

Merged opened this

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

Merged

scout/forge:scout/11434-the-forge-toolbar-names-the-environment → main 3 commits fork 1 thread · 1 unresolved

  • Merged. scout/11434-the-forge-toolbar-names-the-environment was merged into main as 480d1f8.

Review

Sign in to review this change.
6 files changed +19 −15
src/apps/toolbar.ts +3 −3
@@ -86,7 +86,7 @@ const toolbarSource = `(function () {
8686 panel.appendChild(el);
8787 }
8888 if (d.app) line(d.app, true);
89 if (d.env === "production") line("Production");
89 if (d.env === "production") line("production");
9090 var LS = "color:#8ab4ff;text-decoration:none;display:flex;align-items:center;min-height:44px";
9191 var pullHref = "";
9292 // The pull this preview shows, one tap away: built from the script's own origin, never from page text.
@@ -96,12 +96,12 @@ const toolbarSource = `(function () {
9696 if (d.env === "production") {}
9797 else if (pullHref) {
9898 var pl = document.createElement("a");
99 pl.textContent = "Preview of pull #" + d.pull;
99 pl.textContent = "preview \\u00b7 #" + d.pull;
100100 pl.href = pullHref;
101101 pl.rel = "noopener";
102102 pl.style.cssText = LS;
103103 panel.appendChild(pl);
104 } else if (d.pull) line("Preview of pull #" + d.pull);
104 } else if (d.pull) line("preview \\u00b7 #" + d.pull);
105105 if (d.title) line(d.title);
106106 var CW = ${JSON.stringify(CHECK_WORDS)};
107107 if (d.env !== "production" && d.check && Object.prototype.hasOwnProperty.call(CW, d.check)) line(CW[d.check]);
test/apps-pill-check.test.ts +1 −1
@@ -92,7 +92,7 @@ describe("the pill's check line", () => {
9292 // Production, even handed a check, names the app and says no check.
9393 const prod = drawn({ app: "notes", env: "production", check: "passed" });
9494 expect(prod).toContain("notes");
95 expect(prod).toContain("Production");
95 expect(prod).toContain("production");
9696 expect(prod.some((t) => /^(Checks|No checks)/.test(t))).toBe(false);
9797 });
9898
test/apps-pill-freshness.test.ts +3 −3
@@ -269,14 +269,14 @@ describe("the pill's script draws the freshness line", () => {
269269 ];
270270 for (const [extra, said] of cases) {
271271 const lines = panelLines({ ...base, ...extra });
272 expect(lines.slice(0, 4)).toEqual(["site", "Preview of pull #7", "Add a thing", said]);
272 expect(lines.slice(0, 4)).toEqual(["site", "preview \u00b7 #7", "Add a thing", said]);
273273 expect(lines.filter((l) => words.includes(l as never))).toEqual([said]);
274274 }
275275 });
276276
277277 test("the line follows the pull when there is no title", () => {
278278 const lines = panelLines({ ...base, title: "", state: "merged" });
279 expect(lines.slice(0, 3)).toEqual(["site", "Preview of pull #7", FRESHNESS_WORDS.merged]);
279 expect(lines.slice(0, 3)).toEqual(["site", "preview \u00b7 #7", FRESHNESS_WORDS.merged]);
280280 });
281281
282282 test("merged and closed win over deploying and behind; deploying wins over behind", () => {
@@ -290,7 +290,7 @@ describe("the pill's script draws the freshness line", () => {
290290 expect(panelLines({ ...base, state: "open" }).filter((l) => words.includes(l as never))).toEqual([]);
291291 expect(panelLines({ ...base }).filter((l) => words.includes(l as never))).toEqual([]);
292292 const prod = panelLines({ app: "site", repo: "alice/site", env: "production" });
293 expect(prod.slice(0, 2)).toEqual(["site", "Production"]);
293 expect(prod.slice(0, 2)).toEqual(["site", "production"]);
294294 expect(prod.filter((l) => words.includes(l as never))).toEqual([]);
295295 });
296296 });
test/apps-toolbar.test.ts +7 −3
@@ -476,15 +476,19 @@ describe("the pill's keyboard and touch behaviour", () => {
476476
477477
478478 test("on a preview with a repo the pull line links to the pull; otherwise it is plain text", () => {
479 const a = tree({ app: "notes", repo: "alice/notes", pull: "12" }).lines.find((l) => l.textContent === "Preview of pull #12")!;
479 const a = tree({ app: "notes", repo: "alice/notes", pull: "12" }).lines.find((l) => l.textContent === "preview \u00b7 #12")!;
480480 expect(a.tag).toBe("a");
481481 expect(a.href).toBe("https://forge.test/alice/notes/pulls/12");
482482 expect(a.style.cssText).toContain("min-height:44px");
483483 const prod = tree({ app: "notes", repo: "alice/notes", env: "production", pull: "12" });
484 expect(prod.lines.some((l) => l.textContent.includes("Preview"))).toBe(false);
484 expect(prod.lines.some((l) => l.textContent.startsWith("preview \u00b7"))).toBe(false);
outdated

Now vacuous: the drawn text is lowercase "preview", so includes("Preview") is always false. Assert on "preview \u00b7" so this fails if production draws the pull line.

485 expect(prod.lines.some((l) => l.textContent === "production")).toBe(true);
486 // An unknown environment with no pull draws no environment line at all.
487 const unknown = tree({ app: "notes", repo: "alice/notes", env: "staging" });
488 expect(unknown.lines.some((l) => l.textContent === "production" || l.textContent.startsWith("preview"))).toBe(false);
485489 for (const bad of [{ pull: "12x" }, { pull: "../1" }, { pull: "1234567890" }, { repo: "" }]) {
486490 const t = tree({ app: "notes", repo: "alice/notes", pull: "12", ...bad });
487 const l = t.lines.find((x) => x.textContent.startsWith("Preview of pull"))!;
491 const l = t.lines.find((x) => x.textContent.startsWith("preview \u00b7"))!;
488492 expect(l.tag === "a").toBe(false);
489493 }
490494 });
test/lost-journey.test.ts +4 −4
@@ -229,7 +229,7 @@ describe("lost journey: where you are and three exits", () => {
229229 expect(focusable(home)).toBe(true);
230230 expect(home.href).toBe(`${origin}/`);
231231
232 const pullLink = run.named(`Preview of pull #${pull}`)!;
232 const pullLink = run.named(`preview \u00b7 #${pull}`)!;
233233 expect(focusable(pullLink)).toBe(true);
234234 expect(pullLink.href).toBe(`${origin}/alice/public/pulls/${pull}`);
235235
@@ -258,8 +258,8 @@ describe("lost journey: where you are and three exits", () => {
258258 const cookie = cookieFor("public", "production");
259259 const html = await (await ask(host, "/", cookie)).text();
260260 const run = await boot(html, await crewOf(host, cookie), `http://${host}/`);
261 expect(run.named("Production")).toBeDefined();
262 expect(run.built.some((e) => String(e.textContent).startsWith("Preview of pull"))).toBe(false);
261 expect(run.named("production")).toBeDefined();
262 expect(run.built.some((e) => String(e.textContent).startsWith("preview \u00b7"))).toBe(false);
263263 expect(run.named("Home")!.href).toBe(`${new URL(servers.url).origin}/`);
264264 });
265265
@@ -272,7 +272,7 @@ describe("lost journey: where you are and three exits", () => {
272272 expect(tag[2]).toContain(` data-env="pull-${pull}"`);
273273 expect(tag[2]).toContain(` data-pull="${pull}"`);
274274 const run = await boot(html, await crewOf(host), `http://${host}/`);
275 expect(run.named(`Preview of pull #${pull}`)!.href).toBe(`${new URL(servers.url).origin}/alice/public/pulls/${pull}`);
275 expect(run.named(`preview \u00b7 #${pull}`)!.href).toBe(`${new URL(servers.url).origin}/alice/public/pulls/${pull}`);
276276 expect(run.named("Home")).toBeDefined();
277277 expect(run.named("Tell the crew")).toBeUndefined();
278278 // Comment goes to the forge's own page, which asks the stranger to sign in there.
test/toolbar-injection.test.ts +1 −1
@@ -85,6 +85,6 @@ test("the pill overlays the page: fixed, out of flow, in a shadow root", () => {
8585 });
8686
8787 test("on a preview the pill links to the pull's forge page in plain words", () => {
88 expect(toolbarJs).toContain('"Preview of pull #"');
88 expect(toolbarJs).toContain('"preview \\u00b7 #"');
8989 expect(toolbarJs).toContain('"/pulls/"');
9090 });

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs