Skip to content

test(ui): jest 30#93303

Merged
scttcper merged 41 commits intomasterfrom
scttcper/jest-30
Jul 14, 2025
Merged

test(ui): jest 30#93303
scttcper merged 41 commits intomasterfrom
scttcper/jest-30

Conversation

@scttcper
Copy link
Member

@scttcper scttcper commented Jun 11, 2025

jest 30 changelog the biggest change being the newer version of JSDOM which breaks a few things for us.

Two major issues around window.location:

Can no longer assign mocks directly to the location object (location.assign(), location.replace()) now error when used.

solution: test helper like testableWindowLocation.assign() that we mock out in tests

Can no longer directly set the url in tests window.location.search = '?something=true'

solution make jsdom available as a global and use jsdom.reconfigure({url: something}) which lets you set the url. getsentry/jest-sentry-environment#26

@github-actions github-actions bot added the Scope: Frontend Automatically applied to PRs that change frontend components label Jun 11, 2025
@codecov
Copy link

codecov bot commented Jun 11, 2025

❌ 1 Tests Failed:

Tests completed Failed Passed Skipped
10723 1 10722 9
View the top 1 failed test(s) by shortest run time
useActiveReplayTab with replay-ai-summaries feature flag should use AI as a default, when there is a click search in the url
Stack Traces | 0.031s run time
Error: Expected test not to call console.error().

If the error is expected, test for it explicitly by mocking it out using jest.spyOn(console, 'error').mockImplementation() and test that the warning occurs.

