Skip to content

set up vitest + RTL, added Navbar tests#277

Open
parinaB wants to merge 1 commit into
GitMetricsLab:mainfrom
parinaB:main
Open

set up vitest + RTL, added Navbar tests#277
parinaB wants to merge 1 commit into
GitMetricsLab:mainfrom
parinaB:main

Conversation

@parinaB
Copy link
Copy Markdown

@parinaB parinaB commented May 16, 2026

Related Issue


Description

The frontend had zero test coverage — no test runner, no configuration, no test files. This PR sets up the complete testing infrastructure and adds the first test suite for the Navbar component.

Changes made:

  • Installed vitest, @testing-library/react, @testing-library/user-event, @testing-library/jest-dom, jsdom as dev dependencies
  • Added test block to vite.config.ts with jsdom environment
  • Created src/setupTests.ts to load jest-dom matchers
  • Added "test": "vitest" script to package.json
  • Created src/components/__test__/Navbar.test.tsx

How Has This Been Tested?

Ran npm test locally. All 9 tests pass.

Test Files  1 passed
Tests       9 passed

Tests cover:

  • Logo and nav links render correctly
  • Theme toggle calls toggleTheme on click
  • Mobile menu opens and closes correctly
  • Null guard when ThemeContext is missing

Screenshots (if applicable)

Screenshot 2026-05-16 at 4 37 10 PM

Note: spec/auth.routes.spec.cjs and spec/user.model.spec.cjs backend tests are failing but are pre-existing failures unrelated to this PR. I'll open a separate issue to track those.


Type of Change

  • Bug fix
  • New feature
  • Code style update
  • Breaking change
  • Documentation update

Summary by CodeRabbit

  • Tests
    • Added test coverage for the navigation component to verify core functionality
    • Established testing framework to support code quality and ongoing reliability improvements

Review Change Stack

@netlify
Copy link
Copy Markdown

netlify Bot commented May 16, 2026

Deploy Preview for github-spy ready!

Name Link
🔨 Latest commit 634daa6
🔍 Latest deploy log https://app.netlify.com/projects/github-spy/deploys/6a08502b170f670008c3d924
😎 Deploy Preview https://deploy-preview-277--github-spy.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 16, 2026

📝 Walkthrough

Walkthrough

This PR establishes frontend component testing infrastructure for the React codebase. It introduces the Vitest test runner and React Testing Library dependencies, configures Vitest with jsdom environment, sets up Jest DOM matchers, and provides a comprehensive test suite for the Navbar component as an initial example.

Changes

Frontend Test Infrastructure

Layer / File(s) Summary
Test Dependencies and Scripts
package.json
Adds test npm script for vitest and introduces dev dependencies: vitest, @testing-library/jest-dom, @testing-library/react, @testing-library/user-event, and jsdom.
Vitest Configuration and Setup
vite.config.ts, src/setupTests.ts
Vite config extended with test block specifying jsdom environment, global test variables, and setupTests.ts as the setup file. Setup file imports testing-library Jest DOM matchers.
Navbar Component Test Suite
src/components/__test__/Navbar.test.tsx
Complete test suite for the Navbar component with helper function using MemoryRouter and mocked ThemeContext. Tests cover desktop and mobile rendering, theme toggle button interaction, hamburger menu open/close, menu link navigation, and error handling when context is missing.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 A tester's delight, now tests take flight,
Vitest and Library shine so bright,
Navbar checked thrice, both dark and light,
Mobile, desktop—every click feels right!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main changes: setting up vitest and React Testing Library, and adding the first test suite for Navbar.
Description check ✅ Passed The PR description follows the template with all required sections: Related Issue, Description, How Has This Been Tested, Screenshots, and Type of Change, with comprehensive details throughout.
Linked Issues check ✅ Passed All coding objectives from issue #275 are met: vitest and React Testing Library dependencies added, vite.config.ts configured with test block and jsdom, setupTests.ts created, test script added to package.json, and Navbar test suite created.
Out of Scope Changes check ✅ Passed All changes directly support the testing infrastructure setup and Navbar component testing as specified in issue #275; no out-of-scope modifications detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

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

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

🎉 Thank you @parinaB for your contribution. Please make sure your PR follows https://github.com/GitMetricsLab/github_tracker/blob/main/CONTRIBUTING.md#-pull-request-guidelines

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.

