Skip to content

CI/CD: Refresh Frontend Test Suites#1056

Merged
rahulharpal1603 merged 9 commits into
AOSSIE-Org:mainfrom
rohan-pandeyy:ci-cd/frontend-test-suites
May 30, 2026
Merged

CI/CD: Refresh Frontend Test Suites#1056
rahulharpal1603 merged 9 commits into
AOSSIE-Org:mainfrom
rohan-pandeyy:ci-cd/frontend-test-suites

Conversation

@rohan-pandeyy
Copy link
Copy Markdown
Contributor

@rohan-pandeyy rohan-pandeyy commented Jan 21, 2026

closes #889

Description

Addressing the need for a reliable, modern testing baseline for the frontend. This PR introduces a layered frontend testing strategy and incrementally expands it with navigation interaction sanity tests.

The intent is to provide fast, stable and high-signal checks.

Changes

Infrastructure

  • Test Utils: src/test-utils.tsx with a customRender function that wraps components in Redux, Router, and Theme providers.
  • Fresh Store: src/app/store.ts and test utils to create a fresh Redux store for every test run. prevents state leakage.

New Tests

  • Page Sanity Tests

    • Home: Confirms the page renders a valid core state (gallery, empty state, or loading).
    • Settings: Verifies presence of key sections:
      • Folder Management
      • User Preferences
      • Application Controls
  • Sidebar Navigation

    • Verifies all primary navigation links render correctly.
    • Validates route changes when sidebar links are clicked:
      • Home
      • AI Tagging
      • Favourites
      • Videos
      • Albums
      • Memories
      • Settings

Checklist

  • Sanity Tests:
    • Home Page Structure
    • Settings Page Sections
  • Sidebar navigation structure & interactions

Summary by CodeRabbit

  • Tests

    • Expanded test infrastructure with console suppression, extensive platform and HTTP mocks, and shared test utilities/providers.
    • Added many unit and interaction tests: pages, sidebar navigation, theme toggle, settings, dialogs, empty states, loader, utilities, and date grouping.
    • Removed a previous matchMedia polyfill.
  • Refactor

    • Simplified store setup by extracting a root reducer.
  • Chores

    • Added a browser-mapping package dependency.

@github-actions github-actions Bot added CI/CD enhancement New feature or request tests labels Jan 21, 2026
@rohan-pandeyy rohan-pandeyy changed the title CI/CD: Refresh Frontend Sanity Tests & Infrastructure CI/CD: Refresh Frontend Test Suites Jan 21, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jan 21, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds extensive frontend test scaffolding and deterministic mocks (Tauri, Axios, window.matchMedia), shared React test utilities/providers, many new unit/integration tests for pages and components, exports a combined Redux rootReducer, and adds baseline-browser-mapping to package.json.

Changes

Cohort / File(s) Summary
Jest setup & runtime mocks
frontend/jest.setup.ts
Suppresses test console output; adds window.matchMedia handling and broad Jest mocks for Tauri core/plugins and a comprehensive Axios mock (default export, create, HTTP methods with preset responses).
Test utilities & providers
frontend/src/test-utils.tsx
New test harness: AllTheProviders, CustomRenderOptions, and customRender exported as render to wrap components with Redux Provider, ThemeProvider, QueryClientProvider, and MemoryRouter.
New frontend tests
frontend/src/pages/__tests__/PageSanity.test.tsx, frontend/src/pages/__tests__/SettingsPage.test.tsx, frontend/src/pages/__tests__/allPages.test.tsx, frontend/src/components/__tests__/Sidebar.test.tsx, frontend/src/components/__tests__/ThemeToggle.test.tsx, frontend/src/components/__tests__/DeleteImageDialog.test.tsx, frontend/src/components/__tests__/EmptyStates.test.tsx, frontend/src/components/__tests__/GlobalLoader.test.tsx, frontend/src/components/__tests__/InfoDialog.test.tsx, frontend/src/lib/__tests__/utils.test.ts, frontend/src/utils/__tests__/dateUtils.test.ts
Adds numerous unit and interaction tests covering pages, navigation, theme toggle, dialogs, empty states, global loader, utils, and date helpers. One test file removes a previous global matchMedia polyfill.
Store export change
frontend/src/app/store.ts
Exports a new rootReducer = combineReducers(...) and updates store configuration to use reducer: rootReducer. No behavioral changes to individual reducers.
Dependency update
frontend/package.json
Adds baseline-browser-mapping to dependencies and devDependencies.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

