diff --git a/src/__tests__/fireEvent.test.js b/src/__tests__/fireEvent.test.js index fa0b9c255..21b1258ab 100644 --- a/src/__tests__/fireEvent.test.js +++ b/src/__tests__/fireEvent.test.js @@ -168,28 +168,28 @@ test('event with multiple handler parameters', () => { test('should not fire on disabled TouchableOpacity', () => { const handlePress = jest.fn(); const screen = render( - - Trigger - + + + Trigger + + ); - expect(() => fireEvent.press(screen.getByText('Trigger'))).toThrow( - 'No handler function found for event: "press"' - ); + fireEvent.press(screen.getByText('Trigger')); expect(handlePress).not.toHaveBeenCalled(); }); test('should not fire on disabled Pressable', () => { const handlePress = jest.fn(); const screen = render( - - Trigger - + + + Trigger + + ); - expect(() => fireEvent.press(screen.getByText('Trigger'))).toThrow( - 'No handler function found for event: "press"' - ); + fireEvent.press(screen.getByText('Trigger')); expect(handlePress).not.toHaveBeenCalled(); }); diff --git a/src/fireEvent.js b/src/fireEvent.js index c367679f5..350a950e0 100644 --- a/src/fireEvent.js +++ b/src/fireEvent.js @@ -6,30 +6,50 @@ const findEventHandler = ( element: ReactTestInstance, eventName: string, callsite?: any, - nearestHostDescendent?: ReactTestInstance + nearestHostDescendent?: ReactTestInstance, + hasDescendandHandler?: boolean ) => { + const handler = getEventHandler(element, eventName); + const hasHandler = handler != null || hasDescendandHandler; + const isHostComponent = typeof element.type === 'string'; const hostElement = isHostComponent ? element : nearestHostDescendent; const isEventEnabled = hostElement?.props.onStartShouldSetResponder?.() !== false; + if (handler && isEventEnabled) return handler; - const eventHandlerName = toEventHandlerName(eventName); + // Do not bubble event to the root element + if (element.parent === null || element.parent.parent === null) { + if (hasHandler) { + return null; + } else { + throw new ErrorWithStack( + `No handler function found for event: "${eventName}"`, + callsite || invokeEvent + ); + } + } + + return findEventHandler( + element.parent, + eventName, + callsite, + hostElement, + hasHandler + ); +}; - if (typeof element.props[eventHandlerName] === 'function' && isEventEnabled) { +const getEventHandler = (element: ReactTestInstance, eventName: string) => { + const eventHandlerName = toEventHandlerName(eventName); + if (typeof element.props[eventHandlerName] === 'function') { return element.props[eventHandlerName]; - } else if (typeof element.props[eventName] === 'function' && isEventEnabled) { - return element.props[eventName]; } - // Do not bubble event to the root element - if (element.parent === null || element.parent.parent === null) { - throw new ErrorWithStack( - `No handler function found for event: "${eventName}"`, - callsite || invokeEvent - ); + if (typeof element.props[eventName] === 'function') { + return element.props[eventName]; } - return findEventHandler(element.parent, eventName, callsite, hostElement); + return undefined; }; const invokeEvent = (