mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Revert "Flutter Driver - Create widget finders from serialized finders extensions (#67456)" (#67687)
This reverts commit 74f6fa4564
.
This commit is contained in:
parent
74f6fa4564
commit
4042eb97b9
@ -1,115 +0,0 @@
|
|||||||
// Copyright 2014 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
|
||||||
import 'package:flutter/widgets.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
|
|
||||||
import 'find.dart';
|
|
||||||
|
|
||||||
/// A factory which creates [Finder]s from [SerializableFinder]s.
|
|
||||||
mixin CreateFinderFactory {
|
|
||||||
/// Creates the flutter widget finder from [SerializableFinder].
|
|
||||||
Finder createFinder(SerializableFinder finder) {
|
|
||||||
switch (finder.finderType) {
|
|
||||||
case 'ByText':
|
|
||||||
return _createByTextFinder(finder as ByText);
|
|
||||||
case 'ByTooltipMessage':
|
|
||||||
return _createByTooltipMessageFinder(finder as ByTooltipMessage);
|
|
||||||
case 'BySemanticsLabel':
|
|
||||||
return _createBySemanticsLabelFinder(finder as BySemanticsLabel);
|
|
||||||
case 'ByValueKey':
|
|
||||||
return _createByValueKeyFinder(finder as ByValueKey);
|
|
||||||
case 'ByType':
|
|
||||||
return _createByTypeFinder(finder as ByType);
|
|
||||||
case 'PageBack':
|
|
||||||
return _createPageBackFinder();
|
|
||||||
case 'Ancestor':
|
|
||||||
return _createAncestorFinder(finder as Ancestor);
|
|
||||||
case 'Descendant':
|
|
||||||
return _createDescendantFinder(finder as Descendant);
|
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Finder _createByTextFinder(ByText arguments) {
|
|
||||||
return find.text(arguments.text);
|
|
||||||
}
|
|
||||||
|
|
||||||
Finder _createByTooltipMessageFinder(ByTooltipMessage arguments) {
|
|
||||||
return find.byElementPredicate((Element element) {
|
|
||||||
final Widget widget = element.widget;
|
|
||||||
if (widget is Tooltip) {
|
|
||||||
return widget.message == arguments.text;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}, description: 'widget with text tooltip "${arguments.text}"');
|
|
||||||
}
|
|
||||||
|
|
||||||
Finder _createBySemanticsLabelFinder(BySemanticsLabel arguments) {
|
|
||||||
return find.byElementPredicate((Element element) {
|
|
||||||
if (element is! RenderObjectElement) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
final String semanticsLabel = element.renderObject?.debugSemantics?.label;
|
|
||||||
if (semanticsLabel == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
final Pattern label = arguments.label;
|
|
||||||
return label is RegExp
|
|
||||||
? label.hasMatch(semanticsLabel)
|
|
||||||
: label == semanticsLabel;
|
|
||||||
}, description: 'widget with semantic label "${arguments.label}"');
|
|
||||||
}
|
|
||||||
|
|
||||||
Finder _createByValueKeyFinder(ByValueKey arguments) {
|
|
||||||
switch (arguments.keyValueType) {
|
|
||||||
case 'int':
|
|
||||||
return find.byKey(ValueKey<int>(arguments.keyValue as int));
|
|
||||||
case 'String':
|
|
||||||
return find.byKey(ValueKey<String>(arguments.keyValue as String));
|
|
||||||
default:
|
|
||||||
throw 'Unsupported ByValueKey type: ${arguments.keyValueType}';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Finder _createByTypeFinder(ByType arguments) {
|
|
||||||
return find.byElementPredicate((Element element) {
|
|
||||||
return element.widget.runtimeType.toString() == arguments.type;
|
|
||||||
}, description: 'widget with runtimeType "${arguments.type}"');
|
|
||||||
}
|
|
||||||
|
|
||||||
Finder _createPageBackFinder() {
|
|
||||||
return find.byElementPredicate((Element element) {
|
|
||||||
final Widget widget = element.widget;
|
|
||||||
if (widget is Tooltip) {
|
|
||||||
return widget.message == 'Back';
|
|
||||||
}
|
|
||||||
if (widget is CupertinoNavigationBarBackButton) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}, description: 'Material or Cupertino back button');
|
|
||||||
}
|
|
||||||
|
|
||||||
Finder _createAncestorFinder(Ancestor arguments) {
|
|
||||||
final Finder finder = find.ancestor(
|
|
||||||
of: createFinder(arguments.of),
|
|
||||||
matching: createFinder(arguments.matching),
|
|
||||||
matchRoot: arguments.matchRoot,
|
|
||||||
);
|
|
||||||
return arguments.firstMatchOnly ? finder.first : finder;
|
|
||||||
}
|
|
||||||
|
|
||||||
Finder _createDescendantFinder(Descendant arguments) {
|
|
||||||
final Finder finder = find.descendant(
|
|
||||||
of: createFinder(arguments.of),
|
|
||||||
matching: createFinder(arguments.matching),
|
|
||||||
matchRoot: arguments.matchRoot,
|
|
||||||
);
|
|
||||||
return arguments.firstMatchOnly ? finder.first : finder;
|
|
||||||
}
|
|
||||||
}
|
|
@ -24,7 +24,7 @@ mixin DeserializeFinderFactory {
|
|||||||
case 'Descendant': return Descendant.deserialize(json, this);
|
case 'Descendant': return Descendant.deserialize(json, this);
|
||||||
case 'Ancestor': return Ancestor.deserialize(json, this);
|
case 'Ancestor': return Ancestor.deserialize(json, this);
|
||||||
}
|
}
|
||||||
return null;
|
throw DriverError('Unsupported search specification type $finderType');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter_driver/src/common/create_finder_factory.dart';
|
|
||||||
import 'package:meta/meta.dart';
|
import 'package:meta/meta.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
@ -124,7 +123,7 @@ class _DriverBinding extends BindingBase with SchedulerBinding, ServicesBinding,
|
|||||||
/// return Some(json['title']);
|
/// return Some(json['title']);
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// Finder createFinder(SerializableFinder finder, CreateFinderFactory finderFactory) {
|
/// Finder createFinder(SerializableFinder finder) {
|
||||||
/// Some someFinder = finder as Some;
|
/// Some someFinder = finder as Some;
|
||||||
///
|
///
|
||||||
/// return find.byElementPredicate((Element element) {
|
/// return find.byElementPredicate((Element element) {
|
||||||
@ -157,13 +156,11 @@ abstract class FinderExtension {
|
|||||||
String get finderType;
|
String get finderType;
|
||||||
|
|
||||||
/// Deserializes the finder from JSON generated by [SerializableFinder.serialize].
|
/// Deserializes the finder from JSON generated by [SerializableFinder.serialize].
|
||||||
/// [finderFactory] could be used to deserialize nested finders.
|
|
||||||
SerializableFinder deserialize(Map<String, String> params, DeserializeFinderFactory finderFactory);
|
SerializableFinder deserialize(Map<String, String> params, DeserializeFinderFactory finderFactory);
|
||||||
|
|
||||||
/// Signature for functions that run the given finder and return the [Element]
|
/// Signature for functions that run the given finder and return the [Element]
|
||||||
/// found, if any, or null otherwise.
|
/// found, if any, or null otherwise.
|
||||||
/// [finderFactory] could be used to create nested finders.
|
Finder createFinder(SerializableFinder finder);
|
||||||
Finder createFinder(SerializableFinder finder, CreateFinderFactory finderFactory);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The class that manages communication between a Flutter Driver test and the
|
/// The class that manages communication between a Flutter Driver test and the
|
||||||
@ -172,7 +169,7 @@ abstract class FinderExtension {
|
|||||||
/// This is not normally used directly. It is instantiated automatically when
|
/// This is not normally used directly. It is instantiated automatically when
|
||||||
/// calling [enableFlutterDriverExtension].
|
/// calling [enableFlutterDriverExtension].
|
||||||
@visibleForTesting
|
@visibleForTesting
|
||||||
class FlutterDriverExtension with DeserializeFinderFactory, CreateFinderFactory {
|
class FlutterDriverExtension with DeserializeFinderFactory {
|
||||||
/// Creates an object to manage a Flutter Driver connection.
|
/// Creates an object to manage a Flutter Driver connection.
|
||||||
FlutterDriverExtension(
|
FlutterDriverExtension(
|
||||||
this._requestDataHandler,
|
this._requestDataHandler,
|
||||||
@ -357,39 +354,112 @@ class FlutterDriverExtension with DeserializeFinderFactory, CreateFinderFactory
|
|||||||
return finder;
|
return finder;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
Finder _createByTextFinder(ByText arguments) {
|
||||||
SerializableFinder deserializeFinder(Map<String, String> json) {
|
return find.text(arguments.text);
|
||||||
final SerializableFinder standard = super.deserializeFinder(json);
|
|
||||||
if (standard != null) {
|
|
||||||
return standard;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final String finderType = json['finderType'];
|
Finder _createByTooltipMessageFinder(ByTooltipMessage arguments) {
|
||||||
if (_finderExtensions.containsKey(finderType)) {
|
return find.byElementPredicate((Element element) {
|
||||||
return _finderExtensions[finderType].deserialize(json, this);
|
final Widget widget = element.widget;
|
||||||
|
if (widget is Tooltip)
|
||||||
|
return widget.message == arguments.text;
|
||||||
|
return false;
|
||||||
|
}, description: 'widget with text tooltip "${arguments.text}"');
|
||||||
}
|
}
|
||||||
|
|
||||||
throw DriverError('Unsupported search specification type $finderType');
|
Finder _createBySemanticsLabelFinder(BySemanticsLabel arguments) {
|
||||||
|
return find.byElementPredicate((Element element) {
|
||||||
|
if (element is! RenderObjectElement) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final String semanticsLabel = element.renderObject?.debugSemantics?.label;
|
||||||
|
if (semanticsLabel == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final Pattern label = arguments.label;
|
||||||
|
return label is RegExp
|
||||||
|
? label.hasMatch(semanticsLabel)
|
||||||
|
: label == semanticsLabel;
|
||||||
|
}, description: 'widget with semantic label "${arguments.label}"');
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
Finder _createByValueKeyFinder(ByValueKey arguments) {
|
||||||
Finder createFinder(SerializableFinder finder) {
|
switch (arguments.keyValueType) {
|
||||||
final Finder standard = super.createFinder(finder);
|
case 'int':
|
||||||
if(standard != null) {
|
return find.byKey(ValueKey<int>(arguments.keyValue as int));
|
||||||
return standard;
|
case 'String':
|
||||||
|
return find.byKey(ValueKey<String>(arguments.keyValue as String));
|
||||||
|
default:
|
||||||
|
throw 'Unsupported ByValueKey type: ${arguments.keyValueType}';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Finder _createByTypeFinder(ByType arguments) {
|
||||||
|
return find.byElementPredicate((Element element) {
|
||||||
|
return element.widget.runtimeType.toString() == arguments.type;
|
||||||
|
}, description: 'widget with runtimeType "${arguments.type}"');
|
||||||
|
}
|
||||||
|
|
||||||
|
Finder _createPageBackFinder() {
|
||||||
|
return find.byElementPredicate((Element element) {
|
||||||
|
final Widget widget = element.widget;
|
||||||
|
if (widget is Tooltip)
|
||||||
|
return widget.message == 'Back';
|
||||||
|
if (widget is CupertinoNavigationBarBackButton)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}, description: 'Material or Cupertino back button');
|
||||||
|
}
|
||||||
|
|
||||||
|
Finder _createAncestorFinder(Ancestor arguments) {
|
||||||
|
final Finder finder = find.ancestor(
|
||||||
|
of: _createFinder(arguments.of),
|
||||||
|
matching: _createFinder(arguments.matching),
|
||||||
|
matchRoot: arguments.matchRoot,
|
||||||
|
);
|
||||||
|
return arguments.firstMatchOnly ? finder.first : finder;
|
||||||
|
}
|
||||||
|
|
||||||
|
Finder _createDescendantFinder(Descendant arguments) {
|
||||||
|
final Finder finder = find.descendant(
|
||||||
|
of: _createFinder(arguments.of),
|
||||||
|
matching: _createFinder(arguments.matching),
|
||||||
|
matchRoot: arguments.matchRoot,
|
||||||
|
);
|
||||||
|
return arguments.firstMatchOnly ? finder.first : finder;
|
||||||
|
}
|
||||||
|
|
||||||
|
Finder _createFinder(SerializableFinder finder) {
|
||||||
|
switch (finder.finderType) {
|
||||||
|
case 'ByText':
|
||||||
|
return _createByTextFinder(finder as ByText);
|
||||||
|
case 'ByTooltipMessage':
|
||||||
|
return _createByTooltipMessageFinder(finder as ByTooltipMessage);
|
||||||
|
case 'BySemanticsLabel':
|
||||||
|
return _createBySemanticsLabelFinder(finder as BySemanticsLabel);
|
||||||
|
case 'ByValueKey':
|
||||||
|
return _createByValueKeyFinder(finder as ByValueKey);
|
||||||
|
case 'ByType':
|
||||||
|
return _createByTypeFinder(finder as ByType);
|
||||||
|
case 'PageBack':
|
||||||
|
return _createPageBackFinder();
|
||||||
|
case 'Ancestor':
|
||||||
|
return _createAncestorFinder(finder as Ancestor);
|
||||||
|
case 'Descendant':
|
||||||
|
return _createDescendantFinder(finder as Descendant);
|
||||||
|
default:
|
||||||
if (_finderExtensions.containsKey(finder.finderType)) {
|
if (_finderExtensions.containsKey(finder.finderType)) {
|
||||||
return _finderExtensions[finder.finderType].createFinder(finder, this);
|
return _finderExtensions[finder.finderType].createFinder(finder);
|
||||||
|
} else {
|
||||||
|
throw 'Unsupported finder type: ${finder.finderType}';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw DriverError('Unsupported search specification type ${finder.finderType}');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<TapResult> _tap(Command command) async {
|
Future<TapResult> _tap(Command command) async {
|
||||||
final Tap tapCommand = command as Tap;
|
final Tap tapCommand = command as Tap;
|
||||||
final Finder computedFinder = await _waitForElement(
|
final Finder computedFinder = await _waitForElement(
|
||||||
createFinder(tapCommand.finder).hitTestable()
|
_createFinder(tapCommand.finder).hitTestable()
|
||||||
);
|
);
|
||||||
await _prober.tap(computedFinder);
|
await _prober.tap(computedFinder);
|
||||||
return const TapResult();
|
return const TapResult();
|
||||||
@ -397,13 +467,13 @@ class FlutterDriverExtension with DeserializeFinderFactory, CreateFinderFactory
|
|||||||
|
|
||||||
Future<WaitForResult> _waitFor(Command command) async {
|
Future<WaitForResult> _waitFor(Command command) async {
|
||||||
final WaitFor waitForCommand = command as WaitFor;
|
final WaitFor waitForCommand = command as WaitFor;
|
||||||
await _waitForElement(createFinder(waitForCommand.finder));
|
await _waitForElement(_createFinder(waitForCommand.finder));
|
||||||
return const WaitForResult();
|
return const WaitForResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<WaitForAbsentResult> _waitForAbsent(Command command) async {
|
Future<WaitForAbsentResult> _waitForAbsent(Command command) async {
|
||||||
final WaitForAbsent waitForAbsentCommand = command as WaitForAbsent;
|
final WaitForAbsent waitForAbsentCommand = command as WaitForAbsent;
|
||||||
await _waitForAbsentElement(createFinder(waitForAbsentCommand.finder));
|
await _waitForAbsentElement(_createFinder(waitForAbsentCommand.finder));
|
||||||
return const WaitForAbsentResult();
|
return const WaitForAbsentResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -458,7 +528,7 @@ class FlutterDriverExtension with DeserializeFinderFactory, CreateFinderFactory
|
|||||||
|
|
||||||
Future<GetSemanticsIdResult> _getSemanticsId(Command command) async {
|
Future<GetSemanticsIdResult> _getSemanticsId(Command command) async {
|
||||||
final GetSemanticsId semanticsCommand = command as GetSemanticsId;
|
final GetSemanticsId semanticsCommand = command as GetSemanticsId;
|
||||||
final Finder target = await _waitForElement(createFinder(semanticsCommand.finder));
|
final Finder target = await _waitForElement(_createFinder(semanticsCommand.finder));
|
||||||
final Iterable<Element> elements = target.evaluate();
|
final Iterable<Element> elements = target.evaluate();
|
||||||
if (elements.length > 1) {
|
if (elements.length > 1) {
|
||||||
throw StateError('Found more than one element with the same ID: $elements');
|
throw StateError('Found more than one element with the same ID: $elements');
|
||||||
@ -477,7 +547,7 @@ class FlutterDriverExtension with DeserializeFinderFactory, CreateFinderFactory
|
|||||||
|
|
||||||
Future<GetOffsetResult> _getOffset(Command command) async {
|
Future<GetOffsetResult> _getOffset(Command command) async {
|
||||||
final GetOffset getOffsetCommand = command as GetOffset;
|
final GetOffset getOffsetCommand = command as GetOffset;
|
||||||
final Finder finder = await _waitForElement(createFinder(getOffsetCommand.finder));
|
final Finder finder = await _waitForElement(_createFinder(getOffsetCommand.finder));
|
||||||
final Element element = finder.evaluate().single;
|
final Element element = finder.evaluate().single;
|
||||||
final RenderBox box = element.renderObject as RenderBox;
|
final RenderBox box = element.renderObject as RenderBox;
|
||||||
Offset localPoint;
|
Offset localPoint;
|
||||||
@ -504,7 +574,7 @@ class FlutterDriverExtension with DeserializeFinderFactory, CreateFinderFactory
|
|||||||
|
|
||||||
Future<DiagnosticsTreeResult> _getDiagnosticsTree(Command command) async {
|
Future<DiagnosticsTreeResult> _getDiagnosticsTree(Command command) async {
|
||||||
final GetDiagnosticsTree diagnosticsCommand = command as GetDiagnosticsTree;
|
final GetDiagnosticsTree diagnosticsCommand = command as GetDiagnosticsTree;
|
||||||
final Finder finder = await _waitForElement(createFinder(diagnosticsCommand.finder));
|
final Finder finder = await _waitForElement(_createFinder(diagnosticsCommand.finder));
|
||||||
final Element element = finder.evaluate().single;
|
final Element element = finder.evaluate().single;
|
||||||
DiagnosticsNode diagnosticsNode;
|
DiagnosticsNode diagnosticsNode;
|
||||||
switch (diagnosticsCommand.diagnosticsType) {
|
switch (diagnosticsCommand.diagnosticsType) {
|
||||||
@ -523,7 +593,7 @@ class FlutterDriverExtension with DeserializeFinderFactory, CreateFinderFactory
|
|||||||
|
|
||||||
Future<ScrollResult> _scroll(Command command) async {
|
Future<ScrollResult> _scroll(Command command) async {
|
||||||
final Scroll scrollCommand = command as Scroll;
|
final Scroll scrollCommand = command as Scroll;
|
||||||
final Finder target = await _waitForElement(createFinder(scrollCommand.finder));
|
final Finder target = await _waitForElement(_createFinder(scrollCommand.finder));
|
||||||
final int totalMoves = scrollCommand.duration.inMicroseconds * scrollCommand.frequency ~/ Duration.microsecondsPerSecond;
|
final int totalMoves = scrollCommand.duration.inMicroseconds * scrollCommand.frequency ~/ Duration.microsecondsPerSecond;
|
||||||
final Offset delta = Offset(scrollCommand.dx, scrollCommand.dy) / totalMoves.toDouble();
|
final Offset delta = Offset(scrollCommand.dx, scrollCommand.dy) / totalMoves.toDouble();
|
||||||
final Duration pause = scrollCommand.duration ~/ totalMoves;
|
final Duration pause = scrollCommand.duration ~/ totalMoves;
|
||||||
@ -544,14 +614,14 @@ class FlutterDriverExtension with DeserializeFinderFactory, CreateFinderFactory
|
|||||||
|
|
||||||
Future<ScrollResult> _scrollIntoView(Command command) async {
|
Future<ScrollResult> _scrollIntoView(Command command) async {
|
||||||
final ScrollIntoView scrollIntoViewCommand = command as ScrollIntoView;
|
final ScrollIntoView scrollIntoViewCommand = command as ScrollIntoView;
|
||||||
final Finder target = await _waitForElement(createFinder(scrollIntoViewCommand.finder));
|
final Finder target = await _waitForElement(_createFinder(scrollIntoViewCommand.finder));
|
||||||
await Scrollable.ensureVisible(target.evaluate().single, duration: const Duration(milliseconds: 100), alignment: scrollIntoViewCommand.alignment ?? 0.0);
|
await Scrollable.ensureVisible(target.evaluate().single, duration: const Duration(milliseconds: 100), alignment: scrollIntoViewCommand.alignment ?? 0.0);
|
||||||
return const ScrollResult();
|
return const ScrollResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<GetTextResult> _getText(Command command) async {
|
Future<GetTextResult> _getText(Command command) async {
|
||||||
final GetText getTextCommand = command as GetText;
|
final GetText getTextCommand = command as GetText;
|
||||||
final Finder target = await _waitForElement(createFinder(getTextCommand.finder));
|
final Finder target = await _waitForElement(_createFinder(getTextCommand.finder));
|
||||||
|
|
||||||
final Widget widget = target.evaluate().single.widget;
|
final Widget widget = target.evaluate().single.widget;
|
||||||
String text;
|
String text;
|
||||||
|
@ -18,9 +18,6 @@ import 'package:flutter_driver/src/common/wait.dart';
|
|||||||
import 'package:flutter_driver/src/extension/extension.dart';
|
import 'package:flutter_driver/src/extension/extension.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
import 'stubs/stub_finder.dart';
|
|
||||||
import 'stubs/stub_finder_extension.dart';
|
|
||||||
|
|
||||||
Future<void> silenceDriverLogger(AsyncCallback callback) async {
|
Future<void> silenceDriverLogger(AsyncCallback callback) async {
|
||||||
final DriverLogCallback oldLogger = driverLog;
|
final DriverLogCallback oldLogger = driverLog;
|
||||||
driverLog = (String source, String message) { };
|
driverLog = (String source, String message) { };
|
||||||
@ -33,18 +30,18 @@ Future<void> silenceDriverLogger(AsyncCallback callback) async {
|
|||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
group('waitUntilNoTransientCallbacks', () {
|
group('waitUntilNoTransientCallbacks', () {
|
||||||
FlutterDriverExtension driverExtension;
|
FlutterDriverExtension extension;
|
||||||
Map<String, dynamic> result;
|
Map<String, dynamic> result;
|
||||||
int messageId = 0;
|
int messageId = 0;
|
||||||
final List<String> log = <String>[];
|
final List<String> log = <String>[];
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
result = null;
|
result = null;
|
||||||
driverExtension = FlutterDriverExtension((String message) async { log.add(message); return (messageId += 1).toString(); }, false);
|
extension = FlutterDriverExtension((String message) async { log.add(message); return (messageId += 1).toString(); }, false);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('returns immediately when transient callback queue is empty', (WidgetTester tester) async {
|
testWidgets('returns immediately when transient callback queue is empty', (WidgetTester tester) async {
|
||||||
driverExtension.call(const WaitUntilNoTransientCallbacks().serialize())
|
extension.call(const WaitUntilNoTransientCallbacks().serialize())
|
||||||
.then<void>(expectAsync1((Map<String, dynamic> r) {
|
.then<void>(expectAsync1((Map<String, dynamic> r) {
|
||||||
result = r;
|
result = r;
|
||||||
}));
|
}));
|
||||||
@ -64,7 +61,7 @@ void main() {
|
|||||||
// Intentionally blank. We only care about existence of a callback.
|
// Intentionally blank. We only care about existence of a callback.
|
||||||
});
|
});
|
||||||
|
|
||||||
driverExtension.call(const WaitUntilNoTransientCallbacks().serialize())
|
extension.call(const WaitUntilNoTransientCallbacks().serialize())
|
||||||
.then<void>(expectAsync1((Map<String, dynamic> r) {
|
.then<void>(expectAsync1((Map<String, dynamic> r) {
|
||||||
result = r;
|
result = r;
|
||||||
}));
|
}));
|
||||||
@ -86,7 +83,7 @@ void main() {
|
|||||||
|
|
||||||
testWidgets('handler', (WidgetTester tester) async {
|
testWidgets('handler', (WidgetTester tester) async {
|
||||||
expect(log, isEmpty);
|
expect(log, isEmpty);
|
||||||
final Map<String, dynamic> response = await driverExtension.call(const RequestData('hello').serialize());
|
final Map<String, dynamic> response = await extension.call(const RequestData('hello').serialize());
|
||||||
final RequestDataResult result = RequestDataResult.fromJson(response['response'] as Map<String, dynamic>);
|
final RequestDataResult result = RequestDataResult.fromJson(response['response'] as Map<String, dynamic>);
|
||||||
expect(log, <String>['hello']);
|
expect(log, <String>['hello']);
|
||||||
expect(result.message, '1');
|
expect(result.message, '1');
|
||||||
@ -94,18 +91,18 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
group('waitForCondition', () {
|
group('waitForCondition', () {
|
||||||
FlutterDriverExtension driverExtension;
|
FlutterDriverExtension extension;
|
||||||
Map<String, dynamic> result;
|
Map<String, dynamic> result;
|
||||||
int messageId = 0;
|
int messageId = 0;
|
||||||
final List<String> log = <String>[];
|
final List<String> log = <String>[];
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
result = null;
|
result = null;
|
||||||
driverExtension = FlutterDriverExtension((String message) async { log.add(message); return (messageId += 1).toString(); }, false);
|
extension = FlutterDriverExtension((String message) async { log.add(message); return (messageId += 1).toString(); }, false);
|
||||||
});
|
});
|
||||||
|
|
||||||
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 {
|
||||||
driverExtension.call(const WaitForCondition(NoTransientCallbacks()).serialize())
|
extension.call(const WaitForCondition(NoTransientCallbacks()).serialize())
|
||||||
.then<void>(expectAsync1((Map<String, dynamic> r) {
|
.then<void>(expectAsync1((Map<String, dynamic> r) {
|
||||||
result = r;
|
result = r;
|
||||||
}));
|
}));
|
||||||
@ -125,7 +122,7 @@ void main() {
|
|||||||
// Intentionally blank. We only care about existence of a callback.
|
// Intentionally blank. We only care about existence of a callback.
|
||||||
});
|
});
|
||||||
|
|
||||||
driverExtension.call(const WaitForCondition(NoTransientCallbacks()).serialize())
|
extension.call(const WaitForCondition(NoTransientCallbacks()).serialize())
|
||||||
.then<void>(expectAsync1((Map<String, dynamic> r) {
|
.then<void>(expectAsync1((Map<String, dynamic> r) {
|
||||||
result = r;
|
result = r;
|
||||||
}));
|
}));
|
||||||
@ -147,7 +144,7 @@ void main() {
|
|||||||
|
|
||||||
testWidgets('waiting for NoPendingFrame returns immediately when frame is synced', (
|
testWidgets('waiting for NoPendingFrame returns immediately when frame is synced', (
|
||||||
WidgetTester tester) async {
|
WidgetTester tester) async {
|
||||||
driverExtension.call(const WaitForCondition(NoPendingFrame()).serialize())
|
extension.call(const WaitForCondition(NoPendingFrame()).serialize())
|
||||||
.then<void>(expectAsync1((Map<String, dynamic> r) {
|
.then<void>(expectAsync1((Map<String, dynamic> r) {
|
||||||
result = r;
|
result = r;
|
||||||
}));
|
}));
|
||||||
@ -165,7 +162,7 @@ void main() {
|
|||||||
testWidgets('waiting for NoPendingFrame returns until no pending scheduled frame', (WidgetTester tester) async {
|
testWidgets('waiting for NoPendingFrame returns until no pending scheduled frame', (WidgetTester tester) async {
|
||||||
SchedulerBinding.instance.scheduleFrame();
|
SchedulerBinding.instance.scheduleFrame();
|
||||||
|
|
||||||
driverExtension.call(const WaitForCondition(NoPendingFrame()).serialize())
|
extension.call(const WaitForCondition(NoPendingFrame()).serialize())
|
||||||
.then<void>(expectAsync1((Map<String, dynamic> r) {
|
.then<void>(expectAsync1((Map<String, dynamic> r) {
|
||||||
result = r;
|
result = r;
|
||||||
}));
|
}));
|
||||||
@ -189,7 +186,7 @@ void main() {
|
|||||||
'waiting for combined conditions returns immediately', (WidgetTester tester) async {
|
'waiting for combined conditions returns immediately', (WidgetTester tester) async {
|
||||||
const SerializableWaitCondition combinedCondition =
|
const SerializableWaitCondition combinedCondition =
|
||||||
CombinedCondition(<SerializableWaitCondition>[NoTransientCallbacks(), NoPendingFrame()]);
|
CombinedCondition(<SerializableWaitCondition>[NoTransientCallbacks(), NoPendingFrame()]);
|
||||||
driverExtension.call(const WaitForCondition(combinedCondition).serialize())
|
extension.call(const WaitForCondition(combinedCondition).serialize())
|
||||||
.then<void>(expectAsync1((Map<String, dynamic> r) {
|
.then<void>(expectAsync1((Map<String, dynamic> r) {
|
||||||
result = r;
|
result = r;
|
||||||
}));
|
}));
|
||||||
@ -213,7 +210,7 @@ void main() {
|
|||||||
|
|
||||||
const SerializableWaitCondition combinedCondition =
|
const SerializableWaitCondition combinedCondition =
|
||||||
CombinedCondition(<SerializableWaitCondition>[NoTransientCallbacks(), NoPendingFrame()]);
|
CombinedCondition(<SerializableWaitCondition>[NoTransientCallbacks(), NoPendingFrame()]);
|
||||||
driverExtension.call(const WaitForCondition(combinedCondition).serialize())
|
extension.call(const WaitForCondition(combinedCondition).serialize())
|
||||||
.then<void>(expectAsync1((Map<String, dynamic> r) {
|
.then<void>(expectAsync1((Map<String, dynamic> r) {
|
||||||
result = r;
|
result = r;
|
||||||
}));
|
}));
|
||||||
@ -242,7 +239,7 @@ void main() {
|
|||||||
|
|
||||||
const SerializableWaitCondition combinedCondition =
|
const SerializableWaitCondition combinedCondition =
|
||||||
CombinedCondition(<SerializableWaitCondition>[NoPendingFrame(), NoTransientCallbacks()]);
|
CombinedCondition(<SerializableWaitCondition>[NoPendingFrame(), NoTransientCallbacks()]);
|
||||||
driverExtension.call(const WaitForCondition(combinedCondition).serialize())
|
extension.call(const WaitForCondition(combinedCondition).serialize())
|
||||||
.then<void>(expectAsync1((Map<String, dynamic> r) {
|
.then<void>(expectAsync1((Map<String, dynamic> r) {
|
||||||
result = r;
|
result = r;
|
||||||
}));
|
}));
|
||||||
@ -264,7 +261,7 @@ void main() {
|
|||||||
|
|
||||||
testWidgets(
|
testWidgets(
|
||||||
"waiting for NoPendingPlatformMessages returns immediately when there're no platform messages", (WidgetTester tester) async {
|
"waiting for NoPendingPlatformMessages returns immediately when there're no platform messages", (WidgetTester tester) async {
|
||||||
driverExtension
|
extension
|
||||||
.call(const WaitForCondition(NoPendingPlatformMessages()).serialize())
|
.call(const WaitForCondition(NoPendingPlatformMessages()).serialize())
|
||||||
.then<void>(expectAsync1((Map<String, dynamic> r) {
|
.then<void>(expectAsync1((Map<String, dynamic> r) {
|
||||||
result = r;
|
result = r;
|
||||||
@ -292,7 +289,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
channel.invokeMethod<String>('sayHello', 'hello');
|
channel.invokeMethod<String>('sayHello', 'hello');
|
||||||
|
|
||||||
driverExtension
|
extension
|
||||||
.call(const WaitForCondition(NoPendingPlatformMessages()).serialize())
|
.call(const WaitForCondition(NoPendingPlatformMessages()).serialize())
|
||||||
.then<void>(expectAsync1((Map<String, dynamic> r) {
|
.then<void>(expectAsync1((Map<String, dynamic> r) {
|
||||||
result = r;
|
result = r;
|
||||||
@ -337,7 +334,7 @@ void main() {
|
|||||||
channel1.invokeMethod<String>('sayHello', 'hello');
|
channel1.invokeMethod<String>('sayHello', 'hello');
|
||||||
channel2.invokeMethod<String>('sayHello', 'hello');
|
channel2.invokeMethod<String>('sayHello', 'hello');
|
||||||
|
|
||||||
driverExtension
|
extension
|
||||||
.call(const WaitForCondition(NoPendingPlatformMessages()).serialize())
|
.call(const WaitForCondition(NoPendingPlatformMessages()).serialize())
|
||||||
.then<void>(expectAsync1((Map<String, dynamic> r) {
|
.then<void>(expectAsync1((Map<String, dynamic> r) {
|
||||||
result = r;
|
result = r;
|
||||||
@ -386,7 +383,7 @@ void main() {
|
|||||||
channel1.invokeMethod<String>('sayHello', 'hello');
|
channel1.invokeMethod<String>('sayHello', 'hello');
|
||||||
|
|
||||||
// Calls the waiting API before the second channel message is sent.
|
// Calls the waiting API before the second channel message is sent.
|
||||||
driverExtension
|
extension
|
||||||
.call(const WaitForCondition(NoPendingPlatformMessages()).serialize())
|
.call(const WaitForCondition(NoPendingPlatformMessages()).serialize())
|
||||||
.then<void>(expectAsync1((Map<String, dynamic> r) {
|
.then<void>(expectAsync1((Map<String, dynamic> r) {
|
||||||
result = r;
|
result = r;
|
||||||
@ -436,7 +433,7 @@ void main() {
|
|||||||
|
|
||||||
channel1.invokeMethod<String>('sayHello', 'hello');
|
channel1.invokeMethod<String>('sayHello', 'hello');
|
||||||
|
|
||||||
driverExtension
|
extension
|
||||||
.call(const WaitForCondition(NoPendingPlatformMessages()).serialize())
|
.call(const WaitForCondition(NoPendingPlatformMessages()).serialize())
|
||||||
.then<void>(expectAsync1((Map<String, dynamic> r) {
|
.then<void>(expectAsync1((Map<String, dynamic> r) {
|
||||||
result = r;
|
result = r;
|
||||||
@ -465,9 +462,9 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
group('getSemanticsId', () {
|
group('getSemanticsId', () {
|
||||||
FlutterDriverExtension driverExtension;
|
FlutterDriverExtension extension;
|
||||||
setUp(() {
|
setUp(() {
|
||||||
driverExtension = FlutterDriverExtension((String arg) async => '', true);
|
extension = FlutterDriverExtension((String arg) async => '', true);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('works when semantics are enabled', (WidgetTester tester) async {
|
testWidgets('works when semantics are enabled', (WidgetTester tester) async {
|
||||||
@ -476,7 +473,7 @@ void main() {
|
|||||||
const Text('hello', textDirection: TextDirection.ltr));
|
const Text('hello', textDirection: TextDirection.ltr));
|
||||||
|
|
||||||
final Map<String, String> arguments = GetSemanticsId(const ByText('hello')).serialize();
|
final Map<String, String> arguments = GetSemanticsId(const ByText('hello')).serialize();
|
||||||
final Map<String, dynamic> response = await driverExtension.call(arguments);
|
final Map<String, dynamic> response = await extension.call(arguments);
|
||||||
final GetSemanticsIdResult result = GetSemanticsIdResult.fromJson(response['response'] as Map<String, dynamic>);
|
final GetSemanticsIdResult result = GetSemanticsIdResult.fromJson(response['response'] as Map<String, dynamic>);
|
||||||
|
|
||||||
expect(result.id, 1);
|
expect(result.id, 1);
|
||||||
@ -488,7 +485,7 @@ void main() {
|
|||||||
const Text('hello', textDirection: TextDirection.ltr));
|
const Text('hello', textDirection: TextDirection.ltr));
|
||||||
|
|
||||||
final Map<String, String> arguments = GetSemanticsId(const ByText('hello')).serialize();
|
final Map<String, String> arguments = GetSemanticsId(const ByText('hello')).serialize();
|
||||||
final Map<String, dynamic> response = await driverExtension.call(arguments);
|
final Map<String, dynamic> response = await extension.call(arguments);
|
||||||
|
|
||||||
expect(response['isError'], true);
|
expect(response['isError'], true);
|
||||||
expect(response['response'], contains('Bad state: No semantics data found'));
|
expect(response['response'], contains('Bad state: No semantics data found'));
|
||||||
@ -507,7 +504,7 @@ void main() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
final Map<String, String> arguments = GetSemanticsId(const ByText('hello')).serialize();
|
final Map<String, String> arguments = GetSemanticsId(const ByText('hello')).serialize();
|
||||||
final Map<String, dynamic> response = await driverExtension.call(arguments);
|
final Map<String, dynamic> response = await extension.call(arguments);
|
||||||
|
|
||||||
expect(response['isError'], true);
|
expect(response['isError'], true);
|
||||||
expect(response['response'], contains('Bad state: Found more than one element with the same ID'));
|
expect(response['response'], contains('Bad state: Found more than one element with the same ID'));
|
||||||
@ -516,11 +513,11 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('getOffset', (WidgetTester tester) async {
|
testWidgets('getOffset', (WidgetTester tester) async {
|
||||||
final FlutterDriverExtension driverExtension = FlutterDriverExtension((String arg) async => '', true);
|
final FlutterDriverExtension extension = FlutterDriverExtension((String arg) async => '', 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();
|
||||||
final Map<String, dynamic> response = await driverExtension.call(arguments);
|
final Map<String, dynamic> response = await extension.call(arguments);
|
||||||
final GetOffsetResult result = GetOffsetResult.fromJson(response['response'] as Map<String, dynamic>);
|
final GetOffsetResult result = GetOffsetResult.fromJson(response['response'] as Map<String, dynamic>);
|
||||||
return Offset(result.dx, result.dy);
|
return Offset(result.dx, result.dy);
|
||||||
}
|
}
|
||||||
@ -548,11 +545,11 @@ 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 extension = FlutterDriverExtension((String arg) async => '', 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();
|
||||||
final Map<String, dynamic> result = await driverExtension.call(arguments);
|
final Map<String, dynamic> result = await extension.call(arguments);
|
||||||
if (result['isError'] as bool) {
|
if (result['isError'] as bool) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -610,7 +607,7 @@ void main() {
|
|||||||
|
|
||||||
// Check if error thrown for other types
|
// Check if error thrown for other types
|
||||||
final Map<String, String> arguments = GetText(ByValueKey('column'), timeout: const Duration(seconds: 1)).serialize();
|
final Map<String, String> arguments = GetText(ByValueKey('column'), timeout: const Duration(seconds: 1)).serialize();
|
||||||
final Map<String, dynamic> response = await driverExtension.call(arguments);
|
final Map<String, dynamic> response = await extension.call(arguments);
|
||||||
expect(response['isError'], true);
|
expect(response['isError'], true);
|
||||||
expect(response['response'], contains('is currently not supported by getText'));
|
expect(response['response'], contains('is currently not supported by getText'));
|
||||||
});
|
});
|
||||||
@ -618,7 +615,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 extension = FlutterDriverExtension((String arg) async => '', 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(
|
||||||
@ -626,7 +623,7 @@ void main() {
|
|||||||
matching: ByValueKey('text2'),
|
matching: ByValueKey('text2'),
|
||||||
matchRoot: matchRoot,
|
matchRoot: matchRoot,
|
||||||
), timeout: const Duration(seconds: 1)).serialize();
|
), timeout: const Duration(seconds: 1)).serialize();
|
||||||
final Map<String, dynamic> result = await driverExtension.call(arguments);
|
final Map<String, dynamic> result = await extension.call(arguments);
|
||||||
if (result['isError'] as bool) {
|
if (result['isError'] as bool) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -663,7 +660,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 extension = FlutterDriverExtension((String arg) async => '', true);
|
||||||
|
|
||||||
Future<String> getDescendantText() async {
|
Future<String> getDescendantText() async {
|
||||||
final Map<String, String> arguments = GetText(Descendant(
|
final Map<String, String> arguments = GetText(Descendant(
|
||||||
@ -671,7 +668,7 @@ void main() {
|
|||||||
matching: const ByType('Text'),
|
matching: const ByType('Text'),
|
||||||
firstMatchOnly: true,
|
firstMatchOnly: true,
|
||||||
), timeout: const Duration(seconds: 1)).serialize();
|
), timeout: const Duration(seconds: 1)).serialize();
|
||||||
final Map<String, dynamic> result = await driverExtension.call(arguments);
|
final Map<String, dynamic> result = await extension.call(arguments);
|
||||||
if (result['isError'] as bool) {
|
if (result['isError'] as bool) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -697,7 +694,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 extension = FlutterDriverExtension((String arg) async => '', 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(
|
||||||
@ -705,7 +702,7 @@ void main() {
|
|||||||
matching: ByValueKey(matching),
|
matching: ByValueKey(matching),
|
||||||
matchRoot: matchRoot,
|
matchRoot: matchRoot,
|
||||||
), OffsetType.topLeft, timeout: const Duration(seconds: 1)).serialize();
|
), OffsetType.topLeft, timeout: const Duration(seconds: 1)).serialize();
|
||||||
final Map<String, dynamic> response = await driverExtension.call(arguments);
|
final Map<String, dynamic> response = await extension.call(arguments);
|
||||||
if (response['isError'] as bool) {
|
if (response['isError'] as bool) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -767,7 +764,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 extension = FlutterDriverExtension((String arg) async => '', true);
|
||||||
|
|
||||||
Future<Offset> getAncestorTopLeft() async {
|
Future<Offset> getAncestorTopLeft() async {
|
||||||
final Map<String, String> arguments = GetOffset(Ancestor(
|
final Map<String, String> arguments = GetOffset(Ancestor(
|
||||||
@ -775,7 +772,7 @@ void main() {
|
|||||||
matching: const ByType('Container'),
|
matching: const ByType('Container'),
|
||||||
firstMatchOnly: true,
|
firstMatchOnly: true,
|
||||||
), OffsetType.topLeft, timeout: const Duration(seconds: 1)).serialize();
|
), OffsetType.topLeft, timeout: const Duration(seconds: 1)).serialize();
|
||||||
final Map<String, dynamic> response = await driverExtension.call(arguments);
|
final Map<String, dynamic> response = await extension.call(arguments);
|
||||||
if (response['isError'] as bool) {
|
if (response['isError'] as bool) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -815,11 +812,11 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('GetDiagnosticsTree', (WidgetTester tester) async {
|
testWidgets('GetDiagnosticsTree', (WidgetTester tester) async {
|
||||||
final FlutterDriverExtension driverExtension = FlutterDriverExtension((String arg) async => '', true);
|
final FlutterDriverExtension extension = FlutterDriverExtension((String arg) async => '', 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();
|
||||||
final Map<String, dynamic> response = await driverExtension.call(arguments);
|
final Map<String, dynamic> response = await extension.call(arguments);
|
||||||
final DiagnosticsTreeResult result = DiagnosticsTreeResult(response['response'] as Map<String, dynamic>);
|
final DiagnosticsTreeResult result = DiagnosticsTreeResult(response['response'] as Map<String, dynamic>);
|
||||||
return result.json;
|
return result.json;
|
||||||
}
|
}
|
||||||
@ -880,120 +877,18 @@ void main() {
|
|||||||
expect(children.single['children'], isEmpty);
|
expect(children.single['children'], isEmpty);
|
||||||
});
|
});
|
||||||
|
|
||||||
group('extension finders', () {
|
|
||||||
final Widget debugTree = Directionality(
|
|
||||||
textDirection: TextDirection.ltr,
|
|
||||||
child: Center(
|
|
||||||
child: Column(
|
|
||||||
key: const ValueKey<String>('Column'),
|
|
||||||
children: <Widget>[
|
|
||||||
const Text('Foo', key: ValueKey<String>('Text1')),
|
|
||||||
const Text('Bar', key: ValueKey<String>('Text2')),
|
|
||||||
FlatButton(
|
|
||||||
child: const Text('Whatever'),
|
|
||||||
key: const ValueKey<String>('Button'),
|
|
||||||
onPressed: () {},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
testWidgets('unknown extension finder', (WidgetTester tester) async {
|
|
||||||
final FlutterDriverExtension driverExtension = FlutterDriverExtension(
|
|
||||||
(String arg) async => '',
|
|
||||||
true,
|
|
||||||
finders: <FinderExtension>[],
|
|
||||||
);
|
|
||||||
|
|
||||||
Future<Map<String, dynamic>> getText(SerializableFinder finder) async {
|
|
||||||
final Map<String, String> arguments = GetText(finder, timeout: const Duration(seconds: 1)).serialize();
|
|
||||||
return await driverExtension.call(arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
await tester.pumpWidget(debugTree);
|
|
||||||
|
|
||||||
final Map<String, dynamic> result = await getText(StubFinder('Text1'));
|
|
||||||
expect(result['isError'], true);
|
|
||||||
expect(result['response'] is String, true);
|
|
||||||
expect(result['response'] as String, contains('Unsupported search specification type Stub'));
|
|
||||||
});
|
|
||||||
|
|
||||||
testWidgets('simple extension finder', (WidgetTester tester) async {
|
|
||||||
final FlutterDriverExtension driverExtension = FlutterDriverExtension(
|
|
||||||
(String arg) async => '',
|
|
||||||
true,
|
|
||||||
finders: <FinderExtension>[
|
|
||||||
StubFinderExtension(),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
Future<GetTextResult> getText(SerializableFinder finder) async {
|
|
||||||
final Map<String, String> arguments = GetText(finder, timeout: const Duration(seconds: 1)).serialize();
|
|
||||||
final Map<String, dynamic> response = await driverExtension.call(arguments);
|
|
||||||
return GetTextResult.fromJson(response['response'] as Map<String, dynamic>);
|
|
||||||
}
|
|
||||||
|
|
||||||
await tester.pumpWidget(debugTree);
|
|
||||||
|
|
||||||
final GetTextResult result = await getText(StubFinder('Text1'));
|
|
||||||
expect(result.text, 'Foo');
|
|
||||||
});
|
|
||||||
|
|
||||||
testWidgets('complex extension finder', (WidgetTester tester) async {
|
|
||||||
final FlutterDriverExtension driverExtension = FlutterDriverExtension(
|
|
||||||
(String arg) async => '',
|
|
||||||
true,
|
|
||||||
finders: <FinderExtension>[
|
|
||||||
StubFinderExtension(),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
Future<GetTextResult> getText(SerializableFinder finder) async {
|
|
||||||
final Map<String, String> arguments = GetText(finder, timeout: const Duration(seconds: 1)).serialize();
|
|
||||||
final Map<String, dynamic> response = await driverExtension.call(arguments);
|
|
||||||
return GetTextResult.fromJson(response['response'] as Map<String, dynamic>);
|
|
||||||
}
|
|
||||||
|
|
||||||
await tester.pumpWidget(debugTree);
|
|
||||||
|
|
||||||
final GetTextResult result = await getText(Descendant(of: StubFinder('Column'), matching: StubFinder('Text1')));
|
|
||||||
expect(result.text, 'Foo');
|
|
||||||
});
|
|
||||||
|
|
||||||
testWidgets('extension finder with command', (WidgetTester tester) async {
|
|
||||||
final FlutterDriverExtension driverExtension = FlutterDriverExtension(
|
|
||||||
(String arg) async => '',
|
|
||||||
true,
|
|
||||||
finders: <FinderExtension>[
|
|
||||||
StubFinderExtension(),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
Future<Map<String, dynamic>> tap(SerializableFinder finder) async {
|
|
||||||
final Map<String, String> arguments = Tap(finder, timeout: const Duration(seconds: 1)).serialize();
|
|
||||||
return await driverExtension.call(arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
await tester.pumpWidget(debugTree);
|
|
||||||
|
|
||||||
final Map<String, dynamic> result = await tap(StubFinder('Button'));
|
|
||||||
expect(result['isError'], false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
group('waitUntilFrameSync', () {
|
group('waitUntilFrameSync', () {
|
||||||
FlutterDriverExtension driverExtension;
|
FlutterDriverExtension extension;
|
||||||
Map<String, dynamic> result;
|
Map<String, dynamic> result;
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
driverExtension = FlutterDriverExtension((String arg) async => '', true);
|
extension = FlutterDriverExtension((String arg) async => '', true);
|
||||||
result = null;
|
result = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('returns immediately when frame is synced', (
|
testWidgets('returns immediately when frame is synced', (
|
||||||
WidgetTester tester) async {
|
WidgetTester tester) async {
|
||||||
driverExtension.call(const WaitUntilNoPendingFrame().serialize())
|
extension.call(const WaitUntilNoPendingFrame().serialize())
|
||||||
.then<void>(expectAsync1((Map<String, dynamic> r) {
|
.then<void>(expectAsync1((Map<String, dynamic> r) {
|
||||||
result = r;
|
result = r;
|
||||||
}));
|
}));
|
||||||
@ -1014,7 +909,7 @@ void main() {
|
|||||||
// Intentionally blank. We only care about existence of a callback.
|
// Intentionally blank. We only care about existence of a callback.
|
||||||
});
|
});
|
||||||
|
|
||||||
driverExtension.call(const WaitUntilNoPendingFrame().serialize())
|
extension.call(const WaitUntilNoPendingFrame().serialize())
|
||||||
.then<void>(expectAsync1((Map<String, dynamic> r) {
|
.then<void>(expectAsync1((Map<String, dynamic> r) {
|
||||||
result = r;
|
result = r;
|
||||||
}));
|
}));
|
||||||
@ -1038,7 +933,7 @@ void main() {
|
|||||||
'waits until no pending scheduled frame', (WidgetTester tester) async {
|
'waits until no pending scheduled frame', (WidgetTester tester) async {
|
||||||
SchedulerBinding.instance.scheduleFrame();
|
SchedulerBinding.instance.scheduleFrame();
|
||||||
|
|
||||||
driverExtension.call(const WaitUntilNoPendingFrame().serialize())
|
extension.call(const WaitUntilNoPendingFrame().serialize())
|
||||||
.then<void>(expectAsync1((Map<String, dynamic> r) {
|
.then<void>(expectAsync1((Map<String, dynamic> r) {
|
||||||
result = r;
|
result = r;
|
||||||
}));
|
}));
|
||||||
|
@ -1,19 +0,0 @@
|
|||||||
// Copyright 2014 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
import 'package:flutter_driver/flutter_driver.dart';
|
|
||||||
|
|
||||||
class StubFinder extends SerializableFinder {
|
|
||||||
StubFinder(this.keyString);
|
|
||||||
|
|
||||||
final String keyString;
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get finderType => 'Stub';
|
|
||||||
|
|
||||||
@override
|
|
||||||
Map<String, String> serialize() {
|
|
||||||
return super.serialize()..addAll(<String, String>{'keyString': keyString});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
// Copyright 2014 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
import 'package:flutter/src/widgets/framework.dart';
|
|
||||||
import 'package:flutter_driver/driver_extension.dart';
|
|
||||||
import 'package:flutter_driver/src/common/create_finder_factory.dart';
|
|
||||||
import 'package:flutter_test/src/finders.dart';
|
|
||||||
import 'package:flutter_driver/src/common/find.dart';
|
|
||||||
|
|
||||||
import 'stub_finder.dart';
|
|
||||||
|
|
||||||
class StubFinderExtension extends FinderExtension {
|
|
||||||
@override
|
|
||||||
Finder createFinder(
|
|
||||||
SerializableFinder finder,
|
|
||||||
CreateFinderFactory finderFactory,
|
|
||||||
) {
|
|
||||||
return find.byWidgetPredicate((Widget widget) {
|
|
||||||
final Key key = widget.key;
|
|
||||||
if (key is! ValueKey<String>) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return (key as ValueKey<String>).value == (finder as StubFinder).keyString;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
SerializableFinder deserialize(
|
|
||||||
Map<String, String> params,
|
|
||||||
DeserializeFinderFactory finderFactory,
|
|
||||||
) {
|
|
||||||
return StubFinder(params['keyString']);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get finderType => 'Stub';
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user