Skip to content

feat: add accessibility tests support #3162

Merged
kasya merged 35 commits intoOWASP:mainfrom
Utkarsh-0304:feat/accessibility_tests
Jan 13, 2026
Merged

feat: add accessibility tests support #3162
kasya merged 35 commits intoOWASP:mainfrom
Utkarsh-0304:feat/accessibility_tests

Conversation

@Utkarsh-0304
Copy link
Contributor

Proposed change

Resolves #3058

This PR introduces accessibility tests for react components with the help of axe library. It also sets up CI checks so that accessibility issues are caught early in development. Also, all the existing accessibility conflicts thus encountered are hence also fixed.

Checklist

  • Required: I read and followed the contributing guidelines
  • Required: I ran make check-test locally and all tests passed
  • I used AI for code, documentation, or tests in this PR

@github-actions github-actions bot added frontend docker Pull requests that update Docker code frontend-tests makefile labels Jan 3, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 3, 2026

Summary by CodeRabbit

  • New Features

    • Added comprehensive accessibility testing coverage for all frontend components to ensure compliance with accessibility standards.
  • Bug Fixes

    • Improved accessibility across components including screen reader support, semantic HTML structure, and ARIA labels.
  • Tests

    • Added automated accessibility tests integrated into CI/CD pipeline.

✏️ Tip: You can customize this high-level summary in your review settings.

Walkthrough

Adds comprehensive frontend accessibility (a11y) testing using Jest Axe with 70+ component test files, infrastructure for running tests via Docker and CI/CD, and consolidates test mock data into a centralized directory. Also makes targeted accessibility improvements to components (heading semantics, aria-labels, roles) and centralizes Next.js mock setup in jest.setup.ts.

Changes

