Change the enterText method to move the caret to the end of the input text
Summary
The WidgetTester.enterText
and TestTextInput.enterText
methods
now move the caret to the end of the input text.
Context
The caret indicates the insertion point within the current text in an active input field. Typically, when a new character is entered, the caret stays immediately after it. In Flutter the caret position is represented by a collapsed selection. When the selection is invalid, usually the user won’t be able to modify or add text until they change the selection to a valid value.
WidgetTester.enterText
and TestTextInput.enterText
are 2 methods
used in tests to replace the content of the target text field. Prior
to this change, WidgetTester.enterText
and TestTextInput.enterText
set the selection to an invalid range (-1, -1), indicating there’s
no selection or caret. This contradicts the typical behavior of an
input field.
Description of change
In addition to replacing the text with the supplied text,
WidgetTester.enterText
and TestTextInput.enterText
now set the
selection to TextSelection.collapsed(offset: text.length)
, instead
of TextSelection.collapsed(offset: -1)
.
Migration guide
It should be very uncommon for tests to have to rely on the
previous behavior of enterText
, since usually the selection
should not be invalid. Consider changing the expected values of
your tests to adopt the enterText
change.
Common test failures this change may introduce includes:
-
Golden test failures:
The caret appears at the end of the text, as opposed to before the text prior to the change.
-
Different
TextEditingValue.selection
after callingenterText
:The text field’s
TextEditingValue
now has a collapsed selection with a non-negative offset, as opposed toTextSelection.collapsed(offset: -1)
prior to the change. For instance, you may seeexpect(controller.value.selection.baseOffset, -1);
failing afterenterText
calls.
If your tests have to rely on setting the selection to invalid,
the previous behavior can be achieved usingupdateEditingValue
:
TestTextInput.enterText
Code before migration:
await testTextInput.enterText(text);
Code after migration:
await testTextInput.updateEditingValue(TextEditingValue(
text: text,
));
WidgetTester.enterText
Code before migration:
await tester.enterText(finder, text);
Code after migration:
await tester.showKeyboard(finder);
await tester.updateEditingValue(TextEditingValue(
text: text,
));
await tester.idle();
Timeline
Landed in version: 2.1.0-13.0.pre
In stable release: 2.5
References
API documentation:
Relevant issues:
Relevant PRs: