Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 9de3717

Browse files
committedSep 12, 2024
fix: improve text input value getting in type, clear, paste
1 parent 8390011 commit 9de3717

File tree

8 files changed

+20
-17
lines changed

8 files changed

+20
-17
lines changed
 

‎src/matchers/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ export interface JestNativeMatchers<R> {
218218
toHaveAccessibleName(expectedName?: TextMatch, options?: TextMatchOptions): R;
219219

220220
/**
221-
* Assert whether a host `TextInput` element has a given display value based on `value` and `defaultValue` props.
221+
* Assert whether a host `TextInput` element has a given display value based on `value`, unmanaged native state, and `defaultValue` props.
222222
*
223223
* @see
224224
* [Jest Matchers docs](https://callstack.github.io/react-native-testing-library/docs/jest-matchers#tohavedisplayvalue)

‎src/queries/__tests__/display-value.test.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as React from 'react';
22
import { TextInput, View } from 'react-native';
3-
43
import { render, screen } from '../..';
4+
import '../../matchers/extend-expect';
55

66
const PLACEHOLDER_FRESHNESS = 'Add custom freshness';
77
const PLACEHOLDER_CHEF = 'Who inspected freshness?';
@@ -32,11 +32,11 @@ test('getByDisplayValue, queryByDisplayValue', () => {
3232
render(<Banana />);
3333
const input = screen.getByDisplayValue(/custom/i);
3434

35-
expect(input.props.value).toBe(INPUT_FRESHNESS);
35+
expect(input).toHaveDisplayValue(INPUT_FRESHNESS);
3636

3737
const sameInput = screen.getByDisplayValue(INPUT_FRESHNESS);
3838

39-
expect(sameInput.props.value).toBe(INPUT_FRESHNESS);
39+
expect(sameInput).toHaveDisplayValue(INPUT_FRESHNESS);
4040
expect(() => screen.getByDisplayValue('no value')).toThrow(
4141
'Unable to find an element with displayValue: no value',
4242
);

‎src/user-event/__tests__/clear.test.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ describe('clear()', () => {
113113
const user = userEvent.setup();
114114
await user.clear(textInput);
115115

116-
expect(textInput.props.value).toBe('Hello!');
116+
expect(textInput).toHaveDisplayValue('Hello!');
117117
});
118118

119119
it('does respect pointer-events prop', async () => {
@@ -125,7 +125,7 @@ describe('clear()', () => {
125125
const user = userEvent.setup();
126126
await user.clear(textInput);
127127

128-
expect(textInput.props.value).toBe('Hello!');
128+
expect(textInput).toHaveDisplayValue('Hello!');
129129
});
130130

131131
it('supports multiline', async () => {

‎src/user-event/__tests__/paste.test.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ describe('paste()', () => {
130130
const user = userEvent.setup();
131131
await user.paste(textInput, 'Hi!');
132132

133-
expect(textInput.props.value).toBe('Hello!');
133+
expect(textInput).toHaveDisplayValue('Hello!');
134134
});
135135

136136
it('does respect pointer-events prop', async () => {
@@ -142,7 +142,7 @@ describe('paste()', () => {
142142
const user = userEvent.setup();
143143
await user.paste(textInput, 'Hi!');
144144

145-
expect(textInput.props.value).toBe('Hello!');
145+
expect(textInput).toHaveDisplayValue('Hello!');
146146
});
147147

148148
it('supports multiline', async () => {

‎src/user-event/clear.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { ReactTestInstance } from 'react-test-renderer';
22
import { ErrorWithStack } from '../helpers/errors';
33
import { isHostTextInput } from '../helpers/host-component-names';
4-
import { isTextInputEditable } from '../helpers/text-input';
4+
import { getTextInputValue, isTextInputEditable } from '../helpers/text-input';
55
import { isPointerEventEnabled } from '../helpers/pointer-events';
66
import { EventBuilder } from './event-builder';
77
import { UserEventInstance } from './setup';
@@ -24,7 +24,7 @@ export async function clear(this: UserEventInstance, element: ReactTestInstance)
2424
dispatchEvent(element, 'focus', EventBuilder.Common.focus());
2525

2626
// 2. Select all
27-
const textToClear = element.props.value ?? element.props.defaultValue ?? '';
27+
const textToClear = getTextInputValue(element);
2828
const selectionRange = {
2929
start: 0,
3030
end: textToClear.length,

‎src/user-event/paste.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { ReactTestInstance } from 'react-test-renderer';
22
import { ErrorWithStack } from '../helpers/errors';
33
import { isHostTextInput } from '../helpers/host-component-names';
44
import { isPointerEventEnabled } from '../helpers/pointer-events';
5-
import { isTextInputEditable } from '../helpers/text-input';
5+
import { getTextInputValue, isTextInputEditable } from '../helpers/text-input';
66
import { nativeState } from '../native-state';
77
import { EventBuilder } from './event-builder';
88
import { UserEventInstance } from './setup';
@@ -28,7 +28,7 @@ export async function paste(
2828
dispatchEvent(element, 'focus', EventBuilder.Common.focus());
2929

3030
// 2. Select all
31-
const textToClear = element.props.value ?? element.props.defaultValue ?? '';
31+
const textToClear = getTextInputValue(element);
3232
const rangeToClear = { start: 0, end: textToClear.length };
3333
dispatchEvent(element, 'selectionChange', EventBuilder.TextInput.selectionChange(rangeToClear));
3434

‎src/user-event/type/__tests__/type.test.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -374,14 +374,17 @@ describe('type()', () => {
374374
});
375375
});
376376

377-
it('sets native state value for unmanaged text inputs', async () => {
377+
it('unmanaged text inputs preserve their native state', async () => {
378378
render(<TextInput testID="input" />);
379379

380380
const user = userEvent.setup();
381381
const input = screen.getByTestId('input');
382382
expect(input).toHaveDisplayValue('');
383383

384-
await user.type(input, 'abc');
385-
expect(input).toHaveDisplayValue('abc');
384+
await user.type(input, 'Hello');
385+
expect(input).toHaveDisplayValue('Hello');
386+
387+
await user.type(input, ' World');
388+
expect(input).toHaveDisplayValue('Hello World');
386389
});
387390
});

‎src/user-event/type/type.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { isHostTextInput } from '../../helpers/host-component-names';
33
import { nativeState } from '../../native-state';
44
import { EventBuilder } from '../event-builder';
55
import { ErrorWithStack } from '../../helpers/errors';
6-
import { isTextInputEditable } from '../../helpers/text-input';
6+
import { getTextInputValue, isTextInputEditable } from '../../helpers/text-input';
77
import { isPointerEventEnabled } from '../../helpers/pointer-events';
88
import { UserEventConfig, UserEventInstance } from '../setup';
99
import { dispatchEvent, wait, getTextContentSize } from '../utils';
@@ -45,7 +45,7 @@ export async function type(
4545
dispatchEvent(element, 'pressOut', EventBuilder.Common.touch());
4646
}
4747

48-
let currentText = element.props.value ?? element.props.defaultValue ?? '';
48+
let currentText = getTextInputValue(element);
4949
for (const key of keys) {
5050
const previousText = element.props.value ?? currentText;
5151
const proposedText = applyKey(previousText, key);

0 commit comments

Comments
 (0)
Please sign in to comment.