Skip to content

Commit 8db3270

Browse files
authored
Add contributors loading theme contrast tests (JhaSourav07#3120)
## Description Fixes JhaSourav07#2845 Added isolated Vitest coverage for `app/contributors/loading.tsx`, focusing on dark/light theme visual cohesion, text contrast expectations, Tailwind theme classes, and foreground visibility. ## Pillar - [ ] 🎨 Pillar 1 — New Theme Design - [ ] 📐 Pillar 2 — Geometric SVG Improvement - [ ] 🕐 Pillar 3 — Timezone Logic Optimization - [x] 🛠️ Other (Bug fix, refactoring, docs) ## Visual Preview Not applicable — test-only change. ## Checklist before requesting a review: - [x] I have read the `CONTRIBUTING.md` file. - [ ] I have tested these changes locally (`localhost:3000/api/streak?user=YOUR_USERNAME`). - [x] I have run `npm run format` and `npm run lint` locally and resolved all errors (CI will fail otherwise). - [x] My commits follow the Conventional Commits format (e.g., `feat(themes): ...`, `fix(calculate): ...`). - [ ] I have updated `README.md` if I added a new theme or URL parameter. - [x] I have started the repo. - [x] I have made sure that i have only one commit to merge in this PR. - [ ] The SVG output matches the CommitPulse "premium quality" aesthetic standard (no raw elements, smooth animations, correct fonts). - [x] (Recommended) I joined the CommitPulse Discord community for contributor discussions, mentorship, and faster PR support.
2 parents 23723d5 + 5ce95f2 commit 8db3270

1 file changed

Lines changed: 90 additions & 0 deletions

File tree

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import { render, screen } from '@testing-library/react';
2+
import { describe, expect, it } from 'vitest';
3+
import Loading from './loading';
4+
5+
function hasClasses(element: Element | null, classes: string[]) {
6+
expect(element).not.toBeNull();
7+
8+
for (const className of classes) {
9+
expect(element!.classList.contains(className)).toBe(true);
10+
}
11+
}
12+
13+
describe('Contributors loading theme contrast', () => {
14+
it('renders an accessible loading status', () => {
15+
render(<Loading />);
16+
17+
const status = screen.getByRole('status');
18+
19+
expect(status.getAttribute('aria-live')).toBe('polite');
20+
expect(screen.getByText('Loading the collective...')).toBeTruthy();
21+
expect(screen.getByText('Fetching contributor data from GitHub')).toBeTruthy();
22+
});
23+
24+
it('applies cohesive dark visual shell classes', () => {
25+
render(<Loading />);
26+
27+
const page = screen.getByRole('status').parentElement;
28+
29+
hasClasses(page, [
30+
'flex',
31+
'min-h-screen',
32+
'items-center',
33+
'justify-center',
34+
'bg-[#050505]',
35+
'text-white',
36+
]);
37+
});
38+
39+
it('keeps contributor loading text visually readable', () => {
40+
render(<Loading />);
41+
42+
const primaryText = screen.getByText('Loading the collective...');
43+
const secondaryText = screen.getByText('Fetching contributor data from GitHub');
44+
45+
hasClasses(primaryText, ['text-zinc-400', 'font-light', 'text-lg']);
46+
hasClasses(secondaryText, ['text-sm', 'text-zinc-600', 'font-mono']);
47+
});
48+
49+
it('uses premium spinner styling with visible foreground contrast', () => {
50+
render(<Loading />);
51+
52+
const status = screen.getByRole('status');
53+
const spinnerWrapper = status.firstElementChild;
54+
const spinner = spinnerWrapper?.firstElementChild ?? null;
55+
56+
hasClasses(status, ['flex', 'flex-col', 'items-center', 'gap-6']);
57+
hasClasses(spinnerWrapper, ['relative']);
58+
hasClasses(spinner, [
59+
'h-16',
60+
'w-16',
61+
'animate-spin',
62+
'rounded-full',
63+
'border-2',
64+
'border-white/10',
65+
'border-t-cyan-400',
66+
]);
67+
});
68+
69+
it('keeps glow overlay behind spinner without clipping foreground content', () => {
70+
render(<Loading />);
71+
72+
const status = screen.getByRole('status');
73+
const spinnerWrapper = status.firstElementChild;
74+
const glowOverlay = spinnerWrapper?.children.item(1) ?? null;
75+
76+
hasClasses(glowOverlay, [
77+
'absolute',
78+
'inset-0',
79+
'h-16',
80+
'w-16',
81+
'rounded-full',
82+
'bg-cyan-400/20',
83+
'blur-xl',
84+
'animate-pulse',
85+
]);
86+
87+
expect(status.classList.contains('overflow-hidden')).toBe(false);
88+
expect(status.classList.contains('text-transparent')).toBe(false);
89+
});
90+
});

0 commit comments

Comments
 (0)