From 0b392310d406878155ff7cb5af01406ee5b083be Mon Sep 17 00:00:00 2001 From: Nicolas Gallagher Date: Thu, 15 Aug 2019 16:57:27 -0700 Subject: [PATCH] [react-events] DOM event testing library This patch formalizes the mock native events and event sequences used in unit tests. The `createEventTarget` function returns an object that can be used to dispatch native event sequences on the target without having to manually do so across all the scenarios we need to account for. Unit tests can be written as if we were only working with PointerEvent, but they will dispatch realistic native event sequences based on the execution environment (e.g., is PointerEvent supported?) and pointer type. ``` describe.each(environments)('Suite', (hasPointerEvents) => { beforeEach(() => { // setup }); test.each(pointerTypes)('Test', (pointerType) => { const target = createEventTarget(node); target.pointerdown({pointerType}); expect(callback).toBeCalled(); }); }); ``` Every native event that is dispatched now includes a complete object by default. The properties of the events can be customized. Properties that shouldn't be relied on in responder implementations are excluded from the mock native events to ensure tests will fail. Equivalent properties are normalized across different event types, e.g., 'pointerId' is converted to 'identifier' before a TouchEvent is dispatched. --- packages/react-events/src/dom/Press.js | 2 + packages/react-events/src/dom/Scroll.js | 26 +- .../__tests__/ContextMenu-test.internal.js | 26 +- .../src/dom/__tests__/Focus-test.internal.js | 125 ++-- .../__tests__/FocusWithin-test.internal.js | 134 ++-- .../src/dom/__tests__/Hover-test.internal.js | 110 +-- .../dom/__tests__/Keyboard-test.internal.js | 17 +- .../src/dom/__tests__/Press-test.internal.js | 669 +++++++----------- .../src/dom/__tests__/Scroll-test.internal.js | 177 ++--- packages/react-events/src/dom/test-utils.js | 481 ------------- .../src/dom/testing-library/domEnvironment.js | 51 ++ .../dom/testing-library/domEventSequences.js | 175 +++++ .../src/dom/testing-library/domEvents.js | 370 ++++++++++ .../src/dom/testing-library/index.js | 109 +++ 14 files changed, 1248 insertions(+), 1224 deletions(-) delete mode 100644 packages/react-events/src/dom/test-utils.js create mode 100644 packages/react-events/src/dom/testing-library/domEnvironment.js create mode 100644 packages/react-events/src/dom/testing-library/domEventSequences.js create mode 100644 packages/react-events/src/dom/testing-library/domEvents.js create mode 100644 packages/react-events/src/dom/testing-library/index.js diff --git a/packages/react-events/src/dom/Press.js b/packages/react-events/src/dom/Press.js index 40251331f94bc..f526497097f4c 100644 --- a/packages/react-events/src/dom/Press.js +++ b/packages/react-events/src/dom/Press.js @@ -520,6 +520,7 @@ const pressResponderImpl = { const isPressed = state.isPressed; handleStopPropagation(props, context, nativeEvent); + switch (type) { // START case 'pointerdown': @@ -632,6 +633,7 @@ const pressResponderImpl = { const previousPointerType = state.pointerType; handleStopPropagation(props, context, nativeEvent); + switch (type) { // MOVE case 'pointermove': diff --git a/packages/react-events/src/dom/Scroll.js b/packages/react-events/src/dom/Scroll.js index 5fa1e34a8e5e5..44b782b977c72 100644 --- a/packages/react-events/src/dom/Scroll.js +++ b/packages/react-events/src/dom/Scroll.js @@ -62,14 +62,16 @@ type ScrollEvent = {| y: null | number, |}; -const targetEventTypes = [ - 'scroll', - 'pointerdown', - 'touchstart', - 'keyup', - 'wheel', -]; -const rootEventTypes = ['touchcancel', 'touchend']; +const hasPointerEvents = + typeof window !== 'undefined' && window.PointerEvent !== undefined; + +const targetEventTypes = hasPointerEvents + ? ['scroll', 'pointerdown', 'keyup', 'wheel'] + : ['scroll', 'mousedown', 'touchstart', 'keyup', 'wheel']; + +const rootEventTypes = hasPointerEvents + ? ['pointercancel', 'pointerup'] + : ['touchcancel', 'touchend']; function isFunction(obj): boolean { return typeof obj === 'function'; @@ -237,17 +239,23 @@ const scrollResponderImpl = { state.pointerType = pointerType; break; } + case 'mousedown': case 'wheel': { state.pointerType = 'mouse'; break; } case 'pointerdown': { state.pointerType = pointerType; + if (pointerType === 'touch' && !state.isTouching) { + state.isTouching = true; + context.addRootEventTypes(rootEventTypes); + } break; } case 'touchstart': { if (!state.isTouching) { state.isTouching = true; + state.pointerType = 'touch'; context.addRootEventTypes(rootEventTypes); } } @@ -262,6 +270,8 @@ const scrollResponderImpl = { const {type} = event; switch (type) { + case 'pointercancel': + case 'pointerup': case 'touchcancel': case 'touchend': { if (state.isTouching) { diff --git a/packages/react-events/src/dom/__tests__/ContextMenu-test.internal.js b/packages/react-events/src/dom/__tests__/ContextMenu-test.internal.js index bf2fb0f3e3a7a..b25cbf29fcbd1 100644 --- a/packages/react-events/src/dom/__tests__/ContextMenu-test.internal.js +++ b/packages/react-events/src/dom/__tests__/ContextMenu-test.internal.js @@ -9,13 +9,7 @@ 'use strict'; -import { - dispatchLongPressContextMenu, - dispatchRightClickContextMenu, - dispatchModifiedClickContextMenu, - platform, - setPointerEvent, -} from '../test-utils'; +import {createEventTarget, platform, setPointerEvent} from '../testing-library'; let React; let ReactFeatureFlags; @@ -62,7 +56,8 @@ describe.each(table)('ContextMenu responder', hasPointerEvents => { }; ReactDOM.render(, container); - dispatchRightClickContextMenu(ref.current, {preventDefault}); + const target = createEventTarget(ref.current); + target.contextmenu({preventDefault}); expect(preventDefault).toHaveBeenCalledTimes(1); expect(onContextMenu).toHaveBeenCalledTimes(1); expect(onContextMenu).toHaveBeenCalledWith( @@ -80,7 +75,8 @@ describe.each(table)('ContextMenu responder', hasPointerEvents => { }; ReactDOM.render(, container); - dispatchLongPressContextMenu(ref.current, {preventDefault}); + const target = createEventTarget(ref.current); + target.contextmenu({preventDefault}, {pointerType: 'touch'}); expect(preventDefault).toHaveBeenCalledTimes(1); expect(onContextMenu).toHaveBeenCalledTimes(1); expect(onContextMenu).toHaveBeenCalledWith( @@ -100,7 +96,8 @@ describe.each(table)('ContextMenu responder', hasPointerEvents => { }; ReactDOM.render(, container); - dispatchRightClickContextMenu(ref.current); + const target = createEventTarget(ref.current); + target.contextmenu(); expect(onContextMenu).toHaveBeenCalledTimes(0); }); @@ -117,7 +114,8 @@ describe.each(table)('ContextMenu responder', hasPointerEvents => { }; ReactDOM.render(, container); - dispatchRightClickContextMenu(ref.current, {preventDefault}); + const target = createEventTarget(ref.current); + target.contextmenu({preventDefault}); expect(preventDefault).toHaveBeenCalledTimes(0); expect(onContextMenu).toHaveBeenCalledTimes(1); }); @@ -142,7 +140,8 @@ describe.each(table)('ContextMenu responder', hasPointerEvents => { }; ReactDOM.render(, container); - dispatchModifiedClickContextMenu(ref.current); + const target = createEventTarget(ref.current); + target.contextmenu({}, {modified: true}); expect(onContextMenu).toHaveBeenCalledTimes(1); expect(onContextMenu).toHaveBeenCalledWith( expect.objectContaining({pointerType: 'mouse', type: 'contextmenu'}), @@ -169,7 +168,8 @@ describe.each(table)('ContextMenu responder', hasPointerEvents => { }; ReactDOM.render(, container); - dispatchModifiedClickContextMenu(ref.current); + const target = createEventTarget(ref.current); + target.contextmenu({}, {modified: true}); expect(onContextMenu).toHaveBeenCalledTimes(0); }); }); diff --git a/packages/react-events/src/dom/__tests__/Focus-test.internal.js b/packages/react-events/src/dom/__tests__/Focus-test.internal.js index 316bc9f19dcde..12700ce55cc3d 100644 --- a/packages/react-events/src/dom/__tests__/Focus-test.internal.js +++ b/packages/react-events/src/dom/__tests__/Focus-test.internal.js @@ -9,15 +9,7 @@ 'use strict'; -import { - blur, - focus, - keydown, - setPointerEvent, - platform, - dispatchPointerDown, - dispatchPointerUp, -} from '../test-utils'; +import {createEventTarget, setPointerEvent, platform} from '../testing-library'; let React; let ReactFeatureFlags; @@ -73,9 +65,9 @@ describe.each(table)('Focus responder', hasPointerEvents => { }); it('does not call callbacks', () => { - const dispatch = arg => ref.current.dispatchEvent(arg); - dispatch(focus()); - dispatch(blur()); + const target = createEventTarget(ref.current); + target.focus(); + target.blur(); expect(onFocus).not.toBeCalled(); expect(onBlur).not.toBeCalled(); }); @@ -97,9 +89,9 @@ describe.each(table)('Focus responder', hasPointerEvents => { }); it('is called after "blur" event', () => { - const dispatch = arg => ref.current.dispatchEvent(arg); - dispatch(focus()); - dispatch(blur()); + const target = createEventTarget(ref.current); + target.focus(); + target.blur(); expect(onBlur).toHaveBeenCalledTimes(1); }); }); @@ -127,19 +119,21 @@ describe.each(table)('Focus responder', hasPointerEvents => { beforeEach(componentInit); it('is called after "focus" event', () => { - ref.current.dispatchEvent(focus()); + const target = createEventTarget(ref.current); + target.focus(); expect(onFocus).toHaveBeenCalledTimes(1); }); it('is not called if descendants of target receive focus', () => { - innerRef.current.dispatchEvent(focus()); + const target = createEventTarget(innerRef.current); + target.focus(); expect(onFocus).not.toBeCalled(); }); it('is called with the correct pointerType: mouse', () => { - const target = ref.current; - dispatchPointerDown(target, {pointerType: 'mouse'}); - dispatchPointerUp(target, {pointerType: 'mouse'}); + const target = createEventTarget(ref.current); + target.pointerdown(); + target.pointerup(); expect(onFocus).toHaveBeenCalledTimes(1); expect(onFocus).toHaveBeenCalledWith( expect.objectContaining({pointerType: 'mouse'}), @@ -147,9 +141,10 @@ describe.each(table)('Focus responder', hasPointerEvents => { }); it('is called with the correct pointerType: touch', () => { - const target = ref.current; - dispatchPointerDown(target, {pointerType: 'touch'}); - dispatchPointerUp(target, {pointerType: 'touch'}); + const target = createEventTarget(ref.current); + const pointerType = 'touch'; + target.pointerdown({pointerType}); + target.pointerup({pointerType}); expect(onFocus).toHaveBeenCalledTimes(1); expect(onFocus).toHaveBeenCalledWith( expect.objectContaining({pointerType: 'touch'}), @@ -158,9 +153,10 @@ describe.each(table)('Focus responder', hasPointerEvents => { if (hasPointerEvents) { it('is called with the correct pointerType: pen', () => { - const target = ref.current; - dispatchPointerDown(target, {pointerType: 'pen'}); - dispatchPointerUp(target, {pointerType: 'pen'}); + const target = createEventTarget(ref.current); + const pointerType = 'pen'; + target.pointerdown({pointerType}); + target.pointerup({pointerType}); expect(onFocus).toHaveBeenCalledTimes(1); expect(onFocus).toHaveBeenCalledWith( expect.objectContaining({pointerType: 'pen'}), @@ -169,10 +165,9 @@ describe.each(table)('Focus responder', hasPointerEvents => { } it('is called with the correct pointerType using a keyboard', () => { - const target = ref.current; - // Keyboard tab - target.dispatchEvent(keydown({key: 'Tab'})); - target.dispatchEvent(focus()); + const target = createEventTarget(ref.current); + target.keydown({key: 'Tab'}); + target.focus(); expect(onFocus).toHaveBeenCalledTimes(1); expect(onFocus).toHaveBeenCalledWith( expect.objectContaining({pointerType: 'keyboard'}), @@ -184,10 +179,11 @@ describe.each(table)('Focus responder', hasPointerEvents => { jest.resetModules(); initializeModules(); componentInit(); - const target = ref.current; - target.dispatchEvent(keydown({key: 'Tab', altKey: true})); - target.dispatchEvent(focus()); + const target = createEventTarget(ref.current); + target.keydown({key: 'Tab', altKey: true}); + target.focus(); + expect(onFocus).toHaveBeenCalledTimes(1); expect(onFocus).toHaveBeenCalledWith( expect.objectContaining({ @@ -220,20 +216,20 @@ describe.each(table)('Focus responder', hasPointerEvents => { }); it('is called after "blur" and "focus" events', () => { - const target = ref.current; - target.dispatchEvent(focus()); + const target = createEventTarget(ref.current); + target.focus(); expect(onFocusChange).toHaveBeenCalledTimes(1); expect(onFocusChange).toHaveBeenCalledWith(true); - target.dispatchEvent(blur()); + target.blur(); expect(onFocusChange).toHaveBeenCalledTimes(2); expect(onFocusChange).toHaveBeenCalledWith(false); }); it('is not called after "blur" and "focus" events on descendants', () => { - const target = innerRef.current; - target.dispatchEvent(focus()); + const target = createEventTarget(innerRef.current); + target.focus(); expect(onFocusChange).toHaveBeenCalledTimes(0); - target.dispatchEvent(blur()); + target.blur(); expect(onFocusChange).toHaveBeenCalledTimes(0); }); }); @@ -259,48 +255,52 @@ describe.each(table)('Focus responder', hasPointerEvents => { }); it('is called after "focus" and "blur" if keyboard navigation is active', () => { - const target = ref.current; + const target = createEventTarget(ref.current); + const containerTarget = createEventTarget(container); // use keyboard first - container.dispatchEvent(keydown({key: 'Tab'})); - target.dispatchEvent(focus()); + containerTarget.keydown({key: 'Tab'}); + target.focus(); expect(onFocusVisibleChange).toHaveBeenCalledTimes(1); expect(onFocusVisibleChange).toHaveBeenCalledWith(true); - target.dispatchEvent(blur({relatedTarget: container})); + target.blur({relatedTarget: container}); expect(onFocusVisibleChange).toHaveBeenCalledTimes(2); expect(onFocusVisibleChange).toHaveBeenCalledWith(false); }); it('is called if non-keyboard event is dispatched on target previously focused with keyboard', () => { - const target = ref.current; + const target = createEventTarget(ref.current); + const containerTarget = createEventTarget(container); // use keyboard first - container.dispatchEvent(keydown({key: 'Tab'})); - target.dispatchEvent(focus()); + containerTarget.keydown({key: 'Tab'}); + target.focus(); expect(onFocusVisibleChange).toHaveBeenCalledTimes(1); expect(onFocusVisibleChange).toHaveBeenCalledWith(true); // then use pointer on the target, focus should no longer be visible - dispatchPointerDown(target); + target.pointerdown(); expect(onFocusVisibleChange).toHaveBeenCalledTimes(2); expect(onFocusVisibleChange).toHaveBeenCalledWith(false); // onFocusVisibleChange should not be called again - target.dispatchEvent(blur({relatedTarget: container})); + target.blur({relatedTarget: container}); expect(onFocusVisibleChange).toHaveBeenCalledTimes(2); }); it('is not called after "focus" and "blur" events without keyboard', () => { - const target = ref.current; - dispatchPointerDown(target); - dispatchPointerUp(target); - dispatchPointerDown(container); - target.dispatchEvent(blur({relatedTarget: container})); + const target = createEventTarget(ref.current); + const containerTarget = createEventTarget(container); + target.pointerdown(); + target.pointerup(); + containerTarget.pointerdown(); + target.blur({relatedTarget: container}); expect(onFocusVisibleChange).toHaveBeenCalledTimes(0); }); it('is not called after "blur" and "focus" events on descendants', () => { - const target = innerRef.current; - container.dispatchEvent(keydown({key: 'Tab'})); - target.dispatchEvent(focus()); + const innerTarget = createEventTarget(innerRef.current); + const containerTarget = createEventTarget(container); + containerTarget.keydown({key: 'Tab'}); + innerTarget.focus(); expect(onFocusVisibleChange).toHaveBeenCalledTimes(0); - target.dispatchEvent(blur({relatedTarget: container})); + innerTarget.blur({relatedTarget: container}); expect(onFocusVisibleChange).toHaveBeenCalledTimes(0); }); }); @@ -338,10 +338,13 @@ describe.each(table)('Focus responder', hasPointerEvents => { ReactDOM.render(, container); - outerRef.current.dispatchEvent(focus()); - outerRef.current.dispatchEvent(blur()); - innerRef.current.dispatchEvent(focus()); - innerRef.current.dispatchEvent(blur()); + const innerTarget = createEventTarget(innerRef.current); + const outerTarget = createEventTarget(outerRef.current); + + outerTarget.focus(); + outerTarget.blur(); + innerTarget.focus(); + innerTarget.blur(); expect(events).toEqual([ 'outer: onFocus', 'outer: onFocusChange', diff --git a/packages/react-events/src/dom/__tests__/FocusWithin-test.internal.js b/packages/react-events/src/dom/__tests__/FocusWithin-test.internal.js index ff54b6f3838e1..f6f5ffecb752a 100644 --- a/packages/react-events/src/dom/__tests__/FocusWithin-test.internal.js +++ b/packages/react-events/src/dom/__tests__/FocusWithin-test.internal.js @@ -9,14 +9,7 @@ 'use strict'; -import { - blur, - focus, - keydown, - setPointerEvent, - dispatchPointerDown, - dispatchPointerUp, -} from '../test-utils'; +import {createEventTarget, setPointerEvent} from '../testing-library'; let React; let ReactFeatureFlags; @@ -73,9 +66,9 @@ describe.each(table)('FocusWithin responder', hasPointerEvents => { }); it('prevents custom events being dispatched', () => { - const target = ref.current; - target.dispatchEvent(focus()); - target.dispatchEvent(blur()); + const target = createEventTarget(ref.current); + target.focus(); + target.blur(); expect(onFocusWithinChange).not.toBeCalled(); expect(onFocusWithinVisibleChange).not.toBeCalled(); }); @@ -104,42 +97,46 @@ describe.each(table)('FocusWithin responder', hasPointerEvents => { }); it('is called after "blur" and "focus" events on focus target', () => { - const target = ref.current; - target.dispatchEvent(focus()); + const target = createEventTarget(ref.current); + target.focus(); expect(onFocusWithinChange).toHaveBeenCalledTimes(1); expect(onFocusWithinChange).toHaveBeenCalledWith(true); - target.dispatchEvent(blur({relatedTarget: container})); + target.blur({relatedTarget: container}); expect(onFocusWithinChange).toHaveBeenCalledTimes(2); expect(onFocusWithinChange).toHaveBeenCalledWith(false); }); it('is called after "blur" and "focus" events on descendants', () => { - const target = innerRef.current; - target.dispatchEvent(focus()); + const target = createEventTarget(innerRef.current); + target.focus(); expect(onFocusWithinChange).toHaveBeenCalledTimes(1); expect(onFocusWithinChange).toHaveBeenCalledWith(true); - target.dispatchEvent(blur({relatedTarget: container})); + target.blur({relatedTarget: container}); expect(onFocusWithinChange).toHaveBeenCalledTimes(2); expect(onFocusWithinChange).toHaveBeenCalledWith(false); }); it('is only called once when focus moves within and outside the subtree', () => { - const target = ref.current; - const innerTarget1 = innerRef.current; - const innerTarget2 = innerRef2.current; + const node = ref.current; + const innerNode1 = innerRef.current; + const innerNode2 = innerRef.current; + const target = createEventTarget(node); + const innerTarget1 = createEventTarget(innerNode1); + const innerTarget2 = createEventTarget(innerNode2); + // focus shifts into subtree - innerTarget1.dispatchEvent(focus()); + innerTarget1.focus(); expect(onFocusWithinChange).toHaveBeenCalledTimes(1); expect(onFocusWithinChange).toHaveBeenCalledWith(true); // focus moves around subtree - innerTarget1.dispatchEvent(blur({relatedTarget: innerTarget2})); - innerTarget2.dispatchEvent(focus()); - innerTarget2.dispatchEvent(blur({relatedTarget: target})); - target.dispatchEvent(focus()); - target.dispatchEvent(blur({relatedTarget: innerTarget1})); + innerTarget1.blur({relatedTarget: innerNode2}); + innerTarget2.focus(); + innerTarget2.blur({relatedTarget: node}); + target.focus(); + target.blur({relatedTarget: innerNode1}); expect(onFocusWithinChange).toHaveBeenCalledTimes(1); // focus shifts outside subtree - innerTarget1.dispatchEvent(blur({relatedTarget: container})); + innerTarget1.blur({relatedTarget: container}); expect(onFocusWithinChange).toHaveBeenCalledTimes(2); expect(onFocusWithinChange).toHaveBeenCalledWith(false); }); @@ -168,87 +165,96 @@ describe.each(table)('FocusWithin responder', hasPointerEvents => { }); it('is called after "focus" and "blur" on focus target if keyboard was used', () => { - const target = ref.current; + const target = createEventTarget(ref.current); + const containerTarget = createEventTarget(container); // use keyboard first - container.dispatchEvent(keydown({key: 'Tab'})); - target.dispatchEvent(focus()); + containerTarget.keydown({key: 'Tab'}); + target.focus(); expect(onFocusWithinVisibleChange).toHaveBeenCalledTimes(1); expect(onFocusWithinVisibleChange).toHaveBeenCalledWith(true); - target.dispatchEvent(blur({relatedTarget: container})); + target.blur({relatedTarget: container}); expect(onFocusWithinVisibleChange).toHaveBeenCalledTimes(2); expect(onFocusWithinVisibleChange).toHaveBeenCalledWith(false); }); it('is called after "focus" and "blur" on descendants if keyboard was used', () => { - const innerTarget = innerRef.current; + const innerTarget = createEventTarget(innerRef.current); + const containerTarget = createEventTarget(container); // use keyboard first - container.dispatchEvent(keydown({key: 'Tab'})); - innerTarget.dispatchEvent(focus()); + containerTarget.keydown({key: 'Tab'}); + innerTarget.focus(); expect(onFocusWithinVisibleChange).toHaveBeenCalledTimes(1); expect(onFocusWithinVisibleChange).toHaveBeenCalledWith(true); - innerTarget.dispatchEvent(blur({relatedTarget: container})); + innerTarget.blur({relatedTarget: container}); expect(onFocusWithinVisibleChange).toHaveBeenCalledTimes(2); expect(onFocusWithinVisibleChange).toHaveBeenCalledWith(false); }); it('is called if non-keyboard event is dispatched on target previously focused with keyboard', () => { - const target = ref.current; - const innerTarget1 = innerRef.current; - const innerTarget2 = innerRef2.current; + const node = ref.current; + const innerNode1 = innerRef.current; + const innerNode2 = innerRef2.current; + + const target = createEventTarget(node); + const innerTarget1 = createEventTarget(innerNode1); + const innerTarget2 = createEventTarget(innerNode2); // use keyboard first - target.dispatchEvent(focus()); - target.dispatchEvent(keydown({key: 'Tab'})); - target.dispatchEvent(blur({relatedTarget: innerTarget1})); - innerTarget1.dispatchEvent(focus()); + target.focus(); + target.keydown({key: 'Tab'}); + target.blur({relatedTarget: innerNode1}); + innerTarget1.focus(); expect(onFocusWithinVisibleChange).toHaveBeenCalledTimes(1); expect(onFocusWithinVisibleChange).toHaveBeenCalledWith(true); // then use pointer on the next target, focus should no longer be visible - dispatchPointerDown(innerTarget2); - innerTarget1.dispatchEvent(blur({relatedTarget: innerTarget2})); - innerTarget2.dispatchEvent(focus()); + innerTarget2.pointerdown(); + innerTarget1.blur({relatedTarget: innerNode2}); + innerTarget2.focus(); expect(onFocusWithinVisibleChange).toHaveBeenCalledTimes(2); expect(onFocusWithinVisibleChange).toHaveBeenCalledWith(false); // then use keyboard again - innerTarget2.dispatchEvent(keydown({key: 'Tab', shiftKey: true})); - innerTarget2.dispatchEvent(blur({relatedTarget: innerTarget1})); - innerTarget1.dispatchEvent(focus()); + innerTarget2.keydown({key: 'Tab', shiftKey: true}); + innerTarget2.blur({relatedTarget: innerNode1}); + innerTarget1.focus(); expect(onFocusWithinVisibleChange).toHaveBeenCalledTimes(3); expect(onFocusWithinVisibleChange).toHaveBeenCalledWith(true); // then use pointer on the target, focus should no longer be visible - dispatchPointerDown(innerTarget1); + innerTarget1.pointerdown(); expect(onFocusWithinVisibleChange).toHaveBeenCalledTimes(4); expect(onFocusWithinVisibleChange).toHaveBeenCalledWith(false); // onFocusVisibleChange should not be called again - innerTarget1.dispatchEvent(blur({relatedTarget: container})); + innerTarget1.blur({relatedTarget: container}); expect(onFocusWithinVisibleChange).toHaveBeenCalledTimes(4); }); it('is not called after "focus" and "blur" events without keyboard', () => { - const innerTarget = innerRef.current; - dispatchPointerDown(innerTarget); - dispatchPointerUp(innerTarget); - innerTarget.dispatchEvent(blur({relatedTarget: container})); + const innerTarget = createEventTarget(innerRef.current); + innerTarget.pointerdown(); + innerTarget.pointerup(); + innerTarget.blur({relatedTarget: container}); expect(onFocusWithinVisibleChange).toHaveBeenCalledTimes(0); }); it('is only called once when focus moves within and outside the subtree', () => { - const target = ref.current; - const innerTarget1 = innerRef.current; - const innerTarget2 = innerRef2.current; + const node = ref.current; + const innerNode1 = innerRef.current; + const innerNode2 = innerRef2.current; + const target = createEventTarget(node); + const innerTarget1 = createEventTarget(innerNode1); + const innerTarget2 = createEventTarget(innerNode2); // focus shifts into subtree - innerTarget1.dispatchEvent(focus()); + innerTarget1.focus(); expect(onFocusWithinVisibleChange).toHaveBeenCalledTimes(1); expect(onFocusWithinVisibleChange).toHaveBeenCalledWith(true); // focus moves around subtree - innerTarget1.dispatchEvent(blur({relatedTarget: innerTarget2})); - innerTarget2.dispatchEvent(focus()); - innerTarget2.dispatchEvent(blur({relatedTarget: target})); - target.dispatchEvent(focus()); - target.dispatchEvent(blur({relatedTarget: innerTarget1})); + innerTarget1.blur({relatedTarget: innerNode2}); + innerTarget2.focus(); + innerTarget2.blur({relatedTarget: node}); + target.focus(); + target.blur({relatedTarget: innerNode1}); expect(onFocusWithinVisibleChange).toHaveBeenCalledTimes(1); // focus shifts outside subtree - innerTarget1.dispatchEvent(blur({relatedTarget: container})); + innerTarget1.blur({relatedTarget: container}); expect(onFocusWithinVisibleChange).toHaveBeenCalledTimes(2); expect(onFocusWithinVisibleChange).toHaveBeenCalledWith(false); }); diff --git a/packages/react-events/src/dom/__tests__/Hover-test.internal.js b/packages/react-events/src/dom/__tests__/Hover-test.internal.js index 2198e74551156..019a2d2b06789 100644 --- a/packages/react-events/src/dom/__tests__/Hover-test.internal.js +++ b/packages/react-events/src/dom/__tests__/Hover-test.internal.js @@ -9,14 +9,7 @@ 'use strict'; -import { - dispatchPointerCancel, - dispatchPointerHoverEnter, - dispatchPointerHoverExit, - dispatchPointerHoverMove, - dispatchTouchTap, - setPointerEvent, -} from '../test-utils'; +import {createEventTarget, setPointerEvent} from '../testing-library'; let React; let ReactFeatureFlags; @@ -77,9 +70,9 @@ describe.each(table)('Hover responder', hasPointerEvents => { }); it('does not call callbacks', () => { - const target = ref.current; - dispatchPointerHoverEnter(target); - dispatchPointerHoverExit(target); + const target = createEventTarget(ref.current); + target.pointerenter(); + target.pointerexit(); expect(onHoverChange).not.toBeCalled(); expect(onHoverStart).not.toBeCalled(); expect(onHoverMove).not.toBeCalled(); @@ -103,21 +96,23 @@ describe.each(table)('Hover responder', hasPointerEvents => { }); it('is called for mouse pointers', () => { - const target = ref.current; - dispatchPointerHoverEnter(target); + const target = createEventTarget(ref.current); + target.pointerenter(); expect(onHoverStart).toHaveBeenCalledTimes(1); }); it('is not called for touch pointers', () => { - const target = ref.current; - dispatchTouchTap(target); + const target = createEventTarget(ref.current); + target.pointerdown({pointerType: 'touch'}); + target.pointerup({pointerType: 'touch'}); expect(onHoverStart).not.toBeCalled(); }); it('is called if a mouse pointer is used after a touch pointer', () => { - const target = ref.current; - dispatchTouchTap(target); - dispatchPointerHoverEnter(target); + const target = createEventTarget(ref.current); + target.pointerdown({pointerType: 'touch'}); + target.pointerup({pointerType: 'touch'}); + target.pointerenter(); expect(onHoverStart).toHaveBeenCalledTimes(1); }); }); @@ -138,18 +133,19 @@ describe.each(table)('Hover responder', hasPointerEvents => { }); it('is called for mouse pointers', () => { - const target = ref.current; - dispatchPointerHoverEnter(target); + const target = createEventTarget(ref.current); + target.pointerenter(); expect(onHoverChange).toHaveBeenCalledTimes(1); expect(onHoverChange).toHaveBeenCalledWith(true); - dispatchPointerHoverExit(target); + target.pointerexit(); expect(onHoverChange).toHaveBeenCalledTimes(2); expect(onHoverChange).toHaveBeenCalledWith(false); }); it('is not called for touch pointers', () => { - const target = ref.current; - dispatchTouchTap(target); + const target = createEventTarget(ref.current); + target.pointerdown({pointerType: 'touch'}); + target.pointerup({pointerType: 'touch'}); expect(onHoverChange).not.toBeCalled(); }); }); @@ -170,31 +166,32 @@ describe.each(table)('Hover responder', hasPointerEvents => { }); it('is called for mouse pointers', () => { - const target = ref.current; - dispatchPointerHoverEnter(target); - dispatchPointerHoverExit(target); + const target = createEventTarget(ref.current); + target.pointerenter(); + target.pointerexit(); expect(onHoverEnd).toHaveBeenCalledTimes(1); }); if (hasPointerEvents) { it('is called once for cancelled mouse pointers', () => { - const target = ref.current; - dispatchPointerHoverEnter(target); - dispatchPointerCancel(target); + const target = createEventTarget(ref.current); + target.pointerenter(); + target.pointercancel(); expect(onHoverEnd).toHaveBeenCalledTimes(1); // only called once if cancel follows exit onHoverEnd.mockReset(); - dispatchPointerHoverEnter(target); - dispatchPointerHoverExit(target); - dispatchPointerCancel(target); + target.pointerenter(); + target.pointerexit(); + target.pointercancel(); expect(onHoverEnd).toHaveBeenCalledTimes(1); }); } it('is not called for touch pointers', () => { - const target = ref.current; - dispatchTouchTap(target); + const target = createEventTarget(ref.current); + target.pointerdown({pointerType: 'touch'}); + target.pointerup({pointerType: 'touch'}); expect(onHoverEnd).not.toBeCalled(); }); }); @@ -211,10 +208,10 @@ describe.each(table)('Hover responder', hasPointerEvents => { }; ReactDOM.render(, container); - const target = ref.current; - dispatchPointerHoverEnter(target); - dispatchPointerHoverMove(target, {x: 0, y: 0}); - dispatchPointerHoverMove(target, {x: 1, y: 1}); + const target = createEventTarget(ref.current); + target.pointerenter(); + target.pointerhover({x: 0, y: 0}); + target.pointerhover({x: 1, y: 1}); expect(onHoverMove).toHaveBeenCalledTimes(2); expect(onHoverMove).toHaveBeenCalledWith( expect.objectContaining({type: 'hovermove'}), @@ -254,15 +251,17 @@ describe.each(table)('Hover responder', hasPointerEvents => { }; ReactDOM.render(, container); - const innerTarget = innerRef.current; - const outerTarget = outerRef.current; + const innerNode = innerRef.current; + const outerNode = outerRef.current; + const innerTarget = createEventTarget(innerNode); + const outerTarget = createEventTarget(outerNode); - dispatchPointerHoverEnter(outerTarget, {relatedTarget: container}); - dispatchPointerHoverExit(outerTarget, {relatedTarget: innerTarget}); - dispatchPointerHoverEnter(innerTarget, {relatedTarget: outerTarget}); - dispatchPointerHoverExit(innerTarget, {relatedTarget: outerTarget}); - dispatchPointerHoverEnter(outerTarget, {relatedTarget: innerTarget}); - dispatchPointerHoverExit(outerTarget, {relatedTarget: container}); + outerTarget.pointerenter({relatedTarget: container}); + outerTarget.pointerexit({relatedTarget: innerNode}); + innerTarget.pointerenter({relatedTarget: outerNode}); + innerTarget.pointerexit({relatedTarget: outerNode}); + outerTarget.pointerenter({relatedTarget: innerNode}); + outerTarget.pointerexit({relatedTarget: container}); expect(events).toEqual([ 'outer: onHoverStart', @@ -315,12 +314,13 @@ describe.each(table)('Hover responder', hasPointerEvents => { }; ReactDOM.render(, container); - const target = ref.current; + const node = ref.current; + const target = createEventTarget(node); - dispatchPointerHoverEnter(target, {x: 10, y: 10}); - dispatchPointerHoverMove(target, {x: 10, y: 10}); - dispatchPointerHoverMove(target, {x: 20, y: 20}); - dispatchPointerHoverExit(target, {x: 20, y: 20}); + target.pointerenter({x: 10, y: 10}); + target.pointerhover({x: 10, y: 10}); + target.pointerhover({x: 20, y: 20}); + target.pointerexit({x: 20, y: 20}); expect(eventLog).toEqual([ { @@ -330,7 +330,7 @@ describe.each(table)('Hover responder', hasPointerEvents => { pageY: 10, clientX: 10, clientY: 10, - target, + target: node, timeStamp: timeStamps[0], type: 'hoverstart', pointerType: 'mouse', @@ -342,7 +342,7 @@ describe.each(table)('Hover responder', hasPointerEvents => { pageY: 10, clientX: 10, clientY: 10, - target, + target: node, timeStamp: timeStamps[1], type: 'hovermove', pointerType: 'mouse', @@ -354,7 +354,7 @@ describe.each(table)('Hover responder', hasPointerEvents => { pageY: 20, clientX: 20, clientY: 20, - target, + target: node, timeStamp: timeStamps[2], type: 'hovermove', pointerType: 'mouse', @@ -366,7 +366,7 @@ describe.each(table)('Hover responder', hasPointerEvents => { pageY: 20, clientX: 20, clientY: 20, - target, + target: node, timeStamp: timeStamps[3], type: 'hoverend', pointerType: 'mouse', diff --git a/packages/react-events/src/dom/__tests__/Keyboard-test.internal.js b/packages/react-events/src/dom/__tests__/Keyboard-test.internal.js index f3a655f79039b..613d1e6cace3f 100644 --- a/packages/react-events/src/dom/__tests__/Keyboard-test.internal.js +++ b/packages/react-events/src/dom/__tests__/Keyboard-test.internal.js @@ -14,7 +14,7 @@ let ReactFeatureFlags; let ReactDOM; let useKeyboardResponder; -import {keydown, keyup} from '../test-utils'; +import {createEventTarget} from '../testing-library'; function initializeModules(hasPointerEvents) { jest.resetModules(); @@ -59,9 +59,9 @@ describe('Keyboard event responder', () => { }); it('prevents custom events being dispatched', () => { - const target = ref.current; - target.dispatchEvent(keydown()); - target.dispatchEvent(keyup()); + const target = createEventTarget(ref.current); + target.keydown(); + target.keyup(); expect(onKeyDown).not.toBeCalled(); expect(onKeyUp).not.toBeCalled(); }); @@ -83,7 +83,8 @@ describe('Keyboard event responder', () => { }); it('is called after "keydown" event', () => { - ref.current.dispatchEvent(keydown({key: 'Q'})); + const target = createEventTarget(ref.current); + target.keydown({key: 'Q'}); expect(onKeyDown).toHaveBeenCalledTimes(1); expect(onKeyDown).toHaveBeenCalledWith( expect.objectContaining({key: 'Q', type: 'keydown'}), @@ -109,9 +110,9 @@ describe('Keyboard event responder', () => { }); it('is called after "keydown" event', () => { - const target = ref.current; - target.dispatchEvent(keydown({key: 'Q'})); - target.dispatchEvent(keyup({key: 'Q'})); + const target = createEventTarget(ref.current); + target.keydown({key: 'Q'}); + target.keyup({key: 'Q'}); expect(onKeyDown).toHaveBeenCalledTimes(1); expect(onKeyDown).toHaveBeenCalledWith( expect.objectContaining({key: 'Q', type: 'keydown'}), diff --git a/packages/react-events/src/dom/__tests__/Press-test.internal.js b/packages/react-events/src/dom/__tests__/Press-test.internal.js index a6a42a5d011a3..10ddd2af356ca 100644 --- a/packages/react-events/src/dom/__tests__/Press-test.internal.js +++ b/packages/react-events/src/dom/__tests__/Press-test.internal.js @@ -9,27 +9,13 @@ 'use strict'; -import { - click, - dispatchPointerCancel, - dispatchPointerDown, - dispatchPointerUp, - dispatchPointerHoverMove, - dispatchPointerMove, - keydown, - keyup, - scroll, - pointerdown, - pointerup, - setPointerEvent, -} from '../test-utils'; +import {createEventTarget, setPointerEvent} from '../testing-library'; let React; let ReactFeatureFlags; let ReactDOM; let PressResponder; let usePressResponder; -let Scheduler; function initializeModules(hasPointerEvents) { jest.resetModules(); @@ -40,7 +26,6 @@ function initializeModules(hasPointerEvents) { ReactDOM = require('react-dom'); PressResponder = require('react-events/press').PressResponder; usePressResponder = require('react-events/press').usePressResponder; - Scheduler = require('scheduler'); } function removePressMoveStrings(eventString) { @@ -92,9 +77,9 @@ describe.each(environmentTable)('Press responder', hasPointerEvents => { }); it('does not call callbacks', () => { - const target = ref.current; - dispatchPointerDown(target); - dispatchPointerUp(target); + const target = createEventTarget(ref.current); + target.pointerdown(); + target.pointerup(); expect(onPressStart).not.toBeCalled(); expect(onPress).not.toBeCalled(); expect(onPressEnd).not.toBeCalled(); @@ -120,7 +105,8 @@ describe.each(environmentTable)('Press responder', hasPointerEvents => { it.each(pointerTypesTable)( 'is called after pointer down: %s', pointerType => { - dispatchPointerDown(ref.current, {pointerType}); + const target = createEventTarget(ref.current); + target.pointerdown({pointerType}); expect(onPressStart).toHaveBeenCalledTimes(1); expect(onPressStart).toHaveBeenCalledWith( expect.objectContaining({pointerType, type: 'pressstart'}), @@ -129,7 +115,8 @@ describe.each(environmentTable)('Press responder', hasPointerEvents => { ); it('is called after auxillary-button pointer down', () => { - dispatchPointerDown(ref.current, {button: 1, pointerType: 'mouse'}); + const target = createEventTarget(ref.current); + target.pointerdown({button: 1, pointerType: 'mouse'}); expect(onPressStart).toHaveBeenCalledTimes(1); expect(onPressStart).toHaveBeenCalledWith( expect.objectContaining({ @@ -140,39 +127,31 @@ describe.each(environmentTable)('Press responder', hasPointerEvents => { ); }); - it('is not called after "pointermove" following auxillary-button press', () => { - const target = ref.current; - target.getBoundingClientRect = () => ({ - top: 0, - left: 0, - bottom: 100, - right: 100, - }); - dispatchPointerDown(target, { - button: 1, - pointerType: 'mouse', - }); - dispatchPointerUp(target, { - button: 1, - pointerType: 'mouse', - }); - dispatchPointerHoverMove(target, {x: 110, y: 110}); - dispatchPointerHoverMove(target, {x: 50, y: 50}); + it('is not called after pointer move following auxillary-button press', () => { + const node = ref.current; + const target = createEventTarget(node); + target.setBoundingClientRect({x: 0, y: 0, width: 100, height: 100}); + target.pointerdown({button: 1, pointerType: 'mouse'}); + target.pointerup({button: 1, pointerType: 'mouse'}); + target.pointerhover({x: 110, y: 110}); + target.pointerhover({x: 50, y: 50}); expect(onPressStart).toHaveBeenCalledTimes(1); }); it('ignores any events not caused by primary/auxillary-click or touch/pen contact', () => { - const target = ref.current; - dispatchPointerDown(target, {button: 2}); - dispatchPointerDown(target, {button: 5}); + const target = createEventTarget(ref.current); + target.pointerdown({button: 2}); + target.pointerup({button: 2}); + target.pointerdown({button: 5}); + target.pointerup({button: 5}); expect(onPressStart).toHaveBeenCalledTimes(0); }); it('is called once after "keydown" events for Enter', () => { - const target = ref.current; - target.dispatchEvent(keydown({key: 'Enter'})); - target.dispatchEvent(keydown({key: 'Enter'})); - target.dispatchEvent(keydown({key: 'Enter'})); + const target = createEventTarget(ref.current); + target.keydown({key: 'Enter'}); + target.keydown({key: 'Enter'}); + target.keydown({key: 'Enter'}); expect(onPressStart).toHaveBeenCalledTimes(1); expect(onPressStart).toHaveBeenCalledWith( expect.objectContaining({pointerType: 'keyboard', type: 'pressstart'}), @@ -180,11 +159,11 @@ describe.each(environmentTable)('Press responder', hasPointerEvents => { }); it('is called once after "keydown" events for Spacebar', () => { - const target = ref.current; + const target = createEventTarget(ref.current); const preventDefault = jest.fn(); - target.dispatchEvent(keydown({key: ' ', preventDefault})); + target.keydown({key: ' ', preventDefault}); expect(preventDefault).toBeCalled(); - target.dispatchEvent(keydown({key: ' ', preventDefault})); + target.keydown({key: ' ', preventDefault}); expect(onPressStart).toHaveBeenCalledTimes(1); expect(onPressStart).toHaveBeenCalledWith( expect.objectContaining({ @@ -195,7 +174,8 @@ describe.each(environmentTable)('Press responder', hasPointerEvents => { }); it('is not called after "keydown" for other keys', () => { - ref.current.dispatchEvent(keydown({key: 'a'})); + const target = createEventTarget(ref.current); + target.keydown({key: 'a'}); expect(onPressStart).not.toBeCalled(); }); }); @@ -219,9 +199,9 @@ describe.each(environmentTable)('Press responder', hasPointerEvents => { it.each(pointerTypesTable)( 'is called after pointer up: %s', pointerType => { - const target = ref.current; - dispatchPointerDown(target, {pointerType}); - dispatchPointerUp(target, {pointerType}); + const target = createEventTarget(ref.current); + target.pointerdown({pointerType}); + target.pointerup({pointerType}); expect(onPressEnd).toHaveBeenCalledTimes(1); expect(onPressEnd).toHaveBeenCalledWith( expect.objectContaining({pointerType, type: 'pressend'}), @@ -230,9 +210,9 @@ describe.each(environmentTable)('Press responder', hasPointerEvents => { ); it('is called after auxillary-button pointer up', () => { - const target = ref.current; - dispatchPointerDown(target, {button: 1, pointerType: 'mouse'}); - dispatchPointerUp(target, {button: 1, pointerType: 'mouse'}); + const target = createEventTarget(ref.current); + target.pointerdown({button: 1, pointerType: 'mouse'}); + target.pointerup({button: 1, pointerType: 'mouse'}); expect(onPressEnd).toHaveBeenCalledTimes(1); expect(onPressEnd).toHaveBeenCalledWith( expect.objectContaining({ @@ -244,11 +224,11 @@ describe.each(environmentTable)('Press responder', hasPointerEvents => { }); it('is called after "keyup" event for Enter', () => { - const target = ref.current; - target.dispatchEvent(keydown({key: 'Enter'})); + const target = createEventTarget(ref.current); + target.keydown({key: 'Enter'}); // click occurs before keyup - target.dispatchEvent(click()); - target.dispatchEvent(keyup({key: 'Enter'})); + target.click(); + target.keyup({key: 'Enter'}); expect(onPressEnd).toHaveBeenCalledTimes(1); expect(onPressEnd).toHaveBeenCalledWith( expect.objectContaining({pointerType: 'keyboard', type: 'pressend'}), @@ -256,9 +236,9 @@ describe.each(environmentTable)('Press responder', hasPointerEvents => { }); it('is called after "keyup" event for Spacebar', () => { - const target = ref.current; - target.dispatchEvent(keydown({key: ' '})); - target.dispatchEvent(keyup({key: ' '})); + const target = createEventTarget(ref.current); + target.keydown({key: ' '}); + target.keyup({key: ' '}); expect(onPressEnd).toHaveBeenCalledTimes(1); expect(onPressEnd).toHaveBeenCalledWith( expect.objectContaining({pointerType: 'keyboard', type: 'pressend'}), @@ -266,24 +246,22 @@ describe.each(environmentTable)('Press responder', hasPointerEvents => { }); it('is not called after "keyup" event for other keys', () => { - const target = ref.current; - target.dispatchEvent(keydown({key: 'Enter'})); - target.dispatchEvent(keyup({key: 'a'})); + const target = createEventTarget(ref.current); + target.keydown({key: 'Enter'}); + target.keyup({key: 'a'}); expect(onPressEnd).not.toBeCalled(); }); it('is called with keyboard modifiers', () => { - const target = ref.current; - target.dispatchEvent(keydown({key: 'Enter'})); - target.dispatchEvent( - keyup({ - key: 'Enter', - metaKey: true, - ctrlKey: true, - altKey: true, - shiftKey: true, - }), - ); + const target = createEventTarget(ref.current); + target.keydown({key: 'Enter'}); + target.keyup({ + key: 'Enter', + metaKey: true, + ctrlKey: true, + altKey: true, + shiftKey: true, + }); expect(onPressEnd).toHaveBeenCalledWith( expect.objectContaining({ pointerType: 'keyboard', @@ -316,21 +294,22 @@ describe.each(environmentTable)('Press responder', hasPointerEvents => { it.each(pointerTypesTable)( 'is called after pointer down and up: %s', pointerType => { - const target = ref.current; - dispatchPointerDown(target, {pointerType}); + const target = createEventTarget(ref.current); + target.pointerdown({pointerType}); expect(onPressChange).toHaveBeenCalledTimes(1); expect(onPressChange).toHaveBeenCalledWith(true); - dispatchPointerUp(target, {pointerType}); + target.pointerup({pointerType}); expect(onPressChange).toHaveBeenCalledTimes(2); expect(onPressChange).toHaveBeenCalledWith(false); }, ); it('is called after valid "keydown" and "keyup" events', () => { - ref.current.dispatchEvent(keydown({key: 'Enter'})); + const target = createEventTarget(ref.current); + target.keydown({key: 'Enter'}); expect(onPressChange).toHaveBeenCalledTimes(1); expect(onPressChange).toHaveBeenCalledWith(true); - ref.current.dispatchEvent(keyup({key: 'Enter'})); + target.keyup({key: 'Enter'}); expect(onPressChange).toHaveBeenCalledTimes(2); expect(onPressChange).toHaveBeenCalledWith(false); }); @@ -361,9 +340,9 @@ describe.each(environmentTable)('Press responder', hasPointerEvents => { it.each(pointerTypesTable)( 'is called after pointer up: %s', pointerType => { - const target = ref.current; - dispatchPointerDown(target, {pointerType}); - dispatchPointerUp(target, {pointerType, x: 10, y: 10}); + const target = createEventTarget(ref.current); + target.pointerdown({pointerType}); + target.pointerup({pointerType, x: 10, y: 10}); expect(onPress).toHaveBeenCalledTimes(1); expect(onPress).toHaveBeenCalledWith( expect.objectContaining({pointerType, type: 'press'}), @@ -372,16 +351,16 @@ describe.each(environmentTable)('Press responder', hasPointerEvents => { ); it('is not called after auxillary-button press', () => { - const target = ref.current; - dispatchPointerDown(target, {button: 1, pointerType: 'mouse'}); - dispatchPointerUp(target, {button: 1, pointerType: 'mouse'}); + const target = createEventTarget(ref.current); + target.pointerdown({button: 1, pointerType: 'mouse'}); + target.pointerup({button: 1, pointerType: 'mouse'}); expect(onPress).not.toHaveBeenCalled(); }); it('is called after valid "keyup" event', () => { - const target = ref.current; - target.dispatchEvent(keydown({key: 'Enter'})); - target.dispatchEvent(keyup({key: 'Enter'})); + const target = createEventTarget(ref.current); + target.keydown({key: 'Enter'}); + target.keyup({key: 'Enter'}); expect(onPress).toHaveBeenCalledTimes(1); expect(onPress).toHaveBeenCalledWith( expect.objectContaining({pointerType: 'keyboard', type: 'press'}), @@ -391,27 +370,22 @@ describe.each(environmentTable)('Press responder', hasPointerEvents => { it('is not called after invalid "keyup" event', () => { const inputRef = React.createRef(); const Component = () => { - const listener = usePressResponder({ - onPress, - }); + const listener = usePressResponder({onPress}); return ; }; ReactDOM.render(, container); - const target = inputRef.current; - target.dispatchEvent(keydown({key: 'Enter'})); - target.dispatchEvent(keyup({key: 'Enter'})); - target.dispatchEvent(keydown({key: ' '})); - target.dispatchEvent(keyup({key: ' '})); + const target = createEventTarget(inputRef.current); + target.keydown({key: 'Enter'}); + target.keyup({key: 'Enter'}); + target.keydown({key: ' '}); + target.keyup({key: ' '}); expect(onPress).not.toBeCalled(); }); it('is called with modifier keys', () => { - const target = ref.current; - dispatchPointerDown(target, {metaKey: true, pointerType: 'mouse'}); - dispatchPointerUp(target, { - metaKey: true, - pointerType: 'mouse', - }); + const target = createEventTarget(ref.current); + target.pointerdown({metaKey: true, pointerType: 'mouse'}); + target.pointerup({metaKey: true, pointerType: 'mouse'}); expect(onPress).toHaveBeenCalledWith( expect.objectContaining({ pointerType: 'mouse', @@ -426,9 +400,7 @@ describe.each(environmentTable)('Press responder', hasPointerEvents => { const divRef = React.createRef(); const Component = () => { - const listener = usePressResponder({ - onPress, - }); + const listener = usePressResponder({onPress}); return (