-
Notifications
You must be signed in to change notification settings - Fork 200
Expand file tree
/
Copy pathfocus.test.tsx
More file actions
99 lines (79 loc) · 3.15 KB
/
focus.test.tsx
File metadata and controls
99 lines (79 loc) · 3.15 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
/* eslint-disable class-methods-use-this */
import React, { JSX, useRef } from 'react';
import { render, cleanup } from '@testing-library/react';
import { spyElementPrototype } from '../src/test/domHook';
import { getFocusNodeList, triggerFocus, useLockFocus } from '../src/Dom/focus';
describe('focus', () => {
beforeAll(() => {
spyElementPrototype(HTMLElement, 'offsetParent', {
get: () => document.body,
});
});
it('getFocusNodeList', () => {
const div = document.createElement('div');
div.setAttribute('tabIndex', '0');
document.body.appendChild(div);
div.innerHTML = [
'<input disabled />',
'<button></button>',
'<textarea tabindex="-1"></textarea>',
'<a>noop</a>',
'<a href="light">go</a>',
'<div contenteditable="true"></div>',
].join('');
(div.lastChild as any).isContentEditable = true;
const focusList = getFocusNodeList(div);
expect(focusList).toHaveLength(4);
const tabFocusList = getFocusNodeList(div, true);
expect(tabFocusList).toHaveLength(5);
});
it('triggerFocus should set cursor position for textarea', () => {
const textarea = document.createElement('textarea');
textarea.value = 'test content';
const focusSpy = jest.spyOn(textarea, 'focus');
const setSelectionRangeSpy = jest.spyOn(textarea, 'setSelectionRange');
// Test cursor: 'start'
triggerFocus(textarea, { cursor: 'start' });
expect(setSelectionRangeSpy).toHaveBeenCalledWith(0, 0);
// Test cursor: 'end'
triggerFocus(textarea, { cursor: 'end' });
expect(setSelectionRangeSpy).toHaveBeenCalledWith(12, 12); // 'test content'.length = 12
// Test cursor: 'all'
triggerFocus(textarea, { cursor: 'all' });
expect(setSelectionRangeSpy).toHaveBeenCalledWith(0, 12); // select all text
expect(focusSpy).toHaveBeenCalledTimes(3);
focusSpy.mockRestore();
setSelectionRangeSpy.mockRestore();
});
describe('useLockFocus', () => {
const TestComponent: React.FC<{ lock: boolean }> = ({ lock }) => {
const elementRef = useRef<HTMLDivElement>(null);
useLockFocus(lock, () => elementRef.current);
return (
<>
<button data-testid="outer-button">Outer</button>
<div ref={elementRef} data-testid="focus-container" tabIndex={0}>
<input key="input1" data-testid="input1" />
<button key="button1" data-testid="button1">
Button
</button>
</div>
</>
);
};
it('should restore focus to range when focusing other elements', () => {
const { getByTestId } = render(<TestComponent lock={true} />);
const focusContainer = getByTestId('focus-container');
const input1 = getByTestId('input1') as HTMLInputElement;
// Should focus to first focusable element after lock
expect(document.activeElement).toBe(focusContainer);
// Focus inside container first
input1.focus();
expect(document.activeElement).toBe(input1);
// Focus outer button
const outerButton = getByTestId('outer-button') as HTMLButtonElement;
outerButton.focus();
expect(document.activeElement).toBe(input1);
});
});
});