main
md 98 lines 3.19 KB
Rendered Raw
1 # `dom-event-testing-library`
2
3 A library for unit testing events via high-level interactions, e.g., `pointerdown`,
4 that produce realistic and complete DOM event sequences.
5
6 There are number of challenges involved in unit testing modules that work with
7 DOM events.
8
9 1. Gesture recognizers may need to support environments with and without support for
10 the `PointerEvent` API.
11 2. Gesture recognizers may need to support various user interaction modes including
12 mouse, touch, and pen use.
13 3. Gesture recognizers must account for the actual event sequences browsers produce
14 (e.g., emulated touch and mouse events.)
15 4. Gesture recognizers must work with "virtual" events produced by tools like
16 screen-readers.
17
18 Writing unit tests to cover all these scenarios is tedious and error prone. This
19 event testing library is designed to solve these issues by allowing developers to
20 more easily dispatch events in unit tests, and to more reliably test pointer
21 interactions using a high-level API based on `PointerEvent`. Here's a basic example:
22
23 ```js
24 import {
25 describeWithPointerEvent,
26 testWithPointerType,
27 createEventTarget,
28 setPointerEvent,
29 resetActivePointers
30 } from 'dom-event-testing-library';
31
32 describeWithPointerEvent('useTap', hasPointerEvent => {
33 beforeEach(() => {
34 // basic PointerEvent mock
35 setPointerEvent(hasPointerEvent);
36 });
37
38 afterEach(() => {
39 // clear active pointers between test runs
40 resetActivePointers();
41 });
42
43 // test all the pointer types supported by the environment
44 testWithPointerType('pointer down', pointerType => {
45 const ref = createRef(null);
46 const onTapStart = jest.fn();
47 render(() => {
48 useTap(ref, { onTapStart });
49 return <div ref={ref} />
50 });
51
52 // create an event target
53 const target = createEventTarget(ref.current);
54 // dispatch high-level pointer event
55 target.pointerdown({ pointerType });
56
57 expect(onTapStart).toBeCalled();
58 });
59 });
60 ```
61
62 This tests the interaction in multiple scenarios. In each case, a realistic DOM
63 event sequence–with complete mock events–is produced. When running in a mock
64 environment without the `PointerEvent` API, the test runs for both `mouse` and
65 `touch` pointer types. When `touch` is the pointer type it produces emulated mouse
66 events. When running in a mock environment with the `PointerEvent` API, the test
67 runs for `mouse`, `touch`, and `pen` pointer types.
68
69 It's important to cover all these scenarios because it's very easy to introduce
70 bugs – e.g., double calling of callbacks – if not accounting for emulated mouse
71 events, differences in target capturing between `touch` and `mouse` pointers, and
72 the different semantics of `button` across event APIs.
73
74 Default values are provided for the expected native events properties. They can
75 also be customized as needed in a test.
76
77 ```js
78 target.pointerdown({
79 button: 0,
80 buttons: 1,
81 pageX: 10,
82 pageY: 10,
83 pointerType,
84 // NOTE: use x,y instead of clientX,clientY
85 x: 10,
86 y: 10
87 });
88 ```
89
90 Tests that dispatch multiple pointer events will dispatch multi-touch native events
91 on the target.
92
93 ```js
94 // first pointer is active
95 target.pointerdown({pointerId: 1, pointerType});
96 // second pointer is active
97 target.pointerdown({pointerId: 2, pointerType});
98 ```