Files
beacon-web/tests/setup.ts
T
MrAlders0n 3e43cfd009 fix: follow up on last week's merges (#55-#101) (#102)
Bugs: clear compare params on tab change, recover channel live messages after a 429,
observer copy link keeps only region params, route table no longer navigates on region
change with nothing selected, map borders memo on data identity, live overview can't
resurrect a failed query, French relative times, no language write on first visit,
0/0 node locations hidden outside the map, path/signal stats use the shared retry rule.

i18n: node/packet/mesh/observer strings that were still hardcoded after #62.

Cleanup: formatUtc, ACTION_BUTTON_CLASS, observer-stats, useWindowedStats, observer-id;
observer pages use StatCard/Card/Field/Segmented/SearchBar/SelectDropdown; one details
chrome on the stats tabs; comment and translations-guide trims; localStorage stub for
Node 26 in the test setup.
2026-09-30 10:19:32 -04:00

46 lines
1.7 KiB
TypeScript

import "@testing-library/jest-dom/vitest";
import { cleanup } from "@testing-library/react";
import { afterEach, vi } from "vitest";
import i18n from "../src/i18n";
// jsdom doesn't implement matchMedia. Provide a default stub so components that read media queries
// mount as "desktop" by default — a hover-capable pointer, not below the mobile width. Individual
// tests can override window.matchMedia with their own controllable mock to drive a query.
// (hover: …) → true keeps hover-driven UI (tooltips, the path popover) in hover mode by default;
// width queries → false keep the desktop layout.
if (!window.matchMedia) {
window.matchMedia = vi.fn().mockImplementation((query: string) => ({
matches: /hover/.test(query),
media: query,
onchange: null,
addEventListener: vi.fn(),
removeEventListener: vi.fn(),
addListener: vi.fn(),
removeListener: vi.fn(),
dispatchEvent: vi.fn(),
}));
}
// Node 26 exposes `localStorage` as undefined without `--localstorage-file`, shadowing jsdom's.
if (!globalThis.localStorage) {
const store = new Map<string, string>();
Object.defineProperty(globalThis, "localStorage", {
value: {
getItem: (key: string) => (store.has(key) ? store.get(key)! : null),
setItem: (key: string, value: string) => store.set(key, String(value)),
removeItem: (key: string) => store.delete(key),
clear: () => store.clear(),
key: (index: number) => Array.from(store.keys())[index] ?? null,
get length() { return store.size; },
},
configurable: true,
writable: true,
});
}
afterEach(async () => {
cleanup();
await i18n.changeLanguage("en");
try { localStorage.clear(); } catch { /* stubbed per-test */ }
});