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

No one assigned

    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