// node --test examples/web/hello/hello.test.mjs (after `cargo wasm`; skips without Chrome) // index.html as served, in headless Chrome: the module graph loads, both components render signed out, // and Count runs the real hello module in the page. The PLC directory and the PDS are stubbed, and so is // @atproto/oauth-client-browser (esm.sh) unless ATLIBS_DOCS_NETWORK=1, which loads the real one. import assert from "node:assert/strict"; import { test } from "node:test"; import { browse, CHROME } from "../../../docs/browser.mjs"; const ROOT = new URL("../../../", import.meta.url).pathname; const NETWORK = process.env.ATLIBS_DOCS_NETWORK === "1"; const did = "did:plc:lpfuqerea3deuoyrn7ojser4"; // url prefix -> [content type, body] const STUBS = { [`https://plc.directory/${did}`]: ["application/json", JSON.stringify({ service: [{ id: "#atproto_pds", serviceEndpoint: "https://pds.example" }] })], "https://pds.example/xrpc/com.atproto.repo.listRecords?": ["application/json", JSON.stringify({ records: [{ uri: `at://${did}/xyz.statusphere.status/a`, value: { status: "🙂" } }] })], ...(!NETWORK && { "https://esm.sh/": ["text/javascript", "export const BrowserOAuthClient = { load: async () => ({ init: async () => undefined }) }"] }), }; test("hello boots in Chrome, signed out, and counts records", { 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 stub = Object.entries(STUBS).find(([prefix]) => request.url.startsWith(prefix))?.[1]; const [type, body] = stub ?? ["text/plain", "not stubbed"]; const responseHeaders = [{ name: "content-type", value: type }, { name: "access-control-allow-origin", value: "*" }, { name: "access-control-allow-headers", value: "*" }]; send("Fetch.fulfillRequest", { requestId, responseCode: stub ? 200 : 404, 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("/examples/web/hello/index.html"); // until main.js's cubit.init() has rendered: the sign-in form shown, the status form hidden const signedOut = `!!customElements.get("hello-count") && document.querySelector("hello-status .status")?.hidden === true && !document.querySelector("hello-status .login").hidden`; const until = async (expression) => { for (const end = Date.now() + 15_000; Date.now() < end; await new Promise((ok) => setTimeout(ok, 100))) if (await evaluate(expression)) return; assert.fail(`timed out: ${expression}\n${errors.join("\n")}`); }; await until(signedOut); await evaluate(`(() => { const form = document.querySelector("hello-count form"); form.did.value = ${JSON.stringify(did)}; form.requestSubmit() })()`); await until(`document.querySelector("hello-count .out").textContent !== ""`); assert.equal(await evaluate(`document.querySelector("hello-count .out").textContent`), "1 records in xyz.statusphere.status"); assert.deepEqual(errors, []); }, { root: ROOT }));