aboutsummaryrefslogtreecommitdiffstats
path: root/src/utils/hooks/use-autofocus/use-autofocus.test.ts
blob: 1a9a3bec12ecf8f6e250c3467d9f41a878120993 (plain)
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
import {
  afterEach,
  beforeEach,
  describe,
  expect,
  it,
  jest,
} from '@jest/globals';
import { renderHook, screen as rtlScreen } from '@testing-library/react';
import { useAutofocus } from './use-autofocus';

describe('useAutofocus', () => {
  // When less than 1ms, setTimeout use 1. Default delay is 0ms.
  const defaultTimeoutDelay = 1;
  const input = document.createElement('input');
  input.type = 'text';

  beforeEach(() => {
    document.body.append(input);
    jest.useFakeTimers();
  });

  afterEach(() => {
    document.body.removeChild(input);
    jest.runOnlyPendingTimers();
    jest.useRealTimers();
  });

  it('gives focus to the element without condition', () => {
    const { result } = renderHook(() => useAutofocus<HTMLInputElement>());
    result.current.current = input;

    jest.advanceTimersByTime(defaultTimeoutDelay);

    expect(rtlScreen.getByRole('textbox')).toHaveFocus();
  });

  it('can give focus to the element with custom delay', () => {
    const delay = 2000;
    const { result } = renderHook(() =>
      useAutofocus<HTMLInputElement>({ delay })
    );
    result.current.current = input;

    jest.advanceTimersByTime(defaultTimeoutDelay);

    expect(rtlScreen.getByRole('textbox')).not.toHaveFocus();

    jest.advanceTimersByTime(delay);

    expect(rtlScreen.getByRole('textbox')).toHaveFocus();
  });

  it('can give focus to the element when the condition is met', () => {
    const condition = jest.fn(() => true);
    const { result } = renderHook(() =>
      useAutofocus<HTMLInputElement>({ condition })
    );
    result.current.current = input;

    jest.advanceTimersByTime(defaultTimeoutDelay);

    expect(rtlScreen.getByRole('textbox')).toHaveFocus();
    expect(condition).toHaveBeenCalledTimes(1);
  });

  it('does not give focus to the element when the condition is not met', () => {
    const condition = jest.fn(() => false);
    const { result } = renderHook(() =>
      useAutofocus<HTMLInputElement>({ condition })
    );
    result.current.current = input;

    jest.advanceTimersByTime(defaultTimeoutDelay);

    expect(rtlScreen.getByRole('textbox')).not.toHaveFocus();
    expect(condition).toHaveBeenCalledTimes(1);
  });
});