mirror of
https://github.com/callstack/react-native-testing-library.git
synced 2026-09-18 23:09:04 +08:00
fix: Respect maxLength prop in type() function (#1641)
* fix: Respect maxLength prop in type() function This commit modifies the `type()` function to respect the `maxLength` prop of the input element. If the current text length exceeds the `maxLength` value, typing events will not be emitted. This ensures that the input value does not exceed the specified maximum length. 1. Create an input element with a `maxLength` prop. 2. Use the `type()` function to input text that exceeds the `maxLength` value. 3. Verify that the input value does not exceed the specified maximum length. 4. Check that no typing events are emitted once the `maxLength` is reached. Additionally, see that `yarn test` passes with an additional test added to `src/user-event/type/__tests__/type.test.tsx` * refactor: code review changes * refactor: tweaks * refactor: final tweaks * refactor: final tweaks 2 * chore: tweak codecov --------- Co-authored-by: Maciej Jastrzębski <mdjastrzebski@gmail.com>
This commit is contained in:
+5
-1
@@ -2,8 +2,12 @@ coverage:
|
||||
precision: 2
|
||||
round: down
|
||||
range: 70...100
|
||||
status:
|
||||
project:
|
||||
default:
|
||||
threshold: 0.5% # Allowable coverage drop in percentage points
|
||||
|
||||
comment:
|
||||
behavior: default
|
||||
require_changes: false
|
||||
require_base: no
|
||||
require_base: false
|
||||
|
||||
@@ -19,6 +19,10 @@ export function createEventLogger() {
|
||||
return { events, logEvent };
|
||||
}
|
||||
|
||||
export function getEventsName(events: EventEntry[]) {
|
||||
export function getEventsNames(events: EventEntry[]) {
|
||||
return events.map((event) => event.name);
|
||||
}
|
||||
|
||||
export function lastEventPayload(events: EventEntry[], name: string) {
|
||||
return events.filter((e) => e.name === name).pop()?.payload;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as React from 'react';
|
||||
import { TextInput, TextInputProps, View } from 'react-native';
|
||||
import { createEventLogger } from '../../test-utils';
|
||||
import { createEventLogger, getEventsNames } from '../../test-utils';
|
||||
import { render, userEvent, screen } from '../..';
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -47,8 +47,7 @@ describe('clear()', () => {
|
||||
const user = userEvent.setup();
|
||||
await user.clear(textInput);
|
||||
|
||||
const eventNames = events.map((e) => e.name);
|
||||
expect(eventNames).toEqual([
|
||||
expect(getEventsNames(events)).toEqual([
|
||||
'focus',
|
||||
'selectionChange',
|
||||
'keyPress',
|
||||
@@ -71,8 +70,7 @@ describe('clear()', () => {
|
||||
const user = userEvent.setup();
|
||||
await user.clear(textInput);
|
||||
|
||||
const eventNames = events.map((e) => e.name);
|
||||
expect(eventNames).toEqual([
|
||||
expect(getEventsNames(events)).toEqual([
|
||||
'focus',
|
||||
'selectionChange',
|
||||
'keyPress',
|
||||
@@ -92,8 +90,7 @@ describe('clear()', () => {
|
||||
const user = userEvent.setup();
|
||||
await user.clear(textInput);
|
||||
|
||||
const eventNames = events.map((e) => e.name);
|
||||
expect(eventNames).toEqual([
|
||||
expect(getEventsNames(events)).toEqual([
|
||||
'focus',
|
||||
'selectionChange',
|
||||
'keyPress',
|
||||
@@ -140,8 +137,7 @@ describe('clear()', () => {
|
||||
const user = userEvent.setup();
|
||||
await user.clear(textInput);
|
||||
|
||||
const eventNames = events.map((e) => e.name);
|
||||
expect(eventNames).toEqual([
|
||||
expect(getEventsNames(events)).toEqual([
|
||||
'focus',
|
||||
'selectionChange',
|
||||
'keyPress',
|
||||
@@ -170,8 +166,7 @@ describe('clear()', () => {
|
||||
const user = userEvent.setup();
|
||||
await user.clear(screen.getByTestId('input'));
|
||||
|
||||
const eventNames = events.map((e) => e.name);
|
||||
expect(eventNames).toEqual(['changeText', 'endEditing']);
|
||||
expect(getEventsNames(events)).toEqual(['changeText', 'endEditing']);
|
||||
|
||||
expect(events).toMatchSnapshot();
|
||||
});
|
||||
|
||||
@@ -31,9 +31,14 @@ export async function clear(this: UserEventInstance, element: ReactTestInstance)
|
||||
};
|
||||
dispatchEvent(element, 'selectionChange', EventBuilder.TextInput.selectionChange(selectionRange));
|
||||
|
||||
// 3. Press backspace
|
||||
// 3. Press backspace with selected text
|
||||
const finalText = '';
|
||||
await emitTypingEvents(this.config, element, 'Backspace', finalText, previousText);
|
||||
await emitTypingEvents(element, {
|
||||
config: this.config,
|
||||
key: 'Backspace',
|
||||
text: finalText,
|
||||
previousText,
|
||||
});
|
||||
|
||||
// 4. Exit element
|
||||
await wait(this.config);
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
TouchableOpacity,
|
||||
View,
|
||||
} from 'react-native';
|
||||
import { createEventLogger, getEventsName } from '../../../test-utils';
|
||||
import { createEventLogger, getEventsNames } from '../../../test-utils';
|
||||
import { render, screen } from '../../..';
|
||||
import { userEvent } from '../..';
|
||||
import * as WarnAboutRealTimers from '../../utils/warn-about-real-timers';
|
||||
@@ -34,7 +34,7 @@ describe('userEvent.press with real timers', () => {
|
||||
);
|
||||
await user.press(screen.getByTestId('pressable'));
|
||||
|
||||
expect(getEventsName(events)).toEqual(['pressIn', 'press', 'pressOut']);
|
||||
expect(getEventsNames(events)).toEqual(['pressIn', 'press', 'pressOut']);
|
||||
});
|
||||
|
||||
test('does not trigger event when pressable is disabled', async () => {
|
||||
@@ -130,7 +130,7 @@ describe('userEvent.press with real timers', () => {
|
||||
);
|
||||
await user.press(screen.getByTestId('pressable'));
|
||||
|
||||
expect(getEventsName(events)).toEqual(['pressIn', 'press', 'pressOut']);
|
||||
expect(getEventsNames(events)).toEqual(['pressIn', 'press', 'pressOut']);
|
||||
});
|
||||
|
||||
test('crawls up in the tree to find an element that responds to touch events', async () => {
|
||||
@@ -200,7 +200,7 @@ describe('userEvent.press with real timers', () => {
|
||||
);
|
||||
await userEvent.press(screen.getByText('press me'));
|
||||
|
||||
expect(getEventsName(events)).toEqual(['pressIn', 'press', 'pressOut']);
|
||||
expect(getEventsNames(events)).toEqual(['pressIn', 'press', 'pressOut']);
|
||||
});
|
||||
|
||||
test('does not trigger on disabled Text', async () => {
|
||||
@@ -254,7 +254,7 @@ describe('userEvent.press with real timers', () => {
|
||||
);
|
||||
await userEvent.press(screen.getByPlaceholderText('email'));
|
||||
|
||||
expect(getEventsName(events)).toEqual(['pressIn', 'pressOut']);
|
||||
expect(getEventsNames(events)).toEqual(['pressIn', 'pressOut']);
|
||||
});
|
||||
|
||||
test('does not call onPressIn and onPressOut on non editable TetInput', async () => {
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
View,
|
||||
Button,
|
||||
} from 'react-native';
|
||||
import { createEventLogger, getEventsName } from '../../../test-utils';
|
||||
import { createEventLogger, getEventsNames } from '../../../test-utils';
|
||||
import { render, screen } from '../../..';
|
||||
import { userEvent } from '../..';
|
||||
|
||||
@@ -129,7 +129,7 @@ describe('userEvent.press with fake timers', () => {
|
||||
);
|
||||
await user.press(screen.getByTestId('pressable'));
|
||||
|
||||
expect(getEventsName(events)).toEqual(['pressIn', 'press', 'pressOut']);
|
||||
expect(getEventsNames(events)).toEqual(['pressIn', 'press', 'pressOut']);
|
||||
});
|
||||
|
||||
test('crawls up in the tree to find an element that responds to touch events', async () => {
|
||||
@@ -199,7 +199,7 @@ describe('userEvent.press with fake timers', () => {
|
||||
);
|
||||
|
||||
await userEvent.press(screen.getByText('press me'));
|
||||
expect(getEventsName(events)).toEqual(['pressIn', 'press', 'pressOut']);
|
||||
expect(getEventsNames(events)).toEqual(['pressIn', 'press', 'pressOut']);
|
||||
});
|
||||
|
||||
test('press works on Button', async () => {
|
||||
@@ -208,7 +208,7 @@ describe('userEvent.press with fake timers', () => {
|
||||
render(<Button title="press me" onPress={logEvent('press')} />);
|
||||
|
||||
await userEvent.press(screen.getByText('press me'));
|
||||
expect(getEventsName(events)).toEqual(['press']);
|
||||
expect(getEventsNames(events)).toEqual(['press']);
|
||||
});
|
||||
|
||||
test('longPress works Text', async () => {
|
||||
@@ -226,7 +226,7 @@ describe('userEvent.press with fake timers', () => {
|
||||
);
|
||||
|
||||
await userEvent.longPress(screen.getByText('press me'));
|
||||
expect(getEventsName(events)).toEqual(['pressIn', 'longPress', 'pressOut']);
|
||||
expect(getEventsNames(events)).toEqual(['pressIn', 'longPress', 'pressOut']);
|
||||
});
|
||||
|
||||
test('does not trigger on disabled Text', async () => {
|
||||
@@ -280,7 +280,7 @@ describe('userEvent.press with fake timers', () => {
|
||||
);
|
||||
|
||||
await userEvent.press(screen.getByPlaceholderText('email'));
|
||||
expect(getEventsName(events)).toEqual(['pressIn', 'pressOut']);
|
||||
expect(getEventsNames(events)).toEqual(['pressIn', 'pressOut']);
|
||||
});
|
||||
|
||||
test('longPress works on TextInput', async () => {
|
||||
@@ -295,7 +295,7 @@ describe('userEvent.press with fake timers', () => {
|
||||
);
|
||||
|
||||
await userEvent.longPress(screen.getByPlaceholderText('email'));
|
||||
expect(getEventsName(events)).toEqual(['pressIn', 'pressOut']);
|
||||
expect(getEventsNames(events)).toEqual(['pressIn', 'pressOut']);
|
||||
});
|
||||
|
||||
test('does not call onPressIn and onPressOut on non editable TextInput', async () => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as React from 'react';
|
||||
import { TextInput } from 'react-native';
|
||||
import { createEventLogger } from '../../../test-utils';
|
||||
import { createEventLogger, getEventsNames } from '../../../test-utils';
|
||||
import { render, screen } from '../../..';
|
||||
import { userEvent } from '../..';
|
||||
|
||||
@@ -56,8 +56,7 @@ describe('type() for managed TextInput', () => {
|
||||
const user = userEvent.setup();
|
||||
await user.type(screen.getByTestId('input'), 'Wow');
|
||||
|
||||
const eventNames = events.map((e) => e.name);
|
||||
expect(eventNames).toEqual([
|
||||
expect(getEventsNames(events)).toEqual([
|
||||
'pressIn',
|
||||
'focus',
|
||||
'pressOut',
|
||||
@@ -90,8 +89,7 @@ describe('type() for managed TextInput', () => {
|
||||
const user = userEvent.setup();
|
||||
await user.type(screen.getByTestId('input'), 'ABC');
|
||||
|
||||
const eventNames = events.map((e) => e.name);
|
||||
expect(eventNames).toEqual([
|
||||
expect(getEventsNames(events)).toEqual([
|
||||
'pressIn',
|
||||
'focus',
|
||||
'pressOut',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as React from 'react';
|
||||
import { TextInput, TextInputProps, View } from 'react-native';
|
||||
import { createEventLogger } from '../../../test-utils';
|
||||
import { createEventLogger, getEventsNames, lastEventPayload } from '../../../test-utils';
|
||||
import { render, screen } from '../../..';
|
||||
import { userEvent } from '../..';
|
||||
|
||||
@@ -31,7 +31,6 @@ function renderTextInputWithToolkit(props: TextInputProps = {}) {
|
||||
);
|
||||
|
||||
return {
|
||||
...screen,
|
||||
events,
|
||||
};
|
||||
}
|
||||
@@ -39,13 +38,12 @@ function renderTextInputWithToolkit(props: TextInputProps = {}) {
|
||||
describe('type()', () => {
|
||||
it('supports basic case', async () => {
|
||||
jest.spyOn(Date, 'now').mockImplementation(() => 100100100100);
|
||||
const { events, ...queries } = renderTextInputWithToolkit();
|
||||
const { events } = renderTextInputWithToolkit();
|
||||
|
||||
const user = userEvent.setup();
|
||||
await user.type(queries.getByTestId('input'), 'abc');
|
||||
await user.type(screen.getByTestId('input'), 'abc');
|
||||
|
||||
const eventNames = events.map((e) => e.name);
|
||||
expect(eventNames).toEqual([
|
||||
expect(getEventsNames(events)).toEqual([
|
||||
'pressIn',
|
||||
'focus',
|
||||
'pressOut',
|
||||
@@ -70,13 +68,12 @@ describe('type()', () => {
|
||||
|
||||
it.each(['modern', 'legacy'])('works with %s fake timers', async (type) => {
|
||||
jest.useFakeTimers({ legacyFakeTimers: type === 'legacy' });
|
||||
const { events, ...queries } = renderTextInputWithToolkit();
|
||||
const { events } = renderTextInputWithToolkit();
|
||||
|
||||
const user = userEvent.setup();
|
||||
await user.type(queries.getByTestId('input'), 'abc');
|
||||
await user.type(screen.getByTestId('input'), 'abc');
|
||||
|
||||
const eventNames = events.map((e) => e.name);
|
||||
expect(eventNames).toEqual([
|
||||
expect(getEventsNames(events)).toEqual([
|
||||
'pressIn',
|
||||
'focus',
|
||||
'pressOut',
|
||||
@@ -98,15 +95,14 @@ describe('type()', () => {
|
||||
});
|
||||
|
||||
it('supports defaultValue prop', async () => {
|
||||
const { events, ...queries } = renderTextInputWithToolkit({
|
||||
const { events } = renderTextInputWithToolkit({
|
||||
defaultValue: 'xxx',
|
||||
});
|
||||
|
||||
const user = userEvent.setup();
|
||||
await user.type(queries.getByTestId('input'), 'ab');
|
||||
await user.type(screen.getByTestId('input'), 'ab');
|
||||
|
||||
const eventNames = events.map((e) => e.name);
|
||||
expect(eventNames).toEqual([
|
||||
expect(getEventsNames(events)).toEqual([
|
||||
'pressIn',
|
||||
'focus',
|
||||
'pressOut',
|
||||
@@ -126,27 +122,25 @@ describe('type()', () => {
|
||||
});
|
||||
|
||||
it('does respect editable prop', async () => {
|
||||
const { events, ...queries } = renderTextInputWithToolkit({
|
||||
const { events } = renderTextInputWithToolkit({
|
||||
editable: false,
|
||||
});
|
||||
|
||||
const user = userEvent.setup();
|
||||
await user.type(queries.getByTestId('input'), 'ab');
|
||||
await user.type(screen.getByTestId('input'), 'ab');
|
||||
|
||||
const eventNames = events.map((e) => e.name);
|
||||
expect(eventNames).toEqual([]);
|
||||
expect(getEventsNames(events)).toEqual([]);
|
||||
});
|
||||
|
||||
it('supports backspace', async () => {
|
||||
const { events, ...queries } = renderTextInputWithToolkit({
|
||||
const { events } = renderTextInputWithToolkit({
|
||||
defaultValue: 'xxx',
|
||||
});
|
||||
|
||||
const user = userEvent.setup();
|
||||
await user.type(queries.getByTestId('input'), '{Backspace}a');
|
||||
await user.type(screen.getByTestId('input'), '{Backspace}a');
|
||||
|
||||
const eventNames = events.map((e) => e.name);
|
||||
expect(eventNames).toEqual([
|
||||
expect(getEventsNames(events)).toEqual([
|
||||
'pressIn',
|
||||
'focus',
|
||||
'pressOut',
|
||||
@@ -166,15 +160,14 @@ describe('type()', () => {
|
||||
});
|
||||
|
||||
it('supports multiline', async () => {
|
||||
const { events, ...queries } = renderTextInputWithToolkit({
|
||||
const { events } = renderTextInputWithToolkit({
|
||||
multiline: true,
|
||||
});
|
||||
|
||||
const user = userEvent.setup();
|
||||
await user.type(queries.getByTestId('input'), '{Enter}\n');
|
||||
await user.type(screen.getByTestId('input'), '{Enter}\n');
|
||||
|
||||
const eventNames = events.map((e) => e.name);
|
||||
expect(eventNames).toEqual([
|
||||
expect(getEventsNames(events)).toEqual([
|
||||
'pressIn',
|
||||
'focus',
|
||||
'pressOut',
|
||||
@@ -198,14 +191,14 @@ describe('type()', () => {
|
||||
});
|
||||
|
||||
test('skips press events when `skipPress: true`', async () => {
|
||||
const { events, ...queries } = renderTextInputWithToolkit();
|
||||
const { events } = renderTextInputWithToolkit();
|
||||
|
||||
const user = userEvent.setup();
|
||||
await user.type(queries.getByTestId('input'), 'a', {
|
||||
await user.type(screen.getByTestId('input'), 'a', {
|
||||
skipPress: true,
|
||||
});
|
||||
|
||||
const eventNames = events.map((e) => e.name);
|
||||
const eventNames = getEventsNames(events);
|
||||
expect(eventNames).not.toContainEqual('pressIn');
|
||||
expect(eventNames).not.toContainEqual('pressOut');
|
||||
expect(eventNames).toEqual([
|
||||
@@ -217,18 +210,21 @@ describe('type()', () => {
|
||||
'endEditing',
|
||||
'blur',
|
||||
]);
|
||||
|
||||
expect(lastEventPayload(events, 'endEditing')).toMatchObject({
|
||||
nativeEvent: { text: 'a', target: 0 },
|
||||
});
|
||||
});
|
||||
|
||||
it('triggers submit event with `submitEditing: true`', async () => {
|
||||
const { events, ...queries } = renderTextInputWithToolkit();
|
||||
const { events } = renderTextInputWithToolkit();
|
||||
|
||||
const user = userEvent.setup();
|
||||
await user.type(queries.getByTestId('input'), 'a', {
|
||||
await user.type(screen.getByTestId('input'), 'a', {
|
||||
submitEditing: true,
|
||||
});
|
||||
|
||||
const eventNames = events.map((e) => e.name);
|
||||
expect(eventNames).toEqual([
|
||||
expect(getEventsNames(events)).toEqual([
|
||||
'pressIn',
|
||||
'focus',
|
||||
'pressOut',
|
||||
@@ -241,8 +237,7 @@ describe('type()', () => {
|
||||
'blur',
|
||||
]);
|
||||
|
||||
expect(events[7].name).toBe('submitEditing');
|
||||
expect(events[7].payload).toMatchObject({
|
||||
expect(lastEventPayload(events, 'submitEditing')).toMatchObject({
|
||||
nativeEvent: { text: 'a', target: 0 },
|
||||
currentTarget: {},
|
||||
target: {},
|
||||
@@ -262,8 +257,12 @@ describe('type()', () => {
|
||||
const user = userEvent.setup();
|
||||
await user.type(screen.getByTestId('input'), 'abc');
|
||||
|
||||
const eventNames = events.map((e) => e.name);
|
||||
expect(eventNames).toEqual(['changeText', 'changeText', 'changeText', 'endEditing']);
|
||||
expect(getEventsNames(events)).toEqual([
|
||||
'changeText',
|
||||
'changeText',
|
||||
'changeText',
|
||||
'endEditing',
|
||||
]);
|
||||
|
||||
expect(events).toMatchSnapshot('input: "abc"');
|
||||
});
|
||||
@@ -318,8 +317,13 @@ describe('type()', () => {
|
||||
|
||||
await userEvent.type(screen.getByTestId('input'), 'abc');
|
||||
|
||||
const eventNames = events.map((event) => event.name);
|
||||
expect(eventNames).toEqual(['focus', 'changeText', 'changeText', 'changeText', 'blur']);
|
||||
expect(getEventsNames(events)).toEqual([
|
||||
'focus',
|
||||
'changeText',
|
||||
'changeText',
|
||||
'changeText',
|
||||
'blur',
|
||||
]);
|
||||
});
|
||||
|
||||
// See: https://github.com/callstack/react-native-testing-library/issues/1588
|
||||
@@ -338,4 +342,37 @@ describe('type()', () => {
|
||||
await userEvent.type(screen.getByTestId('input'), 'abc');
|
||||
expect(handleKeyPress).toHaveBeenCalledTimes(3);
|
||||
});
|
||||
|
||||
it('respects the "maxLength" prop', async () => {
|
||||
const { events } = renderTextInputWithToolkit({ maxLength: 2 });
|
||||
|
||||
const user = userEvent.setup();
|
||||
await user.type(screen.getByTestId('input'), 'abcd');
|
||||
|
||||
expect(getEventsNames(events)).toEqual([
|
||||
'pressIn',
|
||||
'focus',
|
||||
'pressOut',
|
||||
'keyPress', // a
|
||||
'change',
|
||||
'changeText',
|
||||
'selectionChange',
|
||||
'keyPress', // b
|
||||
'change',
|
||||
'changeText',
|
||||
'selectionChange',
|
||||
'keyPress', // c
|
||||
'keyPress', // d
|
||||
'endEditing',
|
||||
'blur',
|
||||
]);
|
||||
|
||||
expect(lastEventPayload(events, 'changeText')).toBe('ab');
|
||||
expect(lastEventPayload(events, 'endEditing')).toMatchObject({
|
||||
nativeEvent: {
|
||||
target: 0,
|
||||
text: 'ab',
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
+37
-16
@@ -47,9 +47,17 @@ export async function type(
|
||||
let currentText = element.props.value ?? element.props.defaultValue ?? '';
|
||||
for (const key of keys) {
|
||||
const previousText = element.props.value ?? currentText;
|
||||
currentText = applyKey(previousText, key);
|
||||
const proposedText = applyKey(previousText, key);
|
||||
const isAccepted = isTextChangeAccepted(element, proposedText);
|
||||
currentText = isAccepted ? proposedText : previousText;
|
||||
|
||||
await emitTypingEvents(this.config, element, key, currentText, previousText);
|
||||
await emitTypingEvents(element, {
|
||||
config: this.config,
|
||||
key,
|
||||
text: currentText,
|
||||
previousText,
|
||||
isAccepted,
|
||||
});
|
||||
}
|
||||
|
||||
const finalText = element.props.value ?? currentText;
|
||||
@@ -64,41 +72,49 @@ export async function type(
|
||||
dispatchEvent(element, 'blur', EventBuilder.Common.blur());
|
||||
}
|
||||
|
||||
type EmitTypingEventsContext = {
|
||||
config: UserEventConfig;
|
||||
key: string;
|
||||
text: string;
|
||||
previousText: string;
|
||||
isAccepted?: boolean;
|
||||
};
|
||||
|
||||
export async function emitTypingEvents(
|
||||
config: UserEventConfig,
|
||||
element: ReactTestInstance,
|
||||
key: string,
|
||||
currentText: string,
|
||||
previousText: string,
|
||||
{ config, key, text, previousText, isAccepted }: EmitTypingEventsContext,
|
||||
) {
|
||||
const isMultiline = element.props.multiline === true;
|
||||
|
||||
await wait(config);
|
||||
dispatchEvent(element, 'keyPress', EventBuilder.TextInput.keyPress(key));
|
||||
|
||||
// Platform difference (based on experiments):
|
||||
// - iOS and RN Web: TextInput emits only `keyPress` event when max length has been reached
|
||||
// - Android: TextInputs does not emit any events
|
||||
if (isAccepted === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
// According to the docs only multiline TextInput emits textInput event
|
||||
// @see: https://github.com/facebook/react-native/blob/42a2898617da1d7a98ef574a5b9e500681c8f738/packages/react-native/Libraries/Components/TextInput/TextInput.d.ts#L754
|
||||
if (isMultiline) {
|
||||
dispatchEvent(
|
||||
element,
|
||||
'textInput',
|
||||
EventBuilder.TextInput.textInput(currentText, previousText),
|
||||
);
|
||||
dispatchEvent(element, 'textInput', EventBuilder.TextInput.textInput(text, previousText));
|
||||
}
|
||||
|
||||
dispatchEvent(element, 'change', EventBuilder.TextInput.change(currentText));
|
||||
dispatchEvent(element, 'changeText', currentText);
|
||||
dispatchEvent(element, 'change', EventBuilder.TextInput.change(text));
|
||||
dispatchEvent(element, 'changeText', text);
|
||||
|
||||
const selectionRange = {
|
||||
start: currentText.length,
|
||||
end: currentText.length,
|
||||
start: text.length,
|
||||
end: text.length,
|
||||
};
|
||||
dispatchEvent(element, 'selectionChange', EventBuilder.TextInput.selectionChange(selectionRange));
|
||||
|
||||
// According to the docs only multiline TextInput emits contentSizeChange event
|
||||
// @see: https://reactnative.dev/docs/textinput#oncontentsizechange
|
||||
if (isMultiline) {
|
||||
const contentSize = getTextContentSize(currentText);
|
||||
const contentSize = getTextContentSize(text);
|
||||
dispatchEvent(
|
||||
element,
|
||||
'contentSizeChange',
|
||||
@@ -118,3 +134,8 @@ function applyKey(text: string, key: string) {
|
||||
|
||||
return text + key;
|
||||
}
|
||||
|
||||
function isTextChangeAccepted(element: ReactTestInstance, text: string) {
|
||||
const maxLength = element.props.maxLength;
|
||||
return maxLength === undefined || text.length <= maxLength;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user