The Node.js® Website
1import { render, fireEvent, screen, act } from '@testing-library/react';
2
3import { useCopyToClipboard } from '..';
4
5const mockWriteText = jest.fn();
6const originalNavigator = { ...window.navigator };
7
8describe('useCopyToClipboard', () => {
9 beforeEach(() => {
10 jest.useFakeTimers();
11
12 Object.defineProperty(window, 'navigator', {
13 value: {
14 clipboard: {
15 writeText: mockWriteText,
16 },
17 },
18 });
19 });
20
21 afterEach(() => {
22 Object.defineProperty(window, 'navigator', {
23 value: originalNavigator,
24 });
25 });
26
27 it('should call clipboard API with `test` once', async () => {
28 const navigatorClipboardWriteTextSpy = jest
29 .fn()
30 .mockImplementation(() => Promise.resolve());
31
32 Object.defineProperty(window.navigator, 'clipboard', {
33 writable: true,
34 value: {
35 writeText: navigatorClipboardWriteTextSpy,
36 },
37 });
38
39 const TestComponent = ({ textToCopy }) => {
40 const [copied, copyText] = useCopyToClipboard();
41
42 return (
43 <button onClick={() => copyText(textToCopy)} type="button">
44 {copied ? 'copied' : 'copy'}
45 </button>
46 );
47 };
48
49 render(<TestComponent textToCopy="test" />);
50
51 const button = screen.getByRole('button');
52
53 await fireEvent.click(button);
54
55 expect(await screen.findByText(/copied/i)).toBeInTheDocument();
56
57 act(() => jest.advanceTimersByTime(3000));
58
59 expect(await screen.findByText(/copy/i)).toBeInTheDocument();
60
61 expect(navigatorClipboardWriteTextSpy).toHaveBeenCalledTimes(1);
62 expect(navigatorClipboardWriteTextSpy).toHaveBeenCalledWith('test');
63 });
64});