TypeScript/JavaScript

Suggested reviewers

  • rahulharpal1603

Poem

🐰 I hopped through mocks and routes tonight,

Wrapped providers snug and tests polite,
Reducers joined in tidy rows,
Clicks and toggles, passing shows,
A carrot for each green test light 🥕

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'CI/CD: Refresh Frontend Test Suites' clearly and concisely summarizes the main objective of adding and updating frontend test infrastructure and test suites.
Linked Issues check ✅ Passed The PR fully addresses objectives from issue #889: refreshes test suites with modern provider-wrapped renders, adds high-value navigation and page sanity tests, establishes fresh Redux store per test to prevent state leakage, and increases CI confidence in UI stability.
Out of Scope Changes check ✅ Passed All changes are directly related to refreshing frontend test infrastructure and adding comprehensive test coverage for pages, components, and utilities, with no unrelated modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

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: 1

🤖 Fix all issues with AI agents
In `@frontend/src/components/__tests__/Sidebar.test.tsx`:
- Around line 21-28: Update the test assertions in Sidebar.test.tsx to use the
ROUTES constants instead of hard-coded string paths: replace assertions that
expect literal paths like "/settings", "/home", "/ai-tagging", "/favourites",
"/videos", "/albums", "/memories" with assertions that build the expected path
from ROUTES (e.g., `"/" + ROUTES.HOME` or `"/" + ROUTES.SETTINGS` as
appropriate) so the tests reference the same source-of-truth ROUTES constants
used by the Route definitions; update every navigation assertion in the file
that currently uses string literals to use the ROUTES.* symbols to avoid
coupling to hard-coded paths.
🧹 Nitpick comments (1)
frontend/src/components/__tests__/Sidebar.test.tsx (1)

54-149: Consider table‑driven navigation tests to reduce repetition.

The interaction tests follow the same pattern; a data‑driven approach trims boilerplate and makes it easier to add new routes.

♻️ Example refactor using test.each
+  const navCases = [
+    { label: 'Settings', start: '/', target: ROUTES.SETTINGS, page: 'Settings Page' },
+    { label: 'Home', start: ROUTES.SETTINGS, target: ROUTES.HOME, page: 'Home Page' },
+    { label: 'AI Tagging', start: '/', target: ROUTES.AI, page: 'AI Tagging Page' },
+    { label: 'Favourites', start: '/', target: ROUTES.FAVOURITES, page: 'Favourites Page' },
+    { label: 'Videos', start: '/', target: ROUTES.VIDEOS, page: 'Videos Page' },
+    { label: 'Albums', start: '/', target: ROUTES.ALBUMS, page: 'Albums Page' },
+    { label: 'Memories', start: '/', target: ROUTES.MEMORIES, page: 'Memories Page' },
+  ];
+
-  test('clicking Settings link navigates to /settings', async () => {
-    const user = userEvent.setup();
-    render(<SidebarWithRoutes />, { initialRoutes: ['/'] });
-    expect(screen.getByTestId('location-display')).toHaveTextContent('/'); // start location
-    await user.click(screen.getByText('Settings')); // click settings
-    expect(screen.getByTestId('location-display')).toHaveTextContent('/settings');
-    expect(screen.getByText('Settings Page')).toBeInTheDocument();
-  });
+  test.each(navCases)(
+    'clicking %s navigates to %s',
+    async ({ label, start, target, page }) => {
+      const user = userEvent.setup();
+      render(<SidebarWithRoutes />, { initialRoutes: [start] });
+      await user.click(screen.getByText(label));
+      expect(screen.getByTestId('location-display')).toHaveTextContent(target);
+      expect(screen.getByText(page)).toBeInTheDocument();
+    },
+  );

Comment thread frontend/src/components/__tests__/Sidebar.test.tsx Outdated
@rohan-pandeyy
Copy link
Copy Markdown
Contributor Author

