From 7f1526c08dfda02fde96c0c48a2d645818d2ceea Mon Sep 17 00:00:00 2001 From: starwork Date: Thu, 4 Jun 2026 01:11:32 +0530 Subject: [PATCH 1/2] test: improve RefreshButton accessibility coverage --- components/dashboard/RefreshButton.test.tsx | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/components/dashboard/RefreshButton.test.tsx b/components/dashboard/RefreshButton.test.tsx index c21121868..ea32d7c9c 100644 --- a/components/dashboard/RefreshButton.test.tsx +++ b/components/dashboard/RefreshButton.test.tsx @@ -55,6 +55,22 @@ afterEach(() => { }); describe('RefreshButton', () => { + it('has correct aria-label for accessibility', () => { + render(); + expect(screen.getByRole('button')).toHaveAttribute( + 'aria-label', + 'Refresh dashboard contribution data' + ); + }); + + it('has correct title attribute for tooltip accessibility', () => { + render(); + expect(screen.getByRole('button')).toHaveAttribute( + 'title', + 'Refresh dashboard contribution data' + ); + }); + it("renders 'Refresh Data' button text", () => { render(); expect(screen.getByText('Refresh Data')).toBeDefined(); From 0b05fbab7da30f8dce05e5bc26b24372dcb8acf3 Mon Sep 17 00:00:00 2001 From: starwork Date: Thu, 4 Jun 2026 03:46:28 +0530 Subject: [PATCH 2/2] test: add RefreshButton accessibility test suite --- .../RefreshButton.accessibility.test.tsx | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 components/dashboard/RefreshButton.accessibility.test.tsx diff --git a/components/dashboard/RefreshButton.accessibility.test.tsx b/components/dashboard/RefreshButton.accessibility.test.tsx new file mode 100644 index 000000000..fe41aa7b3 --- /dev/null +++ b/components/dashboard/RefreshButton.accessibility.test.tsx @@ -0,0 +1,88 @@ +import { render, screen } from '@testing-library/react'; +import { describe, it, expect, vi, beforeEach } from 'vitest'; +import RefreshButton from './RefreshButton'; +import { useRouter, useSearchParams } from 'next/navigation'; +import { useTransition } from 'react'; + +vi.mock('next/navigation', () => ({ + useRouter: vi.fn(), + useSearchParams: vi.fn(), +})); + +vi.mock('react', async () => { + const actual = await vi.importActual('react'); + return { + ...actual, + useTransition: vi.fn(), + }; +}); + +const mockPush = vi.fn(); +const mockReplace = vi.fn(); +const mockRefresh = vi.fn(); + +beforeEach(() => { + vi.clearAllMocks(); + + (useRouter as unknown as ReturnType).mockReturnValue({ + push: mockPush, + replace: mockReplace, + refresh: mockRefresh, + }); + + (useSearchParams as unknown as ReturnType).mockReturnValue({ + get: () => null, + toString: () => '', + }); + + (useTransition as unknown as ReturnType).mockReturnValue([ + false, + (cb: () => void) => cb(), + ]); +}); + +describe('RefreshButton Accessibility', () => { + it('has correct aria-label for screen readers', () => { + render(); + + expect(screen.getByRole('button')).toHaveAttribute( + 'aria-label', + 'Refresh dashboard contribution data' + ); + }); + + it('has correct title attribute for tooltip accessibility', () => { + render(); + + expect(screen.getByRole('button')).toHaveAttribute( + 'title', + 'Refresh dashboard contribution data' + ); + }); + + it('is reachable via keyboard focus', () => { + render(); + + const btn = screen.getByRole('button'); + btn.focus(); + + expect(btn).toHaveFocus(); + }); + + it('is accessible via role', () => { + render(); + + expect(screen.getByRole('button')).toBeInTheDocument(); + }); + + it('supports disabled state when pending', () => { + (useTransition as unknown as ReturnType).mockReturnValueOnce([ + true, + (cb: () => void) => cb(), + ]); + + render(); + + expect(screen.getByRole('button')).toBeDisabled(); + }); +});