Unverified Commit 67d8556b authored by LongCatIsLooong's avatar LongCatIsLooong Committed by GitHub

`enterText` to move the caret to the end (#79506)

parent fb68d074
...@@ -848,18 +848,24 @@ void main() { ...@@ -848,18 +848,24 @@ void main() {
); );
testWidgets('cursor layout has correct width', (WidgetTester tester) async { testWidgets('cursor layout has correct width', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController.fromValue(
const TextEditingValue(selection: TextSelection.collapsed(offset: 0)),
);
final FocusNode focusNode = FocusNode();
EditableText.debugDeterministicCursor = true; EditableText.debugDeterministicCursor = true;
await tester.pumpWidget( await tester.pumpWidget(
overlay( overlay(
child: const RepaintBoundary( child: RepaintBoundary(
child: TextField( child: TextField(
cursorWidth: 15.0, cursorWidth: 15.0,
controller: controller,
focusNode: focusNode,
), ),
), ),
) )
); );
await tester.enterText(find.byType(TextField), ' '); focusNode.requestFocus();
await skipPastScrollingAnimation(tester); await tester.pump();
await expectLater( await expectLater(
find.byType(TextField), find.byType(TextField),
...@@ -869,19 +875,25 @@ void main() { ...@@ -869,19 +875,25 @@ void main() {
}); });
testWidgets('cursor layout has correct radius', (WidgetTester tester) async { testWidgets('cursor layout has correct radius', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController.fromValue(
const TextEditingValue(selection: TextSelection.collapsed(offset: 0)),
);
final FocusNode focusNode = FocusNode();
EditableText.debugDeterministicCursor = true; EditableText.debugDeterministicCursor = true;
await tester.pumpWidget( await tester.pumpWidget(
overlay( overlay(
child: const RepaintBoundary( child: RepaintBoundary(
child: TextField( child: TextField(
cursorWidth: 15.0, cursorWidth: 15.0,
cursorRadius: Radius.circular(3.0), cursorRadius: const Radius.circular(3.0),
controller: controller,
focusNode: focusNode,
), ),
), ),
) )
); );
await tester.enterText(find.byType(TextField), ' '); focusNode.requestFocus();
await skipPastScrollingAnimation(tester); await tester.pump();
await expectLater( await expectLater(
find.byType(TextField), find.byType(TextField),
...@@ -891,19 +903,25 @@ void main() { ...@@ -891,19 +903,25 @@ void main() {
}); });
testWidgets('cursor layout has correct height', (WidgetTester tester) async { testWidgets('cursor layout has correct height', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController.fromValue(
const TextEditingValue(selection: TextSelection.collapsed(offset: 0)),
);
final FocusNode focusNode = FocusNode();
EditableText.debugDeterministicCursor = true; EditableText.debugDeterministicCursor = true;
await tester.pumpWidget( await tester.pumpWidget(
overlay( overlay(
child: const RepaintBoundary( child: RepaintBoundary(
child: TextField( child: TextField(
cursorWidth: 15.0, cursorWidth: 15.0,
cursorHeight: 30.0, cursorHeight: 30.0,
controller: controller,
focusNode: focusNode,
), ),
), ),
) )
); );
await tester.enterText(find.byType(TextField), ' '); focusNode.requestFocus();
await skipPastScrollingAnimation(tester); await tester.pump();
await expectLater( await expectLater(
find.byType(TextField), find.byType(TextField),
...@@ -1115,8 +1133,8 @@ void main() { ...@@ -1115,8 +1133,8 @@ void main() {
await tester.tapAt(ePos); await tester.tapAt(ePos);
await tester.pump(); await tester.pump();
expect(controller.selection.baseOffset, -1); expect(controller.selection.baseOffset, testValue.length);
expect(controller.selection.extentOffset, -1); expect(controller.selection.isCollapsed, isTrue);
}); });
testWidgets('Can long press to select', (WidgetTester tester) async { testWidgets('Can long press to select', (WidgetTester tester) async {
...@@ -1584,8 +1602,7 @@ void main() { ...@@ -1584,8 +1602,7 @@ void main() {
await tester.pump(); await tester.pump();
expect(controller.selection.isCollapsed, true); expect(controller.selection.isCollapsed, true);
expect(controller.selection.baseOffset, -1); expect(controller.selection.baseOffset, testValue.length);
expect(controller.selection.extentOffset, -1);
}); });
testWidgets('Can select text by dragging with a mouse', (WidgetTester tester) async { testWidgets('Can select text by dragging with a mouse', (WidgetTester tester) async {
...@@ -5218,7 +5235,8 @@ void main() { ...@@ -5218,7 +5235,8 @@ void main() {
const String testValue = 'x'; const String testValue = 'x';
await tester.enterText(find.byType(TextField), testValue); await tester.enterText(find.byType(TextField), testValue);
await skipPastScrollingAnimation(tester); await skipPastScrollingAnimation(tester);
expect(controller.selection.baseOffset, -1); expect(controller.selection.isCollapsed, true);
expect(controller.selection.baseOffset, testValue.length);
// Tap the selection handle to bring up the "paste / select all" menu. // Tap the selection handle to bring up the "paste / select all" menu.
await tester.tapAt(textOffsetToPosition(tester, 0)); await tester.tapAt(textOffsetToPosition(tester, 0));
......
...@@ -166,10 +166,14 @@ class TestTextInput { ...@@ -166,10 +166,14 @@ class TestTextInput {
} }
/// Simulates the user typing the given text. /// Simulates the user typing the given text.
///
/// Calling this method replaces the content of the connected input field with
/// `text`, and places the caret at the end of the text.
void enterText(String text) { void enterText(String text) {
assert(isRegistered); assert(isRegistered);
updateEditingValue(TextEditingValue( updateEditingValue(TextEditingValue(
text: text, text: text,
selection: TextSelection.collapsed(offset: text.length),
)); ));
} }
......
...@@ -1040,13 +1040,16 @@ class WidgetTester extends WidgetController implements HitTestDispatcher, Ticker ...@@ -1040,13 +1040,16 @@ class WidgetTester extends WidgetController implements HitTestDispatcher, Ticker
}); });
} }
/// Give the text input widget specified by [finder] the focus and /// Give the text input widget specified by [finder] the focus and replace its
/// enter [text] as if it been provided by the onscreen keyboard. /// content with [text], as if it had been provided by the onscreen keyboard.
/// ///
/// The widget specified by [finder] must be an [EditableText] or have /// The widget specified by [finder] must be an [EditableText] or have
/// an [EditableText] descendant. For example `find.byType(TextField)` /// an [EditableText] descendant. For example `find.byType(TextField)`
/// or `find.byType(TextFormField)`, or `find.byType(EditableText)`. /// or `find.byType(TextFormField)`, or `find.byType(EditableText)`.
/// ///
/// When the returned future completes, the text input widget's text will be
/// exactly `text`, and the caret will be placed at the end of `text`.
///
/// To just give [finder] the focus without entering any text, /// To just give [finder] the focus without entering any text,
/// see [showKeyboard]. /// see [showKeyboard].
Future<void> enterText(Finder finder, String text) async { Future<void> enterText(Finder finder, String text) async {
......
...@@ -7,6 +7,24 @@ import 'package:flutter/services.dart'; ...@@ -7,6 +7,24 @@ import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
void main() { void main() {
testWidgets('enterText works', (WidgetTester tester) async {
await tester.pumpWidget(
const MaterialApp(
home: Material(
child: TextField(),
),
),
);
final EditableTextState state = tester.state(find.byType(EditableText));
expect(state.textEditingValue.text, '');
await tester.enterText(find.byType(EditableText), 'let there be text');
expect(state.textEditingValue.text, 'let there be text');
expect(state.textEditingValue.selection.isCollapsed, isTrue);
expect(state.textEditingValue.selection.baseOffset, 17);
});
testWidgets('receiveAction() forwards exception when exception occurs during action processing', (WidgetTester tester) async { testWidgets('receiveAction() forwards exception when exception occurs during action processing', (WidgetTester tester) async {
// Setup a widget that can receive focus so that we can open the keyboard. // Setup a widget that can receive focus so that we can open the keyboard.
const Widget widget = MaterialApp( const Widget widget = MaterialApp(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment