Skip to content

react-core InstrumentRenderer tests fail on Node 25+ because the built-in localStorage hides happy-dom's #1569

Description

@gdevenyi

Summary

Two react-core unit tests fail on Node 25 and later. They pass in CI, because CI uses Node 24 from .nvmrc. The engines field in package.json allows >=v24.15.0, so a contributor on a newer Node gets a red pnpm test on a clean main.

The failing tests:

  • src/components/InstrumentRenderer/__tests__/ScalarInstrumentRenderer.test.tsx › should render InteractiveContent for an INTERACTIVE instrument
  • src/components/InstrumentRenderer/__tests__/SeriesInstrumentRenderer.test.tsx › should render an INTERACTIVE item, and complete the series when it submits
TypeError: Cannot read properties of undefined (reading 'getItem')
 ❯ @douglasneuroinformatics/libui/src/hooks/useTheme/useTheme.ts:34:43
 ❯ useTheme .../libui/src/hooks/useTheme/useTheme.ts:30:28
 ❯ _InteractiveContent2 src/components/InteractiveContent/InteractiveContent.tsx:46:28

Cause

Node 25 and later enable the Web Storage API by default. Node then defines globalThis.localStorage as an accessor. Without --localstorage-file, that accessor returns undefined. This built-in global hides the localStorage that happy-dom (the react-core vitest environment) provides, so useTheme reads getItem from undefined.

On Node v26.8.2:

$ node -e "console.log(typeof globalThis.localStorage)"
undefined

With the built-in storage turned off, all 19 tests in the directory pass:

NODE_OPTIONS=--no-experimental-webstorage pnpm exec vitest run --project react-core src/components/InstrumentRenderer
# Tests  19 passed (19)

Reproduce

  1. Use Node 25 or later (seen on v26.8.2).
  2. On main (898bbaed8), run pnpm exec vitest run --project react-core src/components/InstrumentRenderer.
  3. The 2 tests above fail. On Node 24 they pass.

Possible fixes

  • Make the vitest setup replace the Node accessor with happy-dom's localStorage, or pass --no-experimental-webstorage to the test workers. This lets the suite run the same on every Node version that engines allows.
  • Or narrow engines.node to the Node 24 line, so a newer Node fails early with a clear message.

These failures appeared as unrelated noise when #1425 and #1426 were rebased. Neither PR touches this code.

🤖 Generated with Claude Code

https://claude.ai/code/session_01DXdGDUtHTWmno4AKLKm7kj

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Area: InfrastructureDeployment, Docker, CI, logging, CLIs, build and test toolingBugType: existing behavior is wrongDifficulty: LowIsolated change, about 2 hours or lessGood First IssueWell-scoped, low-risk and self-contained; a good entry point for a new contributorPriority: LowNice to have, cosmetic or speculative

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions