Skip to content

build: upgrade jest to 30 - #3413

Draft
aresnik11 wants to merge 9 commits into
mainfrom
ajr-bump-jest
Draft

build: upgrade jest to 30#3413
aresnik11 wants to merge 9 commits into
mainfrom
ajr-bump-jest

Conversation

@aresnik11

@aresnik11 aresnik11 commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Overview

Bumps Jest from 29.6.430.x across the gamut monorepo, refreshes the testing-library family to match, and removes some dead jest-related deps. All tests and typechecks pass.

Landed as focused commits:

Commit What
Bump jest core family to v30 jest/jest-environment-jsdom → 30.x, babel-jest → 30.4.1, ts-jest^29.4.12 (supports jest 30; ts-jest 30 isn't published yet). Pulls in jsdom 26.
Remove unused jest deps jest-environment-jsdom-global (peer capped at jest 29, unused), @testing-library/react-hooks (unused — renderHook comes from RTL), mutationobserver-shim (jsdom 26 has native MutationObserver)
Refresh testing-library for jest 30 @testing-library/jest-dom ^5^7, @testing-library/dom ^8^10
Add explicit @types/jest ^30 — jest global types were only present transitively before
Replace removed jest matcher aliases toBeCalledtoHaveBeenCalled, lastCalledWithtoHaveBeenLastCalledWith
Fix Modal primary-variant test for jest-dom v7 Give the test a non-last view so the Next button is actually enabled
Update snapshot headers for jest 30 goo.gljestjs.io header URL; no content drift

Breaking changes addressed

  • Removed expect matcher aliases — jest 30 deleted them; migrated toBeCalled/lastCalledWith.
  • jsdom 21 → 26 — validated getComputedStyle canary tests and timer/rAF-heavy suites; no regressions.
  • jest-dom v5 → v7 — v7 computes styles more accurately, which exposed one latent false-positive test (see notes).
  • Snapshot header URL change — regenerated (metadata only).

Prerequisites (already satisfied — no work needed)

  • Node ^22.13.1 — jest 30 dropped 14/16/19/21.
  • TypeScript 5.9.3 — above jest 30's new 5.4 minimum.
  • @nx/jest@22.6.0 already resolves jest 30 internals.

PR Checklist

  • Related to designs:
  • Related to JIRA ticket: GMT-237
  • Version plan added/updated (or not needed)
  • I have run this code to verify it works
  • This PR includes unit tests for the code change
  • This PR includes testing instructions tests for the code change
  • The alpha package of this PR is passing end-to-end tests in all relevant Codecademy repositories

Testing instructions

# Install the updated deps
yarn install

# Run the full test suite across all projects
yarn test
# (equivalently: yarn nx run-many --target=test --all)

# Typecheck
yarn verify

Expected: all 9 projects green (1587 tests pass, 0 fail), typecheck clean, and a clean working tree afterward (no snapshot churn).

PR Links and Envs

Repository PR Link
Monolith Monolith PR
Mono Mono PR

aresnik11 and others added 7 commits August 18, 2026 09:32
jest/jest-environment-jsdom 29.6.4 -> 30.x, babel-jest 29.6.4 -> 30.4.1,
ts-jest -> ^29.4.12 (supports jest 30; ts-jest 30 unpublished). Pulls in jsdom 26.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Drop jest-environment-jsdom-global (unused; peer capped at jest 29),
@testing-library/react-hooks (unused; renderHook comes from RTL), and
mutationobserver-shim (jsdom 26 has native MutationObserver).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@testing-library/jest-dom ^5.16 -> ^7 and @testing-library/dom ^8 -> ^10
to align with jest 30 / RTL 15 / jsdom 26 (jest-dom v7 requires node 22).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The jest global types (describe/it) were only present transitively before;
removing the unused deps dropped @types/jest, breaking tsconfig types:[jest].
Pin it explicitly at ^30 to match jest 30.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Jest 30 removed the alias matchers. toBeCalled -> toHaveBeenCalled and
lastCalledWith -> toHaveBeenLastCalledWith across Disclosure, GridForm,
and useDebouncedField tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The single-view config disabled the next CTA (last view), so jest-dom v7's
accurate toHaveStyle read the disabled background. Add a second view so the
next button is enabled and its primary variant is actually asserted.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Jest 30 changed the snapshot header URL (goo.gl -> jestjs.io); no content drift.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@nx-cloud

nx-cloud Bot commented Aug 18, 2026

Copy link
Copy Markdown

View your CI Pipeline Execution ↗ for commit 391e32c


☁️ Nx Cloud last updated this comment at 2026-08-20 20:39:25 UTC

@aresnik11 aresnik11 changed the title Ajr bump jest build: bump Jest Aug 18, 2026
@codecov

codecov Bot commented Aug 19, 2026

Copy link
Copy Markdown

❌ 1 Tests Failed:

Tests completed Failed Passed Skipped
1528 1 1527 0
View the top 1 failed test(s) by shortest run time
parseSelectOptions creates an option list
Stack Traces | 0.004s run time
Error: expect(received).toMatchSnapshot()

Snapshot name: `parseSelectOptions creates an option list 1`

- Snapshot  - 26
+ Received  + 14

  [
-   {
-     "$$typeof": Symbol(react.transitional.element),
-     "_owner": null,
-     "_store": {},
-     "key": "test-val",
-     "props": {
-       "children": "Value",
-       "data-testid": "test-val",
-       "label": "Value",
-       "value": "val",
-     },
-     "type": "option",
-   },
-   {
-     "$$typeof": Symbol(react.transitional.element),
-     "_owner": null,
-     "_store": {},
-     "key": "test-val2",
-     "props": {
-       "children": "Value 2",
-       "data-testid": "test-val2",
-       "label": "Value 2",
-       "value": "val2",
-     },
-     "type": "option",
-   },
+   <option
+     data-testid="test-val"
+     label="Value"
+     value="val"
+   >
+     Value
+   </option>,
+   <option
+     data-testid="test-val2"
+     label="Value 2"
+     value="val2"
+   >
+     Value 2
+   </option>,
  ]
    at Object.<anonymous> (.../Form/__tests__/utils.test.tsx:10:21)
    at Promise.finally.completed (.../jest-circus/build/jestAdapterInit.js:1561:28)
    at new Promise (<anonymous>)
    at callAsyncCircusFn (.../jest-circus/build/jestAdapterInit.js:1501:10)
    at _callCircusTest (.../jest-circus/build/jestAdapterInit.js:1011:40)
    at async _runTest (.../jest-circus/build/jestAdapterInit.js:951:3)
    at async .../jest-circus/build/jestAdapterInit.js:853:7
    at async _runTestsForDescribeBlock (.../jest-circus/build/jestAdapterInit.js:866:11)
    at async _runTestsForDescribeBlock (.../jest-circus/build/jestAdapterInit.js:861:11)
    at async run (.../jest-circus/build/jestAdapterInit.js:765:3)
    at async runAndTransformResultsToJestFormat (.../jest-circus/build/jestAdapterInit.js:1993:21)
    at async jestAdapter (.../jest-circus/build/runner.js:111:19)
    at async runTestInternal (.../jest-runner/build/index.js:276:16)
    at async runTest (.../jest-runner/build/index.js:344:7)

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

@aresnik11 aresnik11 changed the title build: bump Jest build: upgrade jest to 30 Aug 19, 2026
@aresnik11
aresnik11 marked this pull request as ready for review August 19, 2026 18:38
@aresnik11
aresnik11 requested a review from a team as a code owner August 19, 2026 18:38
Comment on lines +372 to +380
{
title: 'Multi view',
children: <>View 2</>,
primaryCta: { actionType: 'confirm', children: 'Done' },
secondaryCta: {
actionType: 'cancel',
children: 'Cancel',
},
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this seems out of place, why did this need to change?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

oh! it was a real test failure where the next button was disabled bc it was testing multiview with only one view. selling the jest bump with this one example!

@dreamwasp dreamwasp left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

these are failing for me locally -

Image

@aresnik11
aresnik11 marked this pull request as draft August 19, 2026 19:29
@aresnik11

Copy link
Copy Markdown
Contributor Author

these are failing for me locally -

Image

apparently its related to node version! im on 22.14.0 and its working. looking into it! explanation: Jest 30 loads a .ts config natively as ESM whenever Node reports native TypeScript support (process.features.typescript), which is default-on in Node ≥ 22.18 / 23.6 / 24. You're on 22.14 (flag off) so jest quietly uses ts-node/CJS and everything resolves. Coworkers on newer Node get the ESM loader, where extensionless imports (and __dirname) are illegal → the config fails to parse → every project's tests fail.

@codecademydev

Copy link
Copy Markdown
Collaborator

📬 Published Alpha Packages:

Package Version npm Diff
@codecademy/gamut 73.0.1-alpha.aeff7c.0 npm diff
@codecademy/gamut-icons 10.0.1-alpha.aeff7c.0 npm diff
@codecademy/gamut-illustrations 1.0.1-alpha.aeff7c.0 npm diff
@codecademy/gamut-kit 3.0.18-alpha.aeff7c.0 npm diff
@codecademy/gamut-patterns 1.0.1-alpha.aeff7c.0 npm diff
@codecademy/gamut-styles 21.0.1-alpha.aeff7c.0 npm diff
@codecademy/gamut-tests 7.0.1-alpha.aeff7c.0 npm diff
@codecademy/variance 1.0.1-alpha.aeff7c.0 npm diff
eslint-plugin-gamut 3.0.1-alpha.aeff7c.0 npm diff

@github-actions

Copy link
Copy Markdown
Contributor

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.

3 participants