Skip to content

Fix React 19 compatibility for @testing-library/react#4296

Open
d10c wants to merge 1 commit intogithub:mainfrom
d10c:d10c/fix-react-19-incompat
Open

Fix React 19 compatibility for @testing-library/react#4296
d10c wants to merge 1 commit intogithub:mainfrom
d10c:d10c/fix-react-19-incompat

Conversation

@d10c
Copy link
Contributor

@d10c d10c commented Feb 6, 2026

This commit fixes TypeError: React.act is not a function errors in the view tests, which have actually existed since the React 19 update in December 2025 but for some reason haven't appeared on our radar until now.

Maybe that's because the view tests are part of the release process and not the CI, and we haven't released since that PR was merged? We should consider moving the view tests to the CI, although they are notoriously flaky.

The problem is that we use @testing-library/react for view testing, and that library hasn't been upgraded to React 19 yet; it imports the act function from the deprecated react-dom/test-utils module (which still exists as a module, but re-exports act from react with a deprecation warning, and then only when NODE_ENV != 'production')

This mock-based solution may be the best workaround until @testing-library/react supports React 19, but I am open to suggestions.

Problem:

All 255 view tests were failing with: TypeError: React.act is not a function or TypeError: actImplementation is not a function

Root Cause:

@testing-library/react@16.x internally uses react-dom/test-utils to access the 'act' function for wrapping component updates. In React 19:

  1. react-dom/test-utils module was deprecated and no longer exports act
  2. act() was moved to the main 'react' package
  3. act() is only exported when NODE_ENV is 'test' or 'development' (it's undefined in production builds)

When @testing-library/react tries to import react-dom/test-utils, it finds:

  const reactAct = typeof React.act === 'function'
    ? React.act
    : DeprecatedReactTestUtils.act;

Both are undefined, so reactAct becomes undefined, causing the error 'actImplementation is not a function' when it tries to call it.

Specific error locations:

  • node_modules/@testing-library/react/dist/act-compat.js:13 (reactAct is undefined)
  • node_modules/@testing-library/react/dist/act-compat.js:46 (actImplementation() call fails)
  • All 37 test suites in src/view/__tests__/ directories

Solution:

Created a Jest manual mock for react-dom/test-utils that provides the act function from React 19's new location:

  1. Created __mocks__/react-dom/test-utils.js:

    • Imports act from 'react' package (React 19's new location)
    • Exports it with the same API that react-dom/test-utils used to have
    • Jest automatically uses manual mocks when they exist in __mocks__/
  2. Updated src/view/jest.config.ts:

    • Added moduleNameMapper entry to explicitly map 'react-dom/test-utils' to our mock file
    • This ensures the mock is used when @testing-library/react tries to import react-dom/test-utils
  3. Updated package.json test:view script:

    • Added NODE_ENV=test to the cross-env command
    • Critical: React 19 only exports act() when NODE_ENV !== 'production'
    • Without this, require('react').act would be undefined even in our mock file
  4. Updated eslint.config.mjs:

    • Added '__mocks__/' to globalIgnores
    • Prevents ESLint from trying to parse the mock file and failing with "not found by the project service" errors

Test Results:

Before the fix (upstream/main at f465109):

 Test Suites: 37 failed, 2 passed, 39 total
 Tests:       255 failed, 2 skipped, 109 passed, 366 total

After the fix (with commit e0745d6):

 Test Suites: 39 passed, 39 total
 Tests:       2 skipped, 364 passed, 366 total

Errors that were fixed are of the form:

    ● SuggestBox › does not render the options by default

      TypeError: React.act is not a function

        81 |   const parseValueToTokens = jest.fn();
        82 |   const render = (props?: Partial<SuggestBoxProps<TestOption>>)
=>
      > 83 |     reactRender(
           |                ^
        84 |       <SuggestBox
        85 |         options={options}
        86 |         onChange={onChange}

        at exports.act (../../node_modules/react-dom/cjs/react-dom-test-utils.production.js:20:16)
        at ../../node_modules/@testing-library/react/dist/act-compat.js:46:25
        at renderRoot (../../node_modules/@testing-library/react/dist/pure.js:189:26)
        at render (../../node_modules/@testing-library/react/dist/pure.js:291:10)
        at render (common/SuggestBox/__tests__/SuggestBox.test.tsx:83:16)

The NODE_ENV=test setting in package.json is the critical fix - it ensures act() is available when React is loaded. The mock file simply re-exports it from the new location, making it available at the old import path that @testing-library/react expects.

Files modified:

  • extensions/ql-vscode/__mocks__/react-dom/test-utils.js (new)
  • extensions/ql-vscode/src/view/jest.config.ts
  • extensions/ql-vscode/package.json
  • extensions/ql-vscode/eslint.config.mjs

This commit fixes test failures caused by React 19's breaking changes
to the test utilities API, which broke @testing-library/react@16.x.

Problem:
All 255 view tests were failing with: 'TypeError: React.act is not a
function' or 'TypeError: actImplementation is not a function'

Root Cause:
@testing-library/react@16.x internally uses react-dom/test-utils to
access the 'act' function for wrapping component updates. In React 19:

1. react-dom/test-utils module was deprecated and no longer exports act
2. act() was moved to the main 'react' package
3. act() is only exported when NODE_ENV is 'test' or 'development'
   (it's undefined in production builds)

When @testing-library/react tries to import react-dom/test-utils, it
finds:
  const reactAct = typeof React.act === 'function'
    ? React.act
    : DeprecatedReactTestUtils.act;

Both are undefined, so reactAct becomes undefined, causing the error
'actImplementation is not a function' when it tries to call it.

Specific error locations:
- node_modules/@testing-library/react/dist/act-compat.js:13
  (reactAct is undefined)
- node_modules/@testing-library/react/dist/act-compat.js:46
  (actImplementation() call fails)
- All 37 test suites in src/view/__tests__/ directories

Solution:
Created a Jest manual mock for react-dom/test-utils that provides the
act function from React 19's new location:

1. Created __mocks__/react-dom/test-utils.js:
   - Imports act from 'react' package (React 19's new location)
   - Exports it with the same API that react-dom/test-utils used to have
   - Jest automatically uses manual mocks when they exist in __mocks__/

2. Updated src/view/jest.config.ts:
   - Added moduleNameMapper entry to explicitly map
     'react-dom/test-utils' to our mock file
   - This ensures the mock is used when @testing-library/react tries
     to import react-dom/test-utils

3. Updated package.json test:view script:
   - Added NODE_ENV=test to the cross-env command
   - Critical: React 19 only exports act() when NODE_ENV !== 'production'
   - Without this, require('react').act would be undefined even in our
     mock file

4. Updated eslint.config.mjs:
   - Added '__mocks__/' to globalIgnores
   - Prevents ESLint from trying to parse the mock file and failing
     with "not found by the project service" errors

Test Results:
Before: 255 failed tests (all with React.act errors)
After: All 364 tests pass (2 skipped)

The NODE_ENV=test setting in package.json is the critical fix - it
ensures act() is available when React is loaded. The mock file simply
re-exports it from the new location, making it available at the old
import path that @testing-library/react expects.

Files modified:
- extensions/ql-vscode/__mocks__/react-dom/test-utils.js (new)
- extensions/ql-vscode/src/view/jest.config.ts
- extensions/ql-vscode/package.json
- extensions/ql-vscode/eslint.config.mjs
@d10c d10c requested a review from nickrolfe February 6, 2026 12:25
@d10c d10c marked this pull request as ready for review February 6, 2026 12:25
@d10c d10c requested a review from a team as a code owner February 6, 2026 12:25
Copilot AI review requested due to automatic review settings February 6, 2026 12:25
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes React 19 compatibility issues in the view tests by creating a mock for the deprecated react-dom/test-utils module. The problem arose because @testing-library/react@16.x still imports act from react-dom/test-utils, which was deprecated in React 19 (where act was moved to the main react package and is only available when NODE_ENV !== 'production'). The fix resolves all 255 failing view tests by providing a mock that re-exports act from React 19's new location.

Changes:

  • Created a Jest manual mock for react-dom/test-utils that exports act from React 19's new location
  • Configured Jest to use the mock via moduleNameMapper in the view test configuration
  • Added NODE_ENV=test to the test:view script to ensure React exports the act function
  • Updated ESLint configuration to ignore the new __mocks__/ directory

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

File Description
extensions/ql-vscode/__mocks__/react-dom/test-utils.js New mock file that re-exports act from React 19's react package to support @testing-library/react's internal usage
extensions/ql-vscode/src/view/jest.config.ts Added moduleNameMapper entry to route react-dom/test-utils imports to the mock file
extensions/ql-vscode/package.json Added NODE_ENV=test to the test:view script to ensure React exports the act function
extensions/ql-vscode/eslint.config.mjs Added __mocks__/ to global ignores to prevent ESLint errors on the mock file

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant