/** * 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. * * @flow strict-local * @format */ import type {PlatformTestComponentBaseProps} from '../PlatformTest/RNTesterPlatformTestTypes'; import type {PointerEvent} from 'react-native'; import RNTesterPlatformTest from '../PlatformTest/RNTesterPlatformTest'; import {check_PointerEvent} from './PointerEventSupport'; import * as React from 'react'; import {useCallback, useRef} from 'react'; import {ScrollView, StyleSheet, View} 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, height: 200, }, }); type Props = $ReadOnly<{}>; export default function PoitnerEventPointerCancelTouch( props: Props, ): React.MixedElement { return ( ); }