🧹 Nitpick comments (4)
src/components/__test__/Navbar.test.tsx (4)

69-70: ⚡ Quick win

Replace brittle link selector based on array position.

Lines 69–70 select the mobile "Home" link by getting all links with that name and clicking the last one (homeLinks[homeLinks.length - 1]). This assumes the mobile link is always last, which is fragile and will break if link order changes.

Consider using a scoped query within the mobile menu container or adding a test ID to distinguish desktop from mobile links.

♻️ Example with scoped query

If the mobile menu has a container with a test ID or role:

 fireEvent.click(hamburger)                          // open
-const homeLinks = screen.getAllByRole('link', { name: /home/i })
-fireEvent.click(homeLinks[homeLinks.length - 1]) // click the mobile one
+const mobileMenu = screen.getByRole('navigation', { name: /mobile/i })
+const mobileHomeLink = within(mobileMenu).getByRole('link', { name: /home/i })
+fireEvent.click(mobileHomeLink)
 expect(screen.queryByText('About')).not.toBeInTheDocument()  // closed

You'll need to import within from @testing-library/react.

🤖 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 `@src/components/__test__/Navbar.test.tsx` around lines 69 - 70, The test
currently finds the mobile "Home" link by array position (homeLinks =
screen.getAllByRole('link', { name: /home/i }) and clicking
homeLinks[homeLinks.length - 1]), which is brittle; change the test to scope the
query to the mobile menu container (e.g., use within on the mobile menu element
or a specific data-testid for the mobile link) and then query that scoped
container for the "Home" link, or add a distinct test id to the mobile link and
use getByTestId; remember to import within from `@testing-library/react` if you
use scoped queries and update the click to target the scoped/mobile element
instead of indexing the whole list.

40-41: ⚡ Quick win

Replace brittle array-index selector with a specific query.

Lines 40 and 46 select the theme button using screen.getAllByRole('button')[0], which assumes the theme button is always the first button in the DOM. This will break if button order changes.

Consider querying by accessible name or adding an aria-label to the theme button in the component.

♻️ Example with aria-label

If the Navbar component adds an aria-label to the theme button:

<button aria-label="Toggle theme" onClick={toggleTheme}>
  {mode === 'light' ? <Moon /> : <Sun />}
</button>

Then update the test:

-const themeBtn = screen.getAllByRole('button')[0]
+const themeBtn = screen.getByRole('button', { name: /toggle theme/i })
 expect(themeBtn).toBeInTheDocument()

Also applies to: 46-46

🤖 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 `@src/components/__test__/Navbar.test.tsx` around lines 40 - 41, The test is
using a brittle index-based selector for the theme button; update Navbar and its
tests so the button has an accessible name (e.g., add aria-label="Toggle theme"
on the theme toggle in the Navbar component where toggleTheme/mode/Moon/Sun are
used) and replace screen.getAllByRole('button')[0] in Navbar.test.tsx with a
specific query such as screen.getByRole('button', { name: /toggle theme/i }) or
screen.getByLabelText('Toggle theme') to reliably target the themeBtn.

2-2: ⚡ Quick win

Prefer userEvent over fireEvent for more realistic interactions.

The test suite uses fireEvent.click throughout (lines 47, 60, 68, 70, 77, 78), but React Testing Library best practices recommend userEvent for simulating actual browser behavior—including focus, hover, and timing—rather than synchronous DOM event dispatch.

Since @testing-library/user-event is already installed (per PR objectives), consider migrating to it for higher-fidelity tests.

♻️ Example migration for one test
-import { render, screen, fireEvent } from '`@testing-library/react`'
+import { render, screen } from '`@testing-library/react`'
+import userEvent from '`@testing-library/user-event`'
 import { describe, it, expect, vi, beforeEach } from 'vitest'

Then in a test:

-it('calls toggleTheme when the theme button is clicked', () => {
+it('calls toggleTheme when the theme button is clicked', async () => {
   const { toggleTheme } = renderNavbar('light')
   const themeBtn = screen.getAllByRole('button')[0]
-  fireEvent.click(themeBtn)
+  await userEvent.click(themeBtn)
   expect(toggleTheme).toHaveBeenCalledTimes(1)
 })

Also applies to: 47-47, 60-60, 68-68, 70-70, 77-77, 78-78

🤖 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 `@src/components/__test__/Navbar.test.tsx` at line 2, The tests import and use
fireEvent for clicks; replace fireEvent with `@testing-library/user-event` to
simulate interactions more realistically: add import of userEvent from
'`@testing-library/user-event`', call const user = userEvent.setup() inside each
test (or a shared beforeEach), and replace fireEvent.click(...) with await
user.click(...) (and add async to tests where needed). Update all occurrences of
fireEvent.click in the Navbar.test.tsx tests (the click calls used around the
render assertions and handlers) to use user.click with appropriate awaits so
focus/timing behavior is preserved.

59-59: ⚡ Quick win

Replace brittle array-index selector for the hamburger button.

Lines 59, 67, and 76 select the hamburger button using screen.getAllByRole('button')[1], which assumes it's always the second button. This will break if button order changes.

Consider adding an accessible label to the hamburger button in the component and querying by name.

♻️ Example with aria-label

If the hamburger button in Navbar has an aria-label:

<button aria-label="Toggle menu" onClick={toggleMenu}>
  <Menu />
</button>

Then update the tests:

-const hamburger = screen.getAllByRole('button')[1]
+const hamburger = screen.getByRole('button', { name: /toggle menu/i })
 fireEvent.click(hamburger)

Also applies to: 67-67, 76-76

🤖 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 `@src/components/__test__/Navbar.test.tsx` at line 59, Tests use a brittle
array-index selector (screen.getAllByRole('button')[1]) to find the hamburger;
update the Navbar component to give the hamburger button an accessible name
(e.g., add aria-label="Toggle menu" on the button that renders the Menu icon /
calls toggleMenu) and change the tests (the places that create the hamburger
variable in Navbar.test.tsx around the current selectors) to query by role+name
such as getByRole('button', { name: /toggle menu/i }) instead of index-based
access so the selector is stable if button order changes.
🤖 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.

Nitpick comments:
In `@src/components/__test__/Navbar.test.tsx`:
- Around line 69-70: The test currently finds the mobile "Home" link by array
position (homeLinks = screen.getAllByRole('link', { name: /home/i }) and
clicking homeLinks[homeLinks.length - 1]), which is brittle; change the test to
scope the query to the mobile menu container (e.g., use within on the mobile
menu element or a specific data-testid for the mobile link) and then query that
scoped container for the "Home" link, or add a distinct test id to the mobile
link and use getByTestId; remember to import within from `@testing-library/react`
if you use scoped queries and update the click to target the scoped/mobile
element instead of indexing the whole list.
- Around line 40-41: The test is using a brittle index-based selector for the
theme button; update Navbar and its tests so the button has an accessible name
(e.g., add aria-label="Toggle theme" on the theme toggle in the Navbar component
where toggleTheme/mode/Moon/Sun are used) and replace
screen.getAllByRole('button')[0] in Navbar.test.tsx with a specific query such
as screen.getByRole('button', { name: /toggle theme/i }) or
screen.getByLabelText('Toggle theme') to reliably target the themeBtn.
- Line 2: The tests import and use fireEvent for clicks; replace fireEvent with
`@testing-library/user-event` to simulate interactions more realistically: add
import of userEvent from '`@testing-library/user-event`', call const user =
userEvent.setup() inside each test (or a shared beforeEach), and replace
fireEvent.click(...) with await user.click(...) (and add async to tests where
needed). Update all occurrences of fireEvent.click in the Navbar.test.tsx tests
(the click calls used around the render assertions and handlers) to use
user.click with appropriate awaits so focus/timing behavior is preserved.
- Line 59: Tests use a brittle array-index selector
(screen.getAllByRole('button')[1]) to find the hamburger; update the Navbar
component to give the hamburger button an accessible name (e.g., add
aria-label="Toggle menu" on the button that renders the Menu icon / calls
toggleMenu) and change the tests (the places that create the hamburger variable
in Navbar.test.tsx around the current selectors) to query by role+name such as
getByRole('button', { name: /toggle menu/i }) instead of index-based access so
the selector is stable if button order changes.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 46bba6f7-8ac8-4a3a-8ec4-ccd05096c876

📥 Commits

Reviewing files that changed from the base of the PR and between 7a15543 and 634daa6.

📒 Files selected for processing (4)
  • package.json
  • src/components/__test__/Navbar.test.tsx
  • src/setupTests.ts
  • vite.config.ts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

test(frontend): set up Vitest + React Testing Library for React components — no frontend test coverage currently exists

1 participant