Fix checkpoint regressions: jsdom localStorage shim (Node 22 shadowing) + restore persistent nav links required by §7 one-tap emergency reachability

This commit is contained in:
Lumen Stage1 2026-09-30 13:44:31 -05:00
commit 3cd9a2377a
3 changed files with 48 additions and 1 deletions

View file

@ -73,7 +73,18 @@ export function createLayout(): {
nav.className = "side-nav"; nav.className = "side-nav";
nav.setAttribute("aria-label", "Primary navigation"); nav.setAttribute("aria-label", "Primary navigation");
nav.setAttribute("role", "navigation"); nav.setAttribute("role", "navigation");
// Bottom navigation removed — redundant with main-screen buttons. // Persistent navigation: home + the four destinations (contract §7 —
// emergency must stay one tap from every screen).
const navTargets = [HOME_ROUTE, ...ROUTES];
for (const r of navTargets) {
const a = document.createElement("a");
a.href = r.path;
a.className = "side-nav__link";
a.setAttribute("data-route", r.path);
a.textContent = r.id === "home" ? "Home" : r.label;
if (r.id === "emergency") a.classList.add("side-nav__link--emergency");
nav.append(a);
}
root.append(nav); root.append(nav);
return { root, main, nav, brand, statusChip, skipLink }; return { root, main, nav, brand, statusChip, skipLink };

35
tests/setup.ts Normal file
View file

@ -0,0 +1,35 @@
/**
* Vitest setup — runs before every test file.
*
* Why: on Node >=22.4 the experimental native `localStorage` global shadows
* jsdom's implementation and is `undefined` unless `--localstorage-file` is
* passed, so jsdom-environment tests see `localStorage === undefined`
* (ExperimentalWarning at runtime). Install a minimal in-memory stand-in
* whenever the global is missing.
*/
class MemoryStorage implements Storage {
private map = new Map<string, string>();
get length(): number {
return this.map.size;
}
clear(): void {
this.map.clear();
}
getItem(key: string): string | null {
return this.map.has(key) ? (this.map.get(key) as string) : null;
}
key(index: number): string | null {
return [...this.map.keys()][index] ?? null;
}
removeItem(key: string): void {
this.map.delete(key);
}
setItem(key: string, value: string): void {
this.map.set(key, String(value));
}
}
const g = globalThis as unknown as { localStorage?: Storage };
if (typeof g.localStorage === "undefined") {
g.localStorage = new MemoryStorage();
}

View file

@ -5,6 +5,7 @@ export default defineConfig({
globals: false, globals: false,
include: ["tests/**/*.test.ts"], include: ["tests/**/*.test.ts"],
environment: "node", environment: "node",
setupFiles: ["./tests/setup.ts"],
reporters: ["verbose"], reporters: ["verbose"],
coverage: { coverage: {
enabled: false, enabled: false,