Skip to content

[Bug] Vitest Test Suite Crashes with TypeError: localStorage.clear is not a function in Node.js 20+ / Bun. #1539

@Itzzavdheshh

Description

@Itzzavdheshh

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

  1. Clone the repository and install dependencies
  2. Ensure you are running Node.js 20+ or Bun as the JS runtime
  3. Run the test suite via bun run test or npx vitest
  4. 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)

Metadata

Metadata

Assignees

Labels

bugSomething isn't working correctlytype:bugBug fixtype:testingTesting

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions