From 31b8e3e209c93b76cea77614567e785e8438cb3b Mon Sep 17 00:00:00 2001 From: Maciej Jastrzebski Date: Thu, 27 Apr 2023 22:05:07 +0200 Subject: [PATCH 1/2] chore: add test --- src/__tests__/fireEvent.test.tsx | 89 +++++++++++++++----------------- 1 file changed, 41 insertions(+), 48 deletions(-) diff --git a/src/__tests__/fireEvent.test.tsx b/src/__tests__/fireEvent.test.tsx index ce6266dfe..6e9fb8f01 100644 --- a/src/__tests__/fireEvent.test.tsx +++ b/src/__tests__/fireEvent.test.tsx @@ -254,73 +254,68 @@ test('should not fire on non-editable TextInput with nested Text', () => { expect(onChangeTextMock).not.toHaveBeenCalled(); }); -test('should not fire on none pointerEvents View', () => { - const handlePress = jest.fn(); - +test('should not fire inside View with pointerEvents="none"', () => { + const onPress = jest.fn(); const screen = render( - + Trigger ); fireEvent.press(screen.getByText('Trigger')); - expect(handlePress).not.toHaveBeenCalled(); + expect(onPress).not.toHaveBeenCalled(); }); -test('should not fire on box-only pointerEvents View', () => { - const handlePress = jest.fn(); - +test('should not fire inside View with pointerEvents="box-only"', () => { + const onPress = jest.fn(); const screen = render( - + Trigger ); fireEvent.press(screen.getByText('Trigger')); - expect(handlePress).not.toHaveBeenCalled(); + expect(onPress).not.toHaveBeenCalled(); }); -test('should fire on box-none pointerEvents View', () => { - const handlePress = jest.fn(); - +test('should fire inside View with pointerEvents="box-none"', () => { + const onPress = jest.fn(); const screen = render( - + Trigger ); fireEvent.press(screen.getByText('Trigger')); - expect(handlePress).toHaveBeenCalled(); + expect(onPress).toHaveBeenCalled(); }); -test('should fire on auto pointerEvents View', () => { - const handlePress = jest.fn(); - +test('should fire inside View with pointerEvents="auto"', () => { + const onPress = jest.fn(); const screen = render( - + Trigger ); fireEvent.press(screen.getByText('Trigger')); - expect(handlePress).toHaveBeenCalled(); + expect(onPress).toHaveBeenCalled(); }); -test('should not fire on box-only pointerEvents View with nested elements', () => { - const handlePress = jest.fn(); - +test('should not fire deeply inside View with pointerEvents="box-only"', () => { + const onPress = jest.fn(); const screen = render( - + Trigger @@ -328,41 +323,39 @@ test('should not fire on box-only pointerEvents View with nested elements', () = ); fireEvent.press(screen.getByText('Trigger')); - expect(handlePress).not.toHaveBeenCalled(); + expect(onPress).not.toHaveBeenCalled(); }); -test('should fire non-pointer events on box-none pointerEvents View', () => { - const handleTouchStart = jest.fn(); - +test('should fire non-pointer events inside View with pointerEvents="box-none"', () => { + const onTouchStart = jest.fn(); const screen = render( - - {}}> - Trigger - - + ); - fireEvent(screen.getByTestId('touch-start-view'), 'touchStart'); - expect(handleTouchStart).toHaveBeenCalled(); + fireEvent(screen.getByTestId('view'), 'touchStart'); + expect(onTouchStart).toHaveBeenCalled(); }); -test('should fire non-touch events on box-none pointerEvents View', () => { - const handleLayout = jest.fn(); +test('should fire non-touch events inside View with pointerEvents="box-none"', () => { + const onLayout = jest.fn(); + const screen = render( + + ); + + fireEvent(screen.getByTestId('view'), 'layout'); + expect(onLayout).toHaveBeenCalled(); +}); +// This test if pointerEvents="box-only" on composite `Pressable` is blocking +// the 'press' event on host View rendered by pressable. +test('should fire on Pressable with pointerEvents="box-only', () => { + const onPress = jest.fn(); const screen = render( - - {}}> - Trigger - - + ); - fireEvent(screen.getByTestId('layout-view'), 'layout'); - expect(handleLayout).toHaveBeenCalled(); + fireEvent.press(screen.getByTestId('pressable')); + expect(onPress).toHaveBeenCalled(); }); test('should pass event up on disabled TouchableOpacity', () => { From 01049dab5914c231058fc63215bde16561b5bd96 Mon Sep 17 00:00:00 2001 From: Maciej Jastrzebski Date: Thu, 27 Apr 2023 22:19:03 +0200 Subject: [PATCH 2/2] fix: check pointer events only on host elements --- src/fireEvent.ts | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/fireEvent.ts b/src/fireEvent.ts index e60398bc1..eb5ce8c28 100644 --- a/src/fireEvent.ts +++ b/src/fireEvent.ts @@ -1,7 +1,7 @@ import { ReactTestInstance } from 'react-test-renderer'; import { TextInput } from 'react-native'; import act from './act'; -import { isHostElement } from './helpers/component-tree'; +import { getHostParent, isHostElement } from './helpers/component-tree'; import { filterNodeByType } from './helpers/filterNodeByType'; import { getHostComponentNames } from './helpers/host-component-names'; @@ -29,20 +29,24 @@ const isTouchResponder = (element?: ReactTestInstance) => { }; const isPointerEventEnabled = ( - element?: ReactTestInstance, + element: ReactTestInstance, isParent?: boolean ): boolean => { - const parentCondition = isParent - ? element?.props.pointerEvents === 'box-only' - : element?.props.pointerEvents === 'box-none'; + const pointerEvents = element.props.pointerEvents; + if (pointerEvents === 'none') { + return false; + } - if (element?.props.pointerEvents === 'none' || parentCondition) { + if (isParent ? pointerEvents === 'box-only' : pointerEvents === 'box-none') { return false; } - if (!element?.parent) return true; + const parent = getHostParent(element); + if (!parent) { + return true; + } - return isPointerEventEnabled(element.parent, true); + return isPointerEventEnabled(parent, true); }; const isTouchEvent = (eventName?: string) => { @@ -50,7 +54,7 @@ const isTouchEvent = (eventName?: string) => { }; const isEventEnabled = ( - element?: ReactTestInstance, + element: ReactTestInstance, touchResponder?: ReactTestInstance, eventName?: string ) => {