mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Add PointerOver/PointerOut handling test
Summary: Changelog: [RNTester][Internal] - Add PointerOver/PointerOut handling test This diff adds another platform test based on WPT testcase for mouseover/mouseout events but instead applied to pointerover/pointerout events recently implemented for RN. Reviewed By: lunaleaps Differential Revision: D40359286 fbshipit-source-id: 672f413f56faca55b9d838150fb66de66d78d6f2
This commit is contained in:
committed by
Facebook GitHub Bot
parent
048194849b
commit
55fca7fd38
+228
@@ -0,0 +1,228 @@
|
||||
/**
|
||||
* 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 type {HostComponent} from 'react-native/Libraries/Renderer/shims/ReactNativeTypes';
|
||||
|
||||
import RNTesterPlatformTest from '../PlatformTest/RNTesterPlatformTest';
|
||||
import * as React from 'react';
|
||||
import {useRef, useCallback} from 'react';
|
||||
import {StyleSheet, View} from 'react-native';
|
||||
|
||||
function getNativeTagFromHostElement(
|
||||
elem: ?React.ElementRef<HostComponent<mixed>> | number,
|
||||
): ?number {
|
||||
if (typeof elem === 'number') {
|
||||
return elem;
|
||||
}
|
||||
if (elem != null) {
|
||||
// $FlowExpectedError - accessing non-public property
|
||||
return elem._nativeTag;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
outer: {
|
||||
padding: 40,
|
||||
height: 60,
|
||||
backgroundColor: 'blue',
|
||||
},
|
||||
inner: {
|
||||
padding: 40,
|
||||
height: 60,
|
||||
backgroundColor: 'green',
|
||||
},
|
||||
released: {
|
||||
padding: 40,
|
||||
height: 60,
|
||||
backgroundColor: 'yellow',
|
||||
},
|
||||
});
|
||||
|
||||
// adapted from https://github.com/web-platform-tests/wpt/blob/master/uievents/order-of-events/mouse-events/mouseover-out.html
|
||||
function PointerEventPointerOverOutTestCase(
|
||||
props: PlatformTestComponentBaseProps,
|
||||
) {
|
||||
const {harness} = props;
|
||||
|
||||
const t = harness.useAsyncTest('PointerOver/Out events');
|
||||
|
||||
const innerNativeTagRef = useRef(-1);
|
||||
const outerNativeTagRef = useRef(-1);
|
||||
|
||||
const handleInnerRefCallback = useCallback(elem => {
|
||||
const nativeTag = getNativeTagFromHostElement(elem);
|
||||
innerNativeTagRef.current = nativeTag != null ? nativeTag : -1;
|
||||
}, []);
|
||||
const handleOuterRefCallback = useCallback(elem => {
|
||||
const nativeTag = getNativeTagFromHostElement(elem);
|
||||
outerNativeTagRef.current = nativeTag != null ? nativeTag : -1;
|
||||
}, []);
|
||||
|
||||
const innerOverRef = useRef(0);
|
||||
const innerOutRef = useRef(0);
|
||||
|
||||
const outerOwnOverRef = useRef(0);
|
||||
const outerOwnOutRef = useRef(0);
|
||||
const outerOverRef = useRef(0);
|
||||
const outerOutRef = useRef(0);
|
||||
|
||||
const innerPointerOverHandler = useCallback(
|
||||
(e: PointerEvent) => {
|
||||
t.step(({assert_equals, assert_true}) => {
|
||||
assert_equals(
|
||||
innerOverRef.current,
|
||||
innerOutRef.current,
|
||||
'pointerover is recieved before pointerout',
|
||||
);
|
||||
switch (innerOverRef.current) {
|
||||
case 0: {
|
||||
assert_equals(
|
||||
outerOwnOverRef.current,
|
||||
1,
|
||||
'should have triggered a pointerover in the outer before',
|
||||
);
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
assert_equals(
|
||||
outerOwnOverRef.current,
|
||||
1,
|
||||
'should have not triggered a pointerover in the outer before',
|
||||
);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
assert_true(false, 'should not get more than two mouseovers');
|
||||
}
|
||||
}
|
||||
});
|
||||
innerOverRef.current++;
|
||||
},
|
||||
[t],
|
||||
);
|
||||
const innerPointerOutHandler = useCallback(
|
||||
(e: PointerEvent) => {
|
||||
t.step(({assert_equals, assert_true}) => {
|
||||
assert_equals(
|
||||
innerOverRef.current,
|
||||
innerOutRef.current + 1,
|
||||
'pointerout is received after pointerover',
|
||||
);
|
||||
switch (innerOutRef.current) {
|
||||
case 0: {
|
||||
assert_equals(
|
||||
outerOwnOutRef.current,
|
||||
1,
|
||||
'pointerout should have been received in the parent when hovering over this element',
|
||||
);
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
assert_true(false, 'should not get more than two pointerouts');
|
||||
}
|
||||
}
|
||||
});
|
||||
innerOutRef.current++;
|
||||
},
|
||||
[t],
|
||||
);
|
||||
|
||||
const outerPointerOverHandler = useCallback(
|
||||
(e: PointerEvent) => {
|
||||
const eventElemTag = getNativeTagFromHostElement(e.target);
|
||||
t.step(({assert_equals}) => {
|
||||
if (eventElemTag === outerNativeTagRef.current) {
|
||||
assert_equals(
|
||||
outerOwnOverRef.current,
|
||||
outerOwnOutRef.current,
|
||||
'outer: pointerover is recieved before pointerout',
|
||||
);
|
||||
outerOwnOverRef.current++;
|
||||
} else {
|
||||
assert_equals(
|
||||
outerOverRef.current - outerOwnOverRef.current,
|
||||
innerOverRef.current - 1,
|
||||
'pointerover: should only receive this via bubbling',
|
||||
);
|
||||
}
|
||||
});
|
||||
outerOverRef.current++;
|
||||
},
|
||||
[t],
|
||||
);
|
||||
const outerPointerOutHandler = useCallback(
|
||||
(e: PointerEvent) => {
|
||||
const eventElemTag = getNativeTagFromHostElement(e.target);
|
||||
t.step(({assert_equals}) => {
|
||||
if (eventElemTag === outerNativeTagRef.current) {
|
||||
assert_equals(
|
||||
outerOwnOverRef.current,
|
||||
outerOwnOutRef.current + 1,
|
||||
'outer: pointerout is recieved after pointerover',
|
||||
);
|
||||
if (outerOwnOutRef.current === 1) {
|
||||
assert_equals(innerOutRef.current, 2, 'inner should be done now');
|
||||
t.done();
|
||||
}
|
||||
outerOwnOutRef.current++;
|
||||
} else {
|
||||
assert_equals(
|
||||
outerOutRef.current - outerOwnOutRef.current,
|
||||
innerOutRef.current - 1,
|
||||
'pointerout: should only recieve this via bubbling',
|
||||
);
|
||||
}
|
||||
});
|
||||
outerOutRef.current++;
|
||||
},
|
||||
[t],
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<View
|
||||
ref={handleOuterRefCallback}
|
||||
onPointerOver={outerPointerOverHandler}
|
||||
onPointerOut={outerPointerOutHandler}
|
||||
style={styles.outer}>
|
||||
<View
|
||||
ref={handleInnerRefCallback}
|
||||
onPointerOver={innerPointerOverHandler}
|
||||
onPointerOut={innerPointerOutHandler}
|
||||
style={styles.inner}
|
||||
/>
|
||||
</View>
|
||||
<View style={styles.released} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
type Props = $ReadOnly<{}>;
|
||||
export default function PointerEventPointerOverOut(
|
||||
props: Props,
|
||||
): React.MixedElement {
|
||||
return (
|
||||
<RNTesterPlatformTest
|
||||
component={PointerEventPointerOverOutTestCase}
|
||||
description=""
|
||||
instructions={[
|
||||
'Move your mouse over the blue view, later over the green one, later over the yellow one.',
|
||||
'Move the mouse from the yellow view to the green one, later to the blue one, and later over this paragraph.',
|
||||
]}
|
||||
title="PointerOver/PointerOut handling"
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -21,6 +21,7 @@ import PointerEventPointerMoveOnChordedMouseButton from './W3CPointerEventPlatfo
|
||||
import PointerEventPointerMoveAcross from './W3CPointerEventPlatformTests/PointerEventPointerMoveAcross';
|
||||
import PointerEventPointerMoveEventOrder from './W3CPointerEventPlatformTests/PointerEventPointerMoveEventOrder';
|
||||
import PointerEventPointerMoveBetween from './W3CPointerEventPlatformTests/PointerEventPointerMoveBetween';
|
||||
import PointerEventPointerOverOut from './W3CPointerEventPlatformTests/PointerEventPointerOverOut';
|
||||
import EventfulView from './W3CPointerEventsEventfulView';
|
||||
import ManyPointersPropertiesExample from './Compatibility/ManyPointersPropertiesExample';
|
||||
|
||||
@@ -214,6 +215,14 @@ export default {
|
||||
return <PointerEventPointerMoveBetween />;
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'pointerevent_pointerover_out',
|
||||
description: '',
|
||||
title: 'WPT: PointerOver/PointerOut handling',
|
||||
render(): React.Node {
|
||||
return <PointerEventPointerOverOut />;
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'relative',
|
||||
description: 'Children laid out using relative positioning',
|
||||
|
||||
Reference in New Issue
Block a user