Unverified Commit ea7017d3 authored by voobel's avatar voobel Committed by GitHub

enableFlutterDriverExtension: optionally disable text entry emulation (#71656)

parent d3179f0e
......@@ -32,17 +32,18 @@ const String _extensionMethodName = 'driver';
typedef DataHandler = Future<String> Function(String? message);
class _DriverBinding extends BindingBase with SchedulerBinding, ServicesBinding, GestureBinding, PaintingBinding, SemanticsBinding, RendererBinding, WidgetsBinding {
_DriverBinding(this._handler, this._silenceErrors, this.finders, this.commands);
_DriverBinding(this._handler, this._silenceErrors, this._enableTextEntryEmulation, this.finders, this.commands);
final DataHandler? _handler;
final bool _silenceErrors;
final bool _enableTextEntryEmulation;
final List<FinderExtension>? finders;
final List<CommandExtension>? commands;
@override
void initServiceExtensions() {
super.initServiceExtensions();
final FlutterDriverExtension extension = FlutterDriverExtension(_handler, _silenceErrors, finders: finders ?? const <FinderExtension>[], commands: commands ?? const <CommandExtension>[]);
final FlutterDriverExtension extension = FlutterDriverExtension(_handler, _silenceErrors, _enableTextEntryEmulation, finders: finders ?? const <FinderExtension>[], commands: commands ?? const <CommandExtension>[]);
registerServiceExtension(
name: _extensionMethodName,
callback: extension.call,
......@@ -78,6 +79,12 @@ class _DriverBinding extends BindingBase with SchedulerBinding, ServicesBinding,
/// will still be returned in the `response` field of the result JSON along
/// with an `isError` boolean.
///
/// The `enableTextEntryEmulation` parameter controls whether the application interacts
/// with the system's text entry methods or a mocked out version used by Flutter Driver.
/// If it is set to false, [FlutterDriver.enterText] will fail,
/// but testing the application with real keyboard input is possible.
/// This value may be updated during a test by calling [FlutterDriver.setTextEntryEmulation].
///
/// The `finders` and `commands` parameters are optional and used to add custom
/// finders or commands, as in the following example.
///
......@@ -217,9 +224,9 @@ class _DriverBinding extends BindingBase with SchedulerBinding, ServicesBinding,
/// }
/// ```
///
void enableFlutterDriverExtension({ DataHandler? handler, bool silenceErrors = false, List<FinderExtension>? finders, List<CommandExtension>? commands}) {
void enableFlutterDriverExtension({ DataHandler? handler, bool silenceErrors = false, bool enableTextEntryEmulation = true, List<FinderExtension>? finders, List<CommandExtension>? commands}) {
assert(WidgetsBinding.instance == null);
_DriverBinding(handler, silenceErrors, finders ?? <FinderExtension>[], commands ?? <CommandExtension>[]);
_DriverBinding(handler, silenceErrors, enableTextEntryEmulation, finders ?? <FinderExtension>[], commands ?? <CommandExtension>[]);
assert(WidgetsBinding.instance is _DriverBinding);
}
......@@ -315,11 +322,14 @@ class FlutterDriverExtension with DeserializeFinderFactory, CreateFinderFactory,
/// Creates an object to manage a Flutter Driver connection.
FlutterDriverExtension(
this._requestDataHandler,
this._silenceErrors, {
this._silenceErrors,
this._enableTextEntryEmulation, {
List<FinderExtension> finders = const <FinderExtension>[],
List<CommandExtension> commands = const <CommandExtension>[],
}) : assert(finders != null) {
registerTextInput();
if (_enableTextEntryEmulation) {
registerTextInput();
}
for(final FinderExtension finder in finders) {
_finderExtensions[finder.finderType] = finder;
......@@ -336,6 +346,8 @@ class FlutterDriverExtension with DeserializeFinderFactory, CreateFinderFactory,
final bool _silenceErrors;
final bool _enableTextEntryEmulation;
void _log(String message) {
driverLog('FlutterDriverExtension', message);
}
......
......@@ -44,7 +44,7 @@ void main() {
setUp(() {
result = null;
driverExtension = FlutterDriverExtension((String message) async { log.add(message); return (messageId += 1).toString(); }, false);
driverExtension = FlutterDriverExtension((String message) async { log.add(message); return (messageId += 1).toString(); }, false, true);
});
testWidgets('returns immediately when transient callback queue is empty', (WidgetTester tester) async {
......@@ -105,7 +105,7 @@ void main() {
setUp(() {
result = null;
driverExtension = FlutterDriverExtension((String message) async { log.add(message); return (messageId += 1).toString(); }, false);
driverExtension = FlutterDriverExtension((String message) async { log.add(message); return (messageId += 1).toString(); }, false, true);
});
testWidgets('waiting for NoTransientCallbacks returns immediately when transient callback queue is empty', (WidgetTester tester) async {
......@@ -471,7 +471,7 @@ void main() {
group('getSemanticsId', () {
FlutterDriverExtension driverExtension;
setUp(() {
driverExtension = FlutterDriverExtension((String arg) async => '', true);
driverExtension = FlutterDriverExtension((String arg) async => '', true, true);
});
testWidgets('works when semantics are enabled', (WidgetTester tester) async {
......@@ -520,7 +520,7 @@ void main() {
});
testWidgets('getOffset', (WidgetTester tester) async {
final FlutterDriverExtension driverExtension = FlutterDriverExtension((String arg) async => '', true);
final FlutterDriverExtension driverExtension = FlutterDriverExtension((String arg) async => '', true, true);
Future<Offset> getOffset(OffsetType offset) async {
final Map<String, String> arguments = GetOffset(ByValueKey(1), offset).serialize();
......@@ -552,7 +552,7 @@ void main() {
testWidgets('getText', (WidgetTester tester) async {
await silenceDriverLogger(() async {
final FlutterDriverExtension driverExtension = FlutterDriverExtension((String arg) async => '', true);
final FlutterDriverExtension driverExtension = FlutterDriverExtension((String arg) async => '', true, true);
Future<String> getTextInternal(SerializableFinder search) async {
final Map<String, String> arguments = GetText(search, timeout: const Duration(seconds: 1)).serialize();
......@@ -622,7 +622,7 @@ void main() {
testWidgets('descendant finder', (WidgetTester tester) async {
await silenceDriverLogger(() async {
final FlutterDriverExtension driverExtension = FlutterDriverExtension((String arg) async => '', true);
final FlutterDriverExtension driverExtension = FlutterDriverExtension((String arg) async => '', true, true);
Future<String> getDescendantText({ String of, bool matchRoot = false}) async {
final Map<String, String> arguments = GetText(Descendant(
......@@ -667,7 +667,7 @@ void main() {
testWidgets('descendant finder firstMatchOnly', (WidgetTester tester) async {
await silenceDriverLogger(() async {
final FlutterDriverExtension driverExtension = FlutterDriverExtension((String arg) async => '', true);
final FlutterDriverExtension driverExtension = FlutterDriverExtension((String arg) async => '', true, true);
Future<String> getDescendantText() async {
final Map<String, String> arguments = GetText(Descendant(
......@@ -701,7 +701,7 @@ void main() {
testWidgets('ancestor finder', (WidgetTester tester) async {
await silenceDriverLogger(() async {
final FlutterDriverExtension driverExtension = FlutterDriverExtension((String arg) async => '', true);
final FlutterDriverExtension driverExtension = FlutterDriverExtension((String arg) async => '', true, true);
Future<Offset> getAncestorTopLeft({ String of, String matching, bool matchRoot = false}) async {
final Map<String, String> arguments = GetOffset(Ancestor(
......@@ -771,7 +771,7 @@ void main() {
testWidgets('ancestor finder firstMatchOnly', (WidgetTester tester) async {
await silenceDriverLogger(() async {
final FlutterDriverExtension driverExtension = FlutterDriverExtension((String arg) async => '', true);
final FlutterDriverExtension driverExtension = FlutterDriverExtension((String arg) async => '', true, true);
Future<Offset> getAncestorTopLeft() async {
final Map<String, String> arguments = GetOffset(Ancestor(
......@@ -819,7 +819,7 @@ void main() {
});
testWidgets('GetDiagnosticsTree', (WidgetTester tester) async {
final FlutterDriverExtension driverExtension = FlutterDriverExtension((String arg) async => '', true);
final FlutterDriverExtension driverExtension = FlutterDriverExtension((String arg) async => '', true, true);
Future<Map<String, Object>> getDiagnosticsTree(DiagnosticsType type, SerializableFinder finder, { int depth = 0, bool properties = true }) async {
final Map<String, String> arguments = GetDiagnosticsTree(finder, type, subtreeDepth: depth, includeProperties: properties).serialize();
......@@ -884,6 +884,45 @@ void main() {
expect(children.single['children'], isEmpty);
});
group('enableTextEntryEmulation', () {
FlutterDriverExtension driverExtension;
Future<Map<String, dynamic>> enterText() async {
final Map<String, String> arguments = const EnterText('foo').serialize();
final Map<String, dynamic> result = await driverExtension.call(arguments);
return result;
}
const Widget testWidget = MaterialApp(
home: Material(
child: Center(
child: TextField(
key: ValueKey<String>('foo'),
autofocus: true,
),
),
),
);
testWidgets('enableTextEntryEmulation false', (WidgetTester tester) async {
driverExtension = FlutterDriverExtension((String arg) async => '', true, false);
await tester.pumpWidget(testWidget);
final Map<String, dynamic> enterTextResult = await enterText();
expect(enterTextResult['isError'], isTrue);
});
testWidgets('enableTextEntryEmulation true', (WidgetTester tester) async {
driverExtension = FlutterDriverExtension((String arg) async => '', true, true);
await tester.pumpWidget(testWidget);
final Map<String, dynamic> enterTextResult = await enterText();
expect(enterTextResult['isError'], isFalse);
});
});
group('extension finders', () {
final Widget debugTree = Directionality(
textDirection: TextDirection.ltr,
......@@ -907,6 +946,7 @@ void main() {
final FlutterDriverExtension driverExtension = FlutterDriverExtension(
(String arg) async => '',
true,
true,
finders: <FinderExtension>[],
);
......@@ -927,6 +967,7 @@ void main() {
final FlutterDriverExtension driverExtension = FlutterDriverExtension(
(String arg) async => '',
true,
true,
finders: <FinderExtension>[
StubFinderExtension(),
],
......@@ -948,6 +989,7 @@ void main() {
final FlutterDriverExtension driverExtension = FlutterDriverExtension(
(String arg) async => '',
true,
true,
finders: <FinderExtension>[
StubFinderExtension(),
],
......@@ -969,6 +1011,7 @@ void main() {
final FlutterDriverExtension driverExtension = FlutterDriverExtension(
(String arg) async => '',
true,
true,
finders: <FinderExtension>[
StubFinderExtension(),
],
......@@ -1013,6 +1056,7 @@ void main() {
final FlutterDriverExtension driverExtension = FlutterDriverExtension(
(String arg) async => '',
true,
true,
commands: <CommandExtension>[],
);
......@@ -1033,6 +1077,7 @@ void main() {
final FlutterDriverExtension driverExtension = FlutterDriverExtension(
(String arg) async => '',
true,
true,
commands: <CommandExtension>[
StubNestedCommandExtension(),
],
......@@ -1058,6 +1103,7 @@ void main() {
final FlutterDriverExtension driverExtension = FlutterDriverExtension(
(String arg) async => '',
true,
true,
commands: <CommandExtension>[
StubProberCommandExtension(),
],
......@@ -1085,7 +1131,7 @@ void main() {
Map<String, dynamic> result;
setUp(() {
driverExtension = FlutterDriverExtension((String arg) async => '', true);
driverExtension = FlutterDriverExtension((String arg) async => '', true, true);
result = null;
});
......
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