docs/solutions/test-failures/2026-04-18-slate-legacy-jsx-fixtures-need-a-live-jsx-binding-under-bun.md
The full slate fixture harness was red even though the product-code tests were
already green.
The failures were not coming from Slate behavior. They were happening before the tests even ran:
React is not definedjsx is not definedThe obvious trap after that was to patch the spec harness instead of fixing the fixture loader. That creates a second source of truth for legacy JSX handling and leaks fake globals into a lane that should just import fixtures and run assertions.
bun test ./test/index.spec.ts failed across large swaths of
interfaces/**, operations/**, normalization/**, and transforms/**
before any assertion ran.legacy-hsx-fixtures loader targeting
packages/slate, packages/slate-history, and
packages/slate-hyperscript fixture trees.packages/slate/test/index.spec.ts still grew an extra helper that wrapped
every fixture import with temporary globalThis.jsx and globalThis.React
mutation.Keep one owner for legacy fixture binding: the Bun preload loader in config/bun-test-setup.ts.
That loader already:
jsxFactory: 'jsx'jsx import from
slate-test-jsx.js
when the fixture does not declare one itselfOnce that loader is in place, the spec harness should stay boring:
globalThis.jsxglobalThis.React with a fake hyperscript objectThat let
packages/slate/test/index.spec.ts
drop the withLegacyClassicJsxGlobals(...) wrapper entirely.
The classic Slate fixture corpus is not normal React test code. It is a legacy hyperscript-shaped file family.
That means the fix belongs at module-load time, not in the spec body.
Once the preload loader owns that translation, every matching fixture module gets the same runtime treatment before evaluation, and the spec files stop carrying duplicate compatibility logic.
React is not defined
or jsx is not defined, inspect the same-path fixture imports before
touching product code.