1- import { View , Text , Platform } from 'react-native' ;
1+ import { View , Text , Platform , TextInput } from 'react-native' ;
22import * as React from 'react' ;
33import {
44 cleanup ,
@@ -40,6 +40,22 @@ const defaultRender: InputOTPRenderFn = (props: RenderProps) => (
4040 </ View >
4141) ;
4242
43+ /**
44+ * Simulate typing on the input like a user would do by typing one character at a time.
45+ *
46+ * @param input - The input element to simulate typing on.
47+ * @param text - The text to simulate typing.
48+ */
49+ const simulateTyping = ( input : TextInput , text : string ) => {
50+ let accumulated = '' ;
51+
52+ for ( const char of text ) {
53+ accumulated += char ;
54+ fireEvent . changeText ( input , accumulated ) ;
55+ fireEvent ( input , 'keyPress' , { nativeEvent : { key : char } } ) ;
56+ }
57+ } ;
58+
4359// Mock Platform.OS
4460jest . mock ( 'react-native/Libraries/Utilities/Platform' , ( ) => ( {
4561 OS : 'ios' ,
@@ -63,7 +79,6 @@ describe('OTPInput', () => {
6379
6480 const input = await screen . findByTestId ( 'otp-input' ) ;
6581 expect ( input ) . toBeTruthy ( ) ;
66- expect ( input . props . maxLength ) . toBe ( 6 ) ;
6782 expect ( input . props . inputMode ) . toBe ( 'numeric' ) ;
6883 expect ( input . props . autoComplete ) . toBe ( 'one-time-code' ) ;
6984 } ) ;
@@ -128,7 +143,6 @@ describe('OTPInput', () => {
128143 ) ;
129144
130145 const input = await screen . findByTestId ( 'otp-input' ) ;
131- expect ( input . props . maxLength ) . toBe ( 4 ) ;
132146 expect ( input . props . placeholder ) . toBe ( placeholder ) ;
133147 expect ( input . props . inputMode ) . toBe ( 'text' ) ;
134148 } ) ;
@@ -162,7 +176,7 @@ describe('OTPInput', () => {
162176 ) ;
163177
164178 const input = await screen . findByTestId ( 'otp-input' ) ;
165- fireEvent . changeText ( input , '123456' ) ;
179+ simulateTyping ( input , '123456' ) ;
166180
167181 expect ( onChangeMock ) . toHaveBeenCalledWith ( '123456' ) ;
168182 expect ( onCompleteMock ) . toHaveBeenCalledWith ( '123456' ) ;
@@ -179,11 +193,11 @@ describe('OTPInput', () => {
179193 ) ;
180194
181195 const input = await screen . findByTestId ( 'otp-input' ) ;
182- fireEvent . changeText ( input , '12345' ) ;
196+ simulateTyping ( input , '12345' ) ;
183197 expect ( onChangeMock ) . toHaveBeenCalledWith ( '12345' ) ;
184198 expect ( onCompleteMock ) . not . toHaveBeenCalled ( ) ;
185199
186- fireEvent . changeText ( input , '123456' ) ;
200+ simulateTyping ( input , '123456' ) ;
187201 expect ( onChangeMock ) . toHaveBeenCalledWith ( '123456' ) ;
188202 expect ( onCompleteMock ) . toHaveBeenCalledWith ( '123456' ) ;
189203 } ) ;
@@ -198,7 +212,7 @@ describe('OTPInput', () => {
198212 ) ;
199213
200214 const input = await screen . findByTestId ( 'otp-input' ) ;
201- fireEvent . changeText ( input , '123' ) ;
215+ simulateTyping ( input , '123' ) ;
202216
203217 const container = await screen . findByTestId ( 'otp-input-container' ) ;
204218 fireEvent . press ( container ) ;
@@ -240,12 +254,13 @@ describe('OTPInput', () => {
240254 const input = await screen . findByTestId ( 'otp-input' ) ;
241255
242256 // Test invalid input
243- fireEvent . changeText ( input , 'abc' ) ;
244- expect ( onChangeMock ) . not . toHaveBeenCalled ( ) ;
257+ simulateTyping ( input , 'abc' ) ;
258+ expect ( onChangeMock ) . toHaveBeenCalledTimes ( 2 ) ;
259+ expect ( onChangeMock ) . toHaveBeenCalledWith ( '' ) ;
245260 expect ( input . props . value ) . toBe ( '' ) ;
246261
247262 // Test valid input
248- fireEvent . changeText ( input , '123' ) ;
263+ simulateTyping ( input , '123' ) ;
249264 expect ( onChangeMock ) . toHaveBeenCalledWith ( '123' ) ;
250265 expect ( input . props . value ) . toBe ( '123' ) ;
251266 } ) ;
@@ -260,7 +275,7 @@ describe('OTPInput', () => {
260275 ) ;
261276
262277 const input = await screen . findByTestId ( 'otp-input' ) ;
263- fireEvent . changeText ( input , '123456' ) ;
278+ simulateTyping ( input , '123456' ) ;
264279
265280 expect ( input . props . value . length ) . toBeLessThanOrEqual ( 4 ) ;
266281 } ) ;
@@ -280,11 +295,11 @@ describe('OTPInput', () => {
280295
281296 const input = await screen . findByTestId ( 'otp-input' ) ;
282297 await act ( async ( ) => {
283- ref . current ?. setValue ( '123 ' ) ;
298+ ref . current ?. setValue ( '1 ' ) ;
284299 } ) ;
285300
286- expect ( input . props . value ) . toBe ( '123 ' ) ;
287- expect ( onChangeMock ) . toHaveBeenCalledWith ( '123 ' ) ;
301+ expect ( input . props . value ) . toBe ( '1 ' ) ;
302+ expect ( onChangeMock ) . toHaveBeenCalledWith ( '1 ' ) ;
288303 } ) ;
289304
290305 test ( 'focus method focuses the input through ref' , async ( ) => {
@@ -359,9 +374,9 @@ describe('OTPInput', () => {
359374
360375 // First set a value
361376 await act ( async ( ) => {
362- ref . current ?. setValue ( '123 ' ) ;
377+ ref . current ?. setValue ( '1 ' ) ;
363378 } ) ;
364- expect ( input . props . value ) . toBe ( '123 ' ) ;
379+ expect ( input . props . value ) . toBe ( '1 ' ) ;
365380
366381 // Then clear it
367382 await act ( async ( ) => {
0 commit comments