Error: Not implemented: navigation (except hash changes)
    at module.exports (.../sentry/node_modules/.pnpm/jsdom@26.1..../jsdom/browser/not-implemented.js:9:17)
    at navigateFetch (.../sentry/node_modules/.pnpm/jsdom@26.1..../living/window/navigation.js:77:3)
    at exports.navigate (.../sentry/node_modules/.pnpm/jsdom@26.1..../living/window/navigation.js:55:3)
    at LocationImpl._locationObjectNavigate (.../sentry/node_modules/.pnpm/jsdom@26.1..../living/window/Location-impl.js:30:5)
    at LocationImpl._locationObjectSetterNavigate (.../sentry/node_modules/.pnpm/jsdom@26.1..../living/window/Location-impl.js:24:17)
    at LocationImpl.set search [as search] (.../sentry/node_modules/.pnpm/jsdom@26.1..../living/window/Location-impl.js:171:10)
    at Location.set search [as search] (.../sentry/node_modules/.pnpm/jsdom@26.1..../living/generated/Location.js:298:39)
    at mockLocation (.../replays/hooks/useActiveReplayTab.spec.tsx:12:25)
    at Object.mockLocation (.../replays/hooks/useActiveReplayTab.spec.tsx:104:7)
    at Promise.finally.completed (.../sentry/node_modules/.pnpm/jest-circus@30.0.4_babel-plugin-macros@3.1..../jest-circus/build/jestAdapterInit.js:1559:28)
    at new Promise (<anonymous>)
    at callAsyncCircusFn (.../sentry/node_modules/.pnpm/jest-circus@30.0.4_babel-plugin-macros@3.1..../jest-circus/build/jestAdapterInit.js:1499:10)
    at _callCircusTest (.../sentry/node_modules/.pnpm/jest-circus@30.0.4_babel-plugin-macros@3.1..../jest-circus/build/jestAdapterInit.js:1009:40)
    at processTicksAndRejections (node:internal/process/task_queues:105:5)
    at _runTest (.../sentry/node_modules/.pnpm/jest-circus@30.0.4_babel-plugin-macros@3.1..../jest-circus/build/jestAdapterInit.js:949:3)
    at _runTestsForDescribeBlock (.../sentry/node_modules/.pnpm/jest-circus@30.0.4_babel-plugin-macros@3.1..../jest-circus/build/jestAdapterInit.js:839:13)
    at _runTestsForDescribeBlock (.../sentry/node_modules/.pnpm/jest-circus@30.0.4_babel-plugin-macros@3.1..../jest-circus/build/jestAdapterInit.js:829:11)
    at _runTestsForDescribeBlock (.../sentry/node_modules/.pnpm/jest-circus@30.0.4_babel-plugin-macros@3.1..../jest-circus/build/jestAdapterInit.js:829:11)
    at run (.../sentry/node_modules/.pnpm/jest-circus@30.0.4_babel-plugin-macros@3.1..../jest-circus/build/jestAdapterInit.js:757:3)
    at runAndTransformResultsToJestFormat (.../sentry/node_modules/.pnpm/jest-circus@30.0.4_babel-plugin-macros@3.1..../jest-circus/build/jestAdapterInit.js:1920:21)
    at jestAdapter (.../sentry/node_modules/.pnpm/jest-circus@30.0.4_babel-plugin-macros@3.1..../jest-circus/build/runner.js:101:19)
    at runTestInternal (.../sentry/node_modules/.pnpm/jest-runner@30.0..../jest-runner/build/testWorker.js:272:16)
    at runTest (.../sentry/node_modules/.pnpm/jest-runner@30.0..../jest-runner/build/testWorker.js:340:7)
    at Object.worker (.../sentry/node_modules/.pnpm/jest-runner@30.0..../jest-runner/build/testWorker.js:494:12) {
  type: 'not implemented'
}
    at console.captureMessage [as error] (.../sentry/node_modules/.pnpm/jest-fail-on-console@3.3..../node_modules/jest-fail-on-console/index.js:83:25)
    at VirtualConsole.<anonymous> (.../sentry/node_modules/.pnpm/@jest+environment-jsdom-abstract@30.0.4_jsdom@26.1.0/node_modules/@.../environment-jsdom-abstract/build/index.js:78:23)
    at VirtualConsole.emit (node:events:518:28)
    at module.exports (.../sentry/node_modules/.pnpm/jsdom@26.1..../jsdom/browser/not-implemented.js:12:26)
    at navigateFetch (.../sentry/node_modules/.pnpm/jsdom@26.1..../living/window/navigation.js:77:3)
    at exports.navigate (.../sentry/node_modules/.pnpm/jsdom@26.1..../living/window/navigation.js:55:3)
    at LocationImpl._locationObjectNavigate (.../sentry/node_modules/.pnpm/jsdom@26.1..../living/window/Location-impl.js:30:5)
    at LocationImpl._locationObjectSetterNavigate (.../sentry/node_modules/.pnpm/jsdom@26.1..../living/window/Location-impl.js:24:17)
    at LocationImpl.set search [as search] (.../sentry/node_modules/.pnpm/jsdom@26.1..../living/window/Location-impl.js:171:10)
    at Location.set search [as search] (.../sentry/node_modules/.pnpm/jsdom@26.1..../living/generated/Location.js:298:39)
    at mockLocation (.../replays/hooks/useActiveReplayTab.spec.tsx:12:25)
    at Object.mockLocation (.../replays/hooks/useActiveReplayTab.spec.tsx:104:7)
    at Promise.finally.completed (.../sentry/node_modules/.pnpm/jest-circus@30.0.4_babel-plugin-macros@3.1..../jest-circus/build/jestAdapterInit.js:1559:28)
    at new Promise (<anonymous>)
    at callAsyncCircusFn (.../sentry/node_modules/.pnpm/jest-circus@30.0.4_babel-plugin-macros@3.1..../jest-circus/build/jestAdapterInit.js:1499:10)
    at _callCircusTest (.../sentry/node_modules/.pnpm/jest-circus@30.0.4_babel-plugin-macros@3.1..../jest-circus/build/jestAdapterInit.js:1009:40)
    at processTicksAndRejections (node:internal/process/task_queues:105:5)
    at _runTest (.../sentry/node_modules/.pnpm/jest-circus@30.0.4_babel-plugin-macros@3.1..../jest-circus/build/jestAdapterInit.js:949:3)
    at _runTestsForDescribeBlock (.../sentry/node_modules/.pnpm/jest-circus@30.0.4_babel-plugin-macros@3.1..../jest-circus/build/jestAdapterInit.js:839:13)
    at _runTestsForDescribeBlock (.../sentry/node_modules/.pnpm/jest-circus@30.0.4_babel-plugin-macros@3.1..../jest-circus/build/jestAdapterInit.js:829:11)
    at _runTestsForDescribeBlock (.../sentry/node_modules/.pnpm/jest-circus@30.0.4_babel-plugin-macros@3.1..../jest-circus/build/jestAdapterInit.js:829:11)
    at run (.../sentry/node_modules/.pnpm/jest-circus@30.0.4_babel-plugin-macros@3.1..../jest-circus/build/jestAdapterInit.js:757:3)
    at runAndTransformResultsToJestFormat (.../sentry/node_modules/.pnpm/jest-circus@30.0.4_babel-plugin-macros@3.1..../jest-circus/build/jestAdapterInit.js:1920:21)
    at jestAdapter (.../sentry/node_modules/.pnpm/jest-circus@30.0.4_babel-plugin-macros@3.1..../jest-circus/build/runner.js:101:19)
    at runTestInternal (.../sentry/node_modules/.pnpm/jest-runner@30.0..../jest-runner/build/testWorker.js:272:16)
    at runTest (.../sentry/node_modules/.pnpm/jest-runner@30.0..../jest-runner/build/testWorker.js:340:7)
    at Object.worker (.../sentry/node_modules/.pnpm/jest-runner@30.0..../jest-runner/build/testWorker.js:494:12)
    at flushUnexpectedConsoleCalls (.../sentry/node_modules/.pnpm/jest-fail-on-console@3.3..../node_modules/jest-fail-on-console/index.js:48:13)
    at Object.<anonymous> (.../sentry/node_modules/.pnpm/jest-fail-on-console@3.3..../node_modules/jest-fail-on-console/index.js:145:7)
    at Promise.finally.completed (.../sentry/node_modules/.pnpm/jest-circus@30.0.4_babel-plugin-macros@3.1..../jest-circus/build/jestAdapterInit.js:1559:28)
    at new Promise (<anonymous>)
    at callAsyncCircusFn (.../sentry/node_modules/.pnpm/jest-circus@30.0.4_babel-plugin-macros@3.1..../jest-circus/build/jestAdapterInit.js:1499:10)
    at _callCircusHook (.../sentry/node_modules/.pnpm/jest-circus@30.0.4_babel-plugin-macros@3.1..../jest-circus/build/jestAdapterInit.js:978:40)
    at processTicksAndRejections (node:internal/process/task_queues:105:5)
    at _runTest (.../sentry/node_modules/.pnpm/jest-circus@30.0.4_babel-plugin-macros@3.1..../jest-circus/build/jestAdapterInit.js:951:5)
    at _runTestsForDescribeBlock (.../sentry/node_modules/.pnpm/jest-circus@30.0.4_babel-plugin-macros@3.1..../jest-circus/build/jestAdapterInit.js:839:13)
    at _runTestsForDescribeBlock (.../sentry/node_modules/.pnpm/jest-circus@30.0.4_babel-plugin-macros@3.1..../jest-circus/build/jestAdapterInit.js:829:11)
    at _runTestsForDescribeBlock (.../sentry/node_modules/.pnpm/jest-circus@30.0.4_babel-plugin-macros@3.1..../jest-circus/build/jestAdapterInit.js:829:11)
    at run (.../sentry/node_modules/.pnpm/jest-circus@30.0.4_babel-plugin-macros@3.1..../jest-circus/build/jestAdapterInit.js:757:3)
    at runAndTransformResultsToJestFormat (.../sentry/node_modules/.pnpm/jest-circus@30.0.4_babel-plugin-macros@3.1..../jest-circus/build/jestAdapterInit.js:1920:21)
    at jestAdapter (.../sentry/node_modules/.pnpm/jest-circus@30.0.4_babel-plugin-macros@3.1..../jest-circus/build/runner.js:101:19)
    at runTestInternal (.../sentry/node_modules/.pnpm/jest-runner@30.0..../jest-runner/build/testWorker.js:272:16)
    at runTest (.../sentry/node_modules/.pnpm/jest-runner@30.0..../jest-runner/build/testWorker.js:340:7)
    at Object.worker (.../sentry/node_modules/.pnpm/jest-runner@30.0..../jest-runner/build/testWorker.js:494:12)

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