Updated PR description.
The total test count is now at 16 (7 navigation + 1 structure + 8 page tests)
Total test suites: 3

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: 2

🤖 Fix all issues with AI agents
In `@frontend/package.json`:
- Line 91: Remove the unnecessary direct devDependency
"baseline-browser-mapping" from package.json: open package.json, locate the
dependency entry "baseline-browser-mapping": "^2.9.19" and delete that line so
it is no longer listed under devDependencies; rely on the transitive dependency
provided by browserslist and run a quick npm/yarn install and lockfile update
(npm install or yarn install) to ensure the lockfile is updated accordingly.

In `@frontend/src/components/__tests__/ThemeToggle.test.tsx`:
- Around line 1-2: Tests in ThemeToggle.test.tsx are racing against Radix UI
portal mounting and exit animations; update the test to use async-safe queries
and waits: replace immediate synchronous queries (e.g., getByText / queryByText)
with await findByText to wait for elements to appear and wrap presence/absence
assertions in waitFor to wait for state/animation transitions after
userEvent.click on the ThemeToggle component; target the ThemeToggle test
utilities and any assertions that check the dropdown/menu text to ensure they
use findByText and waitFor around visibility checks.

Comment thread frontend/package.json
Comment thread frontend/src/components/__tests__/ThemeToggle.test.tsx Outdated
Consolidates and stabilizes frontend tests: suppress console.log in jest.setup to reduce noise; replace repetitive Sidebar navigation specs with a parameterized test.each suite and fix route usage; refactor ThemeToggle tests to use parameterized cases, findByText/waitFor assertions for more reliability. Adds comprehensive SettingsPage unit tests covering interactions and state changes. Removes a redundant matchMedia mock from allPages tests. Updates test-utils to adjust react-query defaults (disable retries, set gc/stale times) and return the test store and queryClient alongside the render result for easier test introspection.
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: 1

🤖 Fix all issues with AI agents
In `@frontend/src/pages/__tests__/SettingsPage.test.tsx`:
- Around line 119-126: A lint violation is caused by the "TODO" comment in
SettingsPage.test.tsx; remove or modify it: either (a) add an inline suppression
by placing "// eslint-disable-next-line no-warning-comments" directly above the
TODO comment, (b) move the note into an external tracker (create a GitHub issue
or README entry) and delete the comment, or (c) reword the comment to avoid the
TODO keyword (e.g., change to "NOTE" or "FUTURE") so the lint rule no longer
triggers; target the comment block in
frontend/src/pages/__tests__/SettingsPage.test.tsx that lists "System
integrations (future scope)".

Comment thread frontend/src/pages/__tests__/SettingsPage.test.tsx
Add comprehensive Jest tests for several frontend pieces: new tests for DeleteImageDialog (rendering and yes/no interactions), EmptyStates (gallery and AI tagging), GlobalLoader (conditional rendering and messages), and InfoDialog (rendering, variants, and close action updating store). Also add lib/utils tests for cn and getErrorMessage (including Axios-like errors) and dateUtils tests for getTimeAgo (uses fake timers) and groupImagesByYearMonthFromMetadata (grouping and edge cases). Minor comment wording tweak in SettingsPage.test.tsx.
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: 2

🧹 Nitpick comments (3)
frontend/src/components/__tests__/DeleteImageDialog.test.tsx (1)

23-37: Extract duplicate confirmation text to a constant.

The confirmation text string is duplicated across tests. Extract it to reduce duplication and simplify future maintenance if the text changes.

