From 9c209f7cb85d72f9b92ea58246d8add9a3b23955 Mon Sep 17 00:00:00 2001 From: doxa-maps Date: Tue, 22 Sep 2026 05:06:24 +0000 Subject: [PATCH] smoke: stop asserting the shell mounts a plugin; it is a catalog now Two of smoke's failures were the gate reporting a product decision. The assertions date from when the root page embedded a live preview. Measured: public/index.html has four occurrences of "profile-config" and all four are escaped snippet and glossary text -- the gallery is a capability-sorted navigation catalog that links to bundles and embeds none. No coverage is lost, which is the only reason this is safe. The generated-profile block asserts the same two things against a real leaf page picked from the manifest, and that surface passes. 21 built leaf pages mount with a profile-config at load. The shell copies were duplicates aimed at the one surface that by design satisfies neither. Both counts are still REPORTED in the shell log line, so a behaviour change stays visible. My carded recommendation was to re-aim these at plugin-studio. That was wrong and I checked before acting on it: the cap-5 studio leaf has exactly one [profile-config] element at load -- its own host -- and zero nested elements or live iframes. It mounts panes on activation. A load-time assertion cannot see behaviour that starts on a click. Negative-tested, after two invalid attempts. Rewriting the bundle src to a 404 makes smoke FAIL exit 1 on "imported no bundle that registered its element". The first two attempts produced a green PASS for bad reasons -- one edit never wrote, and the other removed an attribute from a JS-created element while a bare static one remained -- so the mutation is now asserted to have landed (before=1, after=0) before the result is believed. --- internal/smoke.mjs | 44 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/internal/smoke.mjs b/internal/smoke.mjs index 7b421ad3a..f6fcc5755 100644 --- a/internal/smoke.mjs +++ b/internal/smoke.mjs @@ -10,13 +10,23 @@ * the page. * * WHAT IT ASSERTS - * 1. the shell renders, + * on the SHELL (/): + * 1. it renders (has a ), * 2. it resolves a token from the endpoint the build writes, - * 3. a bundle lazily imports and registers its custom element, - * 4. an element actually mounts, - * 5. no uncaught page errors, - * 6. no failed same-origin requests — this is what caught a 404 on every single + * 3. no uncaught page errors, + * 4. no failed same-origin requests — this is what caught a 404 on every single * page load, from a <script src> for a file that is deliberately never deployed. + * on a GENERATED PROFILE PAGE (picked from the manifest, never hardcoded): + * 5. a bundle imports and registers its custom element, + * 6. an element actually mounts with a profile-config, + * 7. its own #status node reports no complaint, + * 8. no uncaught errors and no failed same-origin requests there either. + * + * ★ 5 and 6 are asserted on the PROFILE PAGE ONLY, and that is deliberate (2026-09-22). They used + * to be asserted on the shell too, from when the root page embedded a live preview. The gallery is + * now a navigation CATALOG that embeds nothing, so those copies reported a product decision as a + * failure. The shell still REPORTS both counts in its log line, so a change of behaviour is + * visible; it just no longer fails on the intended one. * * It checks TWO surfaces, because they resolve a token by different routes and one * passing says nothing about the other: the shell at / fetches the endpoint itself, @@ -72,13 +82,33 @@ try { if (!String(token).startsWith('pk.') && !String(token).startsWith('tk.')) fail.push(`shell could not resolve a token from ./api/maps/token.json (got: ${token}) — every basemap would be blank`) + // ── THE SHELL IS A CATALOG, NOT A HOST — these two counts are REPORTED, NOT ASSERTED ──────── + // + // ★ CORRECTED 2026-09-22. This block used to fail when the shell mounted no element. That was + // right when the root page embedded a live preview; it is wrong now. MEASURED: public/index.html + // contains four occurrences of "profile-config" and ALL FOUR are escaped snippet/glossary text + // (<doxa-map profile-config=…>) — the gallery is a capability-sorted NAVIGATION CATALOG that + // links to bundles and deliberately embeds none. + // + // THE COVERAGE IS NOT LOST, which is the only reason this is safe to relax: the generated-profile + // block below asserts the SAME TWO THINGS ("mounted no element" / "imported no bundle that + // registered its element") against a real leaf page picked from the manifest — and that surface + // passes (mounted=1). 21 of the built leaf pages mount with a profile-config at load. So these + // were duplicate assertions aimed at the one surface that by design satisfies neither. + // + // WHY NOT RE-AIM THEM AT plugin-studio INSTEAD (my first instinct, and it was wrong): the cap-5 + // studio leaf has exactly ONE [profile-config] element at load — its own <plugin-studio> host — + // and ZERO nested elements or live iframes. It mounts panes ON ACTIVATION, which is the lazy + // design that keeps the shell fast. A load-time assertion cannot see behaviour that starts on a + // click. Verified in a browser before changing this. + // + // KEPT AS OUTPUT so a regression is still visible: if the shell ever starts mounting again, or a + // future catalog page is expected to, these numbers say so in the log line below. const registered = await page.evaluate(() => [...document.querySelectorAll('[profile-config]')].map(e => e.tagName.toLowerCase()) .filter(t => !!customElements.get(t))) - if (!registered.length) fail.push('no bundle lazily imported and registered its custom element') const mounted = await page.evaluate(() => document.querySelectorAll('[profile-config]').length) - if (!mounted) fail.push('no element mounted with a profile-config') if (pageErrors.length) fail.push(`uncaught page errors: ${pageErrors.slice(0, 3).join(' | ')}`) if (failed.length) fail.push(`failed same-origin requests: ${failed.slice(0, 3).join(' | ')}`)