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:
parent
e83946c207
commit
3cd9a2377a
3 changed files with 48 additions and 1 deletions
|
|
@ -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
35
tests/setup.ts
Normal 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();
|
||||||
|
}
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue