Skip to content

Commit 2e9f020

Browse files
committed
test(contributors): add loading accessibility coverage
1 parent 2e604a1 commit 2e9f020

1 file changed

Lines changed: 70 additions & 0 deletions

File tree

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
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 accessibility', () => {
14+
it('exposes the loading state through a screen-reader status region', () => {
15+
render(<Loading />);
16+
17+
const status = screen.getByRole('status');
18+
19+
expect(status.getAttribute('aria-live')).toBe('polite');
20+
expect(status.textContent).toContain('Loading the collective...');
21+
expect(status.textContent).toContain('Fetching contributor data from GitHub');
22+
});
23+
24+
it('keeps descriptive loading text available to assistive technologies', () => {
25+
render(<Loading />);
26+
27+
expect(screen.getByText('Loading the collective...')).toBeTruthy();
28+
expect(screen.getByText('Fetching contributor data from GitHub')).toBeTruthy();
29+
});
30+
31+
it('does not expose decorative spinner elements as interactive controls', () => {
32+
render(<Loading />);
33+
34+
expect(screen.queryByRole('button')).toBeNull();
35+
expect(screen.queryByRole('link')).toBeNull();
36+
expect(screen.queryByRole('textbox')).toBeNull();
37+
});
38+
39+
it('preserves visual focus-friendly layout without hidden foreground text', () => {
40+
render(<Loading />);
41+
42+
const status = screen.getByRole('status');
43+
const page = status.parentElement;
44+
45+
hasClasses(page, [
46+
'flex',
47+
'min-h-screen',
48+
'items-center',
49+
'justify-center',
50+
'bg-[#050505]',
51+
'text-white',
52+
]);
53+
54+
expect(status.classList.contains('sr-only')).toBe(false);
55+
expect(status.classList.contains('hidden')).toBe(false);
56+
expect(status.classList.contains('text-transparent')).toBe(false);
57+
});
58+
59+
it('keeps DOM reading order logical for keyboard and screen-reader traversal', () => {
60+
render(<Loading />);
61+
62+
const status = screen.getByRole('status');
63+
const children = Array.from(status.children);
64+
65+
expect(children.length).toBeGreaterThanOrEqual(3);
66+
expect(children[0].tagName.toLowerCase()).toBe('div');
67+
expect(children[1].textContent).toBe('Loading the collective...');
68+
expect(children[2].textContent).toBe('Fetching contributor data from GitHub');
69+
});
70+
});

0 commit comments

Comments
 (0)