# Conflicts:
#	package.json
#	pnpm-lock.yaml
Comment on lines -47 to -51
it('renders user messages differently', () => {
renderComponent();
const userMessage = screen.getByText('User message');
expect(userMessage.closest('div')).toHaveStyle('color: inherit');
});
Copy link
Member Author

Choose a reason for hiding this comment

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

this test doesn't seem to work anymore in latest jsdom. I think it was attempting to read from emotion's styles on a nearby div.

# Conflicts:
#	pnpm-lock.yaml
# Conflicts:
#	pnpm-lock.yaml
cursor[bot]

This comment was marked as outdated.

scttcper added a commit that referenced this pull request Jul 1, 2025
fixes an issue with the next version of jsdom where the dropdown doesn't close when clicking outside. As far as i can tell the behavior is the same with or without these options.

unblocks #93303
scttcper added 2 commits July 8, 2025 10:31
# Conflicts:
#	package.json
#	pnpm-lock.yaml
# Conflicts:
#	pnpm-lock.yaml
// To disable the sentry jest integration, set this to 'jsdom'
testEnvironment: '@sentry/jest-environment/jsdom',
testEnvironmentOptions: {
globalsCleanup: 'on',
Copy link
Member Author

Choose a reason for hiding this comment

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

"@types/history": "^3.2.5",
"@types/invariant": "^2.2.35",
"@types/jest": "29.5.14",
"@types/jest": "30.0.0",
Copy link
Member

Choose a reason for hiding this comment

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

woo!

@scttcper scttcper enabled auto-merge (squash) July 14, 2025 16:26
@scttcper scttcper merged commit 63ede5a into master Jul 14, 2025
46 checks passed
@scttcper scttcper deleted the scttcper/jest-30 branch July 14, 2025 16:37
andrewshie-sentry pushed a commit that referenced this pull request Jul 14, 2025
Pulls just the testable window location changes out for Jest 30 #93303

window.location in the next version of jsdom is not configurable and
cannot be changed via assignment. By using testableWindowLocation we can
mock the entire module and do whatever we want instead of trying to
overwrite the jsdom globals
andrewshie-sentry pushed a commit that referenced this pull request Jul 14, 2025
[jest 30 changelog](https://jestjs.io/blog/2025/06/04/jest-30) the
biggest change being the newer version of JSDOM which breaks a few
things for us.

Two major issues around window.location:

> Can no longer assign mocks directly to the location object
(location.assign(), location.replace()) now error when used.

**solution:** test helper like `testableWindowLocation.assign()` that we
mock out in tests

> Can no longer directly set the url in tests `window.location.search =
'?something=true'`

**solution** make jsdom available as a global and use
`jsdom.reconfigure({url: something})` which lets you set the url.
getsentry/jest-sentry-environment#26
ryan953 added a commit that referenced this pull request Jul 28, 2025
This `require()` call wasn't working since we added
`--experimental-transform-types` in
#93303

We can see our balancer_strategy logging stopped logging `by_path` as
often, instead showing 'other':
<img width="530" height="196" alt="SCR-20250726-mgai"
src="https://github.com/user-attachments/assets/b449b7a7-f750-47c1-9b4c-1e602fe55fbd"
/>


And this impacted at test worker runtimes too:
<img width="531" height="203" alt="SCR-20250726-mfyl"
src="https://github.com/user-attachments/assets/98e4b294-1b16-4b3e-b487-c443132e7d3e"
/>


Without the balancer stats js tests got more than a minute slower,
because the shards are unbalanced and slowest one is taking longer now.
What we learned though is that the jest-balance.json sharing is pretty
good and keeps all the shards at about the same runtime!


I made a new dashboard to see all the CI worker runtimes for
frontend.yaml:
https://sentry.sentry.io/dashboard/141271/?project=5899451&statsPeriod=30d.
The critical path is usually jest, but eslint is taking almost the same
amount of time too running in parallel. If we speedup jest then we'll
save wall-time in CI.
There's also a dashboard to see the slowest test suites and test cases.
It's got the balancer_strategy chart added too:
https://sentry.sentry.io/dashboard/141273/?project=4857230&statsPeriod=30d
@github-actions github-actions bot locked and limited conversation to collaborators Jul 30, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Scope: Frontend Automatically applied to PRs that change frontend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants