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
- Use Node 25 or later (seen on v26.8.2).
- On
main (898bbaed8), run pnpm exec vitest run --project react-core src/components/InstrumentRenderer.
- 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
Summary
Two
react-coreunit tests fail on Node 25 and later. They pass in CI, because CI uses Node 24 from.nvmrc. Theenginesfield inpackage.jsonallows>=v24.15.0, so a contributor on a newer Node gets a redpnpm teston a cleanmain.The failing tests:
src/components/InstrumentRenderer/__tests__/ScalarInstrumentRenderer.test.tsx› should render InteractiveContent for an INTERACTIVE instrumentsrc/components/InstrumentRenderer/__tests__/SeriesInstrumentRenderer.test.tsx› should render an INTERACTIVE item, and complete the series when it submitsCause
Node 25 and later enable the Web Storage API by default. Node then defines
globalThis.localStorageas an accessor. Without--localstorage-file, that accessor returnsundefined. This built-in global hides thelocalStoragethat happy-dom (thereact-corevitest environment) provides, souseThemereadsgetItemfromundefined.On Node v26.8.2:
$ node -e "console.log(typeof globalThis.localStorage)" undefinedWith the built-in storage turned off, all 19 tests in the directory pass:
Reproduce
main(898bbaed8), runpnpm exec vitest run --project react-core src/components/InstrumentRenderer.Possible fixes
localStorage, or pass--no-experimental-webstorageto the test workers. This lets the suite run the same on every Node version thatenginesallows.engines.nodeto 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