Add platform test for pointercancel events caused by touch scrolling

Summary:
Changelog: [Internal] - Add platform test for pointercancel events caused by touch scrolling

This diff adds a new ported Web Platform Test which [verifies that pointercancel events are properly emitted once a touch causes scrolling](https://github.com/web-platform-tests/wpt/blob/master/pointerevents/pointerevent_pointercancel_touch.html).

Reviewed By: lunaleaps

Differential Revision: D43855277

fbshipit-source-id: 94a106058ba2c5e5fe4c1980519ceceddb2bb389
This commit is contained in:
Vincent Riemer 2023-03-16 12:23:25 -07:00 коммит произвёл Facebook GitHub Bot
Родитель 93c1fbd2d8
Коммит b2fda3eca7
2 изменённых файлов: 191 добавлений и 0 удалений

Просмотреть файл

@ -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<PointerEvent | null>(null);
const pointerCancelEventRef = useRef<PointerEvent | null>(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 (
<ScrollView style={styles.scrollContainer}>
<View
onPointerDown={handlePointerDown}
onPointerCancel={handlePointerCancel}
onPointerOut={handlePointerOut}
onPointerLeave={handlePointerLeave}
style={styles.target}
/>
</ScrollView>
);
}
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 (
<RNTesterPlatformTest
component={PointerEventPointerCancelTouchTestCase}
description="This test checks if pointercancel event triggers."
title="Pointer Events pointercancel Tests"
instructions={[
'Start touch over the black rectangle.',
'Then move your finger to scroll the page.',
]}
/>
);
}

Просмотреть файл

@ -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 <PointerEventLayoutChangeShouldFirePointerOver />;
},
},
{
name: 'pointerevent_pointercancel_touch',
description: '',
title: 'WPT 11: Pointer Events pointercancel Tests',
render(): React.Node {
return <PointerEventPointerCancelTouch />;
},
},
{
name: 'relative',
description: 'Children laid out using relative positioning',