Skip to content

Commit

Permalink
Add pointer event test ensuring that pointerover events are fired whe…
Browse files Browse the repository at this point in the history
…n 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
  • Loading branch information
vincentriemer authored and facebook-github-bot committed Oct 20, 2022
1 parent 1546666 commit f5bd272
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -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 (
<>
<View style={styles.spacer} />
<View onPointerUp={redClickHandler} style={styles.red} />
{showBlue && <View {...blueEventHandlers} style={styles.blue} />}
</>
);
}

type Props = $ReadOnly<{}>;
export default function PointerEventLayoutShouldFirePointerOver(
props: Props,
): React.MixedElement {
return (
<RNTesterPlatformTest
component={PointerEventLayoutShouldFirePointerOverTestCase}
description="Tests that the pointerover event is fired and the element has a hover effect when the element underneath the mouse cursor is changed."
instructions={[
'Put your mouse over the red rectangle',
'Click the primary mouse button',
]}
title="Pointerover/enter is sent on layout change"
/>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -223,6 +224,14 @@ export default {
return <PointerEventPointerOverOut />;
},
},
{
name: 'pointerevent_layout_change_should_fire_pointerover',
description: '',
title: 'WPT: Layout change should fire pointerover',
render(): React.Node {
return <PointerEventLayoutChangeShouldFirePointerOver />;
},
},
{
name: 'relative',
description: 'Children laid out using relative positioning',
Expand Down

0 comments on commit f5bd272

Please sign in to comment.