Bug Description
Running the test suite fails immediately with TypeError: localStorage.clear is not a function. This happens because Node.js 20+ and Bun expose a native but incomplete globalThis.localStorage that lacks standard methods like .clear(). When jsdom also tries to set up its own simulated storage, the two implementations clash — and whichever partial native one wins causes test files that call localStorage.clear() to crash before any assertions even run.
Steps to Reproduce
- Clone the repository and install dependencies
- Ensure you are running Node.js 20+ or Bun as the JS runtime
- Run the test suite via
bun run test or npx vitest
- Observe the crash — no tests execute
Expected Behavior
The test suite should run successfully. localStorage in the jsdom environment should be a fully functional mock with all standard Web Storage API methods (getItem, setItem, removeItem, clear, key, length) available.
Actual Behavior
The test runner crashes immediately with:
TypeError: localStorage.clear is not a function
This error surfaces in at least two test files:
src/components/__tests__/ThemeToggle.test.tsx (line 11)
src/lib/tests/editorPersistence.test.ts (line 17)
The root cause is in vitest.setup.ts, which does not guard against or replace the partial native localStorage that Node.js 20+ / Bun inject into globalThis before jsdom initializes.
Expected Behavior
The vitest.setup.ts file should detect when localStorage is missing .clear() (or is otherwise incomplete) and replace it with a full in-memory mock, e.g.:
if (typeof window !== 'undefined') {
if (!window.localStorage || typeof window.localStorage.clear !== 'function') {
let store: Record<string, string> = {};
const mockLocalStorage = {
getItem: (key: string) => store[key] || null,
setItem: (key: string, value: string) => { store[key] = String(value); },
removeItem: (key: string) => { delete store[key]; },
clear: () => { store = {}; },
length: 0,
key: (index: number) => Object.keys(store)[index] || null,
};
Object.defineProperty(window, 'localStorage', { value: mockLocalStorage, writable: true });
Object.defineProperty(globalThis, 'localStorage', { value: mockLocalStorage, writable: true });
}
}
Browser and OS Info
- OS: Windows 11
- Browser: N/A (server-side / test runner environment)
- Runtime: Node.js 20+ or Bun
- Vitest version: (please fill in)
Video Format (if relevant)
N/A
Screenshots / Screen Recording
TypeError: localStorage.clear is not a function
at vitest.setup.ts (or ThemeToggle.test.tsx:11 / editorPersistence.test.ts:17)
Bug Description
Running the test suite fails immediately with
TypeError: localStorage.clear is not a function. This happens because Node.js 20+ and Bun expose a native but incompleteglobalThis.localStoragethat lacks standard methods like.clear(). When jsdom also tries to set up its own simulated storage, the two implementations clash — and whichever partial native one wins causes test files that calllocalStorage.clear()to crash before any assertions even run.Steps to Reproduce
bun run testornpx vitestExpected Behavior
The test suite should run successfully.
localStoragein the jsdom environment should be a fully functional mock with all standard Web Storage API methods (getItem,setItem,removeItem,clear,key,length) available.Actual Behavior
The test runner crashes immediately with:
This error surfaces in at least two test files:
src/components/__tests__/ThemeToggle.test.tsx(line 11)src/lib/tests/editorPersistence.test.ts(line 17)The root cause is in
vitest.setup.ts, which does not guard against or replace the partial nativelocalStoragethat Node.js 20+ / Bun inject intoglobalThisbefore jsdom initializes.Expected Behavior
The
vitest.setup.tsfile should detect whenlocalStorageis missing.clear()(or is otherwise incomplete) and replace it with a full in-memory mock, e.g.:Browser and OS Info
Video Format (if relevant)
N/A
Screenshots / Screen Recording