enableFlutterDriverExtension: optionally disable text entry emulation (#71656)
This commit is contained in:
parent
d3179f0e72
commit
ea7017d3a8
@ -32,17 +32,18 @@ const String _extensionMethodName = 'driver';
|
|||||||
typedef DataHandler = Future<String> Function(String? message);
|
typedef DataHandler = Future<String> Function(String? message);
|
||||||
|
|
||||||
class _DriverBinding extends BindingBase with SchedulerBinding, ServicesBinding, GestureBinding, PaintingBinding, SemanticsBinding, RendererBinding, WidgetsBinding {
|
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 DataHandler? _handler;
|
||||||
final bool _silenceErrors;
|
final bool _silenceErrors;
|
||||||
|
final bool _enableTextEntryEmulation;
|
||||||
final List<FinderExtension>? finders;
|
final List<FinderExtension>? finders;
|
||||||
final List<CommandExtension>? commands;
|
final List<CommandExtension>? commands;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initServiceExtensions() {
|
void initServiceExtensions() {
|
||||||
super.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(
|
registerServiceExtension(
|
||||||
name: _extensionMethodName,
|
name: _extensionMethodName,
|
||||||
callback: extension.call,
|
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
|
/// will still be returned in the `response` field of the result JSON along
|
||||||
/// with an `isError` boolean.
|
/// 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
|
/// The `finders` and `commands` parameters are optional and used to add custom
|
||||||
/// finders or commands, as in the following example.
|
/// 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);
|
assert(WidgetsBinding.instance == null);
|
||||||
_DriverBinding(handler, silenceErrors, finders ?? <FinderExtension>[], commands ?? <CommandExtension>[]);
|
_DriverBinding(handler, silenceErrors, enableTextEntryEmulation, finders ?? <FinderExtension>[], commands ?? <CommandExtension>[]);
|
||||||
assert(WidgetsBinding.instance is _DriverBinding);
|
assert(WidgetsBinding.instance is _DriverBinding);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -315,11 +322,14 @@ class FlutterDriverExtension with DeserializeFinderFactory, CreateFinderFactory,
|
|||||||
/// Creates an object to manage a Flutter Driver connection.
|
/// Creates an object to manage a Flutter Driver connection.
|
||||||
FlutterDriverExtension(
|
FlutterDriverExtension(
|
||||||
this._requestDataHandler,
|
this._requestDataHandler,
|
||||||
this._silenceErrors, {
|
this._silenceErrors,
|
||||||
|
this._enableTextEntryEmulation, {
|
||||||
List<FinderExtension> finders = const <FinderExtension>[],
|
List<FinderExtension> finders = const <FinderExtension>[],
|
||||||
List<CommandExtension> commands = const <CommandExtension>[],
|
List<CommandExtension> commands = const <CommandExtension>[],
|
||||||
}) : assert(finders != null) {
|
}) : assert(finders != null) {
|
||||||
registerTextInput();
|
if (_enableTextEntryEmulation) {
|
||||||
|
registerTextInput();
|
||||||
|
}
|
||||||
|
|
||||||
for(final FinderExtension finder in finders) {
|
for(final FinderExtension finder in finders) {
|
||||||
_finderExtensions[finder.finderType] = finder;
|
_finderExtensions[finder.finderType] = finder;
|
||||||
@ -336,6 +346,8 @@ class FlutterDriverExtension with DeserializeFinderFactory, CreateFinderFactory,
|
|||||||
|
|
||||||
final bool _silenceErrors;
|
final bool _silenceErrors;
|
||||||
|
|
||||||
|
final bool _enableTextEntryEmulation;
|
||||||
|
|
||||||
void _log(String message) {
|
void _log(String message) {
|
||||||
driverLog('FlutterDriverExtension', message);
|
driverLog('FlutterDriverExtension', message);
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ void main() {
|
|||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
result = null;
|
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 {
|
testWidgets('returns immediately when transient callback queue is empty', (WidgetTester tester) async {
|
||||||
@ -105,7 +105,7 @@ void main() {
|
|||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
result = null;
|
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 {
|
testWidgets('waiting for NoTransientCallbacks returns immediately when transient callback queue is empty', (WidgetTester tester) async {
|
||||||
@ -471,7 +471,7 @@ void main() {
|
|||||||
group('getSemanticsId', () {
|
group('getSemanticsId', () {
|
||||||
FlutterDriverExtension driverExtension;
|
FlutterDriverExtension driverExtension;
|
||||||
setUp(() {
|
setUp(() {
|
||||||
driverExtension = FlutterDriverExtension((String arg) async => '', true);
|
driverExtension = FlutterDriverExtension((String arg) async => '', true, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('works when semantics are enabled', (WidgetTester tester) async {
|
testWidgets('works when semantics are enabled', (WidgetTester tester) async {
|
||||||
@ -520,7 +520,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('getOffset', (WidgetTester tester) async {
|
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 {
|
Future<Offset> getOffset(OffsetType offset) async {
|
||||||
final Map<String, String> arguments = GetOffset(ByValueKey(1), offset).serialize();
|
final Map<String, String> arguments = GetOffset(ByValueKey(1), offset).serialize();
|
||||||
@ -552,7 +552,7 @@ void main() {
|
|||||||
|
|
||||||
testWidgets('getText', (WidgetTester tester) async {
|
testWidgets('getText', (WidgetTester tester) async {
|
||||||
await silenceDriverLogger(() 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 {
|
Future<String> getTextInternal(SerializableFinder search) async {
|
||||||
final Map<String, String> arguments = GetText(search, timeout: const Duration(seconds: 1)).serialize();
|
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 {
|
testWidgets('descendant finder', (WidgetTester tester) async {
|
||||||
await silenceDriverLogger(() 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 {
|
Future<String> getDescendantText({ String of, bool matchRoot = false}) async {
|
||||||
final Map<String, String> arguments = GetText(Descendant(
|
final Map<String, String> arguments = GetText(Descendant(
|
||||||
@ -667,7 +667,7 @@ void main() {
|
|||||||
|
|
||||||
testWidgets('descendant finder firstMatchOnly', (WidgetTester tester) async {
|
testWidgets('descendant finder firstMatchOnly', (WidgetTester tester) async {
|
||||||
await silenceDriverLogger(() 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 {
|
Future<String> getDescendantText() async {
|
||||||
final Map<String, String> arguments = GetText(Descendant(
|
final Map<String, String> arguments = GetText(Descendant(
|
||||||
@ -701,7 +701,7 @@ void main() {
|
|||||||
|
|
||||||
testWidgets('ancestor finder', (WidgetTester tester) async {
|
testWidgets('ancestor finder', (WidgetTester tester) async {
|
||||||
await silenceDriverLogger(() 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 {
|
Future<Offset> getAncestorTopLeft({ String of, String matching, bool matchRoot = false}) async {
|
||||||
final Map<String, String> arguments = GetOffset(Ancestor(
|
final Map<String, String> arguments = GetOffset(Ancestor(
|
||||||
@ -771,7 +771,7 @@ void main() {
|
|||||||
|
|
||||||
testWidgets('ancestor finder firstMatchOnly', (WidgetTester tester) async {
|
testWidgets('ancestor finder firstMatchOnly', (WidgetTester tester) async {
|
||||||
await silenceDriverLogger(() 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 {
|
Future<Offset> getAncestorTopLeft() async {
|
||||||
final Map<String, String> arguments = GetOffset(Ancestor(
|
final Map<String, String> arguments = GetOffset(Ancestor(
|
||||||
@ -819,7 +819,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('GetDiagnosticsTree', (WidgetTester tester) async {
|
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 {
|
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();
|
final Map<String, String> arguments = GetDiagnosticsTree(finder, type, subtreeDepth: depth, includeProperties: properties).serialize();
|
||||||
@ -884,6 +884,45 @@ void main() {
|
|||||||
expect(children.single['children'], isEmpty);
|
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', () {
|
group('extension finders', () {
|
||||||
final Widget debugTree = Directionality(
|
final Widget debugTree = Directionality(
|
||||||
textDirection: TextDirection.ltr,
|
textDirection: TextDirection.ltr,
|
||||||
@ -907,6 +946,7 @@ void main() {
|
|||||||
final FlutterDriverExtension driverExtension = FlutterDriverExtension(
|
final FlutterDriverExtension driverExtension = FlutterDriverExtension(
|
||||||
(String arg) async => '',
|
(String arg) async => '',
|
||||||
true,
|
true,
|
||||||
|
true,
|
||||||
finders: <FinderExtension>[],
|
finders: <FinderExtension>[],
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -927,6 +967,7 @@ void main() {
|
|||||||
final FlutterDriverExtension driverExtension = FlutterDriverExtension(
|
final FlutterDriverExtension driverExtension = FlutterDriverExtension(
|
||||||
(String arg) async => '',
|
(String arg) async => '',
|
||||||
true,
|
true,
|
||||||
|
true,
|
||||||
finders: <FinderExtension>[
|
finders: <FinderExtension>[
|
||||||
StubFinderExtension(),
|
StubFinderExtension(),
|
||||||
],
|
],
|
||||||
@ -948,6 +989,7 @@ void main() {
|
|||||||
final FlutterDriverExtension driverExtension = FlutterDriverExtension(
|
final FlutterDriverExtension driverExtension = FlutterDriverExtension(
|
||||||
(String arg) async => '',
|
(String arg) async => '',
|
||||||
true,
|
true,
|
||||||
|
true,
|
||||||
finders: <FinderExtension>[
|
finders: <FinderExtension>[
|
||||||
StubFinderExtension(),
|
StubFinderExtension(),
|
||||||
],
|
],
|
||||||
@ -969,6 +1011,7 @@ void main() {
|
|||||||
final FlutterDriverExtension driverExtension = FlutterDriverExtension(
|
final FlutterDriverExtension driverExtension = FlutterDriverExtension(
|
||||||
(String arg) async => '',
|
(String arg) async => '',
|
||||||
true,
|
true,
|
||||||
|
true,
|
||||||
finders: <FinderExtension>[
|
finders: <FinderExtension>[
|
||||||
StubFinderExtension(),
|
StubFinderExtension(),
|
||||||
],
|
],
|
||||||
@ -1013,6 +1056,7 @@ void main() {
|
|||||||
final FlutterDriverExtension driverExtension = FlutterDriverExtension(
|
final FlutterDriverExtension driverExtension = FlutterDriverExtension(
|
||||||
(String arg) async => '',
|
(String arg) async => '',
|
||||||
true,
|
true,
|
||||||
|
true,
|
||||||
commands: <CommandExtension>[],
|
commands: <CommandExtension>[],
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -1033,6 +1077,7 @@ void main() {
|
|||||||
final FlutterDriverExtension driverExtension = FlutterDriverExtension(
|
final FlutterDriverExtension driverExtension = FlutterDriverExtension(
|
||||||
(String arg) async => '',
|
(String arg) async => '',
|
||||||
true,
|
true,
|
||||||
|
true,
|
||||||
commands: <CommandExtension>[
|
commands: <CommandExtension>[
|
||||||
StubNestedCommandExtension(),
|
StubNestedCommandExtension(),
|
||||||
],
|
],
|
||||||
@ -1058,6 +1103,7 @@ void main() {
|
|||||||
final FlutterDriverExtension driverExtension = FlutterDriverExtension(
|
final FlutterDriverExtension driverExtension = FlutterDriverExtension(
|
||||||
(String arg) async => '',
|
(String arg) async => '',
|
||||||
true,
|
true,
|
||||||
|
true,
|
||||||
commands: <CommandExtension>[
|
commands: <CommandExtension>[
|
||||||
StubProberCommandExtension(),
|
StubProberCommandExtension(),
|
||||||
],
|
],
|
||||||
@ -1085,7 +1131,7 @@ void main() {
|
|||||||
Map<String, dynamic> result;
|
Map<String, dynamic> result;
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
driverExtension = FlutterDriverExtension((String arg) async => '', true);
|
driverExtension = FlutterDriverExtension((String arg) async => '', true, true);
|
||||||
result = null;
|
result = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user