feat: add accessibility tests support #3162
Conversation
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings. WalkthroughAdds 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
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (1)
🧰 Additional context used🧠 Learnings (4)📓 Common learnings📚 Learning: 2025-11-17T16:47:05.578ZApplied to files:
📚 Learning: 2025-07-12T17:36:57.255ZApplied to files:
📚 Learning: 2025-11-17T17:30:42.139ZApplied to files:
⏰ 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)
🔇 Additional comments (3)
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. Comment |
There was a problem hiding this comment.
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()forpublishedAt(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"andaria-label.Consider adding a test for the disabled state to ensure accessibility is maintained when
isDownloadingis 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/linkand theuseUpdateProgramStatushook to isolate the component. ThebaseMockProgramobject includes all necessary fields for realistic rendering.Optional: Consider testing additional prop combinations
For more comprehensive coverage, you could add test cases for different
isAdminandaccessLevelcombinations, 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
GeneralCompliantComponentPropstype is defined locally but likely exists in the component file. If available, import the type fromcomponents/GeneralCompliantComponentto 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 forcompliant: falseto 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/imagethat properly handles thefillandobjectFitprops, 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: trueto 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 toisGitHubAuthEnabled.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
hrefandchildren, while other a11y tests (e.g., LeadersList.a11y.test.tsx lines 8-34) forward additional accessibility props likearia-labelandtitle. 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 }) sinceNavButtonPropsalready defines these asIconType.🔎 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
titleattribute 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:
- Simplifying the mock to focus on accessibility-relevant attributes (role, aria-label, etc.)
- 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
renderfunction automatically wraps renders inact, making the explicitReact.actcall 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 anameproperty 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.tsorsetupTests.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
📒 Files selected for processing (71)
frontend/Makefilefrontend/__tests__/accessibility/components/ActionButton.a11y.test.tsxfrontend/__tests__/accessibility/components/AnchorTitle.a11y.test.tsxfrontend/__tests__/accessibility/components/AutoScrollToTop.a11y.test.tsxfrontend/__tests__/accessibility/components/Badges.a11y.test.tsxfrontend/__tests__/accessibility/components/BarChart.a11y.test.tsxfrontend/__tests__/accessibility/components/BreadCrumbs.a11y.test.tsxfrontend/__tests__/accessibility/components/BreadCrumbsWrapper.a11y.test.tsxfrontend/__tests__/accessibility/components/CalendarButton.a11y.test.tsxfrontend/__tests__/accessibility/components/Card.a11y.test.tsxfrontend/__tests__/accessibility/components/CardDetailsPage.a11y.test.tsxfrontend/__tests__/accessibility/components/ChapterMap.a11y.test.tsxfrontend/__tests__/accessibility/components/ContributionHeatmap.a11y.test.tsxfrontend/__tests__/accessibility/components/ContributorAvatar.a11y.test.tsxfrontend/__tests__/accessibility/components/DashboardCard.a11y.test.tsxfrontend/__tests__/accessibility/components/DisplayIcon.a11y.test.tsxfrontend/__tests__/accessibility/components/DonutBarChart.a11y.test.tsxfrontend/__tests__/accessibility/components/EntityActions.a11y.test.tsxfrontend/__tests__/accessibility/components/Footer.a11y.test.tsxfrontend/__tests__/accessibility/components/GeneralCompliantComponent.a11y.test.tsxfrontend/__tests__/accessibility/components/HealthMetrics.a11y.test.tsxfrontend/__tests__/accessibility/components/InfoBlock.a11y.test.tsxfrontend/__tests__/accessibility/components/InfoItem.a11y.test.tsxfrontend/__tests__/accessibility/components/ItemCardList.a11y.test.tsxfrontend/__tests__/accessibility/components/Leaders.a11y.test.tsxfrontend/__tests__/accessibility/components/LeadersList.a11y.test.tsxfrontend/__tests__/accessibility/components/LineChart.a11y.test.tsxfrontend/__tests__/accessibility/components/LoadingSpinner.a11y.test.tsxfrontend/__tests__/accessibility/components/LoginPageContent.a11y.test.tsxfrontend/__tests__/accessibility/components/LogoCarousel.a11y.test.tsxfrontend/__tests__/accessibility/components/MarkdownWrapper.a11y.test.tsxfrontend/__tests__/accessibility/components/MetricsCard.a11y.test.tsxfrontend/__tests__/accessibility/components/MetricsScoreCircle.a11y.test.tsxfrontend/__tests__/accessibility/components/Milestones.a11y.test.tsxfrontend/__tests__/accessibility/components/Modal.a11y.test.tsxfrontend/__tests__/accessibility/components/ModeToggle.a11y.test.tsxfrontend/__tests__/accessibility/components/MultiSearch.a11y.test.tsxfrontend/__tests__/accessibility/components/NavButton.a11y.test.tsxfrontend/__tests__/accessibility/components/NavDropDown.a11y.test.tsxfrontend/__tests__/accessibility/components/PageLayout.a11y.test.tsxfrontend/__tests__/accessibility/components/Pagination.a11y.test.tsxfrontend/__tests__/accessibility/components/ProgramCard.a11y.test.tsxfrontend/__tests__/accessibility/components/ProjectTypeDashboardCard.a11y.test.tsxfrontend/__tests__/accessibility/components/ProjectsDashboardDropDown.a11y.test.tsxfrontend/__tests__/accessibility/components/ProjectsDashboardNavBar.a11y.test.tsxfrontend/__tests__/accessibility/components/RecentIssues.a11y.test.tsxfrontend/__tests__/accessibility/components/RecentPullRequests.a11y.test.tsxfrontend/__tests__/accessibility/components/RecentRelease.a11y.test.tsxfrontend/__tests__/accessibility/components/Release.a11y.test.tsxfrontend/__tests__/accessibility/components/RepositoryCard.a11y.test.tsxfrontend/__tests__/accessibility/components/ScrollToTop.a11y.test.tsxfrontend/__tests__/accessibility/components/Search.a11y.test.tsxfrontend/__tests__/accessibility/components/SearchPageLayout.a11y.test.tsxfrontend/__tests__/accessibility/components/SecondaryCard.a11y.test.tsxfrontend/__tests__/accessibility/components/SingleModuleCard.a11y.test.tsxfrontend/__tests__/accessibility/components/SkeletonBase.a11y.test.tsxfrontend/__tests__/accessibility/components/SnapshotCard.a11y.test.tsxfrontend/__tests__/accessibility/components/SortBy.a11y.test.tsxfrontend/__tests__/accessibility/components/SponsorCard.a11y.test.tsxfrontend/__tests__/accessibility/components/StatusBadge.a11y.test.tsxfrontend/__tests__/accessibility/components/ToggleableList.a11y.test.tsxfrontend/__tests__/accessibility/components/TopContributorsList.a11y.test.tsxfrontend/__tests__/accessibility/components/TruncatedText.a11y.test.tsxfrontend/__tests__/accessibility/components/UserCard.a11y.test.tsxfrontend/__tests__/accessibility/components/UserMenu.a11y.test.tsxfrontend/__tests__/accessibility/pages/Header.a11y.test.tsxfrontend/docker/Dockerfile.unit.testfrontend/package.jsonfrontend/src/app/settings/api-keys/page.tsxfrontend/src/components/ChapterMap.tsxfrontend/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.tsxfrontend/__tests__/accessibility/components/AutoScrollToTop.a11y.test.tsxfrontend/__tests__/accessibility/components/ActionButton.a11y.test.tsxfrontend/__tests__/accessibility/components/ProgramCard.a11y.test.tsxfrontend/__tests__/accessibility/components/Leaders.a11y.test.tsxfrontend/__tests__/accessibility/components/EntityActions.a11y.test.tsxfrontend/__tests__/accessibility/components/SponsorCard.a11y.test.tsxfrontend/__tests__/accessibility/components/PageLayout.a11y.test.tsxfrontend/__tests__/accessibility/components/UserCard.a11y.test.tsxfrontend/__tests__/accessibility/components/ContributionHeatmap.a11y.test.tsxfrontend/__tests__/accessibility/components/ItemCardList.a11y.test.tsxfrontend/__tests__/accessibility/components/CardDetailsPage.a11y.test.tsxfrontend/__tests__/accessibility/components/SearchPageLayout.a11y.test.tsxfrontend/__tests__/accessibility/components/RecentPullRequests.a11y.test.tsxfrontend/__tests__/accessibility/components/Modal.a11y.test.tsxfrontend/__tests__/accessibility/components/TopContributorsList.a11y.test.tsxfrontend/__tests__/accessibility/components/MetricsCard.a11y.test.tsxfrontend/__tests__/accessibility/components/Release.a11y.test.tsxfrontend/__tests__/accessibility/components/ContributorAvatar.a11y.test.tsxfrontend/__tests__/accessibility/components/MarkdownWrapper.a11y.test.tsxfrontend/__tests__/accessibility/components/CalendarButton.a11y.test.tsxfrontend/__tests__/accessibility/components/Search.a11y.test.tsxfrontend/__tests__/accessibility/components/LineChart.a11y.test.tsxfrontend/__tests__/accessibility/components/SortBy.a11y.test.tsxfrontend/__tests__/accessibility/components/ScrollToTop.a11y.test.tsxfrontend/__tests__/accessibility/components/NavButton.a11y.test.tsxfrontend/__tests__/accessibility/components/Milestones.a11y.test.tsxfrontend/__tests__/accessibility/components/LoginPageContent.a11y.test.tsxfrontend/__tests__/accessibility/components/ProjectsDashboardNavBar.a11y.test.tsxfrontend/__tests__/accessibility/components/Card.a11y.test.tsxfrontend/__tests__/accessibility/components/GeneralCompliantComponent.a11y.test.tsxfrontend/__tests__/accessibility/components/Pagination.a11y.test.tsxfrontend/__tests__/accessibility/components/DonutBarChart.a11y.test.tsxfrontend/__tests__/accessibility/components/RepositoryCard.a11y.test.tsxfrontend/__tests__/accessibility/components/HealthMetrics.a11y.test.tsxfrontend/__tests__/accessibility/components/DashboardCard.a11y.test.tsxfrontend/__tests__/accessibility/components/ProjectTypeDashboardCard.a11y.test.tsxfrontend/__tests__/accessibility/components/LogoCarousel.a11y.test.tsxfrontend/__tests__/accessibility/components/RecentIssues.a11y.test.tsxfrontend/__tests__/accessibility/components/Footer.a11y.test.tsxfrontend/__tests__/accessibility/components/ChapterMap.a11y.test.tsxfrontend/__tests__/accessibility/components/Badges.a11y.test.tsxfrontend/__tests__/accessibility/components/BarChart.a11y.test.tsxfrontend/__tests__/accessibility/components/RecentRelease.a11y.test.tsxfrontend/__tests__/accessibility/components/SingleModuleCard.a11y.test.tsxfrontend/__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.tsxfrontend/__tests__/accessibility/components/AutoScrollToTop.a11y.test.tsxfrontend/__tests__/accessibility/components/ActionButton.a11y.test.tsxfrontend/__tests__/accessibility/components/ProgramCard.a11y.test.tsxfrontend/__tests__/accessibility/components/Leaders.a11y.test.tsxfrontend/__tests__/accessibility/components/EntityActions.a11y.test.tsxfrontend/__tests__/accessibility/components/SponsorCard.a11y.test.tsxfrontend/__tests__/accessibility/components/NavDropDown.a11y.test.tsxfrontend/__tests__/accessibility/components/PageLayout.a11y.test.tsxfrontend/__tests__/accessibility/components/UserCard.a11y.test.tsxfrontend/__tests__/accessibility/components/ContributionHeatmap.a11y.test.tsxfrontend/__tests__/accessibility/components/ItemCardList.a11y.test.tsxfrontend/__tests__/accessibility/components/SearchPageLayout.a11y.test.tsxfrontend/__tests__/accessibility/components/RecentPullRequests.a11y.test.tsxfrontend/__tests__/accessibility/components/Modal.a11y.test.tsxfrontend/__tests__/accessibility/components/TopContributorsList.a11y.test.tsxfrontend/__tests__/accessibility/components/MetricsCard.a11y.test.tsxfrontend/__tests__/accessibility/components/Release.a11y.test.tsxfrontend/__tests__/accessibility/components/AnchorTitle.a11y.test.tsxfrontend/__tests__/accessibility/components/ContributorAvatar.a11y.test.tsxfrontend/__tests__/accessibility/components/BreadCrumbsWrapper.a11y.test.tsxfrontend/__tests__/accessibility/components/MarkdownWrapper.a11y.test.tsxfrontend/__tests__/accessibility/components/Search.a11y.test.tsxfrontend/__tests__/accessibility/components/LineChart.a11y.test.tsxfrontend/__tests__/accessibility/components/SortBy.a11y.test.tsxfrontend/__tests__/accessibility/components/ScrollToTop.a11y.test.tsxfrontend/__tests__/accessibility/components/StatusBadge.a11y.test.tsxfrontend/__tests__/accessibility/components/NavButton.a11y.test.tsxfrontend/__tests__/accessibility/components/DisplayIcon.a11y.test.tsxfrontend/__tests__/accessibility/components/Milestones.a11y.test.tsxfrontend/__tests__/accessibility/components/LoginPageContent.a11y.test.tsxfrontend/__tests__/accessibility/components/LeadersList.a11y.test.tsxfrontend/__tests__/accessibility/components/SkeletonBase.a11y.test.tsxfrontend/__tests__/accessibility/components/MultiSearch.a11y.test.tsxfrontend/__tests__/accessibility/components/ProjectsDashboardNavBar.a11y.test.tsxfrontend/__tests__/accessibility/components/GeneralCompliantComponent.a11y.test.tsxfrontend/__tests__/accessibility/components/ToggleableList.a11y.test.tsxfrontend/__tests__/accessibility/components/DonutBarChart.a11y.test.tsxfrontend/__tests__/accessibility/components/RepositoryCard.a11y.test.tsxfrontend/__tests__/accessibility/components/HealthMetrics.a11y.test.tsxfrontend/__tests__/accessibility/components/ProjectTypeDashboardCard.a11y.test.tsxfrontend/__tests__/accessibility/components/LogoCarousel.a11y.test.tsxfrontend/__tests__/accessibility/components/RecentIssues.a11y.test.tsxfrontend/__tests__/accessibility/components/Footer.a11y.test.tsxfrontend/__tests__/accessibility/components/TruncatedText.a11y.test.tsxfrontend/__tests__/accessibility/components/ChapterMap.a11y.test.tsxfrontend/__tests__/accessibility/components/Badges.a11y.test.tsxfrontend/__tests__/accessibility/components/BarChart.a11y.test.tsxfrontend/__tests__/accessibility/components/RecentRelease.a11y.test.tsxfrontend/__tests__/accessibility/components/ModeToggle.a11y.test.tsxfrontend/__tests__/accessibility/components/SingleModuleCard.a11y.test.tsxfrontend/__tests__/accessibility/components/BreadCrumbs.a11y.test.tsxfrontend/__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.tsxfrontend/__tests__/accessibility/components/ContributionHeatmap.a11y.test.tsxfrontend/__tests__/accessibility/components/Modal.a11y.test.tsxfrontend/__tests__/accessibility/components/MetricsCard.a11y.test.tsxfrontend/__tests__/accessibility/components/AnchorTitle.a11y.test.tsxfrontend/__tests__/accessibility/components/MarkdownWrapper.a11y.test.tsxfrontend/__tests__/accessibility/components/LineChart.a11y.test.tsxfrontend/__tests__/accessibility/components/LeadersList.a11y.test.tsxfrontend/__tests__/accessibility/components/Card.a11y.test.tsxfrontend/__tests__/accessibility/components/GeneralCompliantComponent.a11y.test.tsxfrontend/__tests__/accessibility/components/ProjectsDashboardDropDown.a11y.test.tsxfrontend/__tests__/accessibility/components/DonutBarChart.a11y.test.tsxfrontend/__tests__/accessibility/components/HealthMetrics.a11y.test.tsxfrontend/__tests__/accessibility/components/DashboardCard.a11y.test.tsxfrontend/__tests__/accessibility/components/ProjectTypeDashboardCard.a11y.test.tsxfrontend/__tests__/accessibility/components/MetricsScoreCircle.a11y.test.tsxfrontend/__tests__/accessibility/components/InfoBlock.a11y.test.tsxfrontend/__tests__/accessibility/components/Badges.a11y.test.tsxfrontend/__tests__/accessibility/components/BarChart.a11y.test.tsxfrontend/__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.tsxfrontend/__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.tsxfrontend/__tests__/accessibility/components/LineChart.a11y.test.tsxfrontend/__tests__/accessibility/components/DonutBarChart.a11y.test.tsxfrontend/__tests__/accessibility/components/HealthMetrics.a11y.test.tsxfrontend/__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.tsxfrontend/__tests__/accessibility/components/MetricsCard.a11y.test.tsxfrontend/__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.tsxfrontend/__tests__/accessibility/components/MetricsCard.a11y.test.tsxfrontend/__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.tsxfrontend/__tests__/accessibility/components/MarkdownWrapper.a11y.test.tsxfrontend/__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)
frontend/__tests__/accessibility/components/DashboardCard.a11y.test.tsx
Outdated
Show resolved
Hide resolved
frontend/__tests__/accessibility/components/ProjectTypeDashboardCard.a11y.test.tsx
Outdated
Show resolved
Hide resolved
frontend/__tests__/accessibility/components/SkeletonBase.a11y.test.tsx
Outdated
Show resolved
Hide resolved
|
Please make sure it's ready for review before requesting it -- https://github.com/OWASP/Nest/blob/main/CONTRIBUTING.md#contributing-workflow |
There was a problem hiding this comment.
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
imageUrlprop, 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
DashboardCardwith actualstatsdata 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:
- Missing
__esModule: true, default: ...wrapper for proper ES module interophrefshould 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
📒 Files selected for processing (11)
frontend/Makefilefrontend/__tests__/accessibility/components/AutoScrollToTop.a11y.test.tsxfrontend/__tests__/accessibility/components/BreadCrumbsWrapper.a11y.test.tsxfrontend/__tests__/accessibility/components/DashboardCard.a11y.test.tsxfrontend/__tests__/accessibility/components/LoadingSpinner.a11y.test.tsxfrontend/__tests__/accessibility/components/ModeToggle.a11y.test.tsxfrontend/__tests__/accessibility/components/ProjectTypeDashboardCard.a11y.test.tsxfrontend/__tests__/accessibility/components/SkeletonBase.a11y.test.tsxfrontend/docker/Dockerfile.a11y.testfrontend/jest.setup.tsfrontend/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.tsxfrontend/__tests__/accessibility/components/ProjectTypeDashboardCard.a11y.test.tsxfrontend/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.tsxfrontend/__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"andaria-labelcorrectly 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-a11ytarget correctly follows the same Docker build and execution pattern as the existingtest-frontend-unitandtest-frontend-e2etargets, 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 /appcommand (without-R) correctly changes the directory ownership while leaving source files immutable atroot:root. This allows the node user to create temporary and cache files within/appwhile preventing accidental modifications to source code. The read-only permissions (chmod 444) onpackage.jsonandpnpm-lock.yamlare 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/appdirectory, 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
usePathnamehook that replaceduseRouter().asPathin Next.js 13+ app router, returning a stable pathname for tests.Based on learnings, Next.js 13+ components should use
usePathnameinstead ofuseRouter().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.tsis now used (no local duplication), which addresses the previous review concern.
There was a problem hiding this comment.
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), thetest:a11yscript does not includetsc --noEmitto 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
📒 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.
…-0304/Nest into feat/accessibility_tests
There was a problem hiding this comment.
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 srcThis 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
CMDorENTRYPOINT. While this is likely intentional (with the Makefile providing the command viadocker 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
📒 Files selected for processing (2)
docker/frontend/Dockerfile.a11y.testfrontend/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-scriptsflag 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). Usingnode:24-alpineis appropriate.Likely an incorrect or invalid review comment.
There was a problem hiding this comment.
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, andprojectNameare 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
📒 Files selected for processing (16)
frontend/Makefilefrontend/__tests__/accessibility/components/CardDetailsPage.a11y.test.tsxfrontend/__tests__/accessibility/components/ContributorAvatar.a11y.test.tsxfrontend/__tests__/accessibility/components/ItemCardList.a11y.test.tsxfrontend/__tests__/accessibility/components/Leaders.a11y.test.tsxfrontend/__tests__/accessibility/components/LogoCarousel.a11y.test.tsxfrontend/__tests__/accessibility/components/MarkdownWrapper.a11y.test.tsxfrontend/__tests__/accessibility/components/RecentIssues.a11y.test.tsxfrontend/__tests__/accessibility/components/RecentPullRequests.a11y.test.tsxfrontend/__tests__/accessibility/components/RecentRelease.a11y.test.tsxfrontend/__tests__/accessibility/components/Release.a11y.test.tsxfrontend/__tests__/accessibility/components/SingleModuleCard.a11y.test.tsxfrontend/__tests__/accessibility/components/TopContributorsList.a11y.test.tsxfrontend/__tests__/accessibility/components/UserCard.a11y.test.tsxfrontend/__tests__/accessibility/components/UserMenu.a11y.test.tsxfrontend/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.tsxfrontend/__tests__/accessibility/components/MarkdownWrapper.a11y.test.tsxfrontend/__tests__/accessibility/components/Leaders.a11y.test.tsxfrontend/__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.tsxfrontend/__tests__/accessibility/components/MarkdownWrapper.a11y.test.tsxfrontend/__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-frontendtarget 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-a11ytarget 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
usePathnameto 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
MockedLinkmock provides a simple but effective anchor element for testing, preserving essential props likehrefandclassNamewhile avoiding actual navigation.
87-109: LGTM! Appropriate next/image mock.The mock handles key Next.js Image props (
fill,objectFit) while rendering a standardimgelement 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.
frontend/__tests__/accessibility/components/MarkdownWrapper.a11y.test.tsx
Outdated
Show resolved
Hide resolved
frontend/__tests__/accessibility/components/RecentIssues.a11y.test.tsx
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
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 adivwrapper instead ofsvgto avoid nested SVG issues.Wrapping the
Chartcomponent in an<svg>element is problematic becausereact-apexchartsalready 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'sheight={250}The correct approach is to wrap the Chart in a container
divwith 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. Thearia-labelprovides sufficient accessible text for screen readers.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
frontend/__tests__/accessibility/components/CalendarButton.a11y.test.tsxfrontend/__tests__/accessibility/components/ContributorAvatar.a11y.test.tsxfrontend/__tests__/accessibility/components/MarkdownWrapper.a11y.test.tsxfrontend/__tests__/accessibility/components/RecentIssues.a11y.test.tsxfrontend/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
…fixing thus encountered a11y issues
There was a problem hiding this comment.
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"withoutrel="noopener noreferrer", creating a tabnabbing vulnerability. The new page can accesswindow.openerand 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 addingaria-expandedfor better screen reader support.Since this button controls the expansion/collapse of content, adding the
aria-expandedattribute 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 usingcontainerfor consistency.The test correctly validates accessibility, but uses
baseElementwhile other a11y tests in this PR consistently usecontainer. Unless UserCard renders portals or modals outside the main container, prefercontainerfor 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 comprehensiveMockedLinkthat 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
accessLevelvaluesThis 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: truestate to ensure the disabled button maintains accessibility
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (36)
frontend/__tests__/accessibility/components/CalendarButton.a11y.test.tsxfrontend/__tests__/accessibility/components/ContributionHeatmap.a11y.test.tsxfrontend/__tests__/accessibility/components/ContributorAvatar.a11y.test.tsxfrontend/__tests__/accessibility/components/EntityActions.a11y.test.tsxfrontend/__tests__/accessibility/components/Footer.a11y.test.tsxfrontend/__tests__/accessibility/components/GeneralCompliantComponent.a11y.test.tsxfrontend/__tests__/accessibility/components/InfoBlock.a11y.test.tsxfrontend/__tests__/accessibility/components/LoadingSpinner.a11y.test.tsxfrontend/__tests__/accessibility/components/LoginPageContent.a11y.test.tsxfrontend/__tests__/accessibility/components/MetricsScoreCircle.a11y.test.tsxfrontend/__tests__/accessibility/components/Milestones.a11y.test.tsxfrontend/__tests__/accessibility/components/ModeToggle.a11y.test.tsxfrontend/__tests__/accessibility/components/NavButton.a11y.test.tsxfrontend/__tests__/accessibility/components/NavDropDown.a11y.test.tsxfrontend/__tests__/accessibility/components/PageLayout.a11y.test.tsxfrontend/__tests__/accessibility/components/Pagination.a11y.test.tsxfrontend/__tests__/accessibility/components/ProgramCard.a11y.test.tsxfrontend/__tests__/accessibility/components/RecentIssues.a11y.test.tsxfrontend/__tests__/accessibility/components/Release.a11y.test.tsxfrontend/__tests__/accessibility/components/RepositoryCard.a11y.test.tsxfrontend/__tests__/accessibility/components/Search.a11y.test.tsxfrontend/__tests__/accessibility/components/SearchPageLayout.a11y.test.tsxfrontend/__tests__/accessibility/components/SecondaryCard.a11y.test.tsxfrontend/__tests__/accessibility/components/SingleModuleCard.a11y.test.tsxfrontend/__tests__/accessibility/components/SkeletonBase.a11y.test.tsxfrontend/__tests__/accessibility/components/SortBy.a11y.test.tsxfrontend/__tests__/accessibility/components/StatusBadge.a11y.test.tsxfrontend/__tests__/accessibility/components/TruncatedText.a11y.test.tsxfrontend/__tests__/accessibility/components/UserCard.a11y.test.tsxfrontend/__tests__/accessibility/components/UserMenu.a11y.test.tsxfrontend/jest.setup.tsfrontend/src/components/DonutBarChart.tsxfrontend/src/components/EntityActions.tsxfrontend/src/components/Footer.tsxfrontend/src/components/Pagination.tsxfrontend/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.tsxfrontend/__tests__/accessibility/components/ModeToggle.a11y.test.tsxfrontend/__tests__/accessibility/components/NavButton.a11y.test.tsxfrontend/__tests__/accessibility/components/UserCard.a11y.test.tsxfrontend/__tests__/accessibility/components/SearchPageLayout.a11y.test.tsxfrontend/__tests__/accessibility/components/ProgramCard.a11y.test.tsxfrontend/__tests__/accessibility/components/SecondaryCard.a11y.test.tsxfrontend/__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.tsxfrontend/__tests__/accessibility/components/NavButton.a11y.test.tsxfrontend/__tests__/accessibility/components/TruncatedText.a11y.test.tsxfrontend/__tests__/accessibility/components/UserCard.a11y.test.tsxfrontend/__tests__/accessibility/components/SearchPageLayout.a11y.test.tsxfrontend/__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.tsxfrontend/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.tsxfrontend/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-testidattribute 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-testidaddition 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-labelfrom the non-interactive ellipsis div is the right approach. Since this element is purely decorative (indicating skipped page numbers) and the icon inside already hasaria-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-labelis 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
createMockRepositoryhelper 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
useThemehook 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
TruncatedTexthas no violations. While the component also accepts achildrenprop (per the component code in relevant snippets), testing with thetextprop is sufficient for accessibility validation since both render paths produce similar DOM structures.
frontend/__tests__/accessibility/components/RepositoryCard.a11y.test.tsx
Outdated
Show resolved
Hide resolved
|
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. |
|
@Utkarsh-0304 could you address the comments? As soon as those are done - we can merge this in 👍🏼 |
There was a problem hiding this comment.
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 removingjest.restoreAllMocks()inside the test case.The
afterEachhook on line 43 already callsjest.clearAllMocks(), which resets mock call history. TherestoreAllMocks()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 thenodeuser 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:nodeto these COPY instructions. Also note thatchown node:node /appon line 19 only changes the directory itself, not its contents (would need-Rfor 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
📒 Files selected for processing (72)
.github/workflows/run-ci-cd.yamldocker/frontend/Dockerfile.a11y.testdocker/frontend/Dockerfile.e2e.testdocker/frontend/Dockerfile.unit.testfrontend/__tests__/a11y/components/CardDetailsPage.a11y.test.tsxfrontend/__tests__/a11y/components/ChapterMap.a11y.test.tsxfrontend/__tests__/a11y/components/Leaders.a11y.test.tsxfrontend/__tests__/e2e/pages/About.spec.tsfrontend/__tests__/e2e/pages/ChapterDetails.spec.tsfrontend/__tests__/e2e/pages/Chapters.spec.tsfrontend/__tests__/e2e/pages/CommitteeDetails.spec.tsfrontend/__tests__/e2e/pages/Committees.spec.tsfrontend/__tests__/e2e/pages/Contribute.spec.tsfrontend/__tests__/e2e/pages/OrganizationDetails.spec.tsfrontend/__tests__/e2e/pages/Organizations.spec.tsfrontend/__tests__/e2e/pages/ProjectDetails.spec.tsfrontend/__tests__/e2e/pages/ProjectHealthDashboardMetricsDetails.spec.tsfrontend/__tests__/e2e/pages/Projects.spec.tsfrontend/__tests__/e2e/pages/ProjectsHealthDashboardMetrics.spec.tsfrontend/__tests__/e2e/pages/ProjectsHealthDashboardOverview.spec.tsfrontend/__tests__/e2e/pages/RepositoryDetails.spec.tsfrontend/__tests__/e2e/pages/UserDetails.spec.tsfrontend/__tests__/e2e/pages/Users.spec.tsfrontend/__tests__/mockData/mockAboutData.tsfrontend/__tests__/mockData/mockApiKeysData.tsfrontend/__tests__/mockData/mockBadgeData.tsfrontend/__tests__/mockData/mockChapterData.tsfrontend/__tests__/mockData/mockChapterDetailsData.tsfrontend/__tests__/mockData/mockCommitteeData.tsfrontend/__tests__/mockData/mockCommitteeDetailsData.tsfrontend/__tests__/mockData/mockContributeData.tsfrontend/__tests__/mockData/mockHomeData.tsfrontend/__tests__/mockData/mockModuleData.tsfrontend/__tests__/mockData/mockOrganizationData.tsfrontend/__tests__/mockData/mockProgramData.tsfrontend/__tests__/mockData/mockProjectData.tsfrontend/__tests__/mockData/mockProjectDetailsData.tsfrontend/__tests__/mockData/mockProjectsDashboardMetricsDetailsData.tsfrontend/__tests__/mockData/mockProjectsDashboardOverviewData.tsfrontend/__tests__/mockData/mockProjectsHealthMetricsData.tsfrontend/__tests__/mockData/mockRepositoryData.tsfrontend/__tests__/mockData/mockSnapshotData.tsfrontend/__tests__/mockData/mockUserData.tsfrontend/__tests__/mockData/mockUserDetails.tsfrontend/__tests__/unit/components/Leaders.test.tsxfrontend/__tests__/unit/components/ProgramCard.test.tsxfrontend/__tests__/unit/pages/About.test.tsxfrontend/__tests__/unit/pages/ApiKeysPage.test.tsxfrontend/__tests__/unit/pages/ChapterDetails.test.tsxfrontend/__tests__/unit/pages/Chapters.test.tsxfrontend/__tests__/unit/pages/CommitteeDetails.test.tsxfrontend/__tests__/unit/pages/Committees.test.tsxfrontend/__tests__/unit/pages/Contribute.test.tsxfrontend/__tests__/unit/pages/Home.test.tsxfrontend/__tests__/unit/pages/ModuleDetails.test.tsxfrontend/__tests__/unit/pages/ModuleDetailsPage.test.tsxfrontend/__tests__/unit/pages/Organization.test.tsxfrontend/__tests__/unit/pages/OrganizationDetails.test.tsxfrontend/__tests__/unit/pages/Program.test.tsxfrontend/__tests__/unit/pages/ProgramDetails.test.tsxfrontend/__tests__/unit/pages/ProgramDetailsMentorship.test.tsxfrontend/__tests__/unit/pages/ProjectDetails.test.tsxfrontend/__tests__/unit/pages/ProjectHealthDashboardMetricsDetails.test.tsxfrontend/__tests__/unit/pages/Projects.test.tsxfrontend/__tests__/unit/pages/ProjectsHealthDashboardMetrics.test.tsxfrontend/__tests__/unit/pages/ProjectsHealthDashboardOverview.test.tsxfrontend/__tests__/unit/pages/RepositoryDetails.test.tsxfrontend/__tests__/unit/pages/SnapshotDetails.test.tsxfrontend/__tests__/unit/pages/UserDetails.test.tsxfrontend/__tests__/unit/pages/Users.test.tsxfrontend/jest.config.tsfrontend/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.tsxfrontend/__tests__/e2e/pages/UserDetails.spec.tsfrontend/__tests__/unit/pages/ApiKeysPage.test.tsxfrontend/__tests__/unit/pages/CommitteeDetails.test.tsxfrontend/__tests__/unit/pages/Program.test.tsxfrontend/__tests__/unit/pages/Chapters.test.tsxfrontend/__tests__/e2e/pages/Organizations.spec.tsfrontend/__tests__/e2e/pages/ChapterDetails.spec.tsfrontend/__tests__/e2e/pages/Contribute.spec.tsfrontend/__tests__/e2e/pages/ProjectDetails.spec.tsfrontend/__tests__/e2e/pages/Projects.spec.tsfrontend/__tests__/e2e/pages/Users.spec.tsfrontend/__tests__/e2e/pages/ProjectHealthDashboardMetricsDetails.spec.tsfrontend/__tests__/unit/pages/ChapterDetails.test.tsxfrontend/__tests__/unit/pages/ProgramDetails.test.tsxfrontend/__tests__/unit/pages/ProjectsHealthDashboardOverview.test.tsxfrontend/__tests__/unit/pages/ProjectsHealthDashboardMetrics.test.tsxfrontend/__tests__/e2e/pages/CommitteeDetails.spec.tsfrontend/__tests__/unit/pages/Organization.test.tsxfrontend/__tests__/e2e/pages/OrganizationDetails.spec.tsfrontend/__tests__/unit/pages/Committees.test.tsxfrontend/__tests__/a11y/components/ChapterMap.a11y.test.tsxfrontend/__tests__/unit/pages/ProjectDetails.test.tsxfrontend/__tests__/unit/pages/About.test.tsxfrontend/__tests__/unit/pages/Projects.test.tsxfrontend/__tests__/e2e/pages/Chapters.spec.tsfrontend/__tests__/unit/pages/RepositoryDetails.test.tsxfrontend/__tests__/unit/components/Leaders.test.tsxfrontend/__tests__/unit/pages/ModuleDetailsPage.test.tsxfrontend/__tests__/unit/pages/ProgramDetailsMentorship.test.tsxfrontend/__tests__/e2e/pages/About.spec.tsfrontend/__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.tsxfrontend/__tests__/e2e/pages/Organizations.spec.tsfrontend/__tests__/e2e/pages/Contribute.spec.tsfrontend/__tests__/e2e/pages/ProjectsHealthDashboardOverview.spec.tsfrontend/__tests__/e2e/pages/Projects.spec.tsfrontend/__tests__/e2e/pages/Users.spec.tsfrontend/__tests__/e2e/pages/ProjectHealthDashboardMetricsDetails.spec.tsfrontend/__tests__/a11y/components/ChapterMap.a11y.test.tsxfrontend/__tests__/e2e/pages/ProjectsHealthDashboardMetrics.spec.tsfrontend/__tests__/e2e/pages/Chapters.spec.tsfrontend/__tests__/e2e/pages/About.spec.tsfrontend/__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.tsxfrontend/__tests__/unit/pages/ProgramDetails.test.tsxfrontend/__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.tsxfrontend/__tests__/unit/pages/ProgramDetails.test.tsxfrontend/__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.tsxfrontend/__tests__/unit/pages/ProgramDetails.test.tsxfrontend/__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.tsxfrontend/__tests__/e2e/pages/Organizations.spec.tsfrontend/__tests__/e2e/pages/ChapterDetails.spec.tsfrontend/__tests__/e2e/pages/Contribute.spec.tsfrontend/__tests__/e2e/pages/Projects.spec.tsfrontend/__tests__/e2e/pages/Users.spec.tsfrontend/__tests__/e2e/pages/ProjectHealthDashboardMetricsDetails.spec.tsfrontend/__tests__/unit/pages/ChapterDetails.test.tsxfrontend/__tests__/a11y/components/ChapterMap.a11y.test.tsxfrontend/__tests__/e2e/pages/ProjectsHealthDashboardMetrics.spec.tsfrontend/__tests__/e2e/pages/Chapters.spec.tsfrontend/__tests__/e2e/pages/About.spec.tsfrontend/__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
@mockDataalias 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/mockChapterDataaligns 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/mockModuleDatais 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/mockProjectDetailsDatafollows 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__/mockDatadirectory, 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
@mockDataalias 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/mockChapterDetailsDatais 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/mockCommitteeDetailsDatafollows 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/mockProgramDataformockProgramsis consistent with the centralized mock data approach.docker/frontend/Dockerfile.unit.test (1)
22-22: LGTM!Essential addition to copy the centralized
mockDatadirectory 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
@mockDatamodule 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/mockOrganizationDatais correct.frontend/__tests__/e2e/pages/OrganizationDetails.spec.ts (1)
1-1: LGTM!The import path migration to
@mockData/mockOrganizationDatafor themockOrganizationDetailsDataexport 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/mockApiKeysDatais 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/mockCommitteeDatais correct.frontend/__tests__/e2e/pages/Contribute.spec.ts (1)
2-2: LGTM!The import path update to the centralized
@mockDataalias 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
@mockDatais 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/mockProjectDetailsDataaligns with the centralized mock data approach.frontend/jest.config.ts (1)
38-42: LGTM!The Jest configuration updates are well-structured:
testPathIgnorePatternscorrectly excludes the mock data directory from test discovery.- The
@mockDatamodule alias properly resolves to the centralized mock data location.This enables clean imports like
@mockData/mockChapterDataacross all test suites.Also applies to: 47-47
frontend/__tests__/mockData/mockChapterData.ts (1)
26-35: Both_geolocandgeoLocationfields are intentionally used together throughout the codebase in fallback patterns (e.g.,chapter._geoloc?.lat ?? chapter.geoLocation?.latin ChapterMap.tsx). The mock data correctly includes both fields to reflect the real API structure where_geolocserves as the primary field withgeoLocationas 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/mockProjectsHealthMetricsDatato@mockData/mockProjectsHealthMetricsDatacorrectly 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. ThetoHaveNoViolationsmatcher 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-testidattributes 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
baseElementfor comprehensive accessibility scanning.frontend/__tests__/unit/pages/About.test.tsx (1)
3-3: LGTM!The import path update to
@mockData/mockAboutDataaligns 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/mockUserDatacorrectly 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/mockRepositoryDatais 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. ThemockProjectData.tsfile 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
@mockDataalias, 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
@mockDatamodule, 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
@mockDataalias.frontend/__tests__/e2e/pages/ProjectsHealthDashboardOverview.spec.ts (1)
2-2: LGTM!Import path correctly updated to use the centralized
@mockDataalias, 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
CMDandENTRYPOINTbecause the test command (pnpm run test:a11y) is provided at runtime by the Makefile viadocker 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.
…-0304/Nest into feat/accessibility_tests
kasya
left a comment
There was a problem hiding this comment.
@Utkarsh-0304 great work 👍🏼 Thanks!
16ac56f
|



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
make check-testlocally and all tests passed