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);
|
||||
|
||||
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;
|
||||
});
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user