11import 'package:flutter/foundation.dart' ;
22import 'package:flutter/services.dart' ;
33import 'package:flutter_test/flutter_test.dart' ;
4+ import 'package:flutter_test_robots/src/input_method_engine.dart' ;
45
56/// Simulates keyboard input in your Flutter app.
67///
@@ -61,7 +62,7 @@ extension KeyboardInput on WidgetTester {
6162 /// key simulations leads to unexpected results. By always using methods in this package, instead of
6263 /// standard Flutter methods, the simulated platform is guaranteed to match across calls, and also
6364 /// match the platform that's simulated within the surrounding test, i.e., [defaultTargetPlatform] .
64- /// @{ endtemplate}
65+ /// {@ endtemplate}
6566 Future <void > pressKey (LogicalKeyboardKey key) => sendKeyEvent (key, platform: _keyEventPlatform);
6667
6768 /// Runs [simulateKeyDownEvent] , using the current [defaultTargetPlatform] as the key simulators `platform` value.
@@ -84,6 +85,54 @@ extension KeyboardInput on WidgetTester {
8485 await pumpAndSettle ();
8586 }
8687
88+ /// Simulates the user pressing ENTER in a widget attached to the IME.
89+ ///
90+ /// Instead of key events, this method generates a "\n" insertion followed by a TextInputAction.newline.
91+ ///
92+ /// {@template ime_client_getter}
93+ /// The given [finder] must find a [StatefulWidget] whose [State] implements
94+ /// [DeltaTextInputClient] .
95+ ///
96+ /// If the [DeltaTextInputClient] currently has selected text, that text is first deleted,
97+ /// which is the standard behavior when typing new characters with an existing selection.
98+ /// {@endtemplate}
99+ Future <void > pressEnterWithIme ({
100+ Finder ? finder,
101+ GetDeltaTextInputClient ? getter,
102+ }) async {
103+ if (! testTextInput.hasAnyClients) {
104+ // There isn't any IME connections.
105+ return ;
106+ }
107+
108+ await ime.typeText ('\n ' , finder: finder, getter: getter);
109+ await pump ();
110+ await testTextInput.receiveAction (TextInputAction .newline);
111+ await pump ();
112+ }
113+
114+ /// Simulates pressing an ENTER button, either as a keyboard key, or as a software keyboard action button.
115+ ///
116+ /// First, this method simulates pressing the ENTER key on a physical keyboard. If that key event goes unhandled
117+ /// then this method simulates pressing the newline action button on a software keyboard, which inserts "/n"
118+ /// into the text, and also sends a NEWLINE action to the IME client.
119+ ///
120+ /// {@macro ime_client_getter}
121+ Future <void > pressEnterAdaptive ({
122+ Finder ? finder,
123+ GetDeltaTextInputClient ? getter,
124+ }) async {
125+ final handled = await sendKeyEvent (LogicalKeyboardKey .enter, platform: _keyEventPlatform);
126+ if (handled) {
127+ // The textfield handled the key event.
128+ // It won't bubble up to the OS to generate text deltas or input actions.
129+ await pumpAndSettle ();
130+ return ;
131+ }
132+
133+ await pressEnterWithIme ();
134+ }
135+
87136 Future <void > pressShiftEnter () async {
88137 await sendKeyDownEvent (LogicalKeyboardKey .shift, platform: _keyEventPlatform);
89138 await sendKeyDownEvent (LogicalKeyboardKey .enter, platform: _keyEventPlatform);
@@ -113,6 +162,48 @@ extension KeyboardInput on WidgetTester {
113162 await pumpAndSettle ();
114163 }
115164
165+ /// Simulates the user pressing NUMPAD ENTER in a widget attached to the IME.
166+ ///
167+ /// Instead of key events, this method generates a "\n" insertion followed by a TextInputAction.newline.
168+ /// Does nothing if there isn't an active IME connection.
169+ ///
170+ /// {@macro ime_client_getter}
171+ Future <void > pressNumpadEnterWithIme ({
172+ Finder ? finder,
173+ GetDeltaTextInputClient ? getter,
174+ }) async {
175+ if (! testTextInput.hasAnyClients) {
176+ // There isn't any IME connections.
177+ return ;
178+ }
179+
180+ await ime.typeText ('\n ' , finder: finder, getter: getter);
181+ await testTextInput.receiveAction (TextInputAction .newline);
182+ await pump ();
183+ }
184+
185+ /// Simulates pressing an NUMPAD ENTER button, either as a keyboard key, or as a software keyboard action button.
186+ ///
187+ /// First, this method simulates pressing the NUMPAD ENTER key on a physical keyboard. If that key event goes unhandled
188+ /// then this method simulates pressing the newline action button on a software keyboard, which inserts "/n"
189+ /// into the text, and also sends a NEWLINE action to the IME client.
190+ ///
191+ /// {@macro ime_client_getter}
192+ Future <void > pressNumpadEnterAdaptive ({
193+ Finder ? finder,
194+ GetDeltaTextInputClient ? getter,
195+ }) async {
196+ final handled = await sendKeyEvent (LogicalKeyboardKey .numpadEnter, platform: _keyEventPlatform);
197+ if (handled) {
198+ // The textfield handled the key event.
199+ // It won't bubble up to the OS to generate text deltas or input actions.
200+ await pumpAndSettle ();
201+ return ;
202+ }
203+
204+ await pressNumpadEnterWithIme ();
205+ }
206+
116207 Future <void > pressShiftNumpadEnter () async {
117208 await sendKeyDownEvent (LogicalKeyboardKey .shift, platform: _keyEventPlatform);
118209 await sendKeyDownEvent (LogicalKeyboardKey .numpadEnter, platform: _keyEventPlatform);
0 commit comments