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

A test: 390x844 and 1280x800, no page is covered by a closed overlay (#11831 item 3) #11885

opened this

Check · Review · Land · Live — Its check is queued. Next: reviewer, no review yet.

Ready to land

scout/forge:scout/11854-a-test-390x844-and-1280x800-no-page-is-c → main 1 commit fork

Review

Sign in to review this change.
1 file changed +86 −0
test/no-closed-overlay.test.ts added +86
@@ -0,0 +1,86 @@
1 /**
2 * No page is covered by a closed overlay (#11854, #11831 item 3). In a real
3 * Chromium at 390x844 and 1280x800, on the pages a person lands on, signed in
4 * and signed out: every closed <dialog>, [popover] and [hidden] element draws
5 * nothing (computed display none, no box), and the element on top at a grid of
6 * points over the viewport is never inside one.
7 *
8 * Limit: the pages listed, as served; an overlay opened by a script is not
9 * covered here. Skipped where no Chromium starts (the forge's check has one).
10 */
11 import { afterAll, beforeAll, describe, expect, test } from "bun:test";
12 import { mkdtemp, rm } from "node:fs/promises";
13 import { tmpdir } from "node:os";
14 import { join } from "node:path";
15 import { createApp, type App } from "../src/app.ts";
16 import { serve, type Servers } from "../src/http/server.ts";
17 import { findChromium } from "../src/looks/capture.ts";
18 import { adminCookie } from "./helpers/admin.ts";
19 import { chromiumRuns, evaluateLoaded } from "./helpers/chrome.ts";
20
21 const PATHS = ["/", "/explore", "/login", "/new", "/olive/proj", "/olive/proj/settings"];
22 const VIEWPORTS = [{ width: 390, height: 844 }, { width: 1280, height: 800 }];
23
24 let dir: string;
25 let app: App;
26 let servers: Servers;
27 let cookie: string;
28
29 beforeAll(async () => {
30 dir = await mkdtemp(join(tmpdir(), "forge-overlay-"));
31 app = createApp({ dataDir: dir, port: 0 });
32 servers = await serve(app);
33 cookie = await adminCookie(app, { username: "olive", email: "[email protected]", password: "overlay-password" });
34 await fetch(`${servers.url}/new`, {
35 method: "POST",
36 headers: { cookie },
37 body: new URLSearchParams({ name: "proj", visibility: "private", description: "x" }),
38 redirect: "manual",
39 });
40 });
41
42 afterAll(async () => {
43 servers.stop();
44 app.close();
45 await rm(dir, { recursive: true, force: true });
46 });
47
48 /** Runs in the page: what is drawn that is closed, and what is on top where. */
49 const PROBE = `(() => {
50 const closed = (e) =>
51 (e.matches("dialog") && !e.open) ||
52 (e.hasAttribute("popover") && !e.matches(":popover-open")) ||
53 e.hasAttribute("hidden");
54 const name = (e) => e.tagName.toLowerCase() + (typeof e.className === "string" && e.className ? "." + e.className.trim().split(/\\s+/).join(".") : "");
55 const drawn = [...document.querySelectorAll("dialog, [popover], [hidden]")]
56 .filter((e) => closed(e) && !e.closest("template"))
57 .filter((e) => { const r = e.getBoundingClientRect(); return getComputedStyle(e).display !== "none" || r.width * r.height > 0; })
58 .map(name);
59 const w = document.documentElement.clientWidth, h = window.innerHeight;
60 const covering = new Set();
61 for (let x = 0.05; x < 1; x += 0.15) for (let y = 0.05; y < 1; y += 0.15) {
62 const top = document.elementFromPoint(w * x, h * y);
63 const hit = top && top.closest("dialog, [popover], [hidden]");
64 if (hit && closed(hit)) covering.add(name(hit));
65 }
66 return JSON.stringify({ drawn, covering: [...covering], probed: document.querySelectorAll("*").length });
67 })()`;
68
69 const found = findChromium();
70 const chromium = found !== undefined && chromiumRuns(found) ? found : undefined;
71 if (chromium === undefined) console.log("SKIPPING: no chromium that starts on this machine, so closed overlays are not measured");
72
73 describe.skipIf(chromium === undefined)("no page is covered by a closed overlay", () => {
74 for (const vp of VIEWPORTS)
75 for (const signedIn of [false, true])
76 for (const path of PATHS) {
77 test(`${path} ${signedIn ? "signed in" : "signed out"} at ${vp.width}x${vp.height}`, async () => {
78 const name = cookie.slice(0, cookie.indexOf("="));
79 const cookies = signedIn ? [{ name, value: cookie.slice(name.length + 1) }] : [];
80 const m = JSON.parse(await evaluateLoaded(chromium!, `${servers.url}${path}`, vp, cookies, PROBE)) as { drawn: string[]; covering: string[]; probed: number };
81 expect(m.probed).toBeGreaterThan(10);
82 expect(m.drawn).toEqual([]);
83 expect(m.covering).toEqual([]);
84 }, 30_000);
85 }
86 });

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs