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
Check · Review · Land · Live — Its check is queued.
scout/forge:scout/11854-a-test-390x844-and-1280x800-no-page-is-c → main 1 commit fork
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 | }); |
new above
offline