chore(journeys): migrate tests from Jest to Vitest and update configu…#9209
chore(journeys): migrate tests from Jest to Vitest and update configu…#9209mikeallisonJS wants to merge 4 commits into
Conversation
…rations - Removed Jest configuration and related files. - Updated ESLint and TypeScript configurations to support Vitest. - Modified test files to replace Jest mocks with Vitest equivalents. - Updated README to reflect the change in testing framework. - Adjusted project settings to use Vitest for testing execution.
WalkthroughThe journeys-ui library replaces Jest-based test runner configuration with Vitest, updates shared test setup and test-only shims, migrates component and library specs to ChangesJourneys UI Vitest migration
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
|
|
View your CI Pipeline Execution ↗ for commit fdb0df8
☁️ Nx Cloud last updated this comment at |
|
The latest updates on your projects.
|
|
The latest updates on your projects.
|
|
The latest updates on your projects.
|
|
The latest updates on your projects.
|
|
The latest updates on your projects.
|
Resolve CopyToTeamDialog.spec conflict by taking main's refactored tests and re-applying the Vitest migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The merge brought in specs and behaviour that the Jest→Vitest migration had not covered. Jest swallowed the resulting post-teardown async errors; Vitest (and the nx vitest reporter) surface them and fail otherwise-passing specs. - PromptInput/AiChatButton: migrate leftover jest.fn/jest.mock to vi - ShareDialog: replace a self-referential .then mock that recursed to a stack overflow under Vitest's spy with a normally-resolved clipboard mock - Step: mock StepViewEventCreate in the two seoTitle tests that render an active step, so the on-mount mutation no longer rejects unmocked - VideoControls: clear the single/double-click delay timeout on unmount so a deferred play() can't fire against a torn-down player - setupTests: dispose video.js players after each test, stub jsdom media APIs, polyfill requestAnimationFrame, and harden the next/dynamic shim against late rejections Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
libs/journeys/ui/src/components/Video/utils/unloadYouTubeCaptions/unloadYouTubeCaptions.spec.ts (1)
34-36:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winUndefined-path test currently passes
nullinstead ofundefined.Line 35 duplicates the null case, so the
undefinedbranch is never validated.Suggested fix
it('should return early when ytPlayer is undefined', () => { - unloadYouTubeCaptions(null) + unloadYouTubeCaptions(undefined) expect(mockUnloadModule).not.toHaveBeenCalled() })🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@libs/journeys/ui/src/components/Video/utils/unloadYouTubeCaptions/unloadYouTubeCaptions.spec.ts` around lines 34 - 36, The test in unloadYouTubeCaptions.spec.ts calls unloadYouTubeCaptions(null) but never validates the undefined branch; update the spec so it passes undefined (i.e., unloadYouTubeCaptions(undefined)) or add a separate test that calls unloadYouTubeCaptions(undefined) to cover that path, referencing the unloadYouTubeCaptions function in the test file to ensure the undefined case is actually exercised.libs/journeys/ui/src/components/TemplateView/TemplatePreviewTabs/TemplateCardPreview/TemplateCardPreviewItem/TemplateCardPreviewItem.spec.tsx (1)
170-190:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winGuard
vi.useFakeTimers()cleanup withtry/finallyto prevent cross-test leakage.
vi.useRealTimers()(andclearIntervalSpy.mockRestore()in the unmount test) currently run only on the happy path; if an assertion throws earlier, fake timers/spies can bleed into later tests. Wrap the timer setup/restore (and spy restore) intry/finallyin both tests.Suggested fix
it('should disable focusable elements inside iframe for guestPreview', () => { vi.useFakeTimers() - - const { container } = renderWithProviders( - <TemplateCardPreviewItem step={step} variant="guestPreview" /> - ) - - const iframe = container.querySelector('iframe') - if (iframe?.contentDocument?.body != null) { - const button = iframe.contentDocument.createElement('button') - button.textContent = 'Click me' - iframe.contentDocument.body.appendChild(button) - - act(() => { - vi.advanceTimersByTime(100) - }) - - expect(button.getAttribute('tabindex')).toBe('-1') - } - - vi.useRealTimers() + try { + const { container } = renderWithProviders( + <TemplateCardPreviewItem step={step} variant="guestPreview" /> + ) + + const iframe = container.querySelector('iframe') + if (iframe?.contentDocument?.body != null) { + const button = iframe.contentDocument.createElement('button') + button.textContent = 'Click me' + iframe.contentDocument.body.appendChild(button) + + act(() => { + vi.advanceTimersByTime(100) + }) + + expect(button.getAttribute('tabindex')).toBe('-1') + } + } finally { + vi.useRealTimers() + } }) it('should clean up interval and observer on unmount', () => { vi.useFakeTimers() const clearIntervalSpy = vi.spyOn(global, 'clearInterval') - - const { unmount } = renderWithProviders( - <TemplateCardPreviewItem step={step} variant="guestPreview" /> - ) - - unmount() - expect(clearIntervalSpy).toHaveBeenCalled() - - clearIntervalSpy.mockRestore() - vi.useRealTimers() + try { + const { unmount } = renderWithProviders( + <TemplateCardPreviewItem step={step} variant="guestPreview" /> + ) + unmount() + expect(clearIntervalSpy).toHaveBeenCalled() + } finally { + clearIntervalSpy.mockRestore() + vi.useRealTimers() + } })🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@libs/journeys/ui/src/components/TemplateView/TemplatePreviewTabs/TemplateCardPreview/TemplateCardPreviewItem/TemplateCardPreviewItem.spec.tsx` around lines 170 - 190, The tests in TemplateCardPreviewItem.spec.tsx that call vi.useFakeTimers() (and the unmount test that calls clearIntervalSpy.mockRestore()) must be protected with try/finally to ensure cleanup always runs; update the tests that call vi.useFakeTimers() and the test using clearIntervalSpy to wrap the test body in try { ... } finally { vi.useRealTimers(); /* and clearIntervalSpy.mockRestore() if used in that test */ } so fake timers and mocked restores are executed even if assertions throw, referencing the existing vi.useFakeTimers(), vi.useRealTimers(), and clearIntervalSpy.mockRestore() usages in those tests.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@libs/journeys/ui/setupTests.ts`:
- Around line 66-68: Replace the empty catch handlers that currently read
`.catch(() => {})` with handlers that preserve swallow semantics but return a
value (e.g., `.catch(() => undefined)` or `.catch(() => void 0)`) so lint rule
`@typescript-eslint/no-empty-function` is satisfied; update both occurrences in
setupTests.ts (the two `.catch(() => {})` calls around the promise teardown
logic) to return undefined rather than being empty functions.
In `@libs/journeys/ui/src/components/Button/Button.spec.tsx`:
- Around line 1357-1359: The skipped test "should not show red outline when
editableLabel is not provided" is annotated with an outdated Jest v30 reason;
update the skip comment near the it.skip invocation in Button.spec.tsx to
explain it's skipped due to Vitest-specific compatibility or migration issues
(e.g., Vitest behavior or API differences), include a brief actionable note
(what to check to re-enable: Vitest config or mocking) and keep the it.skip
intact so tests remain skipped until resolved.
In `@libs/journeys/ui/src/components/SearchBar/SearchBar.spec.tsx`:
- Line 20: The test overrides the process-wide global.fetch with "global.fetch =
vi.fn(fetchCountryMock) as Mock" and never restores it; capture the original
global.fetch before the override (e.g., const originalFetch = global.fetch) and
add a teardown (afterEach or afterAll) that restores it (set global.fetch =
originalFetch) or call vi.restoreAllMocks in that teardown so the mocked fetch
does not leak into other suites; reference the existing override line using
global.fetch, fetchCountryMock and vi.fn to locate where to add the capture and
the afterEach/afterAll restore.
- Line 45: The shared refine mock (refine) is created once for the whole suite
causing call counts to leak between tests; update the spec to reset it between
tests by either making refine reassignable (change const refine to let refine)
and reinitializing refine = vi.fn() inside a beforeEach block, or keep const and
call refine.mockClear() in a beforeEach; apply the change where refine is
referenced in SearchBar.spec.tsx so each test starts with a fresh spy for
toHaveBeenCalledTimes assertions.
In
`@libs/journeys/ui/src/components/SearchBar/SearchDropdown/RefinementGroups/RefinementGroup/RefinementGroup.spec.tsx`:
- Around line 212-223: The test sets global mocks for window.ResizeObserver and
spies on HTMLElement.prototype getters (scrollWidth, clientWidth) but never
restores them; update RefinementGroup.spec.tsx to save the original
ResizeObserver and the original getter descriptors or use
vi.restoreAllMocks/vi.resetAllMocks in an afterEach/afterAll block, and then
restore window.ResizeObserver and the HTMLElement.prototype getters (the spies
on 'scrollWidth' and 'clientWidth') so subsequent tests are not affected;
reference the existing mocks created for window.ResizeObserver and the vi.spyOn
calls to locate where to add the teardown.
---
Outside diff comments:
In
`@libs/journeys/ui/src/components/TemplateView/TemplatePreviewTabs/TemplateCardPreview/TemplateCardPreviewItem/TemplateCardPreviewItem.spec.tsx`:
- Around line 170-190: The tests in TemplateCardPreviewItem.spec.tsx that call
vi.useFakeTimers() (and the unmount test that calls
clearIntervalSpy.mockRestore()) must be protected with try/finally to ensure
cleanup always runs; update the tests that call vi.useFakeTimers() and the test
using clearIntervalSpy to wrap the test body in try { ... } finally {
vi.useRealTimers(); /* and clearIntervalSpy.mockRestore() if used in that test
*/ } so fake timers and mocked restores are executed even if assertions throw,
referencing the existing vi.useFakeTimers(), vi.useRealTimers(), and
clearIntervalSpy.mockRestore() usages in those tests.
In
`@libs/journeys/ui/src/components/Video/utils/unloadYouTubeCaptions/unloadYouTubeCaptions.spec.ts`:
- Around line 34-36: The test in unloadYouTubeCaptions.spec.ts calls
unloadYouTubeCaptions(null) but never validates the undefined branch; update the
spec so it passes undefined (i.e., unloadYouTubeCaptions(undefined)) or add a
separate test that calls unloadYouTubeCaptions(undefined) to cover that path,
referencing the unloadYouTubeCaptions function in the test file to ensure the
undefined case is actually exercised.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: f53399b7-c069-447d-a754-75812b708181
📒 Files selected for processing (122)
libs/journeys/ui/README.mdlibs/journeys/ui/eslint.config.mjslibs/journeys/ui/jest.config.tslibs/journeys/ui/project.jsonlibs/journeys/ui/setupTests.tslibs/journeys/ui/src/components/AiChat/ChatHeader/ChatHeader.spec.tsxlibs/journeys/ui/src/components/AiChat/DragHandle/DragHandle.spec.tsxlibs/journeys/ui/src/components/AiChatButton/AiChatButton.spec.tsxlibs/journeys/ui/src/components/BlockRenderer/BlockRenderer.spec.tsxlibs/journeys/ui/src/components/Button/Button.spec.tsxlibs/journeys/ui/src/components/Card/Card.mock.tslibs/journeys/ui/src/components/Card/Card.spec.tsxlibs/journeys/ui/src/components/Card/ContainedCover/BackgroundVideo/BackgroundVideo.spec.tsxlibs/journeys/ui/src/components/CardWrapper/CardWrapper.spec.tsxlibs/journeys/ui/src/components/Conversation/Conversation.spec.tsxlibs/journeys/ui/src/components/CopyToTeamDialog/CopyToTeamDialog.spec.tsxlibs/journeys/ui/src/components/FramePortal/FramePortal.spec.tsxlibs/journeys/ui/src/components/Image/Image.spec.tsxlibs/journeys/ui/src/components/PromptInput/PromptInput.spec.tsxlibs/journeys/ui/src/components/RadioOption/GridVariant/GridVariant.spec.tsxlibs/journeys/ui/src/components/RadioOption/ListVariant/ListVariant.spec.tsxlibs/journeys/ui/src/components/RadioOption/RadioOption.spec.tsxlibs/journeys/ui/src/components/RadioQuestion/GridVariant/GridVariant.spec.tsxlibs/journeys/ui/src/components/RadioQuestion/ListVariant/ListVariant.spec.tsxlibs/journeys/ui/src/components/RadioQuestion/RadioQuestion.spec.tsxlibs/journeys/ui/src/components/SearchBar/LanguageButtons/LanguageButton/LanguageButton.spec.tsxlibs/journeys/ui/src/components/SearchBar/LanguageButtons/LanguageButtons.spec.tsxlibs/journeys/ui/src/components/SearchBar/SearchBar.spec.tsxlibs/journeys/ui/src/components/SearchBar/SearchDropdown/CountryLanguageSelector/CountryLanguageSelector.spec.tsxlibs/journeys/ui/src/components/SearchBar/SearchDropdown/RefinementGroups/RefinementGroup/RefinementGroup.spec.tsxlibs/journeys/ui/src/components/SearchBar/SearchDropdown/RefinementGroups/RefinementGroups.spec.tsxlibs/journeys/ui/src/components/SearchBar/SearchDropdown/SearchbarDropdown.spec.tsxlibs/journeys/ui/src/components/SearchBar/SearchDropdown/Suggestions/Suggestion/Suggestion.spec.tsxlibs/journeys/ui/src/components/SearchBar/SearchDropdown/Suggestions/Suggestions.spec.tsxlibs/journeys/ui/src/components/SignUp/SignUp.spec.tsxlibs/journeys/ui/src/components/Step/Step.spec.tsxlibs/journeys/ui/src/components/StepFooter/ChatButtons/ChatButtons.spec.tsxlibs/journeys/ui/src/components/StepFooter/FooterButtonList/FooterButtonList.spec.tsxlibs/journeys/ui/src/components/StepFooter/FooterButtonList/ReactionButton/ReactionButton.spec.tsxlibs/journeys/ui/src/components/StepFooter/FooterButtonList/ShareButton/ShareButton.spec.tsxlibs/journeys/ui/src/components/StepFooter/FooterButtonList/ShareButton/ShareDialog/ShareDialog.spec.tsxlibs/journeys/ui/src/components/StepFooter/FooterButtonList/StyledFooterButton/StyledFooterButton.spec.tsxlibs/journeys/ui/src/components/StepFooter/StepFooter.apologistChat.spec.tsxlibs/journeys/ui/src/components/StepFooter/StepFooter.spec.tsxlibs/journeys/ui/src/components/StepHeader/InformationButton/InformationButton.spec.tsxlibs/journeys/ui/src/components/StepHeader/Logo/Logo.spec.tsxlibs/journeys/ui/src/components/StepHeader/StepHeader.spec.tsxlibs/journeys/ui/src/components/StepHeader/StepHeaderMenu/StepHeaderMenu.spec.tsxlibs/journeys/ui/src/components/TeamProvider/TeamProvider.spec.tsxlibs/journeys/ui/src/components/TemplateGallery/HeaderAndLanguageFilter/HeaderAndLanguageFilter.spec.tsxlibs/journeys/ui/src/components/TemplateGallery/HeaderAndLanguageFilter/LanguageFilterDialog/LanguageFilterDialog.spec.tsxlibs/journeys/ui/src/components/TemplateGallery/HeaderAndLanguageFilter/LanguagesFilterPopper/LanguagesFilterPopper.spec.tsxlibs/journeys/ui/src/components/TemplateGallery/TagCarousels/CollectionButton/CollectionButton.spec.tsxlibs/journeys/ui/src/components/TemplateGallery/TagCarousels/FeltNeedsButton/FeltNeedsButton.spec.tsxlibs/journeys/ui/src/components/TemplateGallery/TagCarousels/TagCarousels.spec.tsxlibs/journeys/ui/src/components/TemplateGallery/TagsFilter/TagsFilter.spec.tsxlibs/journeys/ui/src/components/TemplateGallery/TemplateGallery.spec.tsxlibs/journeys/ui/src/components/TemplateGalleryCard/TemplateGalleryCard.spec.tsxlibs/journeys/ui/src/components/TemplateView/AccountCheckDialog/AccoutCheckDialog.spec.tsxlibs/journeys/ui/src/components/TemplateView/CreateJourneyButton/CreateJourneyButton.spec.tsxlibs/journeys/ui/src/components/TemplateView/TemplateFooter/TemplateFooter.spec.tsxlibs/journeys/ui/src/components/TemplateView/TemplatePreviewTabs/TemplateCardPreview/TemplateCardPreview.spec.tsxlibs/journeys/ui/src/components/TemplateView/TemplatePreviewTabs/TemplateCardPreview/TemplateCardPreviewItem/TemplateCardPreviewItem.spec.tsxlibs/journeys/ui/src/components/TemplateView/TemplatePreviewTabs/TemplatePreviewTabs.spec.tsxlibs/journeys/ui/src/components/TemplateView/TemplatePreviewTabs/TemplateVideoPreview/TemplateVideoPreview.spec.tsxlibs/journeys/ui/src/components/TemplateView/TemplateTags/TagItem/TagItem.spec.tsxlibs/journeys/ui/src/components/TemplateView/TemplateTags/TemplateTags.spec.tsxlibs/journeys/ui/src/components/TemplateView/TemplateView.spec.tsxlibs/journeys/ui/src/components/TemplateView/TemplateViewHeader/PreviewTemplateButton/PreviewTemplateButton.spec.tsxlibs/journeys/ui/src/components/TemplateView/TemplateViewHeader/TemplateActionButton/TemplateActionButton.spec.tsxlibs/journeys/ui/src/components/TemplateView/TemplateViewHeader/TemplateEditButton/TemplateEditButton.spec.tsxlibs/journeys/ui/src/components/TemplateView/TemplateViewHeader/TemplateViewHeader.spec.tsxlibs/journeys/ui/src/components/TemplateView/UseThisTemplateButton/UseThisTemplateButton.spec.tsxlibs/journeys/ui/src/components/TextField/TextField.spec.tsxlibs/journeys/ui/src/components/TextResponse/TextResponse.spec.tsxlibs/journeys/ui/src/components/TranslationDialogWrapper/TranslationDialogWrapper.spec.tsxlibs/journeys/ui/src/components/Video/InitAndPlay/InitAndPlay.spec.tsxlibs/journeys/ui/src/components/Video/Video.spec.tsxlibs/journeys/ui/src/components/Video/VideoControls/SubtitleButton/SubtitleButton.spec.tsxlibs/journeys/ui/src/components/Video/VideoControls/SubtitleButton/SubtitleMenu/SubtitleMenu.spec.tsxlibs/journeys/ui/src/components/Video/VideoControls/VideoControls.spec.tsxlibs/journeys/ui/src/components/Video/VideoControls/VideoControls.tsxlibs/journeys/ui/src/components/Video/VideoControls/VideoSettings/QualityMenu/QualityMenu.spec.tsxlibs/journeys/ui/src/components/Video/VideoControls/VideoSettings/SettingsButton/SettingsButton.spec.tsxlibs/journeys/ui/src/components/Video/VideoControls/VideoSettings/SettingsMenu/SettingsMenu.spec.tsxlibs/journeys/ui/src/components/Video/VideoControls/VideoSettings/VideoSettings.spec.tsxlibs/journeys/ui/src/components/Video/VideoStats/VideoStats.spec.tsxlibs/journeys/ui/src/components/Video/utils/extractYouTubeCaptionsAndAddTextTracks/extractYouTubeCaptionsAndAddTextTracks.spec.tslibs/journeys/ui/src/components/Video/utils/getCaptionsAndSubtitleTracks/getCaptionsAndSubtitleTracks.spec.tslibs/journeys/ui/src/components/Video/utils/getMuxMetadata/getMuxMetadata.spec.tsxlibs/journeys/ui/src/components/Video/utils/getYouTubePlayer/getYouTubePlayer.spec.tslibs/journeys/ui/src/components/Video/utils/hideAllSubtitles/hideAllSubtitles.spec.tslibs/journeys/ui/src/components/Video/utils/removeAllRemoteTextTracks/removeAllRemoteTextTracks.spec.tslibs/journeys/ui/src/components/Video/utils/setYouTubeCaptionTrack/setYouTubeCaptionTrack.spec.tslibs/journeys/ui/src/components/Video/utils/unloadYouTubeCaptions/unloadYouTubeCaptions.spec.tslibs/journeys/ui/src/components/Video/utils/videoStatsUtils/formatTimeRanges/formatTimeRanges.spec.tslibs/journeys/ui/src/components/Video/utils/videoStatsUtils/getCurrentQuality/getCurrentQuality.spec.tslibs/journeys/ui/src/components/VideoEvents/VideoEvents.spec.tsxlibs/journeys/ui/src/components/VideoWrapper/VideoWrapper.spec.tsxlibs/journeys/ui/src/libs/CommandProvider/CommandProvider.spec.tsxlibs/journeys/ui/src/libs/EditorProvider/EditorProvider.spec.tsxlibs/journeys/ui/src/libs/JourneyProvider/JourneyProvider.spec.tsxlibs/journeys/ui/src/libs/action/action.spec.tslibs/journeys/ui/src/libs/algolia/InstantSearchProvider/InstantSearchProvider.spec.tsxlibs/journeys/ui/src/libs/algolia/SearchBarProvider/SearchBarProvider.spec.tsxlibs/journeys/ui/src/libs/algolia/useAlgoliaVideos/useAlgoliaVideos.spec.tsxlibs/journeys/ui/src/libs/beaconHooks/beaconHooks.spec.tslibs/journeys/ui/src/libs/blurImage/blurImage.spec.tslibs/journeys/ui/src/libs/getGoalDetails/getGoalDetails.spec.tsxlibs/journeys/ui/src/libs/getStepHeading/getStepHeading.spec.tslibs/journeys/ui/src/libs/useCountryQuery/useCountryQuery.spec.tsxlibs/journeys/ui/src/libs/useJourneyQuery/useJourneyQuery.spec.tsxlibs/journeys/ui/src/libs/useJourneysQuery/useJourneysQuery.spec.tsxlibs/journeys/ui/src/libs/useLanguagesContinentsQuery/useLanguagesContinentsQuery.spec.tsxlibs/journeys/ui/src/libs/useLanguagesQuery/useLanguagesQuery.spec.tsxlibs/journeys/ui/src/libs/useNavigationState/useNavigationState.spec.tsxlibs/journeys/ui/src/libs/useTagsQuery/useTagsQuery.spec.tsxlibs/journeys/ui/test/next-i18next-pages.tslibs/journeys/ui/tsconfig.lib.jsonlibs/journeys/ui/tsconfig.spec.jsonlibs/journeys/ui/tsconfig.stories.jsonlibs/journeys/ui/vitest.config.mts
💤 Files with no reviewable changes (2)
- libs/journeys/ui/jest.config.ts
- libs/journeys/ui/src/components/FramePortal/FramePortal.spec.tsx
| // Loads can still be in flight when a test tears down; swallow the | ||
| // late rejection so it does not surface as an unhandled error. | ||
| .catch(() => {}) |
There was a problem hiding this comment.
Fix empty catch handlers to satisfy linting.
Line 68 and Line 87 use catch(() => {}), which violates @typescript-eslint/no-empty-function and will fail lint checks. Keep swallow semantics but return a value.
Suggested patch
- .catch(() => {})
+ .catch(() => undefined)
@@
- .catch(() => {})
+ .catch(() => undefined)Also applies to: 87-87
🧰 Tools
🪛 ESLint
[error] 68-68: Unexpected empty arrow function.
(@typescript-eslint/no-empty-function)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@libs/journeys/ui/setupTests.ts` around lines 66 - 68, Replace the empty catch
handlers that currently read `.catch(() => {})` with handlers that preserve
swallow semantics but return a value (e.g., `.catch(() => undefined)` or
`.catch(() => void 0)`) so lint rule `@typescript-eslint/no-empty-function` is
satisfied; update both occurrences in setupTests.ts (the two `.catch(() => {})`
calls around the promise teardown logic) to return undefined rather than being
empty functions.
| it.skip('should not show red outline when editableLabel is not provided', () => { | ||
| // disabled due to Jest v30 compatibility issues | ||
| render( |
There was a problem hiding this comment.
Update stale skip reason to reference Vitest context.
The comment says this test is disabled due to “Jest v30 compatibility issues,” which is now misleading after the Vitest migration. Please update the reason so future debugging isn’t misdirected.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@libs/journeys/ui/src/components/Button/Button.spec.tsx` around lines 1357 -
1359, The skipped test "should not show red outline when editableLabel is not
provided" is annotated with an outdated Jest v30 reason; update the skip comment
near the it.skip invocation in Button.spec.tsx to explain it's skipped due to
Vitest-specific compatibility or migration issues (e.g., Vitest behavior or API
differences), include a brief actionable note (what to check to re-enable:
Vitest config or mocking) and keep the it.skip intact so tests remain skipped
until resolved.
| import { SearchBar } from './SearchBar' | ||
|
|
||
| global.fetch = jest.fn(fetchCountryMock) as jest.Mock | ||
| global.fetch = vi.fn(fetchCountryMock) as Mock |
There was a problem hiding this comment.
Restore global.fetch after this suite to prevent cross-test leakage.
Line 20 overrides a process-wide global and never restores it, which can contaminate unrelated tests.
Suggested fix
+const originalFetch = global.fetch
global.fetch = vi.fn(fetchCountryMock) as Mock
+
+afterAll(() => {
+ global.fetch = originalFetch
+})📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| global.fetch = vi.fn(fetchCountryMock) as Mock | |
| const originalFetch = global.fetch | |
| global.fetch = vi.fn(fetchCountryMock) as Mock | |
| afterAll(() => { | |
| global.fetch = originalFetch | |
| }) |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@libs/journeys/ui/src/components/SearchBar/SearchBar.spec.tsx` at line 20, The
test overrides the process-wide global.fetch with "global.fetch =
vi.fn(fetchCountryMock) as Mock" and never restores it; capture the original
global.fetch before the override (e.g., const originalFetch = global.fetch) and
add a teardown (afterEach or afterAll) that restores it (set global.fetch =
originalFetch) or call vi.restoreAllMocks in that teardown so the mocked fetch
does not leak into other suites; reference the existing override line using
global.fetch, fetchCountryMock and vi.fn to locate where to add the capture and
the afterEach/afterAll restore.
|
|
||
| describe('SearchBar', () => { | ||
| const refine = jest.fn() | ||
| const refine = vi.fn() |
There was a problem hiding this comment.
Reset shared refine mock between tests.
Line 45 creates one shared spy for the whole suite; call counts can accumulate and make toHaveBeenCalledTimes(...) assertions flaky/order-dependent.
Suggested fix
describe('SearchBar', () => {
const refine = vi.fn()
+ beforeEach(() => {
+ refine.mockClear()
+ })📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const refine = vi.fn() | |
| const refine = vi.fn() | |
| beforeEach(() => { | |
| refine.mockClear() | |
| }) |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@libs/journeys/ui/src/components/SearchBar/SearchBar.spec.tsx` at line 45, The
shared refine mock (refine) is created once for the whole suite causing call
counts to leak between tests; update the spec to reset it between tests by
either making refine reassignable (change const refine to let refine) and
reinitializing refine = vi.fn() inside a beforeEach block, or keep const and
call refine.mockClear() in a beforeEach; apply the change where refine is
referenced in SearchBar.spec.tsx so each test starts with a fresh spy for
toHaveBeenCalledTimes assertions.
| window.ResizeObserver = vi.fn().mockImplementation(() => ({ | ||
| observe: vi.fn(), | ||
| unobserve: vi.fn(), | ||
| disconnect: vi.fn() | ||
| })) | ||
|
|
||
| jest | ||
| vi | ||
| .spyOn(HTMLElement.prototype, 'scrollWidth', 'get') | ||
| .mockImplementation(() => 200) | ||
| jest | ||
| vi | ||
| .spyOn(HTMLElement.prototype, 'clientWidth', 'get') | ||
| .mockImplementation(() => 100) |
There was a problem hiding this comment.
Clean up global/prototype mocks after this tooltip test.
This mutates window.ResizeObserver and HTMLElement.prototype getters without restoration, which can affect later specs.
Suggested fix
it('should show tooltip when hovering over langauge', async () => {
+ const originalResizeObserver = window.ResizeObserver
window.ResizeObserver = vi.fn().mockImplementation(() => ({
observe: vi.fn(),
unobserve: vi.fn(),
disconnect: vi.fn()
}))
@@
await waitFor(() =>
expect(
screen.getByRole('tooltip', { name: 'Spanish, Latin American' })
).toBeInTheDocument()
)
+
+ window.ResizeObserver = originalResizeObserver
+ vi.restoreAllMocks()
})📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| window.ResizeObserver = vi.fn().mockImplementation(() => ({ | |
| observe: vi.fn(), | |
| unobserve: vi.fn(), | |
| disconnect: vi.fn() | |
| })) | |
| jest | |
| vi | |
| .spyOn(HTMLElement.prototype, 'scrollWidth', 'get') | |
| .mockImplementation(() => 200) | |
| jest | |
| vi | |
| .spyOn(HTMLElement.prototype, 'clientWidth', 'get') | |
| .mockImplementation(() => 100) | |
| it('should show tooltip when hovering over langauge', async () => { | |
| const originalResizeObserver = window.ResizeObserver | |
| window.ResizeObserver = vi.fn().mockImplementation(() => ({ | |
| observe: vi.fn(), | |
| unobserve: vi.fn(), | |
| disconnect: vi.fn() | |
| })) | |
| vi | |
| .spyOn(HTMLElement.prototype, 'scrollWidth', 'get') | |
| .mockImplementation(() => 200) | |
| vi | |
| .spyOn(HTMLElement.prototype, 'clientWidth', 'get') | |
| .mockImplementation(() => 100) | |
| await waitFor(() => | |
| expect( | |
| screen.getByRole('tooltip', { name: 'Spanish, Latin American' }) | |
| ).toBeInTheDocument() | |
| ) | |
| window.ResizeObserver = originalResizeObserver | |
| vi.restoreAllMocks() | |
| }) |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@libs/journeys/ui/src/components/SearchBar/SearchDropdown/RefinementGroups/RefinementGroup/RefinementGroup.spec.tsx`
around lines 212 - 223, The test sets global mocks for window.ResizeObserver and
spies on HTMLElement.prototype getters (scrollWidth, clientWidth) but never
restores them; update RefinementGroup.spec.tsx to save the original
ResizeObserver and the original getter descriptors or use
vi.restoreAllMocks/vi.resetAllMocks in an afterEach/afterAll block, and then
restore window.ResizeObserver and the HTMLElement.prototype getters (the spies
on 'scrollWidth' and 'clientWidth') so subsequent tests are not affected;
reference the existing mocks created for window.ResizeObserver and the vi.spyOn
calls to locate where to add the teardown.
…rations
Summary by CodeRabbit
Bug Fixes
Chores