Skip to content

Commit e070688

Browse files
Simulate IME messages when pressing ENTER (Resolves #19) (#20)
1 parent 830b743 commit e070688

File tree

1 file changed

+92
-1
lines changed

1 file changed

+92
-1
lines changed

lib/src/keyboard.dart

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'package:flutter/foundation.dart';
22
import 'package:flutter/services.dart';
33
import '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

Comments
 (0)