Skip to content

chore(journeys): migrate tests from Jest to Vitest and update configu…#9209

Open
mikeallisonJS wants to merge 4 commits into
mainfrom
26-00-MA-chore-journeys-ui-vitest
Open

chore(journeys): migrate tests from Jest to Vitest and update configu…#9209
mikeallisonJS wants to merge 4 commits into
mainfrom
26-00-MA-chore-journeys-ui-vitest

Conversation

@mikeallisonJS
Copy link
Copy Markdown
Collaborator

@mikeallisonJS mikeallisonJS commented May 14, 2026

…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.

Summary by CodeRabbit

  • Bug Fixes

    • Fixed an issue in video player controls where pending single-click actions could execute after the component was unmounted.
  • Chores

    • Migrated testing framework from Jest to Vitest across the library.

Review Change Stack

…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.
@mikeallisonJS mikeallisonJS requested a review from csiyang May 14, 2026 00:31
@mikeallisonJS mikeallisonJS self-assigned this May 14, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 14, 2026

Walkthrough

The 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 vi mocks and Vitest types, and adjusts a few async test assertions plus VideoControls click-timeout cleanup.

Changes

Journeys UI Vitest migration

Layer / File(s) Summary
Runner, config, and shared test harness
libs/journeys/ui/project.json, libs/journeys/ui/vitest.config.mts, libs/journeys/ui/setupTests.ts, libs/journeys/ui/tsconfig*.json, libs/journeys/ui/eslint.config.mjs, libs/journeys/ui/test/next-i18next-pages.ts, libs/journeys/ui/README.md
The library test target is switched to Nx Vitest, Vitest config and type wiring are added, shared setup/mocks are rewritten for Vitest, and the test shim/docs are updated.
Core component specs
libs/journeys/ui/src/components/{AiChat,...,TranslationDialogWrapper}/*.spec.tsx, libs/journeys/ui/src/components/{Button,Card}/..., libs/journeys/ui/src/libs/{action,blurImage,...}/*.spec.ts*
Most existing component and utility specs replace Jest mocks, spies, and types with Vitest equivalents, including typed Apollo mock results and a few skipped-test syntax updates.
Search, gallery, and template specs
libs/journeys/ui/src/components/SearchBar/..., libs/journeys/ui/src/components/TemplateGallery/..., libs/journeys/ui/src/components/TemplateView/..., libs/journeys/ui/src/libs/algolia/..., libs/journeys/ui/src/libs/useNavigationState/useNavigationState.spec.tsx
Search and template-related specs are migrated to Vitest router, media-query, and instantsearch mocks, with some async waits and timer handling adjusted in affected tests.
Video runtime and video specs
libs/journeys/ui/src/components/Video/VideoControls/VideoControls.tsx, libs/journeys/ui/src/components/Video/..., libs/journeys/ui/src/components/VideoEvents/VideoEvents.spec.tsx
VideoControls stores click timeout state in a ref and clears it on unmount, while video component and utility tests move to Vitest mocks, spies, timers, and typed helper access.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • JesusFilm/core#9151: Both PRs modify CopyToTeamDialog test coverage and related template/team test wiring.

Suggested reviewers

  • csiyang
  • edmonday
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 26-00-MA-chore-journeys-ui-vitest

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 14, 2026

Warnings
⚠️ ❗ Big PR (2092 changes)

(change count - 2092): Pull Request size seems relatively large. If Pull Request contains multiple changes, split each into separate PR will helps faster, easier review.

Generated by 🚫 dangerJS against fdb0df8

@nx-cloud
Copy link
Copy Markdown

nx-cloud Bot commented May 14, 2026

View your CI Pipeline Execution ↗ for commit fdb0df8

Command Status Duration Result
nx run watch-e2e:e2e ✅ Succeeded 20s View ↗
nx run journeys-admin-e2e:e2e ✅ Succeeded 29s View ↗
nx run videos-admin-e2e:e2e ✅ Succeeded 6s View ↗
nx run resources-e2e:e2e ✅ Succeeded 13s View ↗
nx run journeys-e2e:e2e ✅ Succeeded 22s View ↗
nx run-many --target=vercel-alias --projects=jo... ✅ Succeeded 1s View ↗
nx run-many --target=upload-sourcemaps --projec... ✅ Succeeded 20s View ↗
nx run-many --target=vercel-alias --projects=re... ✅ Succeeded 1s View ↗
Additional runs (12) ✅ Succeeded ... View ↗

☁️ Nx Cloud last updated this comment at 2026-05-21 20:50:55 UTC

@github-actions github-actions Bot temporarily deployed to Preview - journeys-admin May 14, 2026 00:33 Inactive
@github-actions github-actions Bot temporarily deployed to Preview - resources May 14, 2026 00:33 Inactive
@github-actions github-actions Bot temporarily deployed to Preview - videos-admin May 14, 2026 00:33 Inactive
@github-actions github-actions Bot temporarily deployed to Preview - journeys May 14, 2026 00:33 Inactive
@github-actions github-actions Bot temporarily deployed to Preview - watch May 14, 2026 00:33 Inactive
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 14, 2026

The latest updates on your projects.

Name Status Preview Updated (UTC)
journeys ✅ Ready journeys preview Fri May 22 08:47:10 NZST 2026

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 14, 2026

The latest updates on your projects.

Name Status Preview Updated (UTC)
videos-admin ✅ Ready videos-admin preview Fri May 22 08:47:02 NZST 2026

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 14, 2026

The latest updates on your projects.

Name Status Preview Updated (UTC)
watch ✅ Ready watch preview Fri May 22 08:47:09 NZST 2026

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 14, 2026

The latest updates on your projects.

Name Status Preview Updated (UTC)
resources ✅ Ready resources preview Fri May 22 08:47:49 NZST 2026

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 14, 2026

The latest updates on your projects.

Name Status Preview Updated (UTC)
journeys-admin ✅ Ready journeys-admin preview Fri May 22 08:48:07 NZST 2026

mikeallisonJS and others added 2 commits May 21, 2026 19:18
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>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

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 win

Undefined-path test currently passes null instead of undefined.

Line 35 duplicates the null case, so the undefined branch 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 win

Guard vi.useFakeTimers() cleanup with try/finally to prevent cross-test leakage.

vi.useRealTimers() (and clearIntervalSpy.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) in try/finally in 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

📥 Commits

Reviewing files that changed from the base of the PR and between 678563a and fdb0df8.

📒 Files selected for processing (122)
  • libs/journeys/ui/README.md
  • libs/journeys/ui/eslint.config.mjs
  • libs/journeys/ui/jest.config.ts
  • libs/journeys/ui/project.json
  • libs/journeys/ui/setupTests.ts
  • libs/journeys/ui/src/components/AiChat/ChatHeader/ChatHeader.spec.tsx
  • libs/journeys/ui/src/components/AiChat/DragHandle/DragHandle.spec.tsx
  • libs/journeys/ui/src/components/AiChatButton/AiChatButton.spec.tsx
  • libs/journeys/ui/src/components/BlockRenderer/BlockRenderer.spec.tsx
  • libs/journeys/ui/src/components/Button/Button.spec.tsx
  • libs/journeys/ui/src/components/Card/Card.mock.ts
  • libs/journeys/ui/src/components/Card/Card.spec.tsx
  • libs/journeys/ui/src/components/Card/ContainedCover/BackgroundVideo/BackgroundVideo.spec.tsx
  • libs/journeys/ui/src/components/CardWrapper/CardWrapper.spec.tsx
  • libs/journeys/ui/src/components/Conversation/Conversation.spec.tsx
  • libs/journeys/ui/src/components/CopyToTeamDialog/CopyToTeamDialog.spec.tsx
  • libs/journeys/ui/src/components/FramePortal/FramePortal.spec.tsx
  • libs/journeys/ui/src/components/Image/Image.spec.tsx
  • libs/journeys/ui/src/components/PromptInput/PromptInput.spec.tsx
  • libs/journeys/ui/src/components/RadioOption/GridVariant/GridVariant.spec.tsx
  • libs/journeys/ui/src/components/RadioOption/ListVariant/ListVariant.spec.tsx
  • libs/journeys/ui/src/components/RadioOption/RadioOption.spec.tsx
  • libs/journeys/ui/src/components/RadioQuestion/GridVariant/GridVariant.spec.tsx
  • libs/journeys/ui/src/components/RadioQuestion/ListVariant/ListVariant.spec.tsx
  • libs/journeys/ui/src/components/RadioQuestion/RadioQuestion.spec.tsx
  • libs/journeys/ui/src/components/SearchBar/LanguageButtons/LanguageButton/LanguageButton.spec.tsx
  • libs/journeys/ui/src/components/SearchBar/LanguageButtons/LanguageButtons.spec.tsx
  • libs/journeys/ui/src/components/SearchBar/SearchBar.spec.tsx
  • libs/journeys/ui/src/components/SearchBar/SearchDropdown/CountryLanguageSelector/CountryLanguageSelector.spec.tsx
  • libs/journeys/ui/src/components/SearchBar/SearchDropdown/RefinementGroups/RefinementGroup/RefinementGroup.spec.tsx
  • libs/journeys/ui/src/components/SearchBar/SearchDropdown/RefinementGroups/RefinementGroups.spec.tsx
  • libs/journeys/ui/src/components/SearchBar/SearchDropdown/SearchbarDropdown.spec.tsx
  • libs/journeys/ui/src/components/SearchBar/SearchDropdown/Suggestions/Suggestion/Suggestion.spec.tsx
  • libs/journeys/ui/src/components/SearchBar/SearchDropdown/Suggestions/Suggestions.spec.tsx
  • libs/journeys/ui/src/components/SignUp/SignUp.spec.tsx
  • libs/journeys/ui/src/components/Step/Step.spec.tsx
  • libs/journeys/ui/src/components/StepFooter/ChatButtons/ChatButtons.spec.tsx
  • libs/journeys/ui/src/components/StepFooter/FooterButtonList/FooterButtonList.spec.tsx
  • libs/journeys/ui/src/components/StepFooter/FooterButtonList/ReactionButton/ReactionButton.spec.tsx
  • libs/journeys/ui/src/components/StepFooter/FooterButtonList/ShareButton/ShareButton.spec.tsx
  • libs/journeys/ui/src/components/StepFooter/FooterButtonList/ShareButton/ShareDialog/ShareDialog.spec.tsx
  • libs/journeys/ui/src/components/StepFooter/FooterButtonList/StyledFooterButton/StyledFooterButton.spec.tsx
  • libs/journeys/ui/src/components/StepFooter/StepFooter.apologistChat.spec.tsx
  • libs/journeys/ui/src/components/StepFooter/StepFooter.spec.tsx
  • libs/journeys/ui/src/components/StepHeader/InformationButton/InformationButton.spec.tsx
  • libs/journeys/ui/src/components/StepHeader/Logo/Logo.spec.tsx
  • libs/journeys/ui/src/components/StepHeader/StepHeader.spec.tsx
  • libs/journeys/ui/src/components/StepHeader/StepHeaderMenu/StepHeaderMenu.spec.tsx
  • libs/journeys/ui/src/components/TeamProvider/TeamProvider.spec.tsx
  • libs/journeys/ui/src/components/TemplateGallery/HeaderAndLanguageFilter/HeaderAndLanguageFilter.spec.tsx
  • libs/journeys/ui/src/components/TemplateGallery/HeaderAndLanguageFilter/LanguageFilterDialog/LanguageFilterDialog.spec.tsx
  • libs/journeys/ui/src/components/TemplateGallery/HeaderAndLanguageFilter/LanguagesFilterPopper/LanguagesFilterPopper.spec.tsx
  • libs/journeys/ui/src/components/TemplateGallery/TagCarousels/CollectionButton/CollectionButton.spec.tsx
  • libs/journeys/ui/src/components/TemplateGallery/TagCarousels/FeltNeedsButton/FeltNeedsButton.spec.tsx
  • libs/journeys/ui/src/components/TemplateGallery/TagCarousels/TagCarousels.spec.tsx
  • libs/journeys/ui/src/components/TemplateGallery/TagsFilter/TagsFilter.spec.tsx
  • libs/journeys/ui/src/components/TemplateGallery/TemplateGallery.spec.tsx
  • libs/journeys/ui/src/components/TemplateGalleryCard/TemplateGalleryCard.spec.tsx
  • libs/journeys/ui/src/components/TemplateView/AccountCheckDialog/AccoutCheckDialog.spec.tsx
  • libs/journeys/ui/src/components/TemplateView/CreateJourneyButton/CreateJourneyButton.spec.tsx
  • libs/journeys/ui/src/components/TemplateView/TemplateFooter/TemplateFooter.spec.tsx
  • libs/journeys/ui/src/components/TemplateView/TemplatePreviewTabs/TemplateCardPreview/TemplateCardPreview.spec.tsx
  • libs/journeys/ui/src/components/TemplateView/TemplatePreviewTabs/TemplateCardPreview/TemplateCardPreviewItem/TemplateCardPreviewItem.spec.tsx
  • libs/journeys/ui/src/components/TemplateView/TemplatePreviewTabs/TemplatePreviewTabs.spec.tsx
  • libs/journeys/ui/src/components/TemplateView/TemplatePreviewTabs/TemplateVideoPreview/TemplateVideoPreview.spec.tsx
  • libs/journeys/ui/src/components/TemplateView/TemplateTags/TagItem/TagItem.spec.tsx
  • libs/journeys/ui/src/components/TemplateView/TemplateTags/TemplateTags.spec.tsx
  • libs/journeys/ui/src/components/TemplateView/TemplateView.spec.tsx
  • libs/journeys/ui/src/components/TemplateView/TemplateViewHeader/PreviewTemplateButton/PreviewTemplateButton.spec.tsx
  • libs/journeys/ui/src/components/TemplateView/TemplateViewHeader/TemplateActionButton/TemplateActionButton.spec.tsx
  • libs/journeys/ui/src/components/TemplateView/TemplateViewHeader/TemplateEditButton/TemplateEditButton.spec.tsx
  • libs/journeys/ui/src/components/TemplateView/TemplateViewHeader/TemplateViewHeader.spec.tsx
  • libs/journeys/ui/src/components/TemplateView/UseThisTemplateButton/UseThisTemplateButton.spec.tsx
  • libs/journeys/ui/src/components/TextField/TextField.spec.tsx
  • libs/journeys/ui/src/components/TextResponse/TextResponse.spec.tsx
  • libs/journeys/ui/src/components/TranslationDialogWrapper/TranslationDialogWrapper.spec.tsx
  • libs/journeys/ui/src/components/Video/InitAndPlay/InitAndPlay.spec.tsx
  • libs/journeys/ui/src/components/Video/Video.spec.tsx
  • libs/journeys/ui/src/components/Video/VideoControls/SubtitleButton/SubtitleButton.spec.tsx
  • libs/journeys/ui/src/components/Video/VideoControls/SubtitleButton/SubtitleMenu/SubtitleMenu.spec.tsx
  • libs/journeys/ui/src/components/Video/VideoControls/VideoControls.spec.tsx
  • libs/journeys/ui/src/components/Video/VideoControls/VideoControls.tsx
  • libs/journeys/ui/src/components/Video/VideoControls/VideoSettings/QualityMenu/QualityMenu.spec.tsx
  • libs/journeys/ui/src/components/Video/VideoControls/VideoSettings/SettingsButton/SettingsButton.spec.tsx
  • libs/journeys/ui/src/components/Video/VideoControls/VideoSettings/SettingsMenu/SettingsMenu.spec.tsx
  • libs/journeys/ui/src/components/Video/VideoControls/VideoSettings/VideoSettings.spec.tsx
  • libs/journeys/ui/src/components/Video/VideoStats/VideoStats.spec.tsx
  • libs/journeys/ui/src/components/Video/utils/extractYouTubeCaptionsAndAddTextTracks/extractYouTubeCaptionsAndAddTextTracks.spec.ts
  • libs/journeys/ui/src/components/Video/utils/getCaptionsAndSubtitleTracks/getCaptionsAndSubtitleTracks.spec.ts
  • libs/journeys/ui/src/components/Video/utils/getMuxMetadata/getMuxMetadata.spec.tsx
  • libs/journeys/ui/src/components/Video/utils/getYouTubePlayer/getYouTubePlayer.spec.ts
  • libs/journeys/ui/src/components/Video/utils/hideAllSubtitles/hideAllSubtitles.spec.ts
  • libs/journeys/ui/src/components/Video/utils/removeAllRemoteTextTracks/removeAllRemoteTextTracks.spec.ts
  • libs/journeys/ui/src/components/Video/utils/setYouTubeCaptionTrack/setYouTubeCaptionTrack.spec.ts
  • libs/journeys/ui/src/components/Video/utils/unloadYouTubeCaptions/unloadYouTubeCaptions.spec.ts
  • libs/journeys/ui/src/components/Video/utils/videoStatsUtils/formatTimeRanges/formatTimeRanges.spec.ts
  • libs/journeys/ui/src/components/Video/utils/videoStatsUtils/getCurrentQuality/getCurrentQuality.spec.ts
  • libs/journeys/ui/src/components/VideoEvents/VideoEvents.spec.tsx
  • libs/journeys/ui/src/components/VideoWrapper/VideoWrapper.spec.tsx
  • libs/journeys/ui/src/libs/CommandProvider/CommandProvider.spec.tsx
  • libs/journeys/ui/src/libs/EditorProvider/EditorProvider.spec.tsx
  • libs/journeys/ui/src/libs/JourneyProvider/JourneyProvider.spec.tsx
  • libs/journeys/ui/src/libs/action/action.spec.ts
  • libs/journeys/ui/src/libs/algolia/InstantSearchProvider/InstantSearchProvider.spec.tsx
  • libs/journeys/ui/src/libs/algolia/SearchBarProvider/SearchBarProvider.spec.tsx
  • libs/journeys/ui/src/libs/algolia/useAlgoliaVideos/useAlgoliaVideos.spec.tsx
  • libs/journeys/ui/src/libs/beaconHooks/beaconHooks.spec.ts
  • libs/journeys/ui/src/libs/blurImage/blurImage.spec.ts
  • libs/journeys/ui/src/libs/getGoalDetails/getGoalDetails.spec.tsx
  • libs/journeys/ui/src/libs/getStepHeading/getStepHeading.spec.ts
  • libs/journeys/ui/src/libs/useCountryQuery/useCountryQuery.spec.tsx
  • libs/journeys/ui/src/libs/useJourneyQuery/useJourneyQuery.spec.tsx
  • libs/journeys/ui/src/libs/useJourneysQuery/useJourneysQuery.spec.tsx
  • libs/journeys/ui/src/libs/useLanguagesContinentsQuery/useLanguagesContinentsQuery.spec.tsx
  • libs/journeys/ui/src/libs/useLanguagesQuery/useLanguagesQuery.spec.tsx
  • libs/journeys/ui/src/libs/useNavigationState/useNavigationState.spec.tsx
  • libs/journeys/ui/src/libs/useTagsQuery/useTagsQuery.spec.tsx
  • libs/journeys/ui/test/next-i18next-pages.ts
  • libs/journeys/ui/tsconfig.lib.json
  • libs/journeys/ui/tsconfig.spec.json
  • libs/journeys/ui/tsconfig.stories.json
  • libs/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

Comment on lines +66 to +68
// 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(() => {})
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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

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.

Comment on lines +1357 to 1359
it.skip('should not show red outline when editableLabel is not provided', () => {
// disabled due to Jest v30 compatibility issues
render(
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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

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
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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

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.

Suggested change
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()
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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

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.

Suggested change
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.

Comment on lines +212 to 223
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)
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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

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.

Suggested change
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.

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.

1 participant