[No QA] Run all Jest tests through the OXC transformer - #100438
[No QA] Run all Jest tests through the OXC transformer#100438roryabraham wants to merge 16 commits into
Conversation
babel-jest was still transforming the regular suite so jest.mock stayed hoisted. Route every JS/TS file through OXC, then a small Babel pass for loose CJS, import() lowering, and mock hoisting. Keep babel-jest only as the node_modules/Flow fallback.
CI failed with TDZ on circular imports and jest.mock factories that closed over const. Babel used to rewrite those to var; restore that with plugin-transform-block-scoping so existing tests keep working.
|
HOLD: esbuild CJS still TDZs on the #99910 (import/no-cycle part 3) cuts Test-side esbuild CJS mismatches (mock-factory TDZ, |
Collapse CJS_PLUGINS to satisfy oxfmt, and ignore the Babel plugins the transformer loads by string name so knip does not flag them as unlisted.
Babel was only needed to hoist jest.mock. Emit CJS and lower import() with esbuild, then run a hoist-only Babel pass on files that call jest.mock. Drop the unused Babel CJS plugin knip ignores.
OXC and esbuild do not hoist jest.mock above require(). Splice top-level jest.mock/unmock calls with a scanner instead of a Babel AST pass so the CJS path stays native.
OXC still does not hoist jest.mock. Parse the esbuild CJS output with oxc-parser and splice top-level jest.mock/unmock spans above require() so Jest intercepts them without Babel or a hand-rolled lexer.
DomainTest's mockImplementation must return a Promise. DuplicateTest must treat write spy calls as unknown[][] so the command type guard can narrow parameters off the API write union.
esbuild CJS live-binding getters and leftover const/let caused TDZ and slower module load. Emit CJS with Babel loose modules, lower import(), and hoist jest.mock after OXC strips TS/JSX. Drop oxc-parser.
jest-expo haste uses defaultPlatform ios, so ImageSVG resolves to index.ios.tsx which imports expo-image. Stub expo-image in setup so UI suites can load. Revert the esbuild-era jest.spyOn / mock rewrites now that Babel loose CJS is back.
|
npm has a |
CopilotPageTest looks for mocked icon names like icon-three-dots in the tree. Returning null from expo-image hid those sources on the jest-expo iOS ImageSVG path.
Shard 7 now keeps leftover handles after full-App tests survive ExpoImage/StoreReview, so CI never finishes. --forceExit matches local shard 7, which already passed.
Cancel pending Network queue starts during teardown so Jest workers exit without --forceExit.
# Conflicts: # tests/ui/MoneyRequestReportPreview.test.tsx
Coverage shards exhaust self-hosted runner resources with six native-transform workers. Use four workers so the runner remains responsive.
Codecov Report✅ Changes either increased or maintained existing code coverage, great job!
|
Explanation of Change
Regular Jest still used
babel-jestfor every JS/TS file, while Reassure already used the OXC transformer. The split existed becausejest.mockhas to be hoisted above generatedrequire()calls.This PR routes all Jest runs through
config/babel/oxcJestTransformer.js:tests/,jest/, and__mocks__/).import(), and runsbabel-plugin-jest-hoist.babel-jestremains the fallback for Flow innode_modules.strictMode: falseis required so existing tests that assign to getter-only native mock properties (e.g.AppState.currentState) keep working. The CI Jest cache key now also hashesjest.config.jsand the transformer files.jest-expo's haste map uses
defaultPlatform: 'ios', so@components/ImageSVGresolves toindex.ios.tsxwhich importsexpo-image. That package has no jest-expo mock, sojest/setup.tsstubs it.Benchmark (local,
--maxWorkers=6)Re-run on merged head
c7a8258with Node 26.5.0, npm 11.17.0, and--maxWorkers=6. Cold runs started from a cleared Jest cache.tests/unit/hookscoldtests/unit/hookswarmCorrectness checks on the OXC path:
tests/unit/hooks(157 suites / 1635 tests),tests/actions(83 / 2293),tests/navigation(48 / 564), plusbun test ./tests/tooling/oxcTransformer.test.ts.Fixed Issues
$
PROPOSAL:
Tests
// TODO: The human co-author must fill out the tests you ran before marking this PR as "ready for review"
// Please describe what tests you performed that validates your changed worked.
Offline tests
QA Steps
// TODO: The human co-author must fill out the QA tests you ran before marking this PR as "ready for review".
// Please describe what QA needs to do to validate your changes and what areas do they need to test for regressions.
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectionAvatar, I verified the components usingAvatarare working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))npm run compress-svg)Avataris modified, I verified thatAvataris working as expected in all cases)Designlabel and/or tagged@Expensify/designso the design team can review the changes.mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps.Screenshots/Videos
Android: Native
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari