Skip to content

fix: repair broken Jest test suite and run it in CI - #431

Open
trinadhkoya wants to merge 1 commit into
react-native-community:mainfrom
trinadhkoya:fix/repair-test-suite-and-ci
Open

fix: repair broken Jest test suite and run it in CI#431
trinadhkoya wants to merge 1 commit into
react-native-community:mainfrom
trinadhkoya:fix/repair-test-suite-and-ci

Conversation

@trinadhkoya

Copy link
Copy Markdown

Problem

On a fresh clone, bun run test fails before running a single test. Because neither CI workflow (release.yml, publish-canary.yml) runs the tests, this went unnoticed. There were several independent breakages:

  1. babel.config.js references module:metro-react-native-babel-preset, which isn't a dependency and was removed in RN 0.73+. RN 0.78 (used here) ships @react-native/babel-preset instead.
  2. jest.setup.js calls jest.requireActual("react-native/Libraries/ReactNative/oss/ReactNativeRenderer-prod") — that path no longer exists in RN 0.78, and its result was never even used.
  3. Tests import the deprecated @testing-library/react-hooks, which can't auto-detect a renderer under React 18.
  4. react-test-renderer was pinned to ^19 while react is 18.3.1TypeError: Cannot read properties of undefined (reading 'S').
  5. A leftover global.window = {} in jest.setup.js shadowed the global object and broke setTimeout under @testing-library/react-native.
  6. The Keyboard mock was a no-op (addListener didn't store handlers, emit did nothing), so the useKeyboard tests couldn't drive the hook.
  7. eslint-plugin-react is imported by eslint.config.mjs but wasn't a dependency, so bun run lint also failed.

Changes

  • babel.config.js: switch to @react-native/babel-preset.
  • jest.setup.js: remove the dead requireActual and the global.window shim; make the Keyboard mock a real emitter.
  • Migrate all 8 test files from @testing-library/react-hooks to @testing-library/react-native (renderHook / waitFor).
  • useRefresh.test.ts: await act(async …) so the promise microtask flushes under React 18.
  • package.json: drop the unused @testing-library/react-hooks, align react-test-renderer to 18.3.1, add eslint-plugin-react.
  • Add .github/workflows/ci.yml running typecheck + lint + test on push and PR so this can't silently break again.

Verification

bun run typecheck   ✅
bun run lint        ✅
bun run test        ✅  42 passed, 8 suites

No runtime/source (src/*.ts hook) behavior changes — this is test/build/CI tooling only, so no changeset is included.

Copilot AI lite review requested due to automatic review settings September 4, 2026 13:00
@changeset-bot

changeset-bot Bot commented Sep 4, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 9fcd64a

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

The useAccessibilityInfo tests’ addEventListener mock helper returns undefined, which can break hook effect cleanup that expects a subscription with .remove().

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR repairs the repository’s broken Jest test setup (React Native 0.78 / React 18), modernizes the hook test suites to supported testing-library APIs, and ensures the checks run in CI to prevent future silent breakages.

Changes:

  • Fix Jest/Babel/test tooling incompatibilities (RN 0.78 preset, remove dead setup code, align react-test-renderer with React 18).
  • Migrate hook tests from deprecated @testing-library/react-hooks to @testing-library/react-native (renderHook, waitFor, async act).
  • Add a CI workflow that runs typecheck + lint + test on pushes and PRs.
File summaries
File Description
src/useRefresh.test.ts Migrates to @testing-library/react-native and uses async act for timer-driven refresh completion.
src/useLayout.test.ts Updates hook test renderer import to @testing-library/react-native.
src/useKeyboard.test.ts Updates hook test renderer import to @testing-library/react-native.
src/useInteractionManager.test.ts Updates hook test renderer import to @testing-library/react-native.
src/useImageDimensions.test.ts Updates hook test renderer import to @testing-library/react-native.
src/useBackHandler.test.ts Updates hook test renderer import to @testing-library/react-native.
src/useAppState.test.ts Updates hook test renderer import to @testing-library/react-native.
src/useAccessibilityInfo.test.ts Migrates async update waiting to waitFor with RTL native renderHook.
package.json Removes deprecated test dependency, aligns react-test-renderer, adds missing eslint-plugin-react.
jest.setup.js Removes dead RN renderer require, removes global.window shim, improves Keyboard mock to be event-driven.
bun.lock Updates lockfile for dependency removals/additions and version alignment.
babel.config.js Switches preset to @react-native/babel-preset compatible with RN 0.78+.
.github/workflows/ci.yml Adds CI job to run typecheck, lint, and Jest on push/PR.
Review details
  • Files reviewed: 12/13 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines 1 to 4
import { useAccessibilityInfo } from "./useAccessibilityInfo"
import { act, renderHook } from "@testing-library/react-hooks"
import { act, renderHook, waitFor } from "@testing-library/react-native"
import { AccessibilityChangeEventName, AccessibilityInfo } from "react-native"

@trinadhkoya
trinadhkoya marked this pull request as draft September 5, 2026 14:46
@trinadhkoya
trinadhkoya force-pushed the fix/repair-test-suite-and-ci branch from 65798ee to b93c00d Compare September 5, 2026 14:56
@trinadhkoya
trinadhkoya requested a lite review from Copilot September 5, 2026 15:00
@trinadhkoya
trinadhkoya marked this pull request as ready for review September 5, 2026 15:01

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 Needs a closer look

A couple of updated tests mock React Native APIs without returning the cleanup handles (remove/cancel) that the hooks call, which can cause runtime errors during unmount/cleanup and should be corrected before approval.

Review details

Suppressed comments (2)

src/useAppState.test.ts:5

  • AppState.addEventListener is mocked without returning the subscription object, but useAppState calls subscription.remove() in its effect cleanup. This mock can cause runtime errors during unmount/cleanup and doesn’t reflect the real API; return { remove: ... } from the mock and from mockImplementationOnce.
import { act, renderHook } from "@testing-library/react-native"
import { AppState, AppStateStatus } from "react-native"
import { useAppState } from "./useAppState"

jest.mock("react-native", () => ({

src/useInteractionManager.test.ts:6

  • InteractionManager.runAfterInteractions is mocked without returning the cancellable handle, but useInteractionManager calls interactionPromise.cancel() in its effect cleanup. This mock can cause runtime errors during unmount/cleanup and doesn’t reflect the real API; return an object with cancel both in the default mock and the per-test mockImplementationOnce.
import { act, renderHook } from "@testing-library/react-native"
import { InteractionManager } from "react-native"

jest.mock("react-native", () => ({
	InteractionManager: {
  • Files reviewed: 12/13 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

The test suite could not run at all on a fresh clone, and neither CI
workflow executed the tests, so the breakage went unnoticed.

Fixes:
- babel.config.js: use @react-native/babel-preset (RN 0.78) instead of
  the removed metro-react-native-babel-preset, which was not installed
- jest.setup.js: drop the dead requireActual of the removed
  ReactNativeRenderer-prod path, and the unused global.window shim that
  clobbered setTimeout under @testing-library/react-native
- jest.setup.js: make the Keyboard mock a real emitter so addListener /
  emit actually drive the hook under test
- migrate all test files off the deprecated @testing-library/react-hooks
  to @testing-library/react-native's built-in renderHook / waitFor
- align react-test-renderer with react (18.3.1) to fix the renderer crash
- add the missing eslint-plugin-react dev dependency so lint runs
- return cleanup handles ({ remove } / { cancel }) from the AccessibilityInfo,
  AppState and InteractionManager mocks so effect cleanup no longer throws
  during unmount
- add a CI workflow that runs typecheck, lint and test on push and PR

All 42 tests across 8 suites now pass, along with typecheck and lint.
@trinadhkoya
trinadhkoya force-pushed the fix/repair-test-suite-and-ci branch from d63e3de to 9fcd64a Compare September 5, 2026 15:26

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟢 Approval recommended

The updates are consistent with RN 0.78/React 18 tooling expectations and the CI addition directly enforces the intended test/lint/typecheck guarantees going forward.

Review details
  • Files reviewed: 12/13 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟢 Approval recommended

The changes are consistent with the PR’s stated goals and appear complete, low-risk, and self-validating via CI-enabled typecheck/lint/test execution.

Review details
  • Files reviewed: 12/13 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

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.

2 participants