forked from JhaSourav07/commitpulse
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCopyRepoButton.massive-scaling.test.tsx
More file actions
111 lines (91 loc) · 2.88 KB
/
Copy pathCopyRepoButton.massive-scaling.test.tsx
File metadata and controls
111 lines (91 loc) · 2.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import { beforeEach, describe, it, expect, vi } from 'vitest';
import CopyRepoButton from './CopyRepoButton';
vi.mock('lucide-react', () => ({
Copy: () => <svg data-testid="copy-icon" />,
}));
beforeEach(() => {
vi.clearAllMocks();
Object.assign(navigator, {
clipboard: {
writeText: vi.fn().mockResolvedValue(undefined),
},
});
});
describe('CopyRepoButton Massive Scaling', () => {
it('renders 100 buttons without crashing', () => {
render(
<>
{Array.from({ length: 100 }).map((_, i) => (
<CopyRepoButton key={i} />
))}
</>
);
expect(screen.getAllByText('Copy URL')).toHaveLength(100);
});
it('renders 500 buttons without layout break', () => {
render(
<>
{Array.from({ length: 500 }).map((_, i) => (
<CopyRepoButton key={i} />
))}
</>
);
expect(screen.getAllByRole('button')).toHaveLength(500);
});
it('renders icon for every button under heavy load', () => {
render(
<>
{Array.from({ length: 200 }).map((_, i) => (
<CopyRepoButton key={i} />
))}
</>
);
expect(screen.getAllByTestId('copy-icon')).toHaveLength(200);
});
it('maintains button text consistency across many renders', () => {
render(
<>
{Array.from({ length: 300 }).map((_, i) => (
<CopyRepoButton key={i} />
))}
</>
);
const buttons = screen.getAllByText('Copy URL');
expect(buttons.length).toBe(300);
});
it('handles repeated mounting without throwing errors', () => {
expect(() => {
for (let i = 0; i < 50; i++) {
render(<CopyRepoButton />);
}
}).not.toThrow();
});
it('shows copied state after a successful clipboard write', async () => {
render(<CopyRepoButton />);
fireEvent.click(screen.getByRole('button', { name: /copy url/i }));
await waitFor(() => {
expect(navigator.clipboard.writeText).toHaveBeenCalledWith(
'https://github.com/JhaSourav07/commitpulse'
);
});
expect(screen.getByText('Copied!')).toBeDefined();
});
it('shows an error state when clipboard write fails', async () => {
vi.mocked(navigator.clipboard.writeText).mockRejectedValueOnce(new Error('Permission denied'));
render(<CopyRepoButton />);
fireEvent.click(screen.getByRole('button', { name: /copy url/i }));
await waitFor(() => {
expect(navigator.clipboard.writeText).toHaveBeenCalledWith(
'https://github.com/JhaSourav07/commitpulse'
);
});
expect(screen.queryByText('Copied!')).toBeNull();
// Use a function matcher to handle text split across multiple elements
expect(
screen.getAllByText((content, element) => {
return element?.textContent?.includes('Copy failed') ?? false;
})[0]
).toBeDefined();
});
});