♻️ Proposed fix
 describe('DeleteImagesDialog', () => {
   const mockSetIsOpen = jest.fn();
   const mockExecuteDeleteImages = jest.fn();
+  const confirmationText = 'Do you also want to delete these images from Device ?';

   const defaultProps = {
     isOpen: true,
     setIsOpen: mockSetIsOpen,
     executeDeleteImages: mockExecuteDeleteImages,
   };

   // ...

   describe('Rendering', () => {
     test('renders confirmation text when open', () => {
       render(<DeleteImagesDialog {...defaultProps} />);

-      expect(
-        screen.getByText(
-          'Do you also want to delete these images from Device ?',
-        ),
-      ).toBeInTheDocument();
+      expect(screen.getByText(confirmationText)).toBeInTheDocument();
     });

     test('does not render content when closed', () => {
       render(<DeleteImagesDialog {...defaultProps} isOpen={false} />);

-      expect(
-        screen.queryByText(
-          'Do you also want to delete these images from Device ?',
-        ),
-      ).not.toBeInTheDocument();
+      expect(screen.queryByText(confirmationText)).not.toBeInTheDocument();
     });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/components/__tests__/DeleteImageDialog.test.tsx` around lines 23
- 37, Extract the duplicated confirmation string used in the tests into a shared
constant (e.g., CONFIRMATION_TEXT) at the top of the DeleteImageDialog.test.tsx
file and replace the two inline occurrences inside the expect/getByText and
queryByText calls with that constant; update any other tests in this file that
use the same literal to reference CONFIRMATION_TEXT so all assertions use the
single source of truth for the message shown by the DeleteImagesDialog
component.
frontend/src/components/__tests__/GlobalLoader.test.tsx (1)

17-18: Remove the redundant inline comment in this assertion block.

The comment on Line 17 restates exactly what Line 18 already asserts, so it adds noise without clarifying intent.

As per coding guidelines, "Point out redundant obvious comments that do not add clarity to the code."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/components/__tests__/GlobalLoader.test.tsx` around lines 17 -
18, The inline comment that duplicates the assertion is redundant; remove the
comment line that says "renders an empty div" above the assertion
expect(container.firstChild).toBeEmptyDOMElement() in the GlobalLoader test so
the test reads only the assertion (or replace it with a brief intent-focused
comment if you want to add clarifying context).
frontend/src/lib/__tests__/utils.test.ts (1)

54-75: Add single-field Axios payload cases to close a branch-coverage gap.

Current cases validate { error, message } together, but not payloads containing only one of them. Adding those two cases would lock in expected formatting behavior.

📌 Suggested test additions
+  test.each([
+    [{ error: 'Not Found' }, 'Not Found'],
+    [{ message: 'Image does not exist' }, 'Image does not exist'],
+  ])(
+    'extracts single-field Axios response data correctly',
+    (responseData, expected) => {
+      const axiosErr = fakeAxiosError('Request failed', 'ERR_BAD_REQUEST', responseData);
+      expect(getErrorMessage(axiosErr)).toBe(expected);
+    },
+  );

As per coding guidelines, "Ensure that test code is automated, comprehensive, and follows testing best practices."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/lib/__tests__/utils.test.ts` around lines 54 - 75, Add two unit
tests in frontend/src/lib/__tests__/utils.test.ts using the existing
fakeAxiosError and getErrorMessage helpers to cover single-field response
payloads: one where the response data contains only { error: 'Not Found' } and
assert getErrorMessage(...) returns 'Not Found', and one where the response data
contains only { message: 'Image does not exist' } and assert
getErrorMessage(...) returns 'Image does not exist'; place these alongside the
existing AxiosError tests so the branch where only one field is present is
exercised.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@frontend/src/components/__tests__/InfoDialog.test.tsx`:
- Around line 59-68: Replace the unsafe cast by importing and using the explicit
RootState type from your store and type the retrieved state (e.g. const state =
store.getState() as RootState) instead of using any; also stop inspecting the
implementation detail data-slot attribute—locate the close button via a
user-facing query by finding the dialog element (e.g. the element returned by
screen.getByRole('dialog') or the component wrapper) and then using
within(dialog).getByRole('button', { name: /close/i }) (or an equivalent
user-facing selector) before calling user.click on that button; update
references to store.getState and infoDialog accordingly.

In `@frontend/src/test-utils.tsx`:
- Around line 10-13: Replace weak ReturnType<typeof configureStore> usage with
an explicit Redux store type to preserve RootState typing: change the
CustomRenderOptions property "store?: ReturnType<typeof configureStore>" to
"store?: EnhancedStore<RootState, UnknownAction>" (and update the same typing at
the other occurrences and the test render return type). Also add imports for
EnhancedStore and UnknownAction from `@reduxjs/toolkit` and ensure any factory
function that creates the test store returns EnhancedStore<RootState,
UnknownAction> so callers can use store.getState() without casting.

---

Nitpick comments:
In `@frontend/src/components/__tests__/DeleteImageDialog.test.tsx`:
- Around line 23-37: Extract the duplicated confirmation string used in the
tests into a shared constant (e.g., CONFIRMATION_TEXT) at the top of the
DeleteImageDialog.test.tsx file and replace the two inline occurrences inside
the expect/getByText and queryByText calls with that constant; update any other
tests in this file that use the same literal to reference CONFIRMATION_TEXT so
all assertions use the single source of truth for the message shown by the
DeleteImagesDialog component.

In `@frontend/src/components/__tests__/GlobalLoader.test.tsx`:
- Around line 17-18: The inline comment that duplicates the assertion is
redundant; remove the comment line that says "renders an empty div" above the
assertion expect(container.firstChild).toBeEmptyDOMElement() in the GlobalLoader
test so the test reads only the assertion (or replace it with a brief
intent-focused comment if you want to add clarifying context).

In `@frontend/src/lib/__tests__/utils.test.ts`:
- Around line 54-75: Add two unit tests in
frontend/src/lib/__tests__/utils.test.ts using the existing fakeAxiosError and
getErrorMessage helpers to cover single-field response payloads: one where the
response data contains only { error: 'Not Found' } and assert
getErrorMessage(...) returns 'Not Found', and one where the response data
contains only { message: 'Image does not exist' } and assert
getErrorMessage(...) returns 'Image does not exist'; place these alongside the
existing AxiosError tests so the branch where only one field is present is
exercised.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 38b1f33 and 96bede0.

📒 Files selected for processing (8)
  • frontend/src/components/__tests__/DeleteImageDialog.test.tsx
  • frontend/src/components/__tests__/EmptyStates.test.tsx
  • frontend/src/components/__tests__/GlobalLoader.test.tsx
  • frontend/src/components/__tests__/InfoDialog.test.tsx
  • frontend/src/lib/__tests__/utils.test.ts
  • frontend/src/pages/__tests__/SettingsPage.test.tsx
  • frontend/src/test-utils.tsx
  • frontend/src/utils/__tests__/dateUtils.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • frontend/src/pages/tests/SettingsPage.test.tsx

Comment thread frontend/src/components/__tests__/InfoDialog.test.tsx Outdated
Comment thread frontend/src/test-utils.tsx
@JITENDRAGAHERWAR03
Copy link
Copy Markdown

Hello 👋
I am interested in working on this issue. I have basic knowledge of Python and I’m eager to learn and contribute. I will try to provide a clean and well-documented solution.
Please assign this issue to me if possible.
Thank you 😊

@rohan-pandeyy
Copy link
Copy Markdown
Contributor Author

Hey @JITENDRAGAHERWAR03, thanks for your interest in contributing!

Just a couple of quick pointers:

  • Please request assignment in the issue's comment section, since this is a pull request 😅
  • Also, this issue involves writing test cases in TypeScript rather than Python.

That said, if you're comfortable contributing in TypeScript as well, feel free to leave a comment on issue #889.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 3, 2026

⚠️ This PR has merge conflicts.

Please resolve the merge conflicts before review.

Your PR will only be reviewed by a maintainer after all conflicts have been resolved.

📺 Watch this video to understand why conflicts occur and how to resolve them:
https://www.youtube.com/watch?v=Sqsz1-o7nXk

@akshajtiwari
Copy link
Copy Markdown
Contributor

@rohan-pandeyy Is this PR still in development? otherwise I can move forward in removing the conflicts in this one.

@rohan-pandeyy
Copy link
Copy Markdown
Contributor Author

@akshajtiwari, don't worry, I'll take care of this one. You can focus on the others👍

@rahulharpal1603 rahulharpal1603 merged commit 27a9c6a into AOSSIE-Org:main May 30, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CI/CD enhancement New feature or request tests

Projects

Development

Successfully merging this pull request may close these issues.

CI/CD: Outdated Frontend Test Suites

4 participants