1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// node --test web/cocore/cocore.test.mjs (after `cargo wasm`; skips without Chrome)
// index.html as served, in headless Chrome: the module graph loads, signed out, with a form per action of
// every module. @atproto/oauth-client-browser (esm.sh) and the stylesheet are stubbed.
import assert from "node:assert/strict";
import { readdirSync, readFileSync } from "node:fs";
import { test } from "node:test";
import { browse, CHROME } from "../../../atlibs/docs/browser.mjs";
const ROOT = new URL("./", import.meta.url).pathname;
const NAMES = readdirSync(new URL("modules/", import.meta.url)).filter((f) => f.endsWith(".json")).map((f) => f.slice(0, -5));
const ACTIONS = NAMES.flatMap((name) => JSON.parse(readFileSync(new URL(`modules/${name}.json`, import.meta.url), "utf8")).actions.map((a) => a.label));
const STUBS = {
"https://esm.sh/": ["text/javascript", "export const BrowserOAuthClient = { load: async () => ({ init: async () => undefined }) }"],
"https://cdn.jsdelivr.net/": ["text/css", ""],
};
test("the page boots in Chrome, signed out, with every action's form", { skip: !CHROME && "no Chrome" }, () =>
browse(async ({ send, on, open, evaluate }) => {
const errors = [];
on("Runtime.exceptionThrown", ({ exceptionDetails: e }) => errors.push(e.exception?.description ?? e.text));
on("Log.entryAdded", ({ entry }) => entry.level === "error" && !entry.url?.endsWith("/favicon.ico") && errors.push(`${entry.text} ${entry.url ?? ""}`));
on("Fetch.requestPaused", ({ requestId, request }) => {
const [type, body] = Object.entries(STUBS).find(([prefix]) => request.url.startsWith(prefix))[1];
const responseHeaders = [{ name: "content-type", value: type }, { name: "access-control-allow-origin", value: "*" }];
send("Fetch.fulfillRequest", { requestId, responseCode: 200, responseHeaders, body: Buffer.from(body).toString("base64") });
});
await send("Runtime.enable");
await send("Log.enable");
await send("Fetch.enable", { patterns: Object.keys(STUBS).map((prefix) => ({ urlPattern: `${prefix}*` })) });
await open("/index.html");
const ready = `document.querySelectorAll("#actions details").length === ${NAMES.length} && document.querySelectorAll("#actions form").length === ${ACTIONS.length}`;
for (const end = Date.now() + 15_000; Date.now() < end && !(await evaluate(ready)); ) await new Promise((ok) => setTimeout(ok, 100));
assert.deepEqual(errors, []);
assert.ok(await evaluate(ready), "every module's actions rendered");
assert.equal(await evaluate(`document.querySelector("#login").hidden`), false);
assert.equal(await evaluate(`document.querySelector("#signed-in").hidden`), true);
assert.deepEqual(await evaluate(`[...document.querySelectorAll("#actions h4")].map((h) => h.textContent)`).then((l) => l.sort()), ACTIONS.sort());
}, { root: ROOT }),
);