Cohort / File(s) Summary
A11Y Test Infrastructure & Setup
frontend/jest.setup.ts, frontend/jest.config.ts, frontend/tsconfig.json, frontend/Makefile, frontend/package.json, docker/frontend/Dockerfile.a11y.test
Added Next.js and utility mocks (usePathname, MockedLink, next/image) to jest.setup.ts; configured Jest with @mockData path alias and test path ignore patterns; added test-frontend-a11y npm script and Makefile target; created Docker image for isolated a11y testing.
CI/CD Accessibility Testing Integration
.github/workflows/run-ci-cd.yaml
Introduced run-frontend-a11y-tests job with Docker buildx setup and integrated it as a dependency for build-staging-images and build-production-images jobs; includes 10-minute timeout.
Component Accessibility Improvements
frontend/src/app/settings/api-keys/page.tsx, frontend/src/components/LogoCarousel.tsx, frontend/src/components/DonutBarChart.tsx, frontend/src/components/EntityActions.tsx, frontend/src/components/Pagination.tsx, frontend/src/components/Footer.tsx, frontend/src/components/ShowMoreButton.tsx
Enhanced accessibility: h3→h2 semantic heading change, screen-reader-only sponsor names, aria-label for chart, menu role on dropdown, removed ellipsis aria-label, added data-testid attributes for testing.
Comprehensive A11Y Test Suite (Components)
frontend/__tests__/a11y/components/*.a11y.test.tsx (70\+ files)
Added accessibility tests for ActionButton, AnchorTitle, AutoScrollToTop, Badges, BarChart, BreadCrumbs, BreadCrumbsWrapper, CalendarButton, Card, CardDetailsPage, ChapterMap, ContributionHeatmap, ContributorAvatar, DashboardCard, DisplayIcon, DonutBarChart, EntityActions, Footer, GeneralCompliantComponent, HealthMetrics, InfoBlock, InfoItem, ItemCardList, Leaders, LeadersList, LineChart, LoadingSpinner, LoginPageContent, LogoCarousel, MarkdownWrapper, MetricsCard, MetricsScoreCircle, Milestones, Modal, ModeToggle, MultiSearch, NavButton, NavDropDown, PageLayout, Pagination, ProgramCard, ProjectTypeDashboardCard, ProjectsDashboardDropDown, ProjectsDashboardNavBar, RecentIssues, RecentPullRequests, RecentRelease, Release, RepositoryCard, ScrollToTop, Search, SearchPageLayout, SecondaryCard, SingleModuleCard, SkeletonBase, SnapshotCard, SortBy, SponsorCard, StatusBadge, ToggleableList, TopContributorsList, TruncatedText, UserCard, UserMenu.
Mock Data Path Migration (Unit Tests)
frontend/__tests__/unit/components/ActionButton.test.tsx, frontend/__tests__/unit/pages/About.test.tsx, frontend/__tests__/unit/pages/ApiKeysPage.test.tsx, frontend/__tests__/unit/pages/ChapterDetails.test.tsx, frontend/__tests__/unit/pages/Chapters.test.tsx, frontend/__tests__/unit/pages/CommitteeDetails.test.tsx, frontend/__tests__/unit/pages/Committees.test.tsx, frontend/__tests__/unit/pages/ModuleDetails.test.tsx, frontend/__tests__/unit/pages/ModuleDetailsPage.test.tsx, frontend/__tests__/unit/pages/Organization.test.tsx, frontend/__tests__/unit/pages/OrganizationDetails.test.tsx, frontend/__tests__/unit/pages/Program.test.tsx, frontend/__tests__/unit/pages/ProgramDetails.test.tsx, frontend/__tests__/unit/pages/ProgramDetailsMentorship.test.tsx, frontend/__tests__/unit/pages/ProjectDetails.test.tsx, frontend/__tests__/unit/pages/ProjectHealthDashboardMetricsDetails.test.tsx, frontend/__tests__/unit/pages/Projects.test.tsx, frontend/__tests__/unit/pages/ProjectsHealthDashboardMetrics.test.tsx, frontend/__tests__/unit/pages/ProjectsHealthDashboardOverview.test.tsx, frontend/__tests__/unit/pages/RepositoryDetails.test.tsx, frontend/__tests__/unit/pages/SnapshotDetails.test.tsx, frontend/__tests__/unit/pages/UserDetails.test.tsx, frontend/__tests__/unit/pages/Users.test.tsx, frontend/__tests__/unit/components/Leaders.test.tsx
Updated import paths from @unit/data/* to @mockData/* to use centralized mock data directory.
Mock Data Path Migration (E2E Tests)
frontend/__tests__/e2e/pages/About.spec.ts, frontend/__tests__/e2e/pages/ChapterDetails.spec.ts, frontend/__tests__/e2e/pages/Chapters.spec.ts, frontend/__tests__/e2e/pages/CommitteeDetails.spec.ts, frontend/__tests__/e2e/pages/Committees.spec.ts, frontend/__tests__/e2e/pages/Contribute.spec.ts, frontend/__tests__/e2e/pages/OrganizationDetails.spec.ts, frontend/__tests__/e2e/pages/Organizations.spec.ts, frontend/__tests__/e2e/pages/ProjectDetails.spec.ts, frontend/__tests__/e2e/pages/ProjectHealthDashboardMetricsDetails.spec.ts, frontend/__tests__/e2e/pages/Projects.spec.ts, frontend/__tests__/e2e/pages/ProjectsHealthDashboardMetrics.spec.ts, frontend/__tests__/e2e/pages/ProjectsHealthDashboardOverview.spec.ts, frontend/__tests__/e2e/pages/RepositoryDetails.spec.ts, frontend/__tests__/e2e/pages/UserDetails.spec.ts, frontend/__tests__/e2e/pages/Users.spec.ts
Updated import paths from @unit/data/* to @mockData/* for centralized mock data access.
Local Next.js Link Mock Removal
frontend/__tests__/unit/components/CardDetailsPage.test.tsx, frontend/__tests__/unit/components/Footer.test.tsx, frontend/__tests__/unit/components/LeadersList.test.tsx, frontend/__tests__/unit/components/NavButton.test.tsx, frontend/__tests__/unit/components/NavDropDown.test.tsx, frontend/__tests__/unit/components/ProgramCard.test.tsx, frontend/__tests__/unit/components/ProjectTypeDashboardCard.test.tsx, frontend/__tests__/unit/pages/Contribute.test.tsx, frontend/__tests__/unit/pages/Header.test.tsx, frontend/__tests__/unit/pages/Home.test.tsx
Removed local jest.mock implementations for next/link, consolidating to global setup in jest.setup.ts.
Mock Data Reordering
frontend/__tests__/unit/components/ContributorAvatar.test.tsx, frontend/__tests__/unit/components/SingleModuleCard.test.tsx, frontend/__tests__/unit/components/LogoCarousel.test.tsx
Reordered or relocated mock declarations without changing implementation.
Mock Data Directory Updates
frontend/__tests__/mockData/mockChapterData.ts
Added geolocation fields (suggestedLocation, geoLocation, region) to mock chapter data.
Docker Test Dockerfile Updates
docker/frontend/Dockerfile.unit.test, docker/frontend/Dockerfile.e2e.test
Added/updated copy steps to include tests/mockData directory in test images.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • PR #1881 — Directly related to header unit test infrastructure and jest.setup.ts mock changes for Next.js components.
  • PR #2657 — Related through accessibility-focused component changes and Next.js test mock consolidation.
  • PR #3208 — Related through overlapping frontend test file modifications and mock data migration patterns.

Suggested reviewers

  • arkid15r
🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: add accessibility tests support' clearly and concisely summarizes the primary change of introducing accessibility testing infrastructure for React components.
Description check ✅ Passed The description directly addresses the changeset by explaining the introduction of accessibility tests using axe, CI setup for accessibility checks, and fixes for accessibility conflicts encountered.
Linked Issues check ✅ Passed The PR fully implements the requirements from issue #3058: integrated Axe accessibility testing [multiple test files], configured CI checks for accessibility [.github/workflows/run-ci-cd.yaml, frontend/Makefile], and fixed accessibility issues in components [multiple component updates].
Out of Scope Changes check ✅ Passed All changes are directly related to accessibility testing support: 80+ accessibility test files, test infrastructure updates, component accessibility fixes, and CI/build configuration. Mock data reorganization supports test consolidation. No unrelated changes detected.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 840477f and 16ac56f.

📒 Files selected for processing (3)
  • frontend/__tests__/e2e/pages/ProjectHealthDashboardMetricsDetails.spec.ts
  • frontend/__tests__/e2e/pages/ProjectsHealthDashboardMetrics.spec.ts
  • frontend/__tests__/e2e/pages/ProjectsHealthDashboardOverview.spec.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • frontend/tests/e2e/pages/ProjectsHealthDashboardMetrics.spec.ts
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 1717
File: frontend/__tests__/unit/pages/createProgram.test.tsx:70-86
Timestamp: 2025-07-12T17:36:57.255Z
Learning: When testing React page components that use mocked form components, validation logic should be tested at the form component level, not the page level. Page-level tests should focus on authentication, role checking, submission handling, and navigation logic.
📚 Learning: 2025-11-17T16:47:05.578Z
Learnt from: anurag2787
Repo: OWASP/Nest PR: 2671
File: frontend/__tests__/unit/components/MultiSearch.test.tsx:427-427
Timestamp: 2025-11-17T16:47:05.578Z
Learning: In the frontend test files for the OWASP/Nest repository, `expect(true).toBe(true)` no-op assertions may be intentionally added as workarounds when ESLint rule jest/expect-expect doesn't detect expectations inside helper functions or waitFor callbacks. These can be resolved by configuring the ESLint rule's assertFunctionNames option to recognize custom assertion helpers instead of flagging them as redundant.

Applied to files:

  • frontend/__tests__/e2e/pages/ProjectHealthDashboardMetricsDetails.spec.ts
  • frontend/__tests__/e2e/pages/ProjectsHealthDashboardOverview.spec.ts
📚 Learning: 2025-07-12T17:36:57.255Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 1717
File: frontend/__tests__/unit/pages/createProgram.test.tsx:70-86
Timestamp: 2025-07-12T17:36:57.255Z
Learning: When testing React page components that use mocked form components, validation logic should be tested at the form component level, not the page level. Page-level tests should focus on authentication, role checking, submission handling, and navigation logic.

Applied to files:

  • frontend/__tests__/e2e/pages/ProjectHealthDashboardMetricsDetails.spec.ts
📚 Learning: 2025-11-17T17:30:42.139Z
Learnt from: anurag2787
Repo: OWASP/Nest PR: 2671
File: frontend/__tests__/unit/components/MultiSearch.test.tsx:169-171
Timestamp: 2025-11-17T17:30:42.139Z
Learning: In the OWASP/Nest frontend tests (PR #2671 context), wrapper functions like `expectChaptersCountEqualsThree` that simply call another helper with a fixed parameter (e.g., `expectChaptersCountEquals(3)`) are intentionally used to avoid arrow function callbacks in `waitFor` calls. This pattern prevents adding nesting depth that would trigger rule typescript:S2004. Example: `await waitFor(expectChaptersCountEqualsThree)` avoids the extra nesting from `await waitFor(() => expectChaptersCountEquals(3))`.

Applied to files:

  • frontend/__tests__/e2e/pages/ProjectHealthDashboardMetricsDetails.spec.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Run frontend e2e tests
  • GitHub Check: Run frontend unit tests
  • GitHub Check: Run backend tests
  • GitHub Check: Run frontend accessibility tests
  • GitHub Check: CodeQL (javascript-typescript)
🔇 Additional comments (3)
frontend/__tests__/e2e/pages/ProjectHealthDashboardMetricsDetails.spec.ts (1)

2-2: LGTM!

The import path migration to the centralized @mockData/ alias is consistent with the PR's objective of consolidating mock data and aligns with the Jest and TypeScript path configuration updates.

frontend/__tests__/e2e/pages/ProjectsHealthDashboardOverview.spec.ts (2)

1-4: LGTM!

The import path change to @mockData/mockProjectsDashboardOverviewData aligns with the centralized mock data refactoring. Since @e2e aliases already work for Playwright tests and tsconfig.json was updated with the @mockData/* path alias, path resolution should work correctly.


6-55: Test coverage looks solid.

The tests appropriately cover both the authorization scenario (404 for non-staff users) and the data rendering scenario (verifying health stats visibility). The use of millify for formatted number comparisons ensures the assertions match what users actually see in the UI.


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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
frontend/src/app/settings/api-keys/page.tsx (2)

63-70: Add accessible label to the delete button.

The trash icon button lacks an accessible label, preventing screen reader users from understanding its purpose. This violates WCAG 2.1 SC 4.1.2 (Name, Role, Value).

🔎 Proposed fix
             <Button
               variant="light"
               size="sm"
               onPress={() => onRevoke(key)}
               className="text-red-600 hover:bg-red-50 dark:hover:bg-red-900/20"
+              aria-label={`Revoke ${key.name}`}
             >
               <FaTrash />
             </Button>

341-348: Add accessible label to the visibility toggle button.

The eye/eye-slash icon button lacks an accessible label. Screen reader users cannot determine whether it shows or hides the API key.

🔎 Proposed fix
                   <Button
                     variant="light"
                     size="sm"
                     onPress={() => setShowNewKey(!showNewKey)}
                     isIconOnly
+                    aria-label={showNewKey ? 'Hide API key' : 'Show API key'}
                   >
                     {showNewKey ? <FaEyeSlash /> : <FaEye />}
                   </Button>
🧹 Nitpick comments (24)
frontend/__tests__/accessibility/components/RecentRelease.a11y.test.tsx (1)

58-99: Consider using fixed timestamps for deterministic test data.

Using Date.now() for publishedAt (lines 61, 81) makes the test data non-deterministic, which can complicate debugging if the component renders dates differently based on their values. While this likely won't affect accessibility checks, fixed timestamps are a better practice for test reliability.

🔎 Suggested fix
 const mockReleases: Release[] = [
   {
     name: 'v1.0 The First Release',
-    publishedAt: Date.now(),
+    publishedAt: 1704297600000, // 2024-01-03T12:00:00.000Z
     repositoryName: 'our-awesome-project',
     organizationName: 'our-org',
     tagName: 'v1.0',
     isPreRelease: false,
     author: {
       login: 'testuser',
       name: 'Test User',
       avatarUrl: 'https://example.com/avatar.png',
       key: 'testuser',
       contributionsCount: 0,
       createdAt: 0,
       followersCount: 0,
       followingCount: 0,
       publicRepositoriesCount: 0,
       url: 'https://example.com/user/testuser',
     },
   },
   {
     name: 'v2.0 The Second Release',
-    publishedAt: Date.now(),
+    publishedAt: 1704384000000, // 2024-01-04T12:00:00.000Z
     repositoryName: 'another-cool-project',
     organizationName: 'our-org',
     tagName: 'v2.0',
     isPreRelease: false,
     author: {
       login: 'jane-doe',
       name: 'Jane Doe',
       avatarUrl: 'https://example.com/avatar2.png',
       key: 'jane-doe',
       contributionsCount: 0,
       createdAt: 0,
       followersCount: 0,
       followingCount: 0,
       publicRepositoriesCount: 0,
       url: 'https://example.com/user/jane-doe',
     },
   },
 ]
frontend/__tests__/accessibility/components/CalendarButton.a11y.test.tsx (1)

15-46: Test coverage looks good for static accessibility checks.

The test suite properly covers the main rendering variants of the CalendarButton component. The use of jest-axe with async/await is correct, and the custom icon test demonstrates a good accessible pattern using role="img" and aria-label.

Consider adding a test for the disabled state to ensure accessibility is maintained when isDownloading is true:

🔎 Optional: Add disabled state test
it('should not have any accessibility violations in disabled state', async () => {
  // Note: You may need to mock the handleDownload to control the disabled state
  // or test the button's aria-disabled attribute directly
  const { container } = render(
    <CalendarButton event={mockEvent} />
  )
  
  const button = container.querySelector('button')
  // Simulate disabled state by checking if the component properly handles it
  
  const results = await axe(container)
  expect(results).toHaveNoViolations()
})

This is optional and can be deferred if testing dynamic states is outside the scope of static accessibility tests.

frontend/__tests__/accessibility/components/LogoCarousel.a11y.test.tsx (1)

69-77: LGTM! Solid baseline accessibility test.

The test correctly follows jest-axe patterns: renders the component, runs axe analysis on the container, and asserts no violations. This provides good baseline coverage for the component's accessibility.

For future enhancement, you could consider adding test cases for edge scenarios like:

  • All sponsors with missing images
  • Single sponsor
  • Large number of sponsors

However, the current single comprehensive test is a solid starting point for accessibility coverage.

frontend/__tests__/accessibility/components/NavDropDown.a11y.test.tsx (1)

1-31: LGTM with optional enhancement suggestion.

The test correctly verifies baseline accessibility for the NavDropDown component. The mock data and props are well-structured.

For more comprehensive accessibility coverage of interactive components, consider adding a test for the expanded/open state as well, since dropdowns have different ARIA attributes (like aria-expanded) in different states. Based on learnings, NavDropDown should have proper accessibility features that vary between collapsed and expanded states.

Optional: Test expanded state example
it('should not have accessibility violations when expanded', async () => {
  const { container } = render(<NavDropDown {...defaultProps} />)
  
  // Simulate opening the dropdown (adjust selector/interaction as needed)
  const trigger = container.querySelector('[role="button"]')
  await userEvent.click(trigger)
  
  const results = await axe(container)
  expect(results).toHaveNoViolations()
})
frontend/__tests__/accessibility/components/ProgramCard.a11y.test.tsx (1)

1-40: LGTM! Comprehensive mocking and test setup.

The test properly mocks both next/link and the useUpdateProgramStatus hook to isolate the component. The baseMockProgram object includes all necessary fields for realistic rendering.

Optional: Consider testing additional prop combinations

For more comprehensive coverage, you could add test cases for different isAdmin and accessLevel combinations, as these may affect the component's rendered output and accessibility characteristics:

+ it('should not have accessibility violations when user is admin', async () => {
+   const { container } = render(
+     <ProgramCard program={baseMockProgram} href="/test/path" isAdmin={true} accessLevel="admin" />
+   )
+   const results = await axe(container)
+   expect(results).toHaveNoViolations()
+ })

However, the current baseline test is sufficient for initial a11y coverage.

frontend/__tests__/accessibility/components/ContributorAvatar.a11y.test.tsx (1)

1-80: LGTM: Well-structured accessibility test.

The test follows best practices for accessibility testing with jest-axe and properly isolates the component with appropriate mocks. The test setup is clean and the assertion correctly verifies no accessibility violations.

Consider expanding test coverage to include different component states and prop variations (e.g., with/without project info, different contribution counts, etc.) to ensure accessibility compliance across all component states. This can be addressed in future iterations.

Example of expanded coverage
it('should not have violations without project info', async () => {
  const contributorWithoutProject = { ...mockGitHubContributor, projectName: undefined, projectKey: undefined }
  const { container } = render(<ContributorAvatar contributor={contributorWithoutProject} uniqueKey="test" />)
  expect(await axe(container)).toHaveNoViolations()
})

it('should not have violations with high contribution count', async () => {
  const contributorWithHighCount = { ...mockGitHubContributor, contributionsCount: 1000 }
  const { container } = render(<ContributorAvatar contributor={contributorWithHighCount} uniqueKey="test" />)
  expect(await axe(container)).toHaveNoViolations()
})
frontend/__tests__/accessibility/components/ItemCardList.a11y.test.tsx (1)

1-103: LGTM: Solid accessibility test with comprehensive mocks.

The test is well-structured with complete mock implementations (including __esModule: true) and comprehensive mock data. The test correctly verifies accessibility compliance for the ItemCardList component.

Consider adding test cases for edge scenarios to strengthen accessibility coverage:

  • Empty data array
  • Multiple items in the list
  • Items with missing optional fields (e.g., without labels or hints)

These additional cases can help ensure accessibility compliance across all component states.

frontend/__tests__/accessibility/components/GeneralCompliantComponent.a11y.test.tsx (2)

9-13: Consider importing the type from the component module.

The GeneralCompliantComponentProps type is defined locally but likely exists in the component file. If available, import the type from components/GeneralCompliantComponent to maintain a single source of truth and reduce duplication.

-type GeneralCompliantComponentProps = {
-  compliant: boolean
-  icon: IconType
-  title: string
-}
+import GeneralCompliantComponent, { GeneralCompliantComponentProps } from 'components/GeneralCompliantComponent'

21-29: LGTM with suggestion: Test both compliant states.

The test correctly verifies accessibility with compliant: true. Consider adding a test case for compliant: false to ensure accessibility compliance in both states, as the visual representation likely differs.

Example test for non-compliant state
it('should not have violations when not compliant', async () => {
  const { container } = render(<GeneralCompliantComponent {...baseProps} compliant={false} />)
  const results = await axe(container)
  expect(results).toHaveNoViolations()
})
frontend/__tests__/accessibility/components/UserCard.a11y.test.tsx (1)

1-60: LGTM: Well-implemented accessibility test.

The test includes a sophisticated mock for next/image that properly handles the fill and objectFit props, and correctly verifies accessibility compliance.

The default props use minimal values (empty strings, zero counts). Consider adding a test case with populated optional fields to ensure accessibility compliance when displaying rich user information (company, location, email, badges, etc.).

Example test with populated fields
it('should not have violations with full user details', async () => {
  const populatedProps: UserCardProps = {
    ...defaultProps,
    company: 'OWASP',
    location: 'San Francisco',
    email: 'john@example.com',
    followersCount: 150,
    repositoriesCount: 25,
    badgeCount: 3,
    badges: [{ name: 'Contributor', icon: 'icon-url' }],
  }
  const { container } = render(<UserCard {...populatedProps} />)
  expect(await axe(container)).toHaveNoViolations()
})
frontend/__tests__/accessibility/components/Search.a11y.test.tsx (1)

14-22: LGTM with suggestion: Test both loading states.

The test correctly verifies accessibility. Consider adding a test case for isLoaded: true to ensure the component remains accessible in both loading and loaded states, as the UI likely differs.

Example test for loaded state
it('should not have violations when loaded', async () => {
  const { container } = render(<SearchBar {...defaultProps} isLoaded={true} />)
  const results = await axe(container)
  expect(results).toHaveNoViolations()
})
frontend/__tests__/accessibility/components/UserMenu.a11y.test.tsx (2)

70-77: Consider testing the open dropdown state.

The test currently only validates the closed state of the UserMenu. The open dropdown contains additional interactive elements (menu items, links) that should also be tested for accessibility violations, particularly focus management and keyboard navigation.

Proposed expansion to test open state
 describe('UserMenu Accessibility', () => {
   it('should not have any accessibility violations', async () => {
     const { container } = render(<UserMenu isGitHubAuthEnabled={true} />)
 
     const results = await axe(container)
 
     expect(results).toHaveNoViolations()
   })
+
+  it('should not have accessibility violations when dropdown is open', async () => {
+    const { container, getByRole } = render(<UserMenu isGitHubAuthEnabled />)
+    
+    // Open the dropdown
+    const button = getByRole('button')
+    button.click()
+    
+    const results = await axe(container)
+    expect(results).toHaveNoViolations()
+  })
 })

72-72: Simplify boolean prop syntax.

In JSX, isGitHubAuthEnabled={true} can be simplified to isGitHubAuthEnabled.

Proposed simplification
-    const { container } = render(<UserMenu isGitHubAuthEnabled={true} />)
+    const { container } = render(<UserMenu isGitHubAuthEnabled />)
frontend/__tests__/accessibility/components/NavButton.a11y.test.tsx (1)

10-17: Consider consistent Link mocking across test files.

The simplified Link mock only forwards href and children, while other a11y tests (e.g., LeadersList.a11y.test.tsx lines 8-34) forward additional accessibility props like aria-label and title. For consistency and more comprehensive accessibility testing, consider adopting the more complete mock pattern.

Additionally, line 12's type annotation includes redundant constraints (& { defaultIcon: typeof FaHome; hoverIcon: typeof FaUser }) since NavButtonProps already defines these as IconType.

🔎 Proposed refactor for consistency
-jest.mock('next/link', () => ({ children, href }) => <a href={href}>{children}</a>)
+jest.mock('next/link', () => {
+  return function MockLink({ children, href, 'aria-label': ariaLabel, className, title }) {
+    return (
+      <a href={href} aria-label={ariaLabel} className={className} title={title}>
+        {children}
+      </a>
+    )
+  }
+})

-const defaultProps: NavButtonProps & { defaultIcon: typeof FaHome; hoverIcon: typeof FaUser } = {
+const defaultProps: NavButtonProps = {
   href: '/test-path',
   defaultIcon: FaHome,
   hoverIcon: FaUser,
   text: 'Test Button',
 }
frontend/__tests__/accessibility/components/TruncatedText.a11y.test.tsx (1)

7-15: Consider testing with actual text content.

The test renders TruncatedText with no props, which is valid but may not exercise the component's accessibility features. According to the component implementation (frontend/src/components/TruncatedText.tsx lines 2-44), the component dynamically sets a title attribute for truncated content, which is an important accessibility feature.

🔎 Proposed enhancement to test real-world scenarios
 describe('TruncatedText Accessibility', () => {
   it('should not have any accessibility violations', async () => {
-    const { container } = render(<TruncatedText />)
+    const { container } = render(
+      <TruncatedText text="This is a long text that might be truncated in the UI" />
+    )

     const results = await axe(container)

     expect(results).toHaveNoViolations()
   })
 })
frontend/__tests__/accessibility/components/LineChart.a11y.test.tsx (1)

8-32: Consider simplifying the mock or verifying actual accessibility features.

The mock implementation is quite elaborate, serializing chart options and handling the formatter function. For accessibility testing, this level of detail may be unnecessary unless you're specifically testing how these attributes affect accessibility.

Based on learnings, ApexCharts components should be wrapped in containers with ARIA attributes for proper accessibility. Consider either:

  1. Simplifying the mock to focus on accessibility-relevant attributes (role, aria-label, etc.)
  2. Adding assertions to verify that the LineChart component properly wraps the chart with appropriate ARIA attributes
🔎 Example: Add semantic verification
 describe('LineChart a11y', () => {
   it('should not have any accessibility violations', async () => {
     const { container } = render(<LineChart {...defaultProps} />)
+    
+    // Verify the chart has proper ARIA attributes
+    const chartWrapper = container.querySelector('[role="img"]')
+    expect(chartWrapper).toHaveAttribute('aria-label')

     const results = await axe(container)

     expect(results).toHaveNoViolations()
   })
 })
frontend/__tests__/accessibility/components/ContributionHeatmap.a11y.test.tsx (1)

8-54: Simplify mock to focus on accessibility testing.

The mock implementation invokes the tooltip.custom callback with test data (lines 21-37), including an out-of-bounds dataPointIndex: 999. This adds complexity that's not relevant to accessibility testing and could be confusing for future maintainers.

For a11y tests, the mock should render a simplified representation that preserves semantic structure. The tooltip callback invocation tests the component's internal logic rather than its accessibility characteristics.

🔎 Simplified mock focused on accessibility
 jest.mock('react-apexcharts', () => {
   return function MockChart(props: {
     options: unknown
     series: unknown
     height: string | number
     type: string
   }) {
     const mockSeries = props.series as Array<{
       name: string
       data: Array<{ x: string; y: number; date: string }>
     }>
-    const mockOptions = props.options as Record<string, unknown>
-
-    if (mockOptions.tooltip && typeof mockOptions.tooltip === 'object') {
-      const tooltip = mockOptions.tooltip as { custom?: (...args: unknown[]) => unknown }
-      if (tooltip.custom) {
-        if (mockSeries[0]?.data.length > 0) {
-          tooltip.custom({
-            seriesIndex: 0,
-            dataPointIndex: 0,
-            w: { config: { series: mockSeries } },
-          })
-        }
-        tooltip.custom({
-          seriesIndex: 0,
-          dataPointIndex: 999,
-          w: { config: { series: mockSeries } },
-        })
-      }
-    }

     return (
       <div
         data-testid="mock-heatmap-chart"
         data-type={props.type}
         data-height={props.height}
-        data-series-length={mockSeries.length}
+        role="img"
+        aria-label="Contribution heatmap"
       >
         {mockSeries.map((series) => (
           <div key={series.name} data-testid={`series-${series.name}`}>
             {series.name}: {series.data.length} data points
           </div>
         ))}
       </div>
     )
   }
 })
frontend/__tests__/accessibility/components/CardDetailsPage.a11y.test.tsx (1)

225-237: Remove unnecessary React.act wrapper.

React Testing Library's render function automatically wraps renders in act, making the explicit React.act call redundant. This pattern can also complicate the test flow by requiring manual container extraction.

🔎 Simplified version without explicit act
   it('should have no violations in archived state', async () => {
-    let container: HTMLElement
-
-    await React.act(async () => {
-      const renderResult = render(
-        <DetailsCard {...defaultProps} isActive={false} isArchived={true} />
-      )
-      container = renderResult.container
-    })
+    const { container } = render(
+      <DetailsCard {...defaultProps} isActive={false} isArchived={true} />
+    )

     const results = await axe(container)
     expect(results).toHaveNoViolations()
   })
frontend/__tests__/accessibility/components/BreadCrumbs.a11y.test.tsx (1)

7-15: Consider adding test cases with breadcrumb items.

The current test renders an empty Breadcrumbs component, which may not surface meaningful accessibility issues. Consider adding test cases that render the component with actual breadcrumb items to better validate accessible navigation structures.

💡 Example test case with breadcrumb items
import { BreadcrumbItem } from '@heroui/react'

it('should not have violations with multiple items', async () => {
  const { container } = render(
    <Breadcrumbs>
      <BreadcrumbItem>Home</BreadcrumbItem>
      <BreadcrumbItem>Category</BreadcrumbItem>
      <BreadcrumbItem>Page</BreadcrumbItem>
    </Breadcrumbs>
  )
  
  const results = await axe(container)
  expect(results).toHaveNoViolations()
})
frontend/__tests__/accessibility/components/HealthMetrics.a11y.test.tsx (1)

9-19: Consider safer icon serialization.

Line 14 accesses icon?.name, but React component functions may not have a name property that's meaningful for testing purposes. While this likely won't break the test, consider using a more defensive approach.

🔎 Suggested improvement
 jest.mock('components/BarChart', () => (props: { title: string; icon?: IconType }) => (
   <div
     data-testid="BarChart"
     data-props={JSON.stringify({
       ...props,
-      icon: props.icon?.name || null,
+      icon: typeof props.icon === 'function' ? 'IconType' : null,
     })}
   >
     {props.title}
   </div>
 ))
frontend/__tests__/accessibility/components/MarkdownWrapper.a11y.test.tsx (1)

7-17: Consider expanding the mock to cover more markdown features.

The current mock only handles bold text and links. While adequate for basic testing, MarkdownWrapper likely processes more markdown features (headings, lists, etc.) that could have accessibility implications. Consider adding test cases with more complex markdown content to ensure comprehensive accessibility coverage.

💡 Example expansion

Consider adding test cases that include:

  • Headings (for proper heading hierarchy)
  • Lists (ordered/unordered)
  • Images (for alt text requirements)
  • Code blocks

Example:

describe('MarkdownWrapper a11y', () => {
  it('should not have any accessibility violations', async () => {
    const { container } = render(<MarkdownWrapper content="test" className="custom-class" />)
    const results = await axe(container)
    expect(results).toHaveNoViolations()
  })

  it('should handle complex markdown without violations', async () => {
    const complexMarkdown = `
# Heading 1
## Heading 2
- List item 1
- List item 2
[Link](https://example.com)
    `
    const { container } = render(<MarkdownWrapper content={complexMarkdown} />)
    const results = await axe(container)
    expect(results).toHaveNoViolations()
  })
})
frontend/__tests__/accessibility/components/Release.a11y.test.tsx (1)

47-66: Consider using a fixed timestamp for test determinism.

The test data uses Date.now() on line 49, which creates non-deterministic test data. While this doesn't affect accessibility validation, using a fixed timestamp improves test consistency.

🔎 Suggested change
 const release: ReleaseType = {
   name: 'v1.0 The First Release',
-  publishedAt: Date.now(),
+  publishedAt: 1704297600000, // 2024-01-03T12:00:00.000Z
   repositoryName: 'our-awesome-project',
frontend/__tests__/accessibility/components/ProjectTypeDashboardCard.a11y.test.tsx (1)

35-43: LGTM! Test correctly validates accessibility compliance.

The test properly uses jest-axe to detect accessibility violations in the component's default state. This provides essential baseline coverage for catching a11y regressions.

Optional: Consider expanding test coverage

While the current smoke test is sufficient, you could optionally add tests for different prop variations to ensure accessibility across all component states:

it.each([
  { type: 'healthy' as const, count: 42 },
  { type: 'unhealthy' as const, count: 0 },
  { type: 'critical' as const, count: 100 },
])('should not have violations with type=$type, count=$count', async ({ type, count }) => {
  const { container } = render(
    <ProjectTypeDashboardCard type={type} count={count} icon={FaHeartPulse} />
  )
  const results = await axe(container)
  expect(results).toHaveNoViolations()
})
frontend/__tests__/accessibility/components/LoadingSpinner.a11y.test.tsx (1)

5-5: Consider centralizing the jest-axe matcher setup.

Since this PR introduces 60+ accessibility test files, the expect.extend(toHaveNoViolations) call will be duplicated across all files. Consider moving this to a Jest setup file (e.g., jest.setup.ts or setupTests.ts) to follow DRY principles and simplify maintenance.

🔎 Example centralized setup

Create or update frontend/jest.setup.ts (or similar):

import { toHaveNoViolations } from 'jest-axe'

expect.extend(toHaveNoViolations)

Then reference it in your Jest config:

{
  "setupFilesAfterEnv": ["<rootDir>/jest.setup.ts"]
}

This allows you to remove line 5 from all individual test files.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 53e8020 and 385b804.

📒 Files selected for processing (71)
  • frontend/Makefile
  • frontend/__tests__/accessibility/components/ActionButton.a11y.test.tsx
  • frontend/__tests__/accessibility/components/AnchorTitle.a11y.test.tsx
  • frontend/__tests__/accessibility/components/AutoScrollToTop.a11y.test.tsx
  • frontend/__tests__/accessibility/components/Badges.a11y.test.tsx
  • frontend/__tests__/accessibility/components/BarChart.a11y.test.tsx
  • frontend/__tests__/accessibility/components/BreadCrumbs.a11y.test.tsx
  • frontend/__tests__/accessibility/components/BreadCrumbsWrapper.a11y.test.tsx
  • frontend/__tests__/accessibility/components/CalendarButton.a11y.test.tsx
  • frontend/__tests__/accessibility/components/Card.a11y.test.tsx
  • frontend/__tests__/accessibility/components/CardDetailsPage.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ChapterMap.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ContributionHeatmap.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ContributorAvatar.a11y.test.tsx
  • frontend/__tests__/accessibility/components/DashboardCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/DisplayIcon.a11y.test.tsx
  • frontend/__tests__/accessibility/components/DonutBarChart.a11y.test.tsx
  • frontend/__tests__/accessibility/components/EntityActions.a11y.test.tsx
  • frontend/__tests__/accessibility/components/Footer.a11y.test.tsx
  • frontend/__tests__/accessibility/components/GeneralCompliantComponent.a11y.test.tsx
  • frontend/__tests__/accessibility/components/HealthMetrics.a11y.test.tsx
  • frontend/__tests__/accessibility/components/InfoBlock.a11y.test.tsx
  • frontend/__tests__/accessibility/components/InfoItem.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ItemCardList.a11y.test.tsx
  • frontend/__tests__/accessibility/components/Leaders.a11y.test.tsx
  • frontend/__tests__/accessibility/components/LeadersList.a11y.test.tsx
  • frontend/__tests__/accessibility/components/LineChart.a11y.test.tsx
  • frontend/__tests__/accessibility/components/LoadingSpinner.a11y.test.tsx
  • frontend/__tests__/accessibility/components/LoginPageContent.a11y.test.tsx
  • frontend/__tests__/accessibility/components/LogoCarousel.a11y.test.tsx
  • frontend/__tests__/accessibility/components/MarkdownWrapper.a11y.test.tsx
  • frontend/__tests__/accessibility/components/MetricsCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/MetricsScoreCircle.a11y.test.tsx
  • frontend/__tests__/accessibility/components/Milestones.a11y.test.tsx
  • frontend/__tests__/accessibility/components/Modal.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ModeToggle.a11y.test.tsx
  • frontend/__tests__/accessibility/components/MultiSearch.a11y.test.tsx
  • frontend/__tests__/accessibility/components/NavButton.a11y.test.tsx
  • frontend/__tests__/accessibility/components/NavDropDown.a11y.test.tsx
  • frontend/__tests__/accessibility/components/PageLayout.a11y.test.tsx
  • frontend/__tests__/accessibility/components/Pagination.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ProgramCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ProjectTypeDashboardCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ProjectsDashboardDropDown.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ProjectsDashboardNavBar.a11y.test.tsx
  • frontend/__tests__/accessibility/components/RecentIssues.a11y.test.tsx
  • frontend/__tests__/accessibility/components/RecentPullRequests.a11y.test.tsx
  • frontend/__tests__/accessibility/components/RecentRelease.a11y.test.tsx
  • frontend/__tests__/accessibility/components/Release.a11y.test.tsx
  • frontend/__tests__/accessibility/components/RepositoryCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ScrollToTop.a11y.test.tsx
  • frontend/__tests__/accessibility/components/Search.a11y.test.tsx
  • frontend/__tests__/accessibility/components/SearchPageLayout.a11y.test.tsx
  • frontend/__tests__/accessibility/components/SecondaryCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/SingleModuleCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/SkeletonBase.a11y.test.tsx
  • frontend/__tests__/accessibility/components/SnapshotCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/SortBy.a11y.test.tsx
  • frontend/__tests__/accessibility/components/SponsorCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/StatusBadge.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ToggleableList.a11y.test.tsx
  • frontend/__tests__/accessibility/components/TopContributorsList.a11y.test.tsx
  • frontend/__tests__/accessibility/components/TruncatedText.a11y.test.tsx
  • frontend/__tests__/accessibility/components/UserCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/UserMenu.a11y.test.tsx
  • frontend/__tests__/accessibility/pages/Header.a11y.test.tsx
  • frontend/docker/Dockerfile.unit.test
  • frontend/package.json
  • frontend/src/app/settings/api-keys/page.tsx
  • frontend/src/components/ChapterMap.tsx
  • frontend/src/components/LogoCarousel.tsx
🧰 Additional context used
🧠 Learnings (12)
📚 Learning: 2025-07-12T17:36:57.255Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 1717
File: frontend/__tests__/unit/pages/createProgram.test.tsx:70-86
Timestamp: 2025-07-12T17:36:57.255Z
Learning: When testing React page components that use mocked form components, validation logic should be tested at the form component level, not the page level. Page-level tests should focus on authentication, role checking, submission handling, and navigation logic.

Applied to files:

  • frontend/__tests__/accessibility/components/UserMenu.a11y.test.tsx
  • frontend/__tests__/accessibility/components/AutoScrollToTop.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ActionButton.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ProgramCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/Leaders.a11y.test.tsx
  • frontend/__tests__/accessibility/components/EntityActions.a11y.test.tsx
  • frontend/__tests__/accessibility/components/SponsorCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/PageLayout.a11y.test.tsx
  • frontend/__tests__/accessibility/components/UserCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ContributionHeatmap.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ItemCardList.a11y.test.tsx
  • frontend/__tests__/accessibility/components/CardDetailsPage.a11y.test.tsx
  • frontend/__tests__/accessibility/components/SearchPageLayout.a11y.test.tsx
  • frontend/__tests__/accessibility/components/RecentPullRequests.a11y.test.tsx
  • frontend/__tests__/accessibility/components/Modal.a11y.test.tsx
  • frontend/__tests__/accessibility/components/TopContributorsList.a11y.test.tsx
  • frontend/__tests__/accessibility/components/MetricsCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/Release.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ContributorAvatar.a11y.test.tsx
  • frontend/__tests__/accessibility/components/MarkdownWrapper.a11y.test.tsx
  • frontend/__tests__/accessibility/components/CalendarButton.a11y.test.tsx
  • frontend/__tests__/accessibility/components/Search.a11y.test.tsx
  • frontend/__tests__/accessibility/components/LineChart.a11y.test.tsx
  • frontend/__tests__/accessibility/components/SortBy.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ScrollToTop.a11y.test.tsx
  • frontend/__tests__/accessibility/components/NavButton.a11y.test.tsx
  • frontend/__tests__/accessibility/components/Milestones.a11y.test.tsx
  • frontend/__tests__/accessibility/components/LoginPageContent.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ProjectsDashboardNavBar.a11y.test.tsx
  • frontend/__tests__/accessibility/components/Card.a11y.test.tsx
  • frontend/__tests__/accessibility/components/GeneralCompliantComponent.a11y.test.tsx
  • frontend/__tests__/accessibility/components/Pagination.a11y.test.tsx
  • frontend/__tests__/accessibility/components/DonutBarChart.a11y.test.tsx
  • frontend/__tests__/accessibility/components/RepositoryCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/HealthMetrics.a11y.test.tsx
  • frontend/__tests__/accessibility/components/DashboardCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ProjectTypeDashboardCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/LogoCarousel.a11y.test.tsx
  • frontend/__tests__/accessibility/components/RecentIssues.a11y.test.tsx
  • frontend/__tests__/accessibility/components/Footer.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ChapterMap.a11y.test.tsx
  • frontend/__tests__/accessibility/components/Badges.a11y.test.tsx
  • frontend/__tests__/accessibility/components/BarChart.a11y.test.tsx
  • frontend/__tests__/accessibility/components/RecentRelease.a11y.test.tsx
  • frontend/__tests__/accessibility/components/SingleModuleCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/BreadCrumbs.a11y.test.tsx
📚 Learning: 2025-11-17T16:47:05.578Z
Learnt from: anurag2787
Repo: OWASP/Nest PR: 2671
File: frontend/__tests__/unit/components/MultiSearch.test.tsx:427-427
Timestamp: 2025-11-17T16:47:05.578Z
Learning: In the frontend test files for the OWASP/Nest repository, `expect(true).toBe(true)` no-op assertions may be intentionally added as workarounds when ESLint rule jest/expect-expect doesn't detect expectations inside helper functions or waitFor callbacks. These can be resolved by configuring the ESLint rule's assertFunctionNames option to recognize custom assertion helpers instead of flagging them as redundant.

Applied to files:

  • frontend/__tests__/accessibility/components/UserMenu.a11y.test.tsx
  • frontend/__tests__/accessibility/components/AutoScrollToTop.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ActionButton.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ProgramCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/Leaders.a11y.test.tsx
  • frontend/__tests__/accessibility/components/EntityActions.a11y.test.tsx
  • frontend/__tests__/accessibility/components/SponsorCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/NavDropDown.a11y.test.tsx
  • frontend/__tests__/accessibility/components/PageLayout.a11y.test.tsx
  • frontend/__tests__/accessibility/components/UserCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ContributionHeatmap.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ItemCardList.a11y.test.tsx
  • frontend/__tests__/accessibility/components/SearchPageLayout.a11y.test.tsx
  • frontend/__tests__/accessibility/components/RecentPullRequests.a11y.test.tsx
  • frontend/__tests__/accessibility/components/Modal.a11y.test.tsx
  • frontend/__tests__/accessibility/components/TopContributorsList.a11y.test.tsx
  • frontend/__tests__/accessibility/components/MetricsCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/Release.a11y.test.tsx
  • frontend/__tests__/accessibility/components/AnchorTitle.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ContributorAvatar.a11y.test.tsx
  • frontend/__tests__/accessibility/components/BreadCrumbsWrapper.a11y.test.tsx
  • frontend/__tests__/accessibility/components/MarkdownWrapper.a11y.test.tsx
  • frontend/__tests__/accessibility/components/Search.a11y.test.tsx
  • frontend/__tests__/accessibility/components/LineChart.a11y.test.tsx
  • frontend/__tests__/accessibility/components/SortBy.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ScrollToTop.a11y.test.tsx
  • frontend/__tests__/accessibility/components/StatusBadge.a11y.test.tsx
  • frontend/__tests__/accessibility/components/NavButton.a11y.test.tsx
  • frontend/__tests__/accessibility/components/DisplayIcon.a11y.test.tsx
  • frontend/__tests__/accessibility/components/Milestones.a11y.test.tsx
  • frontend/__tests__/accessibility/components/LoginPageContent.a11y.test.tsx
  • frontend/__tests__/accessibility/components/LeadersList.a11y.test.tsx
  • frontend/__tests__/accessibility/components/SkeletonBase.a11y.test.tsx
  • frontend/__tests__/accessibility/components/MultiSearch.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ProjectsDashboardNavBar.a11y.test.tsx
  • frontend/__tests__/accessibility/components/GeneralCompliantComponent.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ToggleableList.a11y.test.tsx
  • frontend/__tests__/accessibility/components/DonutBarChart.a11y.test.tsx
  • frontend/__tests__/accessibility/components/RepositoryCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/HealthMetrics.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ProjectTypeDashboardCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/LogoCarousel.a11y.test.tsx
  • frontend/__tests__/accessibility/components/RecentIssues.a11y.test.tsx
  • frontend/__tests__/accessibility/components/Footer.a11y.test.tsx
  • frontend/__tests__/accessibility/components/TruncatedText.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ChapterMap.a11y.test.tsx
  • frontend/__tests__/accessibility/components/Badges.a11y.test.tsx
  • frontend/__tests__/accessibility/components/BarChart.a11y.test.tsx
  • frontend/__tests__/accessibility/components/RecentRelease.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ModeToggle.a11y.test.tsx
  • frontend/__tests__/accessibility/components/SingleModuleCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/BreadCrumbs.a11y.test.tsx
  • frontend/__tests__/accessibility/components/SnapshotCard.a11y.test.tsx
📚 Learning: 2025-09-17T02:42:41.928Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 2288
File: frontend/src/components/ActionButton.tsx:0-0
Timestamp: 2025-09-17T02:42:41.928Z
Learning: In frontend/src/components/ActionButton.tsx, the user Rajgupta36 intentionally changed text-blue-600 to text-[#1D7BD7] to align the text color with the border color (#1D7BD7) for visual consistency, prioritizing design alignment over theme tokens.

Applied to files:

  • frontend/__tests__/accessibility/components/ActionButton.a11y.test.tsx
📚 Learning: 2025-06-21T12:21:32.372Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1633
File: frontend/src/components/GradientRadialChart.tsx:67-116
Timestamp: 2025-06-21T12:21:32.372Z
Learning: The react-apexcharts Chart component does not support ARIA attributes like aria-label and role as direct props. To add accessibility attributes to ApexCharts in React, wrap the Chart component in a container div with the appropriate ARIA attributes.

Applied to files:

  • frontend/__tests__/accessibility/components/ActionButton.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ContributionHeatmap.a11y.test.tsx
  • frontend/__tests__/accessibility/components/Modal.a11y.test.tsx
  • frontend/__tests__/accessibility/components/MetricsCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/AnchorTitle.a11y.test.tsx
  • frontend/__tests__/accessibility/components/MarkdownWrapper.a11y.test.tsx
  • frontend/__tests__/accessibility/components/LineChart.a11y.test.tsx
  • frontend/__tests__/accessibility/components/LeadersList.a11y.test.tsx
  • frontend/__tests__/accessibility/components/Card.a11y.test.tsx
  • frontend/__tests__/accessibility/components/GeneralCompliantComponent.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ProjectsDashboardDropDown.a11y.test.tsx
  • frontend/__tests__/accessibility/components/DonutBarChart.a11y.test.tsx
  • frontend/__tests__/accessibility/components/HealthMetrics.a11y.test.tsx
  • frontend/__tests__/accessibility/components/DashboardCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ProjectTypeDashboardCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/MetricsScoreCircle.a11y.test.tsx
  • frontend/__tests__/accessibility/components/InfoBlock.a11y.test.tsx
  • frontend/__tests__/accessibility/components/Badges.a11y.test.tsx
  • frontend/__tests__/accessibility/components/BarChart.a11y.test.tsx
  • frontend/__tests__/accessibility/components/SnapshotCard.a11y.test.tsx
📚 Learning: 2025-07-12T17:14:28.536Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 1717
File: frontend/src/app/mentorship/programs/[programKey]/edit/page.tsx:90-128
Timestamp: 2025-07-12T17:14:28.536Z
Learning: Both ProgramForm (programCard.tsx) and ModuleForm (mainmoduleCard.tsx) components already implement HTML validation using the `required` attribute on form fields. The browser's native validation prevents form submission and displays error messages when required fields are empty, eliminating the need for additional JavaScript validation before GraphQL mutations.

Applied to files:

  • frontend/__tests__/accessibility/components/ProgramCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/SingleModuleCard.a11y.test.tsx
📚 Learning: 2025-04-30T13:41:20.846Z
Learnt from: codic-yeeshu
Repo: OWASP/Nest PR: 1444
File: frontend/src/components/NavDropDown.tsx:0-0
Timestamp: 2025-04-30T13:41:20.846Z
Learning: When implementing dropdown menus or similar interactive components, always include proper accessibility features: ARIA attributes (aria-expanded, aria-haspopup, aria-controls), keyboard navigation support (Enter, Space, Escape keys), and mechanisms to close dropdowns when clicking outside.

Applied to files:

  • frontend/__tests__/accessibility/components/NavDropDown.a11y.test.tsx
📚 Learning: 2025-07-03T03:08:03.290Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1703
File: frontend/src/components/BarChart.tsx:33-46
Timestamp: 2025-07-03T03:08:03.290Z
Learning: In the OWASP Nest project's BarChart component (frontend/src/components/BarChart.tsx), the days and requirements arrays are guaranteed to always have the same length in their use cases, so input validation for array length matching is not needed.

Applied to files:

  • frontend/__tests__/accessibility/components/ContributionHeatmap.a11y.test.tsx
  • frontend/__tests__/accessibility/components/LineChart.a11y.test.tsx
  • frontend/__tests__/accessibility/components/DonutBarChart.a11y.test.tsx
  • frontend/__tests__/accessibility/components/HealthMetrics.a11y.test.tsx
  • frontend/__tests__/accessibility/components/BarChart.a11y.test.tsx
📚 Learning: 2025-06-20T16:12:59.256Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1633
File: frontend/src/components/HealthMetrics.tsx:30-30
Timestamp: 2025-06-20T16:12:59.256Z
Learning: In the DetailsCard component (frontend/src/components/CardDetailsPage.tsx), there's a safety check that ensures HealthMetrics component is only rendered when healthMetricsData exists and has at least one element: `healthMetricsData && healthMetricsData.length > 0`. This makes accessing data[0] safe within the HealthMetrics component.

Applied to files:

  • frontend/__tests__/accessibility/components/CardDetailsPage.a11y.test.tsx
  • frontend/__tests__/accessibility/components/MetricsCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/HealthMetrics.a11y.test.tsx
📚 Learning: 2025-06-20T16:12:59.256Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1633
File: frontend/src/components/HealthMetrics.tsx:30-30
Timestamp: 2025-06-20T16:12:59.256Z
Learning: In the DetailsCard component (frontend/src/components/CardDetailsPage.tsx), there's a length check before rendering HealthMetrics: `healthMetricsData.length > 0`. This ensures that when HealthMetrics is rendered, the data array has at least one element, making accessing data[0] safe within the HealthMetrics component.

Applied to files:

  • frontend/__tests__/accessibility/components/CardDetailsPage.a11y.test.tsx
  • frontend/__tests__/accessibility/components/MetricsCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/HealthMetrics.a11y.test.tsx
📚 Learning: 2025-10-26T12:50:50.512Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 2429
File: backend/Makefile:30-32
Timestamp: 2025-10-26T12:50:50.512Z
Learning: The `exec-backend-e2e-command` and `exec-db-e2e-command` Makefile targets in the backend/Makefile are intended for local development and debugging only, not for CI/CD execution, so the `-it` flags are appropriate.

Applied to files:

  • frontend/Makefile
📚 Learning: 2025-11-17T17:30:42.139Z
Learnt from: anurag2787
Repo: OWASP/Nest PR: 2671
File: frontend/__tests__/unit/components/MultiSearch.test.tsx:169-171
Timestamp: 2025-11-17T17:30:42.139Z
Learning: In the OWASP/Nest frontend tests (PR #2671 context), wrapper functions like `expectChaptersCountEqualsThree` that simply call another helper with a fixed parameter (e.g., `expectChaptersCountEquals(3)`) are intentionally used to avoid arrow function callbacks in `waitFor` calls. This pattern prevents adding nesting depth that would trigger rule typescript:S2004. Example: `await waitFor(expectChaptersCountEqualsThree)` avoids the extra nesting from `await waitFor(() => expectChaptersCountEquals(3))`.

Applied to files:

  • frontend/__tests__/accessibility/components/BreadCrumbsWrapper.a11y.test.tsx
  • frontend/__tests__/accessibility/components/MarkdownWrapper.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ChapterMap.a11y.test.tsx
📚 Learning: 2025-12-29T22:01:53.874Z
Learnt from: ShashaankS
Repo: OWASP/Nest PR: 3086
File: frontend/src/components/SortBy.tsx:45-45
Timestamp: 2025-12-29T22:01:53.874Z
Learning: In frontend/src/components/SortBy.tsx, the SelectItem uses hover:bg-transparent intentionally for better visual appeal and theme consistency. This design choice prioritizes a cleaner aesthetic over hover background feedback.

Applied to files:

  • frontend/__tests__/accessibility/components/SortBy.a11y.test.tsx
🧬 Code graph analysis (22)
frontend/__tests__/accessibility/components/UserMenu.a11y.test.tsx (1)
frontend/src/components/UserMenu.tsx (1)
  • UserMenu (12-125)
frontend/__tests__/accessibility/components/AutoScrollToTop.a11y.test.tsx (1)
frontend/src/components/AutoScrollToTop.tsx (1)
  • AutoScrollToTop (6-14)
frontend/__tests__/accessibility/components/Leaders.a11y.test.tsx (1)
frontend/__tests__/unit/data/mockProjectDetailsData.ts (1)
  • mockProjectDetailsData (1-142)
frontend/__tests__/accessibility/components/PageLayout.a11y.test.tsx (1)
frontend/src/components/PageLayout.tsx (1)
  • PageLayout (13-18)
frontend/__tests__/accessibility/components/UserCard.a11y.test.tsx (1)
frontend/src/types/card.ts (1)
  • UserCardProps (83-97)
frontend/__tests__/accessibility/components/CardDetailsPage.a11y.test.tsx (3)
frontend/src/types/card.ts (1)
  • DetailsCardProps (43-81)
frontend/__tests__/unit/data/mockChapterData.ts (1)
  • mockChapterData (1-32)
backend/apps/mentorship/api/internal/nodes/enum.py (1)
  • ExperienceLevelEnum (12-18)
frontend/__tests__/accessibility/components/TopContributorsList.a11y.test.tsx (1)
frontend/src/types/contributor.ts (1)
  • Contributor (1-8)
frontend/__tests__/accessibility/components/MetricsCard.a11y.test.tsx (1)
frontend/src/types/healthMetrics.ts (1)
  • HealthMetricsProps (26-54)
frontend/__tests__/accessibility/components/ContributorAvatar.a11y.test.tsx (1)
frontend/src/types/contributor.ts (1)
  • Contributor (1-8)
frontend/__tests__/accessibility/components/BreadCrumbsWrapper.a11y.test.tsx (1)
frontend/src/components/BreadCrumbsWrapper.tsx (1)
  • BreadCrumbsWrapper (10-59)
frontend/__tests__/accessibility/components/CalendarButton.a11y.test.tsx (1)
frontend/src/components/CalendarButton.tsx (1)
  • CalendarButton (10-81)
frontend/__tests__/accessibility/components/LineChart.a11y.test.tsx (1)
frontend/src/types/healthMetrics.ts (1)
  • ApexLineChartSeries (1-4)
frontend/__tests__/accessibility/components/ScrollToTop.a11y.test.tsx (1)
frontend/src/components/ScrollToTop.tsx (1)
  • ScrollToTop (6-43)
frontend/__tests__/accessibility/components/NavButton.a11y.test.tsx (1)
frontend/src/types/button.ts (1)
  • NavButtonProps (13-21)
frontend/__tests__/accessibility/components/DisplayIcon.a11y.test.tsx (2)
frontend/src/types/icon.ts (1)
  • Icon (1-3)
frontend/src/components/DisplayIcon.tsx (1)
  • DisplayIcon (7-55)
frontend/__tests__/accessibility/components/RepositoryCard.a11y.test.tsx (1)
frontend/src/types/project.ts (1)
  • RepositoryCardProps (56-67)
frontend/__tests__/accessibility/components/HealthMetrics.a11y.test.tsx (1)
frontend/src/types/healthMetrics.ts (1)
  • HealthMetricsProps (26-54)
frontend/__tests__/accessibility/components/Footer.a11y.test.tsx (1)
frontend/src/components/Footer.tsx (1)
  • Footer (11-115)
frontend/__tests__/accessibility/components/TruncatedText.a11y.test.tsx (1)
frontend/src/components/TruncatedText.tsx (1)
  • TruncatedText (3-45)
frontend/__tests__/accessibility/components/ChapterMap.a11y.test.tsx (1)
frontend/__tests__/unit/data/mockChapterData.ts (1)
  • mockChapterData (1-32)
frontend/__tests__/accessibility/components/ModeToggle.a11y.test.tsx (1)
frontend/src/components/ModeToggle.tsx (1)
  • ModeToggle (7-44)
frontend/__tests__/accessibility/components/SingleModuleCard.a11y.test.tsx (1)
backend/apps/mentorship/api/internal/nodes/enum.py (2)
  • ProgramStatusEnum (22-27)
  • ExperienceLevelEnum (12-18)
🪛 ast-grep (0.40.3)
frontend/__tests__/accessibility/components/Modal.a11y.test.tsx

[warning] 19-19: Usage of dangerouslySetInnerHTML detected. This bypasses React's built-in XSS protection. Always sanitize HTML content using libraries like DOMPurify before injecting it into the DOM to prevent XSS attacks.
Context: dangerouslySetInnerHTML
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml
- https://cwe.mitre.org/data/definitions/79.html

(react-unsafe-html-injection)

🪛 Biome (2.1.2)
frontend/__tests__/accessibility/components/Modal.a11y.test.tsx

[error] 20-20: Avoid passing content using the dangerouslySetInnerHTML prop.

Setting content using code can expose users to cross-site scripting (XSS) attacks

(lint/security/noDangerouslySetInnerHtml)

@arkid15r arkid15r marked this pull request as draft January 3, 2026 17:26
@arkid15r
Copy link
Collaborator

arkid15r commented Jan 3, 2026

Please make sure it's ready for review before requesting it -- https://github.com/OWASP/Nest/blob/main/CONTRIBUTING.md#contributing-workflow

Copy link
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: 0

♻️ Duplicate comments (2)
frontend/__tests__/accessibility/components/LoadingSpinner.a11y.test.tsx (1)

7-23: Past review feedback addressed.

The test now includes coverage for both the default state (no props) and with the imageUrl prop, addressing the previous review comment about testing different prop values.

frontend/__tests__/accessibility/components/DashboardCard.a11y.test.tsx (1)

15-15: Past naming feedback already addressed.

The describe block correctly uses "DashboardCard a11y", consistent with other a11y test files in this PR.

🧹 Nitpick comments (2)
frontend/__tests__/accessibility/components/DashboardCard.a11y.test.tsx (1)

8-22: Consider testing with populated stats prop.

The current test validates the basic accessibility case with undefined optional props. For more comprehensive coverage, consider adding a test case that renders DashboardCard with actual stats data to ensure accessibility is maintained when all props are populated.

frontend/jest.setup.ts (1)

70-84: Refine the Link mock to match the suggested implementation from previous review.

Great work centralizing the mock! However, the implementation still differs from the refinements suggested in the past review:

  1. Missing __esModule: true, default: ... wrapper for proper ES module interop
  2. href should be optional (href?: string) since some Link usages may not always provide it
🔎 Suggested refinement to match past review recommendations
-jest.mock('next/link', () => {
-  return function MockedLink({
-    children,
-    href,
-    className,
-    ...props
-  }: {
-    children: React.ReactNode
-    href: string
-    className?: string
-    [key: string]: unknown
-  }) {
-    return React.createElement('a', { href, className, ...props }, children)
-  }
-})
+jest.mock('next/link', () => ({
+  __esModule: true,
+  default: function MockedLink({
+    children,
+    href,
+    className,
+    ...props
+  }: {
+    children: React.ReactNode
+    href?: string
+    className?: string
+    [key: string]: unknown
+  }) {
+    return React.createElement('a', { href, className, ...props }, children)
+  },
+}))
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 385b804 and 41f3a38.

📒 Files selected for processing (11)
  • frontend/Makefile
  • frontend/__tests__/accessibility/components/AutoScrollToTop.a11y.test.tsx
  • frontend/__tests__/accessibility/components/BreadCrumbsWrapper.a11y.test.tsx
  • frontend/__tests__/accessibility/components/DashboardCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/LoadingSpinner.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ModeToggle.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ProjectTypeDashboardCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/SkeletonBase.a11y.test.tsx
  • frontend/docker/Dockerfile.a11y.test
  • frontend/jest.setup.ts
  • frontend/src/components/DonutBarChart.tsx
🚧 Files skipped from review as they are similar to previous changes (4)
  • frontend/tests/accessibility/components/BreadCrumbsWrapper.a11y.test.tsx
  • frontend/tests/accessibility/components/ModeToggle.a11y.test.tsx
  • frontend/tests/accessibility/components/AutoScrollToTop.a11y.test.tsx
  • frontend/tests/accessibility/components/SkeletonBase.a11y.test.tsx
🧰 Additional context used
🧠 Learnings (8)
📚 Learning: 2025-06-21T12:21:32.372Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1633
File: frontend/src/components/GradientRadialChart.tsx:67-116
Timestamp: 2025-06-21T12:21:32.372Z
Learning: The react-apexcharts Chart component does not support ARIA attributes like aria-label and role as direct props. To add accessibility attributes to ApexCharts in React, wrap the Chart component in a container div with the appropriate ARIA attributes.

Applied to files:

  • frontend/__tests__/accessibility/components/DashboardCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ProjectTypeDashboardCard.a11y.test.tsx
  • frontend/src/components/DonutBarChart.tsx
📚 Learning: 2025-07-12T17:36:57.255Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 1717
File: frontend/__tests__/unit/pages/createProgram.test.tsx:70-86
Timestamp: 2025-07-12T17:36:57.255Z
Learning: When testing React page components that use mocked form components, validation logic should be tested at the form component level, not the page level. Page-level tests should focus on authentication, role checking, submission handling, and navigation logic.

Applied to files:

  • frontend/__tests__/accessibility/components/DashboardCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ProjectTypeDashboardCard.a11y.test.tsx
📚 Learning: 2025-11-17T16:47:05.578Z
Learnt from: anurag2787
Repo: OWASP/Nest PR: 2671
File: frontend/__tests__/unit/components/MultiSearch.test.tsx:427-427
Timestamp: 2025-11-17T16:47:05.578Z
Learning: In the frontend test files for the OWASP/Nest repository, `expect(true).toBe(true)` no-op assertions may be intentionally added as workarounds when ESLint rule jest/expect-expect doesn't detect expectations inside helper functions or waitFor callbacks. These can be resolved by configuring the ESLint rule's assertFunctionNames option to recognize custom assertion helpers instead of flagging them as redundant.

Applied to files:

  • frontend/__tests__/accessibility/components/ProjectTypeDashboardCard.a11y.test.tsx
📚 Learning: 2025-11-17T17:30:42.139Z
Learnt from: anurag2787
Repo: OWASP/Nest PR: 2671
File: frontend/__tests__/unit/components/MultiSearch.test.tsx:169-171
Timestamp: 2025-11-17T17:30:42.139Z
Learning: In the OWASP/Nest frontend tests (PR #2671 context), wrapper functions like `expectChaptersCountEqualsThree` that simply call another helper with a fixed parameter (e.g., `expectChaptersCountEquals(3)`) are intentionally used to avoid arrow function callbacks in `waitFor` calls. This pattern prevents adding nesting depth that would trigger rule typescript:S2004. Example: `await waitFor(expectChaptersCountEqualsThree)` avoids the extra nesting from `await waitFor(() => expectChaptersCountEquals(3))`.

Applied to files:

  • frontend/__tests__/accessibility/components/ProjectTypeDashboardCard.a11y.test.tsx
📚 Learning: 2025-10-26T12:50:50.512Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 2429
File: backend/Makefile:30-32
Timestamp: 2025-10-26T12:50:50.512Z
Learning: The `exec-backend-e2e-command` and `exec-db-e2e-command` Makefile targets in the backend/Makefile are intended for local development and debugging only, not for CI/CD execution, so the `-it` flags are appropriate.

Applied to files:

  • frontend/Makefile
📚 Learning: 2025-07-03T03:08:03.290Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1703
File: frontend/src/components/BarChart.tsx:33-46
Timestamp: 2025-07-03T03:08:03.290Z
Learning: In the OWASP Nest project's BarChart component (frontend/src/components/BarChart.tsx), the days and requirements arrays are guaranteed to always have the same length in their use cases, so input validation for array length matching is not needed.

Applied to files:

  • frontend/src/components/DonutBarChart.tsx
📚 Learning: 2025-07-13T07:31:06.511Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 1717
File: frontend/src/components/ModuleCard.tsx:53-55
Timestamp: 2025-07-13T07:31:06.511Z
Learning: In Next.js 13+ app router, useRouter from 'next/navigation' does not provide asPath or query properties. Use useParams to extract route parameters and usePathname to get the current pathname instead.

Applied to files:

  • frontend/jest.setup.ts
📚 Learning: 2025-07-13T11:29:25.245Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 1717
File: frontend/src/app/mentorship/programs/page.tsx:59-61
Timestamp: 2025-07-13T11:29:25.245Z
Learning: In Next.js 13+ app router, components with the 'use client' directive run entirely on the client side and don't require window object existence checks or SSR hydration considerations. Direct access to window.location and other browser APIs is safe in client components.

Applied to files:

  • frontend/jest.setup.ts
🔇 Additional comments (5)
frontend/src/components/DonutBarChart.tsx (1)

26-29: LGTM! Accessibility wrapper follows best practices.

The wrapper div with role="img" and aria-label correctly makes the chart accessible, following the established pattern for ApexCharts components that don't support ARIA attributes directly.

Based on learnings, ApexCharts requires wrapping for accessibility attributes.

frontend/Makefile (1)

55-79: LGTM! Accessibility test integration follows established patterns.

The new test-frontend-a11y target correctly follows the same Docker build and execution pattern as the existing test-frontend-unit and test-frontend-e2e targets, including layer caching and environment configuration.

frontend/docker/Dockerfile.a11y.test (1)

16-26: File ownership is correctly configured for test execution.

The permission setup actually follows Docker best practices. The chown node:node /app command (without -R) correctly changes the directory ownership while leaving source files immutable at root:root. This allows the node user to create temporary and cache files within /app while preventing accidental modifications to source code. The read-only permissions (chmod 444) on package.json and pnpm-lock.yaml are intentional for immutability. Jest tests can execute successfully with this pattern as they only need to read source files and write temporary data within the /app directory, which the node user owns.

frontend/jest.setup.ts (1)

66-66: LGTM! usePathname mock is appropriate for Next.js 13+.

The mock correctly provides the usePathname hook that replaced useRouter().asPath in Next.js 13+ app router, returning a stable pathname for tests.

Based on learnings, Next.js 13+ components should use usePathname instead of useRouter().asPath.

frontend/__tests__/accessibility/components/ProjectTypeDashboardCard.a11y.test.tsx (1)

1-22: LGTM! Clean and focused accessibility test.

The test follows the standard jest-axe pattern correctly:

  • Properly extends expect with toHaveNoViolations
  • Renders the component with baseline props
  • Runs axe accessibility checks
  • Asserts no violations

The centralized next/link mock from jest.setup.ts is now used (no local duplication), which addresses the previous review concern.

Copy link
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: 0

🧹 Nitpick comments (1)
frontend/package.json (1)

18-18: Consider adding type checking before running accessibility tests.

Unlike test:unit (line 17), the test:a11y script does not include tsc --noEmit to check for TypeScript errors before running tests. This inconsistency could allow type errors in accessibility test files to go unnoticed until runtime.

If this omission is intentional for faster feedback, please confirm. Otherwise, consider adding type checking for consistency and early error detection.

🔎 Suggested improvement for consistency
-    "test:a11y": "NODE_OPTIONS='--experimental-vm-modules --no-warnings=DEP0040' jest __tests__/accessibility/components --coverage=false"
+    "test:a11y": "tsc --noEmit && NODE_OPTIONS='--experimental-vm-modules --no-warnings=DEP0040' jest __tests__/accessibility/components --coverage=false"
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 41f3a38 and decbe07.

📒 Files selected for processing (1)
  • frontend/package.json
🔇 Additional comments (1)
frontend/package.json (1)

17-17: LGTM: Trailing comma added for consistency.

The trailing comma addition is a syntactic improvement that follows JSON best practices and accommodates the new script below.

Copy link
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: 0

🧹 Nitpick comments (2)
docker/frontend/Dockerfile.a11y.test (2)

21-25: Consider Docker layer caching optimization.

Currently, changes to test files or source code will invalidate all subsequent layers. For faster rebuilds during development, consider copying only the files needed for dependency installation first, then copying test and source files after.

However, since this is a test-specific Dockerfile typically rebuilt in CI, the current approach is acceptable.

🔎 Optional optimization for development workflow
 COPY --chmod=444 --chown=root:root package.json pnpm-lock.yaml ./
+COPY .pnpmrc ./
 RUN --mount=type=cache,id=pnpm,target=/pnpm/store \
     pnpm install --frozen-lockfile --ignore-scripts && \
     chown node:node /app
 
 COPY __tests__/accessibility __tests__/accessibility
 COPY __tests__/unit __tests__/unit
-COPY .pnpmrc jest.config.ts jest.setup.ts tsconfig.json ./
+COPY jest.config.ts jest.setup.ts tsconfig.json ./
 COPY public public
 COPY src src

This separates dependency installation from code changes, improving cache hit rates.


27-27: Consider adding a default CMD for clarity.

The Dockerfile doesn't specify a CMD or ENTRYPOINT. While this is likely intentional (with the Makefile providing the command via docker run), adding a default test command would improve usability and documentation.

🔎 Suggested addition
 USER node
+
+CMD ["pnpm", "test:a11y"]

This provides a sensible default while still allowing command override from the Makefile.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between decbe07 and 1fce7ce.

📒 Files selected for processing (2)
  • docker/frontend/Dockerfile.a11y.test
  • frontend/Makefile
🚧 Files skipped from review as they are similar to previous changes (1)
  • frontend/Makefile
🔇 Additional comments (2)
docker/frontend/Dockerfile.a11y.test (2)

3-12: LGTM!

The environment variable configuration and pnpm installation setup follow best practices:

  • Cache mounts optimize build performance
  • --ignore-scripts flag enhances security
  • Retry and timeout settings improve reliability

1-1: No action needed. Node.js 24 is the current stable LTS version as of January 2026 (v24.12.0 released December 10, 2025). Using node:24-alpine is appropriate.

Likely an incorrect or invalid review comment.

Copy link
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: 3

Fix all issues with AI Agents 🤖
In @frontend/__tests__/accessibility/components/ContributorAvatar.a11y.test.tsx:
- Around line 9-15: The Tooltip mock used in jest.mock('@heroui/tooltip') is too
simplistic and should be updated to preserve key ARIA structure: render a
trigger wrapper that accepts an id prop and sets aria-describedby to that id on
the trigger element, and render the tooltip content element with role="tooltip"
and the same id so axe can validate the relationship; also ensure the mock
accepts children and content props and forwards focusable attributes (e.g.,
tabIndex) so focus/navigation tests behave like the real @heroui/tooltip.

In @frontend/__tests__/accessibility/components/MarkdownWrapper.a11y.test.tsx:
- Around line 7-15: The test's jest.mock call uses the wrong module specifier so
it doesn't intercept the component import; update the jest.mock call in
frontend/__tests__/accessibility/components/MarkdownWrapper.a11y.test.tsx from
'markdown-it/index.mjs' to 'markdown-it' so the mock matches the component's
import (keep the same mock implementation that provides render and use).

In @frontend/__tests__/accessibility/components/RecentIssues.a11y.test.tsx:
- Around line 8-23: Remove the local jest.mock('next/link', ...) block from
RecentIssues.a11y.test.tsx because the global setup already mocks next/link;
delete the entire mock declaration (the jest.mock call that returns a default
anchor component) so the test uses the shared mock and avoids
duplication/inconsistency.
🧹 Nitpick comments (1)
frontend/__tests__/accessibility/components/ContributorAvatar.a11y.test.tsx (1)

35-54: Consider testing edge cases with minimal data.

The test currently only validates the happy path with all optional fields populated. Since contributionsCount, projectKey, and projectName are optional (per the Contributor type), consider adding test cases with minimal data to ensure accessibility holds across different rendering scenarios.

Example additional test case
it('should not have accessibility violations with minimal contributor data', async () => {
  const minimalContributor: Contributor = {
    login: 'john-doe',
    name: 'John Doe',
    avatarUrl: 'https://avatars.githubusercontent.com/u/67890',
  }

  const { container } = render(
    <ContributorAvatar contributor={minimalContributor} uniqueKey="minimal-test" />
  )

  const results = await axe(container)
  expect(results).toHaveNoViolations()
})
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1fce7ce and b9c632b.

📒 Files selected for processing (16)
  • frontend/Makefile
  • frontend/__tests__/accessibility/components/CardDetailsPage.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ContributorAvatar.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ItemCardList.a11y.test.tsx
  • frontend/__tests__/accessibility/components/Leaders.a11y.test.tsx
  • frontend/__tests__/accessibility/components/LogoCarousel.a11y.test.tsx
  • frontend/__tests__/accessibility/components/MarkdownWrapper.a11y.test.tsx
  • frontend/__tests__/accessibility/components/RecentIssues.a11y.test.tsx
  • frontend/__tests__/accessibility/components/RecentPullRequests.a11y.test.tsx
  • frontend/__tests__/accessibility/components/RecentRelease.a11y.test.tsx
  • frontend/__tests__/accessibility/components/Release.a11y.test.tsx
  • frontend/__tests__/accessibility/components/SingleModuleCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/TopContributorsList.a11y.test.tsx
  • frontend/__tests__/accessibility/components/UserCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/UserMenu.a11y.test.tsx
  • frontend/jest.setup.ts
🚧 Files skipped from review as they are similar to previous changes (10)
  • frontend/tests/accessibility/components/SingleModuleCard.a11y.test.tsx
  • frontend/tests/accessibility/components/RecentRelease.a11y.test.tsx
  • frontend/tests/accessibility/components/RecentPullRequests.a11y.test.tsx
  • frontend/tests/accessibility/components/TopContributorsList.a11y.test.tsx
  • frontend/tests/accessibility/components/CardDetailsPage.a11y.test.tsx
  • frontend/tests/accessibility/components/LogoCarousel.a11y.test.tsx
  • frontend/tests/accessibility/components/UserMenu.a11y.test.tsx
  • frontend/tests/accessibility/components/ItemCardList.a11y.test.tsx
  • frontend/tests/accessibility/components/UserCard.a11y.test.tsx
  • frontend/tests/accessibility/components/Release.a11y.test.tsx
🧰 Additional context used
🧠 Learnings (5)
📚 Learning: 2025-11-17T16:47:05.578Z
Learnt from: anurag2787
Repo: OWASP/Nest PR: 2671
File: frontend/__tests__/unit/components/MultiSearch.test.tsx:427-427
Timestamp: 2025-11-17T16:47:05.578Z
Learning: In the frontend test files for the OWASP/Nest repository, `expect(true).toBe(true)` no-op assertions may be intentionally added as workarounds when ESLint rule jest/expect-expect doesn't detect expectations inside helper functions or waitFor callbacks. These can be resolved by configuring the ESLint rule's assertFunctionNames option to recognize custom assertion helpers instead of flagging them as redundant.

Applied to files:

  • frontend/__tests__/accessibility/components/ContributorAvatar.a11y.test.tsx
  • frontend/__tests__/accessibility/components/MarkdownWrapper.a11y.test.tsx
  • frontend/__tests__/accessibility/components/Leaders.a11y.test.tsx
  • frontend/__tests__/accessibility/components/RecentIssues.a11y.test.tsx
📚 Learning: 2025-07-12T17:36:57.255Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 1717
File: frontend/__tests__/unit/pages/createProgram.test.tsx:70-86
Timestamp: 2025-07-12T17:36:57.255Z
Learning: When testing React page components that use mocked form components, validation logic should be tested at the form component level, not the page level. Page-level tests should focus on authentication, role checking, submission handling, and navigation logic.

Applied to files:

  • frontend/__tests__/accessibility/components/ContributorAvatar.a11y.test.tsx
  • frontend/__tests__/accessibility/components/MarkdownWrapper.a11y.test.tsx
  • frontend/__tests__/accessibility/components/RecentIssues.a11y.test.tsx
📚 Learning: 2025-11-17T17:30:42.139Z
Learnt from: anurag2787
Repo: OWASP/Nest PR: 2671
File: frontend/__tests__/unit/components/MultiSearch.test.tsx:169-171
Timestamp: 2025-11-17T17:30:42.139Z
Learning: In the OWASP/Nest frontend tests (PR #2671 context), wrapper functions like `expectChaptersCountEqualsThree` that simply call another helper with a fixed parameter (e.g., `expectChaptersCountEquals(3)`) are intentionally used to avoid arrow function callbacks in `waitFor` calls. This pattern prevents adding nesting depth that would trigger rule typescript:S2004. Example: `await waitFor(expectChaptersCountEqualsThree)` avoids the extra nesting from `await waitFor(() => expectChaptersCountEquals(3))`.

Applied to files:

  • frontend/__tests__/accessibility/components/MarkdownWrapper.a11y.test.tsx
📚 Learning: 2025-07-13T07:31:06.511Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 1717
File: frontend/src/components/ModuleCard.tsx:53-55
Timestamp: 2025-07-13T07:31:06.511Z
Learning: In Next.js 13+ app router, useRouter from 'next/navigation' does not provide asPath or query properties. Use useParams to extract route parameters and usePathname to get the current pathname instead.

Applied to files:

  • frontend/jest.setup.ts
📚 Learning: 2025-10-26T12:50:50.512Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 2429
File: backend/Makefile:30-32
Timestamp: 2025-10-26T12:50:50.512Z
Learning: The `exec-backend-e2e-command` and `exec-db-e2e-command` Makefile targets in the backend/Makefile are intended for local development and debugging only, not for CI/CD execution, so the `-it` flags are appropriate.

Applied to files:

  • frontend/Makefile
🧬 Code graph analysis (2)
frontend/__tests__/accessibility/components/ContributorAvatar.a11y.test.tsx (1)
frontend/src/types/contributor.ts (1)
  • Contributor (1-8)
frontend/__tests__/accessibility/components/Leaders.a11y.test.tsx (1)
frontend/__tests__/unit/data/mockProjectDetailsData.ts (1)
  • mockProjectDetailsData (1-142)
🔇 Additional comments (9)
frontend/__tests__/accessibility/components/Leaders.a11y.test.tsx (1)

1-16: LGTM! Clean accessibility test implementation.

The test follows the standard jest-axe pattern and correctly uses shared mock data from the test fixtures.

frontend/__tests__/accessibility/components/RecentIssues.a11y.test.tsx (1)

52-60: LGTM! Test structure is sound.

The accessibility test follows the standard pattern and uses appropriate mock data.

frontend/Makefile (2)

55-58: LGTM! Proper test target dependency.

The test-frontend target now correctly depends on all three test types (unit, e2e, and a11y), ensuring comprehensive test coverage.


74-79: LGTM! Consistent Docker-based test target.

The new test-frontend-a11y target follows the established pattern of the existing unit and e2e test targets, using Docker BuildKit with cache optimization and proper environment configuration.

frontend/jest.setup.ts (3)

66-66: LGTM! Appropriate usePathname mock.

Adding usePathname to the Next.js navigation mock provides necessary support for components that rely on pathname information during testing.


70-84: LGTM! Clean next/link mock implementation.

The MockedLink mock provides a simple but effective anchor element for testing, preserving essential props like href and className while avoiding actual navigation.


87-109: LGTM! Appropriate next/image mock.

The mock handles key Next.js Image props (fill, objectFit) while rendering a standard img element suitable for accessibility testing.

frontend/__tests__/accessibility/components/MarkdownWrapper.a11y.test.tsx (1)

17-25: LGTM! Standard accessibility test pattern.

The test correctly renders the component and validates accessibility with axe.

frontend/__tests__/accessibility/components/ContributorAvatar.a11y.test.tsx (1)

1-7: LGTM!

The imports and jest-axe setup are correct. Properly extends the expect matcher for accessibility assertions.

Copy link
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: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
frontend/src/components/DonutBarChart.tsx (1)

27-59: Use a div wrapper instead of svg to avoid nested SVG issues.

Wrapping the Chart component in an <svg> element is problematic because react-apexcharts already renders its own SVG internally. This creates nested SVGs, which can cause:

  • Unpredictable rendering behavior across browsers
  • Layout and sizing issues due to the viewBox="0 0 100 100" conflicting with the chart's height={250}

The correct approach is to wrap the Chart in a container div with accessibility attributes, as documented in PR #1633 and demonstrated in the ContributionHeatmap component.

Suggested fix
-      <svg
-        role="img"
-        aria-label="Donut chart showing healthy, needs attention, and unhealthy statuses"
-        viewBox="0 0 100 100"
-      >
-        <title>Donut chart depicting health statuses</title>
+      <div
+        role="img"
+        aria-label="Donut chart showing healthy, needs attention, and unhealthy statuses"
+      >
         <Chart
           key={theme}
           options={{
@@ -54,7 +53,7 @@
           height={250}
           type="donut"
         />
-      </svg>
+      </div>

The <title> element is only valid inside SVG elements, so it should be removed. The aria-label provides sufficient accessible text for screen readers.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b9c632b and 75d220c.

📒 Files selected for processing (5)
  • frontend/__tests__/accessibility/components/CalendarButton.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ContributorAvatar.a11y.test.tsx
  • frontend/__tests__/accessibility/components/MarkdownWrapper.a11y.test.tsx
  • frontend/__tests__/accessibility/components/RecentIssues.a11y.test.tsx
  • frontend/src/components/DonutBarChart.tsx
🚧 Files skipped from review as they are similar to previous changes (4)
  • frontend/tests/accessibility/components/MarkdownWrapper.a11y.test.tsx
  • frontend/tests/accessibility/components/ContributorAvatar.a11y.test.tsx
  • frontend/tests/accessibility/components/CalendarButton.a11y.test.tsx
  • frontend/tests/accessibility/components/RecentIssues.a11y.test.tsx
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-06-21T12:21:32.372Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1633
File: frontend/src/components/GradientRadialChart.tsx:67-116
Timestamp: 2025-06-21T12:21:32.372Z
Learning: The react-apexcharts Chart component does not support ARIA attributes like aria-label and role as direct props. To add accessibility attributes to ApexCharts in React, wrap the Chart component in a container div with the appropriate ARIA attributes.

Applied to files:

  • frontend/src/components/DonutBarChart.tsx
📚 Learning: 2025-07-03T03:08:03.290Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1703
File: frontend/src/components/BarChart.tsx:33-46
Timestamp: 2025-07-03T03:08:03.290Z
Learning: In the OWASP Nest project's BarChart component (frontend/src/components/BarChart.tsx), the days and requirements arrays are guaranteed to always have the same length in their use cases, so input validation for array length matching is not needed.

Applied to files:

  • frontend/src/components/DonutBarChart.tsx

@Utkarsh-0304 Utkarsh-0304 marked this pull request as ready for review January 6, 2026 11:57
Copy link
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: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
frontend/src/components/Footer.tsx (1)

56-62: Add security attributes to external links.

The external links in footer sections use target="_blank" without rel="noopener noreferrer", creating a tabnabbing vulnerability. The new page can access window.opener and potentially redirect the original page to a phishing site. Other external links in the component (lines 80, 101) correctly include this attribute.

🔎 Proposed fix
                    <Link
                      target="_blank"
                      className="text-slate-600 hover:text-slate-900 dark:text-slate-400 dark:hover:text-slate-100"
                      href={link.href || '/'}
+                     rel="noopener noreferrer"
                    >
                      {link.text}
                    </Link>
🤖 Fix all issues with AI Agents
In @frontend/__tests__/accessibility/components/CalendarButton.a11y.test.tsx:
- Around line 33-39: The test "should not have any accessibility violations when
custom icon is provided" renders CalendarButton with a custom icon that
unnecessarily includes aria-label on the FaCalendarAlt element; remove the
aria-label attribute from the icon in that test so the button-level aria-label
applied by the CalendarButton component is the sole accessible name, leaving the
icon decorative.

In @frontend/__tests__/accessibility/components/RepositoryCard.a11y.test.tsx:
- Line 56: Update the test description string in the it(...) call for the test
named "should not have any accessibility violations when containing atleast one
archived repository" to correct the typo "atleast" to "at least" so the
description reads "should not have any accessibility violations when containing
at least one archived repository"; modify the string in the test case
declaration to fix this text only.

In @frontend/jest.setup.ts:
- Around line 86-107: The mocked next/image default component currently sets
style: fill && { ... } which yields style: false when fill is false; update the
mock in the jest.mock('next/image', ...) default renderer to only pass a style
object when fill is truthy (e.g., use style: fill ? { objectFit: objectFit as
React.CSSProperties['objectFit'] } : undefined) or use spread syntax (e.g.,
...(fill ? { style: { objectFit: ... } } : {})) so React never receives a
boolean for the style prop.

In @frontend/src/components/EntityActions.tsx:
- Around line 110-113: The dropdown in EntityActions (the component rendering
the <div role="menu">) lacks keyboard navigation and focus management; add
keyboard support by tracking an internal focusIndex state and an array of refs
for menu items (menu item elements using role="menuitem" should have tabIndex
set appropriately), add a keydown handler on the menu container to close on
Escape, move focus with ArrowDown/ArrowUp (wrap-around) and activate
Enter/Space, ensure when the menu opens you programmatically focus the first (or
previously focused) menu item and when it closes return focus to the trigger
button, clean up listeners on unmount, and update tests to simulate keyboard
events (Escape, Arrow keys, Enter) to assert focus movement and menu open/close
behavior.
🧹 Nitpick comments (6)
frontend/src/components/ShowMoreButton.tsx (1)

15-31: Consider adding aria-expanded for better screen reader support.

Since this button controls the expansion/collapse of content, adding the aria-expanded attribute would communicate the current toggle state to assistive technologies.

🔎 Suggested enhancement for accessibility
     <Button
       data-testid="show-more-button"
       type="button"
       disableAnimation
       onPress={handleToggle}
+      aria-expanded={isExpanded}
       className="flex items-center bg-transparent px-0 text-blue-400 hover:underline focus:rounded focus:outline-2 focus:outline-offset-2 focus:outline-blue-500"
     >
frontend/src/components/Pagination.tsx (1)

59-104: Consider wrapping pagination in a semantic nav element.

For better document structure and accessibility, consider wrapping the pagination controls in a <nav> element with an appropriate label:

-  <div className="mt-8 flex flex-col items-center justify-center gap-3">
+  <nav aria-label="Pagination" className="mt-8 flex flex-col items-center justify-center gap-3">
     <div className="flex flex-wrap items-center justify-center gap-2">
       ...
     </div>
-  </div>
+  </nav>

This provides screen reader users with better context about the purpose of this UI region.

frontend/__tests__/accessibility/components/UserCard.a11y.test.tsx (1)

25-32: Consider using container for consistency.

The test correctly validates accessibility, but uses baseElement while other a11y tests in this PR consistently use container. Unless UserCard renders portals or modals outside the main container, prefer container for consistency across the test suite.

🔎 Proposed change for consistency
  it('should not have any accessibility violations', async () => {
-    const { baseElement } = render(<UserCard {...defaultProps} />)
+    const { container } = render(<UserCard {...defaultProps} />)

-    const results = await axe(baseElement)
+    const results = await axe(container)

    expect(results).toHaveNoViolations()
  })
frontend/__tests__/accessibility/components/NavButton.a11y.test.tsx (1)

10-10: Remove redundant local mock; use the global next/link mock from jest.setup.ts.

The global mock in jest.setup.ts (lines 70-84) already provides a comprehensive MockedLink that handles href, className, and other props. This local mock overrides it and only handles href and children, potentially dropping className or other props that NavButton might pass to Link.

🔎 Proposed fix
 import { render } from '@testing-library/react'
 import { axe, toHaveNoViolations } from 'jest-axe'
 import { FaHome } from 'react-icons/fa'
 import { FaUser } from 'react-icons/fa6'
 import { NavButtonProps } from 'types/button'
 import NavButton from 'components/NavButton'

 expect.extend(toHaveNoViolations)

-jest.mock('next/link', () => ({ children, href }) => <a href={href}>{children}</a>)
-
 const defaultProps: NavButtonProps & { defaultIcon: typeof FaHome; hoverIcon: typeof FaUser } = {
   href: '/test-path',
   defaultIcon: FaHome,
   hoverIcon: FaUser,
   text: 'Test Button',
 }
frontend/__tests__/accessibility/components/ProgramCard.a11y.test.tsx (1)

31-42: Consider testing additional program states.

The test currently covers only a published program with admin access. For more comprehensive accessibility coverage, consider adding tests for:

  • Draft and completed program statuses
  • Non-admin users (regular user view)
  • Different accessLevel values

This ensures accessibility is maintained across all user-facing states.

frontend/__tests__/accessibility/components/UserMenu.a11y.test.tsx (1)

36-133: Consider testing additional menu states.

The test suite covers syncing, unauthenticated, and authenticated states with the menu open. For complete coverage, consider adding:

  • Authenticated state with menu closed (isOpen=false) to verify the button's accessibility when the dropdown is not expanded
  • The isLoggingOut: true state to ensure the disabled button maintains accessibility
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 75d220c and ee96230.

📒 Files selected for processing (36)
  • frontend/__tests__/accessibility/components/CalendarButton.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ContributionHeatmap.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ContributorAvatar.a11y.test.tsx
  • frontend/__tests__/accessibility/components/EntityActions.a11y.test.tsx
  • frontend/__tests__/accessibility/components/Footer.a11y.test.tsx
  • frontend/__tests__/accessibility/components/GeneralCompliantComponent.a11y.test.tsx
  • frontend/__tests__/accessibility/components/InfoBlock.a11y.test.tsx
  • frontend/__tests__/accessibility/components/LoadingSpinner.a11y.test.tsx
  • frontend/__tests__/accessibility/components/LoginPageContent.a11y.test.tsx
  • frontend/__tests__/accessibility/components/MetricsScoreCircle.a11y.test.tsx
  • frontend/__tests__/accessibility/components/Milestones.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ModeToggle.a11y.test.tsx
  • frontend/__tests__/accessibility/components/NavButton.a11y.test.tsx
  • frontend/__tests__/accessibility/components/NavDropDown.a11y.test.tsx
  • frontend/__tests__/accessibility/components/PageLayout.a11y.test.tsx
  • frontend/__tests__/accessibility/components/Pagination.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ProgramCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/RecentIssues.a11y.test.tsx
  • frontend/__tests__/accessibility/components/Release.a11y.test.tsx
  • frontend/__tests__/accessibility/components/RepositoryCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/Search.a11y.test.tsx
  • frontend/__tests__/accessibility/components/SearchPageLayout.a11y.test.tsx
  • frontend/__tests__/accessibility/components/SecondaryCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/SingleModuleCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/SkeletonBase.a11y.test.tsx
  • frontend/__tests__/accessibility/components/SortBy.a11y.test.tsx
  • frontend/__tests__/accessibility/components/StatusBadge.a11y.test.tsx
  • frontend/__tests__/accessibility/components/TruncatedText.a11y.test.tsx
  • frontend/__tests__/accessibility/components/UserCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/UserMenu.a11y.test.tsx
  • frontend/jest.setup.ts
  • frontend/src/components/DonutBarChart.tsx
  • frontend/src/components/EntityActions.tsx
  • frontend/src/components/Footer.tsx
  • frontend/src/components/Pagination.tsx
  • frontend/src/components/ShowMoreButton.tsx
🚧 Files skipped from review as they are similar to previous changes (19)
  • frontend/tests/accessibility/components/EntityActions.a11y.test.tsx
  • frontend/tests/accessibility/components/LoginPageContent.a11y.test.tsx
  • frontend/tests/accessibility/components/RecentIssues.a11y.test.tsx
  • frontend/tests/accessibility/components/Pagination.a11y.test.tsx
  • frontend/tests/accessibility/components/SingleModuleCard.a11y.test.tsx
  • frontend/tests/accessibility/components/Search.a11y.test.tsx
  • frontend/tests/accessibility/components/Release.a11y.test.tsx
  • frontend/tests/accessibility/components/NavDropDown.a11y.test.tsx
  • frontend/tests/accessibility/components/LoadingSpinner.a11y.test.tsx
  • frontend/tests/accessibility/components/SkeletonBase.a11y.test.tsx
  • frontend/tests/accessibility/components/ContributorAvatar.a11y.test.tsx
  • frontend/tests/accessibility/components/ContributionHeatmap.a11y.test.tsx
  • frontend/tests/accessibility/components/Footer.a11y.test.tsx
  • frontend/tests/accessibility/components/MetricsScoreCircle.a11y.test.tsx
  • frontend/tests/accessibility/components/StatusBadge.a11y.test.tsx
  • frontend/tests/accessibility/components/GeneralCompliantComponent.a11y.test.tsx
  • frontend/tests/accessibility/components/SortBy.a11y.test.tsx
  • frontend/tests/accessibility/components/PageLayout.a11y.test.tsx
  • frontend/tests/accessibility/components/Milestones.a11y.test.tsx
🧰 Additional context used
🧠 Learnings (9)
📚 Learning: 2025-07-12T17:36:57.255Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 1717
File: frontend/__tests__/unit/pages/createProgram.test.tsx:70-86
Timestamp: 2025-07-12T17:36:57.255Z
Learning: When testing React page components that use mocked form components, validation logic should be tested at the form component level, not the page level. Page-level tests should focus on authentication, role checking, submission handling, and navigation logic.

Applied to files:

  • frontend/__tests__/accessibility/components/UserMenu.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ModeToggle.a11y.test.tsx
  • frontend/__tests__/accessibility/components/NavButton.a11y.test.tsx
  • frontend/__tests__/accessibility/components/UserCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/SearchPageLayout.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ProgramCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/SecondaryCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/CalendarButton.a11y.test.tsx
📚 Learning: 2025-04-30T13:41:20.846Z
Learnt from: codic-yeeshu
Repo: OWASP/Nest PR: 1444
File: frontend/src/components/NavDropDown.tsx:0-0
Timestamp: 2025-04-30T13:41:20.846Z
Learning: When implementing dropdown menus or similar interactive components, always include proper accessibility features: ARIA attributes (aria-expanded, aria-haspopup, aria-controls), keyboard navigation support (Enter, Space, Escape keys), and mechanisms to close dropdowns when clicking outside.

Applied to files:

  • frontend/src/components/EntityActions.tsx
📚 Learning: 2025-11-17T16:47:05.578Z
Learnt from: anurag2787
Repo: OWASP/Nest PR: 2671
File: frontend/__tests__/unit/components/MultiSearch.test.tsx:427-427
Timestamp: 2025-11-17T16:47:05.578Z
Learning: In the frontend test files for the OWASP/Nest repository, `expect(true).toBe(true)` no-op assertions may be intentionally added as workarounds when ESLint rule jest/expect-expect doesn't detect expectations inside helper functions or waitFor callbacks. These can be resolved by configuring the ESLint rule's assertFunctionNames option to recognize custom assertion helpers instead of flagging them as redundant.

Applied to files:

  • frontend/__tests__/accessibility/components/ModeToggle.a11y.test.tsx
  • frontend/__tests__/accessibility/components/NavButton.a11y.test.tsx
  • frontend/__tests__/accessibility/components/TruncatedText.a11y.test.tsx
  • frontend/__tests__/accessibility/components/UserCard.a11y.test.tsx
  • frontend/__tests__/accessibility/components/SearchPageLayout.a11y.test.tsx
  • frontend/__tests__/accessibility/components/ProgramCard.a11y.test.tsx
📚 Learning: 2025-11-17T17:30:42.139Z
Learnt from: anurag2787
Repo: OWASP/Nest PR: 2671
File: frontend/__tests__/unit/components/MultiSearch.test.tsx:169-171
Timestamp: 2025-11-17T17:30:42.139Z
Learning: In the OWASP/Nest frontend tests (PR #2671 context), wrapper functions like `expectChaptersCountEqualsThree` that simply call another helper with a fixed parameter (e.g., `expectChaptersCountEquals(3)`) are intentionally used to avoid arrow function callbacks in `waitFor` calls. This pattern prevents adding nesting depth that would trigger rule typescript:S2004. Example: `await waitFor(expectChaptersCountEqualsThree)` avoids the extra nesting from `await waitFor(() => expectChaptersCountEquals(3))`.

Applied to files:

  • frontend/__tests__/accessibility/components/ModeToggle.a11y.test.tsx
📚 Learning: 2025-09-17T02:42:41.928Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 2288
File: frontend/src/components/ActionButton.tsx:0-0
Timestamp: 2025-09-17T02:42:41.928Z
Learning: In frontend/src/components/ActionButton.tsx, the user Rajgupta36 intentionally changed text-blue-600 to text-[#1D7BD7] to align the text color with the border color (#1D7BD7) for visual consistency, prioritizing design alignment over theme tokens.

Applied to files:

  • frontend/__tests__/accessibility/components/NavButton.a11y.test.tsx
  • frontend/src/components/ShowMoreButton.tsx
📚 Learning: 2025-07-13T07:31:06.511Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 1717
File: frontend/src/components/ModuleCard.tsx:53-55
Timestamp: 2025-07-13T07:31:06.511Z
Learning: In Next.js 13+ app router, useRouter from 'next/navigation' does not provide asPath or query properties. Use useParams to extract route parameters and usePathname to get the current pathname instead.

Applied to files:

  • frontend/jest.setup.ts
📚 Learning: 2025-07-12T17:14:28.536Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 1717
File: frontend/src/app/mentorship/programs/[programKey]/edit/page.tsx:90-128
Timestamp: 2025-07-12T17:14:28.536Z
Learning: Both ProgramForm (programCard.tsx) and ModuleForm (mainmoduleCard.tsx) components already implement HTML validation using the `required` attribute on form fields. The browser's native validation prevents form submission and displays error messages when required fields are empty, eliminating the need for additional JavaScript validation before GraphQL mutations.

Applied to files:

  • frontend/__tests__/accessibility/components/ProgramCard.a11y.test.tsx
📚 Learning: 2025-06-21T12:21:32.372Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1633
File: frontend/src/components/GradientRadialChart.tsx:67-116
Timestamp: 2025-06-21T12:21:32.372Z
Learning: The react-apexcharts Chart component does not support ARIA attributes like aria-label and role as direct props. To add accessibility attributes to ApexCharts in React, wrap the Chart component in a container div with the appropriate ARIA attributes.

Applied to files:

  • frontend/__tests__/accessibility/components/InfoBlock.a11y.test.tsx
  • frontend/src/components/DonutBarChart.tsx
📚 Learning: 2025-07-03T03:08:03.290Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1703
File: frontend/src/components/BarChart.tsx:33-46
Timestamp: 2025-07-03T03:08:03.290Z
Learning: In the OWASP Nest project's BarChart component (frontend/src/components/BarChart.tsx), the days and requirements arrays are guaranteed to always have the same length in their use cases, so input validation for array length matching is not needed.

Applied to files:

  • frontend/src/components/DonutBarChart.tsx
🧬 Code graph analysis (8)
frontend/__tests__/accessibility/components/UserMenu.a11y.test.tsx (3)
frontend/src/hooks/useDjangoSession.ts (1)
  • useDjangoSession (10-83)
frontend/src/hooks/useLogout.ts (1)
  • useLogout (11-30)
frontend/src/components/UserMenu.tsx (1)
  • UserMenu (12-125)
frontend/__tests__/accessibility/components/ModeToggle.a11y.test.tsx (1)
frontend/src/components/ModeToggle.tsx (1)
  • ModeToggle (7-44)
frontend/__tests__/accessibility/components/NavButton.a11y.test.tsx (1)
frontend/src/types/button.ts (1)
  • NavButtonProps (13-21)
frontend/__tests__/accessibility/components/TruncatedText.a11y.test.tsx (1)
frontend/src/components/TruncatedText.tsx (1)
  • TruncatedText (3-45)
frontend/__tests__/accessibility/components/RepositoryCard.a11y.test.tsx (1)
frontend/src/types/project.ts (1)
  • RepositoryCardProps (64-75)
frontend/__tests__/accessibility/components/UserCard.a11y.test.tsx (1)
frontend/src/types/card.ts (1)
  • UserCardProps (89-103)
frontend/__tests__/accessibility/components/ProgramCard.a11y.test.tsx (1)
backend/apps/mentorship/api/internal/nodes/enum.py (1)
  • ProgramStatusEnum (22-27)
frontend/__tests__/accessibility/components/CalendarButton.a11y.test.tsx (1)
frontend/src/components/CalendarButton.tsx (1)
  • CalendarButton (10-81)
🔇 Additional comments (16)
frontend/src/components/ShowMoreButton.tsx (1)

16-16: LGTM! Test ID added for component targeting.

The data-testid attribute follows standard testing practices and enables stable test selectors for the new accessibility test suite.

frontend/src/components/Footer.tsx (1)

34-34: LGTM! Well-implemented test selector.

The data-testid addition follows React Testing Library best practices and provides a stable selector for the accessibility test suite. The naming convention is clear and descriptive.

frontend/src/components/Pagination.tsx (1)

74-76: Correct removal of aria-label from decorative element.

Removing aria-label from the non-interactive ellipsis div is the right approach. Since this element is purely decorative (indicating skipped page numbers) and the icon inside already has aria-hidden="true", there's no need for the wrapper to be exposed to assistive technologies. This change improves accessibility by preventing screen readers from announcing meaningless content.

frontend/src/components/DonutBarChart.tsx (1)

26-26: LGTM! Accessibility wrapper follows best practices.

The wrapper div with aria-label is the correct approach for adding accessibility to ApexCharts, as the Chart component doesn't support ARIA attributes directly as props. The label clearly describes the chart's purpose for screen reader users.

Based on learnings, wrapping Chart components in a container div with ARIA attributes is the recommended pattern.

frontend/__tests__/accessibility/components/CalendarButton.a11y.test.tsx (1)

16-31: LGTM! Test coverage is appropriate.

The tests effectively cover the main usage scenarios (icon-only and with label), ensuring accessibility compliance across different configurations.

frontend/__tests__/accessibility/components/SearchPageLayout.a11y.test.tsx (1)

17-62: LGTM! Comprehensive test coverage.

The test suite effectively covers multiple states (loading vs loaded, different page counts) and uses a clear structure with nested describe blocks. The tests ensure accessibility compliance across all key scenarios.

frontend/__tests__/accessibility/components/RepositoryCard.a11y.test.tsx (1)

34-54: LGTM! Well-structured tests with good coverage.

The tests effectively validate accessibility across different states, including user interactions. The createMockRepository helper promotes maintainability by centralizing mock data creation.

frontend/__tests__/accessibility/components/InfoBlock.a11y.test.tsx (1)

1-33: LGTM! Well-structured accessibility test.

The test follows the established pattern for a11y tests in this codebase, properly extends jest-axe matchers, and covers both scenarios (with and without label prop). The baseProps configuration includes all necessary component props.

frontend/jest.setup.ts (2)

66-66: LGTM! usePathname mock correctly added.

The mock returns a consistent pathname ('/') for testing, which aligns with the other Next.js navigation mocks already present in this setup file.


70-84: LGTM! MockedLink provides a clean test double for Next.js Link.

The mock renders a standard anchor element while preserving href, className, and other props, which is appropriate for accessibility testing where link behavior needs to be evaluated.

frontend/__tests__/accessibility/components/SecondaryCard.a11y.test.tsx (1)

1-22: LGTM! Clean accessibility test for SecondaryCard.

The test follows the established a11y testing pattern and correctly validates that the SecondaryCard component with title, icon, and children has no accessibility violations.

frontend/__tests__/accessibility/components/ModeToggle.a11y.test.tsx (1)

1-19: LGTM! Test correctly mocks next-themes.

The test properly mocks the useTheme hook from next-themes with stubbed theme and setTheme values, which is essential for testing the ModeToggle component in isolation.

frontend/__tests__/accessibility/components/NavButton.a11y.test.tsx (1)

1-27: LGTM! Solid accessibility test structure.

The test properly validates NavButton for accessibility violations using jest-axe, with appropriate default props including icons and text.

frontend/__tests__/accessibility/components/ProgramCard.a11y.test.tsx (1)

31-42: Good use of semantic HTML wrapper.

Wrapping the component in <main> for accessibility testing is excellent practice, as it provides proper document structure for axe to evaluate.

frontend/__tests__/accessibility/components/UserMenu.a11y.test.tsx (1)

74-102: Good practice: testing with menu opened.

Correctly opening the dropdown menu (line 97-98) before running accessibility checks ensures that dynamically rendered content is included in the audit. This is essential for catching issues in conditional UI elements.

frontend/__tests__/accessibility/components/TruncatedText.a11y.test.tsx (1)

7-16: LGTM - minimal but sufficient test.

The accessibility test correctly verifies that TruncatedText has no violations. While the component also accepts a children prop (per the component code in relevant snippets), testing with the text prop is sufficient for accessibility validation since both render paths produce similar DOM structures.

@Utkarsh-0304
Copy link
Contributor Author

Utkarsh-0304 commented Jan 6, 2026

I have implemented accessibility tests for components. Should I create a separate sub-issue for implementing A11y tests on pages as well (#3058 (comment)) or implement pages within this same PR?

P.S I was planning to start as soon as the component test files are reviewed.

@kasya
Copy link
Collaborator

kasya commented Jan 12, 2026

@Utkarsh-0304 could you address the comments? As soon as those are done - we can merge this in 👍🏼

Copy link
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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
frontend/__tests__/unit/pages/Committees.test.tsx (1)

132-132: Minor typo in test description.

There's an extra space in the test name: "opens window" should be "opens window" or perhaps "opens details window".

Suggested fix
-  test('opens  window on View Details button click', async () => {
+  test('opens details page on View Details button click', async () => {
🤖 Fix all issues with AI agents
In @.github/workflows/run-ci-cd.yaml:
- Around line 276-307: Add a blank line between the two steps in the
run-frontend-a11y-tests job: insert a single empty line after the "Build
frontend a11y-testing image" step (the block using docker/build-push-action) and
before the "Run frontend a11y tests" step to match the spacing convention used
by other jobs and improve readability; locate the steps by their names "Build
frontend a11y-testing image" and "Run frontend a11y tests" within the
run-frontend-a11y-tests job and add the empty line in the workflow YAML.
🧹 Nitpick comments (2)
frontend/__tests__/unit/pages/Organization.test.tsx (1)

82-84: Consider removing jest.restoreAllMocks() inside the test case.

The afterEach hook on line 43 already calls jest.clearAllMocks(), which resets mock call history. The restoreAllMocks() inside this specific test is redundant and could be confusing since mock restoration typically belongs in cleanup hooks.

Suggested change
     expect(mockRouter.push).toHaveBeenCalledWith('/organizations/test-org')
-
-    jest.restoreAllMocks()
   })
docker/frontend/Dockerfile.a11y.test (1)

21-25: Consider adding explicit ownership for copied files.

Lines 21-25 copy files without specifying ownership, so they default to root:root. While the node user can read these files due to default permissions (644/755), this is inconsistent with line 16 where ownership is explicitly set.

For consistency and to follow the principle of least privilege, consider adding --chown=node:node to these COPY instructions. Also note that chown node:node /app on line 19 only changes the directory itself, not its contents (would need -R for recursive).

♻️ Suggested improvement
-COPY __tests__/a11y __tests__/a11y
-COPY __tests__/mockData __tests__/mockData
-COPY .pnpmrc jest.config.ts jest.setup.ts tsconfig.json ./
-COPY public public
-COPY src src
+COPY --chown=node:node __tests__/a11y __tests__/a11y
+COPY --chown=node:node __tests__/mockData __tests__/mockData
+COPY --chown=node:node .pnpmrc jest.config.ts jest.setup.ts tsconfig.json ./
+COPY --chown=node:node public public
+COPY --chown=node:node src src
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f2c5357 and 765deff.

📒 Files selected for processing (72)
  • .github/workflows/run-ci-cd.yaml
  • docker/frontend/Dockerfile.a11y.test
  • docker/frontend/Dockerfile.e2e.test
  • docker/frontend/Dockerfile.unit.test
  • frontend/__tests__/a11y/components/CardDetailsPage.a11y.test.tsx
  • frontend/__tests__/a11y/components/ChapterMap.a11y.test.tsx
  • frontend/__tests__/a11y/components/Leaders.a11y.test.tsx
  • frontend/__tests__/e2e/pages/About.spec.ts
  • frontend/__tests__/e2e/pages/ChapterDetails.spec.ts
  • frontend/__tests__/e2e/pages/Chapters.spec.ts
  • frontend/__tests__/e2e/pages/CommitteeDetails.spec.ts
  • frontend/__tests__/e2e/pages/Committees.spec.ts
  • frontend/__tests__/e2e/pages/Contribute.spec.ts
  • frontend/__tests__/e2e/pages/OrganizationDetails.spec.ts
  • frontend/__tests__/e2e/pages/Organizations.spec.ts
  • frontend/__tests__/e2e/pages/ProjectDetails.spec.ts
  • frontend/__tests__/e2e/pages/ProjectHealthDashboardMetricsDetails.spec.ts
  • frontend/__tests__/e2e/pages/Projects.spec.ts
  • frontend/__tests__/e2e/pages/ProjectsHealthDashboardMetrics.spec.ts
  • frontend/__tests__/e2e/pages/ProjectsHealthDashboardOverview.spec.ts
  • frontend/__tests__/e2e/pages/RepositoryDetails.spec.ts
  • frontend/__tests__/e2e/pages/UserDetails.spec.ts
  • frontend/__tests__/e2e/pages/Users.spec.ts
  • frontend/__tests__/mockData/mockAboutData.ts
  • frontend/__tests__/mockData/mockApiKeysData.ts
  • frontend/__tests__/mockData/mockBadgeData.ts
  • frontend/__tests__/mockData/mockChapterData.ts
  • frontend/__tests__/mockData/mockChapterDetailsData.ts
  • frontend/__tests__/mockData/mockCommitteeData.ts
  • frontend/__tests__/mockData/mockCommitteeDetailsData.ts
  • frontend/__tests__/mockData/mockContributeData.ts
  • frontend/__tests__/mockData/mockHomeData.ts
  • frontend/__tests__/mockData/mockModuleData.ts
  • frontend/__tests__/mockData/mockOrganizationData.ts
  • frontend/__tests__/mockData/mockProgramData.ts
  • frontend/__tests__/mockData/mockProjectData.ts
  • frontend/__tests__/mockData/mockProjectDetailsData.ts
  • frontend/__tests__/mockData/mockProjectsDashboardMetricsDetailsData.ts
  • frontend/__tests__/mockData/mockProjectsDashboardOverviewData.ts
  • frontend/__tests__/mockData/mockProjectsHealthMetricsData.ts
  • frontend/__tests__/mockData/mockRepositoryData.ts
  • frontend/__tests__/mockData/mockSnapshotData.ts
  • frontend/__tests__/mockData/mockUserData.ts
  • frontend/__tests__/mockData/mockUserDetails.ts
  • frontend/__tests__/unit/components/Leaders.test.tsx
  • frontend/__tests__/unit/components/ProgramCard.test.tsx
  • frontend/__tests__/unit/pages/About.test.tsx
  • frontend/__tests__/unit/pages/ApiKeysPage.test.tsx
  • frontend/__tests__/unit/pages/ChapterDetails.test.tsx
  • frontend/__tests__/unit/pages/Chapters.test.tsx
  • frontend/__tests__/unit/pages/CommitteeDetails.test.tsx
  • frontend/__tests__/unit/pages/Committees.test.tsx
  • frontend/__tests__/unit/pages/Contribute.test.tsx
  • frontend/__tests__/unit/pages/Home.test.tsx
  • frontend/__tests__/unit/pages/ModuleDetails.test.tsx
  • frontend/__tests__/unit/pages/ModuleDetailsPage.test.tsx
  • frontend/__tests__/unit/pages/Organization.test.tsx
  • frontend/__tests__/unit/pages/OrganizationDetails.test.tsx
  • frontend/__tests__/unit/pages/Program.test.tsx
  • frontend/__tests__/unit/pages/ProgramDetails.test.tsx
  • frontend/__tests__/unit/pages/ProgramDetailsMentorship.test.tsx
  • frontend/__tests__/unit/pages/ProjectDetails.test.tsx
  • frontend/__tests__/unit/pages/ProjectHealthDashboardMetricsDetails.test.tsx
  • frontend/__tests__/unit/pages/Projects.test.tsx
  • frontend/__tests__/unit/pages/ProjectsHealthDashboardMetrics.test.tsx
  • frontend/__tests__/unit/pages/ProjectsHealthDashboardOverview.test.tsx
  • frontend/__tests__/unit/pages/RepositoryDetails.test.tsx
  • frontend/__tests__/unit/pages/SnapshotDetails.test.tsx
  • frontend/__tests__/unit/pages/UserDetails.test.tsx
  • frontend/__tests__/unit/pages/Users.test.tsx
  • frontend/jest.config.ts
  • frontend/tsconfig.json
💤 Files with no reviewable changes (1)
  • frontend/tests/unit/components/ProgramCard.test.tsx
✅ Files skipped from review due to trivial changes (4)
  • frontend/tests/unit/pages/ModuleDetails.test.tsx
  • frontend/tests/unit/pages/UserDetails.test.tsx
  • frontend/tests/unit/pages/OrganizationDetails.test.tsx
  • frontend/tests/unit/pages/SnapshotDetails.test.tsx
🚧 Files skipped from review as they are similar to previous changes (5)
  • frontend/tests/a11y/components/Leaders.a11y.test.tsx
  • frontend/tests/a11y/components/CardDetailsPage.a11y.test.tsx
  • frontend/tsconfig.json
  • frontend/tests/unit/pages/Contribute.test.tsx
  • frontend/tests/unit/pages/Home.test.tsx
🧰 Additional context used
🧠 Learnings (11)
📚 Learning: 2025-07-12T17:36:57.255Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 1717
File: frontend/__tests__/unit/pages/createProgram.test.tsx:70-86
Timestamp: 2025-07-12T17:36:57.255Z
Learning: When testing React page components that use mocked form components, validation logic should be tested at the form component level, not the page level. Page-level tests should focus on authentication, role checking, submission handling, and navigation logic.

Applied to files:

  • frontend/__tests__/unit/pages/Users.test.tsx
  • frontend/__tests__/e2e/pages/UserDetails.spec.ts
  • frontend/__tests__/unit/pages/ApiKeysPage.test.tsx
  • frontend/__tests__/unit/pages/CommitteeDetails.test.tsx
  • frontend/__tests__/unit/pages/Program.test.tsx
  • frontend/__tests__/unit/pages/Chapters.test.tsx
  • frontend/__tests__/e2e/pages/Organizations.spec.ts
  • frontend/__tests__/e2e/pages/ChapterDetails.spec.ts
  • frontend/__tests__/e2e/pages/Contribute.spec.ts
  • frontend/__tests__/e2e/pages/ProjectDetails.spec.ts
  • frontend/__tests__/e2e/pages/Projects.spec.ts
  • frontend/__tests__/e2e/pages/Users.spec.ts
  • frontend/__tests__/e2e/pages/ProjectHealthDashboardMetricsDetails.spec.ts
  • frontend/__tests__/unit/pages/ChapterDetails.test.tsx
  • frontend/__tests__/unit/pages/ProgramDetails.test.tsx
  • frontend/__tests__/unit/pages/ProjectsHealthDashboardOverview.test.tsx
  • frontend/__tests__/unit/pages/ProjectsHealthDashboardMetrics.test.tsx
  • frontend/__tests__/e2e/pages/CommitteeDetails.spec.ts
  • frontend/__tests__/unit/pages/Organization.test.tsx
  • frontend/__tests__/e2e/pages/OrganizationDetails.spec.ts
  • frontend/__tests__/unit/pages/Committees.test.tsx
  • frontend/__tests__/a11y/components/ChapterMap.a11y.test.tsx
  • frontend/__tests__/unit/pages/ProjectDetails.test.tsx
  • frontend/__tests__/unit/pages/About.test.tsx
  • frontend/__tests__/unit/pages/Projects.test.tsx
  • frontend/__tests__/e2e/pages/Chapters.spec.ts
  • frontend/__tests__/unit/pages/RepositoryDetails.test.tsx
  • frontend/__tests__/unit/components/Leaders.test.tsx
  • frontend/__tests__/unit/pages/ModuleDetailsPage.test.tsx
  • frontend/__tests__/unit/pages/ProgramDetailsMentorship.test.tsx
  • frontend/__tests__/e2e/pages/About.spec.ts
  • frontend/__tests__/e2e/pages/Committees.spec.ts
📚 Learning: 2025-11-17T16:47:05.578Z
Learnt from: anurag2787
Repo: OWASP/Nest PR: 2671
File: frontend/__tests__/unit/components/MultiSearch.test.tsx:427-427
Timestamp: 2025-11-17T16:47:05.578Z
Learning: In the frontend test files for the OWASP/Nest repository, `expect(true).toBe(true)` no-op assertions may be intentionally added as workarounds when ESLint rule jest/expect-expect doesn't detect expectations inside helper functions or waitFor callbacks. These can be resolved by configuring the ESLint rule's assertFunctionNames option to recognize custom assertion helpers instead of flagging them as redundant.

Applied to files:

  • frontend/__tests__/unit/pages/ApiKeysPage.test.tsx
  • frontend/__tests__/e2e/pages/Organizations.spec.ts
  • frontend/__tests__/e2e/pages/Contribute.spec.ts
  • frontend/__tests__/e2e/pages/ProjectsHealthDashboardOverview.spec.ts
  • frontend/__tests__/e2e/pages/Projects.spec.ts
  • frontend/__tests__/e2e/pages/Users.spec.ts
  • frontend/__tests__/e2e/pages/ProjectHealthDashboardMetricsDetails.spec.ts
  • frontend/__tests__/a11y/components/ChapterMap.a11y.test.tsx
  • frontend/__tests__/e2e/pages/ProjectsHealthDashboardMetrics.spec.ts
  • frontend/__tests__/e2e/pages/Chapters.spec.ts
  • frontend/__tests__/e2e/pages/About.spec.ts
  • frontend/__tests__/e2e/pages/Committees.spec.ts
📚 Learning: 2025-08-31T13:47:15.861Z
Learnt from: rudransh-shrivastava
Repo: OWASP/Nest PR: 2155
File: frontend/src/server/queries/programsQueries.ts:81-81
Timestamp: 2025-08-31T13:47:15.861Z
Learning: In frontend/src/server/queries/programsQueries.ts, GET_PROGRAM_DETAILS is actively used in frontend/src/app/my/mentorship/programs/[programKey]/edit/page.tsx for program editing functionality and cannot be removed. It serves a different purpose than GET_PROGRAM_ADMIN_DETAILS, providing comprehensive program information needed for editing.

Applied to files:

  • frontend/__tests__/unit/pages/Program.test.tsx
  • frontend/__tests__/unit/pages/ProgramDetails.test.tsx
  • frontend/__tests__/unit/pages/ProgramDetailsMentorship.test.tsx
📚 Learning: 2025-08-31T13:47:15.861Z
Learnt from: rudransh-shrivastava
Repo: OWASP/Nest PR: 2155
File: frontend/src/server/queries/programsQueries.ts:81-81
Timestamp: 2025-08-31T13:47:15.861Z
Learning: In frontend/src/server/queries/programsQueries.ts, GET_PROGRAM_DETAILS and GET_PROGRAM_ADMIN_DETAILS are two separate queries serving different purposes: GET_PROGRAM_DETAILS fetches comprehensive program information while GET_PROGRAM_ADMIN_DETAILS fetches only admin-related details. These queries cannot be removed or merged as they serve different use cases in the application.

Applied to files:

  • frontend/__tests__/unit/pages/Program.test.tsx
  • frontend/__tests__/unit/pages/ProgramDetails.test.tsx
  • frontend/__tests__/unit/pages/ProgramDetailsMentorship.test.tsx
📚 Learning: 2025-08-31T13:47:15.861Z
Learnt from: rudransh-shrivastava
Repo: OWASP/Nest PR: 2155
File: frontend/src/server/queries/programsQueries.ts:81-81
Timestamp: 2025-08-31T13:47:15.861Z
Learning: In frontend/src/server/queries/programsQueries.ts, GET_PROGRAM_DETAILS and GET_PROGRAM_ADMIN_DETAILS are two separate queries serving different purposes: GET_PROGRAM_DETAILS fetches comprehensive program information while GET_PROGRAM_ADMIN_DETAILS fetches only admin-related details.

Applied to files:

  • frontend/__tests__/unit/pages/Program.test.tsx
  • frontend/__tests__/unit/pages/ProgramDetails.test.tsx
  • frontend/__tests__/unit/pages/ProgramDetailsMentorship.test.tsx
📚 Learning: 2025-11-17T17:30:42.139Z
Learnt from: anurag2787
Repo: OWASP/Nest PR: 2671
File: frontend/__tests__/unit/components/MultiSearch.test.tsx:169-171
Timestamp: 2025-11-17T17:30:42.139Z
Learning: In the OWASP/Nest frontend tests (PR #2671 context), wrapper functions like `expectChaptersCountEqualsThree` that simply call another helper with a fixed parameter (e.g., `expectChaptersCountEquals(3)`) are intentionally used to avoid arrow function callbacks in `waitFor` calls. This pattern prevents adding nesting depth that would trigger rule typescript:S2004. Example: `await waitFor(expectChaptersCountEqualsThree)` avoids the extra nesting from `await waitFor(() => expectChaptersCountEquals(3))`.

Applied to files:

  • frontend/__tests__/unit/pages/Chapters.test.tsx
  • frontend/__tests__/e2e/pages/Organizations.spec.ts
  • frontend/__tests__/e2e/pages/ChapterDetails.spec.ts
  • frontend/__tests__/e2e/pages/Contribute.spec.ts
  • frontend/__tests__/e2e/pages/Projects.spec.ts
  • frontend/__tests__/e2e/pages/Users.spec.ts
  • frontend/__tests__/e2e/pages/ProjectHealthDashboardMetricsDetails.spec.ts
  • frontend/__tests__/unit/pages/ChapterDetails.test.tsx
  • frontend/__tests__/a11y/components/ChapterMap.a11y.test.tsx
  • frontend/__tests__/e2e/pages/ProjectsHealthDashboardMetrics.spec.ts
  • frontend/__tests__/e2e/pages/Chapters.spec.ts
  • frontend/__tests__/e2e/pages/About.spec.ts
  • frontend/__tests__/e2e/pages/Committees.spec.ts
📚 Learning: 2025-06-20T16:12:59.256Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1633
File: frontend/src/components/HealthMetrics.tsx:30-30
Timestamp: 2025-06-20T16:12:59.256Z
Learning: In the DetailsCard component (frontend/src/components/CardDetailsPage.tsx), there's a length check before rendering HealthMetrics: `healthMetricsData.length > 0`. This ensures that when HealthMetrics is rendered, the data array has at least one element, making accessing data[0] safe within the HealthMetrics component.

Applied to files:

  • frontend/__tests__/unit/pages/ProjectsHealthDashboardMetrics.test.tsx
📚 Learning: 2025-07-13T07:31:06.511Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 1717
File: frontend/src/components/ModuleCard.tsx:53-55
Timestamp: 2025-07-13T07:31:06.511Z
Learning: In Next.js 13+ app router, useRouter from 'next/navigation' does not provide asPath or query properties. Use useParams to extract route parameters and usePathname to get the current pathname instead.

Applied to files:

  • frontend/__tests__/unit/pages/ModuleDetailsPage.test.tsx
📚 Learning: 2025-09-29T06:02:35.566Z
Learnt from: rudransh-shrivastava
Repo: OWASP/Nest PR: 2178
File: frontend/src/components/SingleModuleCard.tsx:54-54
Timestamp: 2025-09-29T06:02:35.566Z
Learning: In the Module type from types/mentorship.ts, the experienceLevel field is required (experienceLevel: ExperienceLevelEnum), not optional, so null/undefined checks are not needed when accessing this field.

Applied to files:

  • frontend/__tests__/unit/pages/ProgramDetailsMentorship.test.tsx
📚 Learning: 2025-07-12T17:14:28.536Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 1717
File: frontend/src/app/mentorship/programs/[programKey]/edit/page.tsx:90-128
Timestamp: 2025-07-12T17:14:28.536Z
Learning: Both ProgramForm (programCard.tsx) and ModuleForm (mainmoduleCard.tsx) components already implement HTML validation using the `required` attribute on form fields. The browser's native validation prevents form submission and displays error messages when required fields are empty, eliminating the need for additional JavaScript validation before GraphQL mutations.

Applied to files:

  • frontend/__tests__/unit/pages/ProgramDetailsMentorship.test.tsx
📚 Learning: 2025-12-21T19:03:59.068Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1139
File: .github/workflows/setup-backend-environment/action.yaml:16-27
Timestamp: 2025-12-21T19:03:59.068Z
Learning: Composite actions (runs: using: composite) execute as steps within the calling job's context and can access the job context, including job.services.* properties (e.g., job.services.<service_id>.id, job.services.<service_id>.ports). Service containers must be defined at the job level, but a composite action's steps can reference them via the job context.

Applied to files:

  • .github/workflows/run-ci-cd.yaml
🔇 Additional comments (45)
frontend/__tests__/e2e/pages/ProjectHealthDashboardMetricsDetails.spec.ts (1)

1-3: LGTM!

The import path migration from @unit/data/ to @mockData/ aligns with the PR's centralization of mock data. The test logic remains unchanged and correctly covers both unauthorized (404) and authorized rendering scenarios.

frontend/__tests__/unit/pages/ProgramDetails.test.tsx (1)

2-2: LGTM!

The import path update to the centralized @mockData alias is consistent with the PR's mock data migration strategy.

frontend/__tests__/unit/pages/Chapters.test.tsx (1)

1-1: LGTM!

The import path migration to @mockData/mockChapterData aligns with the centralized mock data structure established in this PR.

frontend/__tests__/unit/pages/ModuleDetailsPage.test.tsx (1)

2-2: LGTM!

The import path update to @mockData/mockModuleData is consistent with the centralized mock data organization introduced in this PR.

frontend/__tests__/unit/components/Leaders.test.tsx (1)

1-1: LGTM!

The import path update to @mockData/mockProjectDetailsData follows the established centralization pattern for mock data.

docker/frontend/Dockerfile.e2e.test (1)

21-21: LGTM!

The COPY path update ensures the E2E test Docker image includes mock data from the new centralized __tests__/mockData directory, consistent with the overall mock data migration.

frontend/__tests__/unit/pages/ProgramDetailsMentorship.test.tsx (1)

2-2: LGTM!

The import path migration to the centralized @mockData alias is consistent with the PR's objective of consolidating mock data. This aligns with the Jest config and TypeScript path mappings added elsewhere in the PR.

frontend/__tests__/unit/pages/ChapterDetails.test.tsx (1)

2-2: LGTM!

The import path migration to @mockData/mockChapterDetailsData is consistent with the centralized mock data structure introduced in this PR.

frontend/__tests__/unit/pages/CommitteeDetails.test.tsx (1)

3-3: LGTM!

The import path migration to @mockData/mockCommitteeDetailsData follows the centralized mock data pattern established across the test suite.

frontend/__tests__/unit/pages/Program.test.tsx (1)

1-1: LGTM!

The import path migration to @mockData/mockProgramData for mockPrograms is consistent with the centralized mock data approach.

docker/frontend/Dockerfile.unit.test (1)

22-22: LGTM!

Essential addition to copy the centralized mockData directory into the Docker image. This ensures unit tests can resolve @mockData/* imports when running in the containerized environment.

frontend/__tests__/unit/pages/ProjectHealthDashboardMetricsDetails.test.tsx (1)

2-2: LGTM!

The import path migration to the centralized @mockData module is correct and aligns with the PR's objective to consolidate test mock data.

frontend/__tests__/unit/pages/Organization.test.tsx (1)

1-1: LGTM!

The import path migration to @mockData/mockOrganizationData is correct.

frontend/__tests__/e2e/pages/OrganizationDetails.spec.ts (1)

1-1: LGTM!

The import path migration to @mockData/mockOrganizationData for the mockOrganizationDetailsData export is correct and consistent with the centralized mock data strategy.

frontend/__tests__/unit/pages/ApiKeysPage.test.tsx (1)

4-4: LGTM!

The import path migration to @mockData/mockApiKeysData is correct. The test suite is comprehensive and well-structured with good separation of concerns across describe blocks.

frontend/__tests__/unit/pages/Committees.test.tsx (1)

1-1: LGTM!

The import path migration to @mockData/mockCommitteeData is correct.

frontend/__tests__/e2e/pages/Contribute.spec.ts (1)

2-2: LGTM!

The import path update to the centralized @mockData alias is consistent with the broader refactoring approach in this PR.

frontend/__tests__/unit/pages/ProjectsHealthDashboardOverview.test.tsx (1)

2-2: LGTM!

The import path migration to @mockData is consistent with the centralized mock data structure introduced in this PR.

frontend/__tests__/unit/pages/ProjectDetails.test.tsx (1)

3-3: LGTM!

The import path update to @mockData/mockProjectDetailsData aligns with the centralized mock data approach.

frontend/jest.config.ts (1)

38-42: LGTM!

The Jest configuration updates are well-structured:

  • testPathIgnorePatterns correctly excludes the mock data directory from test discovery.
  • The @mockData module alias properly resolves to the centralized mock data location.

This enables clean imports like @mockData/mockChapterData across all test suites.

Also applies to: 47-47

frontend/__tests__/mockData/mockChapterData.ts (1)

26-35: Both _geoloc and geoLocation fields are intentionally used together throughout the codebase in fallback patterns (e.g., chapter._geoloc?.lat ?? chapter.geoLocation?.lat in ChapterMap.tsx). The mock data correctly includes both fields to reflect the real API structure where _geoloc serves as the primary field with geoLocation as a fallback. No changes needed.

Likely an incorrect or invalid review comment.

frontend/__tests__/unit/pages/ProjectsHealthDashboardMetrics.test.tsx (1)

2-2: LGTM!

The import path update from @unit/data/mockProjectsHealthMetricsData to @mockData/mockProjectsHealthMetricsData correctly aligns with the centralized mock data structure introduced in this PR.

frontend/__tests__/a11y/components/ChapterMap.a11y.test.tsx (3)

1-8: LGTM!

Well-structured accessibility test setup using jest-axe. The toHaveNoViolations matcher is correctly extended into Jest's expect.


24-128: LGTM!

Comprehensive mocking of the Leaflet ecosystem. The mock implementations correctly render DOM elements that can be tested for accessibility, and the data-testid attributes enable precise element selection in tests.


136-169: LGTM!

The accessibility tests cover three distinct states of the ChapterMap component: locked, unlocked, and with user location. Each test properly awaits async operations and uses baseElement for comprehensive accessibility scanning.

frontend/__tests__/unit/pages/About.test.tsx (1)

3-3: LGTM!

The import path update to @mockData/mockAboutData aligns with the centralized mock data approach introduced in this PR.

frontend/__tests__/e2e/pages/Users.spec.ts (1)

2-2: LGTM!

The import path update to @mockData/mockUserData correctly aligns with the centralized mock data structure, ensuring consistency between unit and e2e tests.

frontend/__tests__/unit/pages/RepositoryDetails.test.tsx (1)

3-3: LGTM!

The import path update to @mockData/mockRepositoryData is consistent with the PR's centralized mock data approach.

frontend/__tests__/e2e/pages/Committees.spec.ts (1)

2-2: LGTM!

The import path update to the centralized mock data location is correct and follows the named import pattern consistently with other e2e tests.

frontend/__tests__/unit/pages/Users.test.tsx (1)

1-1: LGTM!

The import path correctly points to the centralized mock data location using a named import.

frontend/__tests__/e2e/pages/UserDetails.spec.ts (1)

1-1: LGTM!

The import path update to the centralized mock data location is correct and consistent with the e2e test pattern.

frontend/__tests__/e2e/pages/RepositoryDetails.spec.ts (1)

1-1: LGTM!

The import path update to the centralized mock data location is correct and uses named import consistently with other e2e tests.

frontend/__tests__/unit/pages/Projects.test.tsx (1)

1-1: The import style is correct and will not cause runtime errors. The mockProjectData.ts file exports a default export (export default mockProjectData), which matches the default import statement used here. While other mock files in the codebase use only named exports, this file is intentionally set up with both a named and default export, making the current import pattern valid.

Likely an incorrect or invalid review comment.

frontend/__tests__/e2e/pages/ChapterDetails.spec.ts (1)

1-1: LGTM!

Import path correctly updated to use the centralized mock data location. The test logic remains unchanged and properly uses the mock data in the GraphQL route handler.

frontend/__tests__/e2e/pages/Organizations.spec.ts (1)

2-2: LGTM!

Import path correctly updated to use the centralized mock data location, consistent with the broader mock data refactoring in this PR.

frontend/__tests__/e2e/pages/Chapters.spec.ts (1)

2-2: LGTM!

Import path correctly updated to use the centralized mock data location.

frontend/__tests__/e2e/pages/About.spec.ts (1)

2-2: LGTM!

Import path correctly updated to use the centralized mock data location. The mock data continues to be properly utilized throughout the test suite for users, topContributors, and project data.

frontend/__tests__/e2e/pages/ProjectDetails.spec.ts (1)

1-1: LGTM!

Import path correctly updated to use the centralized mock data location, completing the consistent migration pattern seen across all e2e test files in this PR.

frontend/__tests__/e2e/pages/ProjectsHealthDashboardMetrics.spec.ts (1)

2-2: LGTM!

Import path correctly updated to use the new centralized @mockData alias, consistent with the broader mock data consolidation in this PR.

frontend/__tests__/e2e/pages/Projects.spec.ts (1)

2-2: LGTM!

Import path updated to the centralized @mockData module, maintaining consistency with other test files in this PR.

frontend/__tests__/e2e/pages/CommitteeDetails.spec.ts (1)

1-1: LGTM!

Import path correctly migrated to the centralized @mockData alias.

frontend/__tests__/e2e/pages/ProjectsHealthDashboardOverview.spec.ts (1)

2-2: LGTM!

Import path correctly updated to use the centralized @mockData alias, consistent with the project-wide mock data refactor.

docker/frontend/Dockerfile.a11y.test (1)

1-27: No issue—test command is correctly provided at runtime.

The Dockerfile intentionally omits CMD and ENTRYPOINT because the test command (pnpm run test:a11y) is provided at runtime by the Makefile via docker run. This is the correct pattern for containerized tests.

.github/workflows/run-ci-cd.yaml (2)

333-338: LGTM!

Correctly gates staging image builds on accessibility test success, consistent with the other test job dependencies.


703-708: LGTM!

Production image builds correctly depend on accessibility tests, mirroring the staging configuration.

coderabbitai[bot]
coderabbitai bot previously approved these changes Jan 12, 2026
kasya
kasya previously approved these changes Jan 13, 2026
Copy link
Collaborator

@kasya kasya left a comment

Choose a reason for hiding this comment

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

@Utkarsh-0304 great work 👍🏼 Thanks!

@kasya kasya dismissed stale reviews from coderabbitai[bot] and themself via 16ac56f January 13, 2026 05:31
@sonarqubecloud
Copy link

@kasya kasya dismissed arkid15r’s stale review January 13, 2026 05:39

Already addressed

@kasya kasya enabled auto-merge January 13, 2026 05:39
@kasya kasya added this pull request to the merge queue Jan 13, 2026
Merged via the queue into OWASP:main with commit c23d078 Jan 13, 2026
28 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci docker Pull requests that update Docker code frontend frontend-tests makefile

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for accessibility tests with Axe for React

3 participants