From f5bd272a33a54b4b516fea17d6a1f5e1419c8e83 Mon Sep 17 00:00:00 2001 From: Vincent Riemer Date: Thu, 20 Oct 2022 11:47:47 -0700 Subject: [PATCH] Add pointer event test ensuring that pointerover events are fired when an element appears under the cursor Summary: Changelog: [RNTester][Internal] - Add pointer event test ensuring that pointerover events are fired when an element appears under the cursor This diff adds a port of an existing web platform test that checks if pointerover & pointerenter events are fired for elements that are mounted underneath the cursor. Reviewed By: lunaleaps Differential Revision: D40449499 fbshipit-source-id: 393f4325f7a9d9025fe9d0aab38642b1e3ab2612 --- ...rEventLayoutChangeShouldFirePointerOver.js | 123 ++++++++++++++++++ .../Experimental/W3CPointerEventsExample.js | 9 ++ 2 files changed, 132 insertions(+) create mode 100644 packages/rn-tester/js/examples/Experimental/W3CPointerEventPlatformTests/PointerEventLayoutChangeShouldFirePointerOver.js diff --git a/packages/rn-tester/js/examples/Experimental/W3CPointerEventPlatformTests/PointerEventLayoutChangeShouldFirePointerOver.js b/packages/rn-tester/js/examples/Experimental/W3CPointerEventPlatformTests/PointerEventLayoutChangeShouldFirePointerOver.js new file mode 100644 index 00000000000000..d3ebdcdbf6d8f1 --- /dev/null +++ b/packages/rn-tester/js/examples/Experimental/W3CPointerEventPlatformTests/PointerEventLayoutChangeShouldFirePointerOver.js @@ -0,0 +1,123 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @format + * @flow + */ + +import type {PlatformTestComponentBaseProps} from '../PlatformTest/RNTesterPlatformTestTypes'; +import type {PointerEvent} from 'react-native/Libraries/Types/CoreEventTypes'; + +import RNTesterPlatformTest from '../PlatformTest/RNTesterPlatformTest'; +import * as React from 'react'; +import {useRef, useCallback, useState, useMemo} from 'react'; +import {StyleSheet, View} from 'react-native'; + +const styles = StyleSheet.create({ + spacer: { + width: 100, + height: 100, + }, + red: { + backgroundColor: 'red', + position: 'absolute', + left: 0, + top: 0, + width: 100, + height: 100, + zIndex: 0, + }, + blue: { + backgroundColor: 'blue', + position: 'absolute', + left: 0, + top: 0, + width: 100, + height: 100, + zIndex: 1, + }, +}); + +// adapted from https://github.com/web-platform-tests/wpt/blob/master/uievents/mouse/layout_change_should_fire_mouseover.html +function PointerEventLayoutShouldFirePointerOverTestCase( + props: PlatformTestComponentBaseProps, +) { + const {harness} = props; + + const testMouseOver = harness.useAsyncTest( + 'Tests that the pointerover event is fired and the element has a hover effect when the element underneath the mouse cursor is changed.', + ); + + const [showBlue, setShowBlue] = useState(false); + + const eventListRef = useRef([]); + + const checkEventSequence = useCallback(() => { + testMouseOver.step(({assert_equals}) => { + const result = eventListRef.current.join(','); + assert_equals( + result, + 'pointerover,pointerenter', + 'The only events recorded should be pointerover and pointerenter (in that order)', + ); + }); + testMouseOver.done(); + }, [testMouseOver]); + + const redClickHandler = useCallback(() => { + setShowBlue(true); + setTimeout(() => { + checkEventSequence(); + }, 2500); + }, [checkEventSequence]); + + const createBlueHoverEventHandler = useCallback( + (eventType: string) => (event: PointerEvent) => { + eventListRef.current.push(eventType); + testMouseOver.step(({assert_equals}) => { + if (eventType === 'pointerenter') { + checkEventSequence(); + } + }); + }, + [checkEventSequence, testMouseOver], + ); + + const blueEventHandlers = useMemo( + () => ({ + onPointerOver: createBlueHoverEventHandler('pointerover'), + onPointerMove: createBlueHoverEventHandler('pointermove'), + onPointerEnter: createBlueHoverEventHandler('pointerenter'), + onPointerLeave: createBlueHoverEventHandler('pointerleave'), + }), + [createBlueHoverEventHandler], + ); + + return ( + <> + + + {showBlue && } + + ); +} + +type Props = $ReadOnly<{}>; +export default function PointerEventLayoutShouldFirePointerOver( + props: Props, +): React.MixedElement { + return ( + + ); +} diff --git a/packages/rn-tester/js/examples/Experimental/W3CPointerEventsExample.js b/packages/rn-tester/js/examples/Experimental/W3CPointerEventsExample.js index ac1684eb398040..7d326130c322d1 100644 --- a/packages/rn-tester/js/examples/Experimental/W3CPointerEventsExample.js +++ b/packages/rn-tester/js/examples/Experimental/W3CPointerEventsExample.js @@ -22,6 +22,7 @@ import PointerEventPointerMoveAcross from './W3CPointerEventPlatformTests/Pointe import PointerEventPointerMoveEventOrder from './W3CPointerEventPlatformTests/PointerEventPointerMoveEventOrder'; import PointerEventPointerMoveBetween from './W3CPointerEventPlatformTests/PointerEventPointerMoveBetween'; import PointerEventPointerOverOut from './W3CPointerEventPlatformTests/PointerEventPointerOverOut'; +import PointerEventLayoutChangeShouldFirePointerOver from './W3CPointerEventPlatformTests/PointerEventLayoutChangeShouldFirePointerOver'; import EventfulView from './W3CPointerEventsEventfulView'; import ManyPointersPropertiesExample from './Compatibility/ManyPointersPropertiesExample'; @@ -223,6 +224,14 @@ export default { return ; }, }, + { + name: 'pointerevent_layout_change_should_fire_pointerover', + description: '', + title: 'WPT: Layout change should fire pointerover', + render(): React.Node { + return ; + }, + }, { name: 'relative', description: 'Children laid out using relative positioning',