-
Notifications
You must be signed in to change notification settings - Fork 5
/
CopyToClipboard.spec.tsx
119 lines (91 loc) · 3.64 KB
/
CopyToClipboard.spec.tsx
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
112
113
114
115
116
117
118
119
import type { CopyToClipboardProps } from '../src';
import type { CopyToClipboardHandleRef } from '../src/CopyToClipboard';
import { useRef } from 'react';
import { it, expect, describe, vi } from 'vitest';
import { render, screen, userEvent, waitFor } from '../../../test/utils';
import { CopyToClipboard } from '../src';
const createComponent = ({ children, ...rest }: Partial<CopyToClipboardProps>) => (
<CopyToClipboard
text="Copy content"
tooltipOptions={{ hoverOpenDelay: 0 }}
data-test-id="test-component"
{...rest}
>
{children || 'Copy content'}
</CopyToClipboard>
);
describe('CopyToClipboard', () => {
it('copies text when clicked on', async () => {
const user = userEvent.setup();
const spy = vi.spyOn(window.navigator.clipboard, 'writeText');
render(createComponent({}));
await user.click(screen.getByTestId('copy-code-button'));
expect(spy).toHaveBeenCalledWith('Copy content');
});
it('handles MouseEnter and MouseLeave', async () => {
const user = userEvent.setup();
render(createComponent({ triggerAriaLabel: 'copy to clipboard' }));
expect(screen.queryByRole('tooltip')).toBeNull();
await user.hover(screen.getByText('Copy content'));
expect(await screen.findByRole('tooltip')).toBeInTheDocument();
await user.unhover(screen.getByText('Copy content'));
expect(screen.queryByRole('tooltip')).toBeNull();
});
it('handles keyboard interactions', async () => {
const user = userEvent.setup();
render(createComponent({}));
expect(screen.queryByRole('tooltip')).toBeNull();
await user.tab();
expect(await screen.findByRole('tooltip')).toBeInTheDocument();
await user.tab();
expect(screen.queryByRole('tooltip')).toBeNull();
});
it('shows the confirmation tooltip when clicked', async () => {
const user = userEvent.setup();
render(createComponent({}));
await user.click(screen.getByRole('button'));
await waitFor(async () => {
expect(await screen.findByText('Copied!')).toBeVisible();
});
});
it('uses the custom copied text when provided', async () => {
const FAKE_CUSTOM_COPIED_TEXT = 'Fake custom text';
const user = userEvent.setup();
render(createComponent({ customCopiedText: FAKE_CUSTOM_COPIED_TEXT }));
await user.click(screen.getByRole('button'));
await waitFor(async () => {
expect(await screen.findByText(FAKE_CUSTOM_COPIED_TEXT)).toBeVisible();
});
});
it('copies imperatively when a ref is passed', async () => {
const WrappedComponent = () => {
const ref = useRef<CopyToClipboardHandleRef>(null);
const handleClick = () => {
ref.current?.handleCopy();
};
return (
// eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
<div data-test-id="wrapper" onClick={handleClick}>
<CopyToClipboard text="Copy content" ref={ref}>
Copy
</CopyToClipboard>
</div>
);
};
const user = userEvent.setup();
const spy = vi.spyOn(window.navigator.clipboard, 'writeText');
render(<WrappedComponent />);
await user.click(screen.getByTestId('wrapper'));
expect(spy).toHaveBeenCalledWith('Copy content');
});
it('renders a button when asChild is false', async () => {
render(createComponent({}));
const trigger = screen.getByRole('button');
expect(trigger.tagName).toBe('BUTTON');
});
it('renders as child when asChild is true', async () => {
render(createComponent({ asChild: true, children: <span>click me</span> }));
const trigger = screen.getByRole('button');
expect(trigger.tagName).toBe('SPAN');
});
});