Add send_text_input_action case to deserialization_factory to allow sendTextInputAction usages through flutter_driver. (#139197)
**As a follow up to https://github.com/flutter/flutter/pull/131776.**
**Summary:**
Previously in https://github.com/flutter/flutter/pull/106561, SendTextInputAction was added to Flutter Driver.
But it still cannot be used from flutter_driver tests. This PR intends to resolve that issue.
**Issue:**
An `DriverError: Unsupported command kind send_text_input_action` would be thrown from `flutter_driver/lib/src/common/deserialization_factory.dart` when a call to `driver.sendTextInputAction(TextInputAction.done);` was made despite the method `sendTextInputAction` is available for use since https://github.com/flutter/flutter/pull/106561.
Previous works has been done in https://github.com/flutter/flutter/pull/131776, I merely added tests.
Best regards.
diff --git a/packages/flutter_driver/lib/src/common/deserialization_factory.dart b/packages/flutter_driver/lib/src/common/deserialization_factory.dart
index f020add..0ad51b7 100644
--- a/packages/flutter_driver/lib/src/common/deserialization_factory.dart
+++ b/packages/flutter_driver/lib/src/common/deserialization_factory.dart
@@ -15,6 +15,7 @@
import 'request_data.dart';
import 'semantics.dart';
import 'text.dart';
+import 'text_input_action.dart';
import 'wait.dart';
/// A factory for deserializing [Finder]s.
@@ -46,6 +47,7 @@
case 'get_layer_tree': return GetLayerTree.deserialize(params);
case 'get_render_tree': return GetRenderTree.deserialize(params);
case 'enter_text': return EnterText.deserialize(params);
+ case 'send_text_input_action': return SendTextInputAction.deserialize(params);
case 'get_text': return GetText.deserialize(params, finderFactory);
case 'request_data': return RequestData.deserialize(params);
case 'scroll': return Scroll.deserialize(params, finderFactory);
diff --git a/packages/flutter_driver/test/src/real_tests/extension_test.dart b/packages/flutter_driver/test/src/real_tests/extension_test.dart
index 3612047..111f521 100644
--- a/packages/flutter_driver/test/src/real_tests/extension_test.dart
+++ b/packages/flutter_driver/test/src/real_tests/extension_test.dart
@@ -10,13 +10,13 @@
library;
import 'package:flutter/foundation.dart';
-import 'package:flutter/material.dart';
+import 'package:flutter/material.dart' hide TextInputAction;
import 'package:flutter/rendering.dart';
import 'package:flutter/scheduler.dart';
-import 'package:flutter/services.dart';
+import 'package:flutter/services.dart' hide TextInputAction;
import 'package:flutter_driver/flutter_driver.dart';
import 'package:flutter_driver/src/extension/extension.dart';
-import 'package:flutter_test/flutter_test.dart';
+import 'package:flutter_test/flutter_test.dart' hide TextInputAction;
import 'stubs/stub_command.dart';
import 'stubs/stub_command_extension.dart';
@@ -1245,4 +1245,41 @@
);
});
});
+
+ group('sendTextInputAction', () {
+ late FlutterDriverExtension driverExtension;
+
+ Future<void> sendAction(TextInputAction action) async {
+ final Map<String, String> arguments = SendTextInputAction(action).serialize();
+ await driverExtension.call(arguments);
+ }
+
+ MaterialApp testWidget(TextEditingController controller) => MaterialApp(
+ home: Material(
+ child: Center(
+ child: TextField(
+ key: const ValueKey<String>('foo'),
+ autofocus: true,
+ controller: controller,
+ onSubmitted: (_) {
+ controller.value = const TextEditingValue(text: 'bar');
+ },
+ ),
+ ),
+ ),
+ );
+
+ testWidgets('press done trigger onSubmitted and change value', (WidgetTester tester) async {
+ driverExtension = FlutterDriverExtension((String? arg) async => '', true, true);
+
+ final TextEditingController controller = TextEditingController(
+ text: 'foo',
+ );
+ await tester.pumpWidget(testWidget(controller));
+
+ expect(controller.value.text, 'foo');
+ await sendAction(TextInputAction.done);
+ expectSync(controller.value.text, 'bar');
+ });
+ });
}