diff --git a/src/__tests__/fireEvent.test.js b/src/__tests__/fireEvent.test.js index 21b1258ab..74d97aa9e 100644 --- a/src/__tests__/fireEvent.test.js +++ b/src/__tests__/fireEvent.test.js @@ -193,6 +193,46 @@ test('should not fire on disabled Pressable', () => { expect(handlePress).not.toHaveBeenCalled(); }); +test('should not fire on non-editable TextInput', () => { + const placeholder = 'Test placeholder'; + const onChangeTextMock = jest.fn(); + const NEW_TEXT = 'New text'; + + const { getByPlaceholderText } = render( + + + + ); + + fireEvent.changeText(getByPlaceholderText(placeholder), NEW_TEXT); + expect(onChangeTextMock).not.toHaveBeenCalled(); +}); + +test('should not fire on non-editable TextInput with nested Text', () => { + const placeholder = 'Test placeholder'; + const onChangeTextMock = jest.fn(); + const NEW_TEXT = 'New text'; + + const { getByPlaceholderText } = render( + + + Test text + + + ); + + fireEvent.changeText(getByPlaceholderText(placeholder), NEW_TEXT); + expect(onChangeTextMock).not.toHaveBeenCalled(); +}); + test('should pass event up on disabled TouchableOpacity', () => { const handleInnerPress = jest.fn(); const handleOuterPress = jest.fn(); diff --git a/src/fireEvent.js b/src/fireEvent.js index 350a950e0..08b9a65ec 100644 --- a/src/fireEvent.js +++ b/src/fireEvent.js @@ -2,6 +2,12 @@ import act from './act'; import { ErrorWithStack } from './helpers/errors'; +const isTextInputComponent = (element: ReactTestInstance) => { + // eslint-disable-next-line import/no-extraneous-dependencies + const { TextInput } = require('react-native'); + return element.type === TextInput; +}; + const findEventHandler = ( element: ReactTestInstance, eventName: string, @@ -14,8 +20,11 @@ const findEventHandler = ( const isHostComponent = typeof element.type === 'string'; const hostElement = isHostComponent ? element : nearestHostDescendent; - const isEventEnabled = - hostElement?.props.onStartShouldSetResponder?.() !== false; + + const isEventEnabled = isTextInputComponent(element) + ? element.props.editable !== false + : hostElement?.props.onStartShouldSetResponder?.() !== false; + if (handler && isEventEnabled) return handler; // Do not bubble event to the root element