diff --git a/packages/rn-tester/js/examples/Experimental/W3CPointerEventPlatformTests/PointerEventPointerCancelTouch.js b/packages/rn-tester/js/examples/Experimental/W3CPointerEventPlatformTests/PointerEventPointerCancelTouch.js new file mode 100644 index 00000000000..09dc77c1cf1 --- /dev/null +++ b/packages/rn-tester/js/examples/Experimental/W3CPointerEventPlatformTests/PointerEventPointerCancelTouch.js @@ -0,0 +1,182 @@ +/** + * 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 {check_PointerEvent} from './PointerEventSupport'; +import * as React from 'react'; +import {useCallback, useRef} from 'react'; +import {StyleSheet, View, ScrollView} from 'react-native'; + +// adapted from https://github.com/web-platform-tests/wpt/blob/master/pointerevents/pointerevent_pointercancel_touch.html +function PointerEventPointerCancelTouchTestCase( + props: PlatformTestComponentBaseProps, +) { + const {harness} = props; + + const testPointerEvent = harness.useAsyncTest('pointercancel event recieved'); + + const pointerDownEventRef = useRef(null); + const pointerCancelEventRef = useRef(null); + + const handlePointerDown = useCallback((event: PointerEvent) => { + event.persist(); + pointerDownEventRef.current = event; + }, []); + + const handlePointerCancel = useCallback( + (event: PointerEvent) => { + event.persist(); + pointerCancelEventRef.current = event; + + testPointerEvent.step(({assert_equals, assert_not_equals}) => { + const pointerDownEvent = pointerDownEventRef.current; + assert_not_equals(pointerDownEvent, null, 'pointerdown was recieved: '); + if (pointerDownEvent != null) { + assert_equals( + event.nativeEvent.pointerId, + pointerDownEvent.nativeEvent.pointerId, + 'pointerId should be the same for pointerdown and pointercancel', + ); + assert_equals( + event.nativeEvent.pointerType, + pointerDownEvent.nativeEvent.pointerType, + 'pointerType should be the same for pointerdown and pointercancel', + ); + assert_equals( + event.nativeEvent.isPrimary, + pointerDownEvent.nativeEvent.isPrimary, + 'isPrimary should be the same for pointerdown and pointercancel', + ); + } + }); + + check_PointerEvent(harness, event, 'pointerCancel', {}); + + testPointerEvent.step(({assert_equals}) => { + assert_equals(event.nativeEvent.x, 0, 'pointercancel.x must be zero'); + assert_equals(event.nativeEvent.y, 0, 'pointercancel.y must be zero'); + assert_equals( + event.nativeEvent.clientX, + 0, + 'pointercancel.clientX must be zero', + ); + assert_equals( + event.nativeEvent.clientY, + 0, + 'pointercancel.clientY must be zero', + ); + }); + }, + [harness, testPointerEvent], + ); + + const handlePointerOut = useCallback( + (event: PointerEvent) => { + testPointerEvent.step(({assert_equals, assert_not_equals}) => { + const pointerCancelEvent = pointerCancelEventRef.current; + assert_not_equals( + pointerCancelEvent, + null, + 'pointercancel was recieved: ', + ); + if (pointerCancelEvent != null) { + assert_equals( + event.nativeEvent.pointerId, + pointerCancelEvent.nativeEvent.pointerId, + 'pointerId should be the same for pointerout and pointercancel', + ); + assert_equals( + event.nativeEvent.pointerType, + pointerCancelEvent.nativeEvent.pointerType, + 'pointerType should be the same for pointerout and pointercancel', + ); + assert_equals( + event.nativeEvent.isPrimary, + pointerCancelEvent.nativeEvent.isPrimary, + 'isPrimary should be the same for pointerout and pointercancel', + ); + } + }); + }, + [testPointerEvent], + ); + + const handlePointerLeave = useCallback( + (event: PointerEvent) => { + testPointerEvent.step(({assert_equals, assert_not_equals}) => { + const pointerCancelEvent = pointerCancelEventRef.current; + assert_not_equals( + pointerCancelEvent, + null, + 'pointercancel was recieved: ', + ); + if (pointerCancelEvent != null) { + assert_equals( + event.nativeEvent.pointerId, + pointerCancelEvent.nativeEvent.pointerId, + 'pointerId should be the same for pointerleave and pointercancel', + ); + assert_equals( + event.nativeEvent.pointerType, + pointerCancelEvent.nativeEvent.pointerType, + 'pointerType should be the same for pointerleave and pointercancel', + ); + assert_equals( + event.nativeEvent.isPrimary, + pointerCancelEvent.nativeEvent.isPrimary, + 'isPrimary should be the same for pointerleave and pointercancel', + ); + } + }); + testPointerEvent.done(); + }, + [testPointerEvent], + ); + + return ( + + + + ); +} + +const styles = StyleSheet.create({ + scrollContainer: {width: '100%', height: '100%'}, + target: { + backgroundColor: 'black', + padding: 32, + }, +}); + +type Props = $ReadOnly<{}>; +export default function PoitnerEventPointerCancelTouch( + 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 fada307fa6f..725379f1320 100644 --- a/packages/rn-tester/js/examples/Experimental/W3CPointerEventsExample.js +++ b/packages/rn-tester/js/examples/Experimental/W3CPointerEventsExample.js @@ -23,6 +23,7 @@ import PointerEventPointerMoveEventOrder from './W3CPointerEventPlatformTests/Po import PointerEventPointerMoveBetween from './W3CPointerEventPlatformTests/PointerEventPointerMoveBetween'; import PointerEventPointerOverOut from './W3CPointerEventPlatformTests/PointerEventPointerOverOut'; import PointerEventLayoutChangeShouldFirePointerOver from './W3CPointerEventPlatformTests/PointerEventLayoutChangeShouldFirePointerOver'; +import PointerEventPointerCancelTouch from './W3CPointerEventPlatformTests/PointerEventPointerCancelTouch'; import EventfulView from './W3CPointerEventsEventfulView'; import ManyPointersPropertiesExample from './Compatibility/ManyPointersPropertiesExample'; @@ -232,6 +233,14 @@ export default { return ; }, }, + { + name: 'pointerevent_pointercancel_touch', + description: '', + title: 'WPT 11: Pointer Events pointercancel Tests', + render(): React.Node { + return ; + }, + }, { name: 'relative', description: 'Children laid out using relative positioning',