[flutter_driver] Add waitForTappable to flutter_driver (#79581)

This commit is contained in:
Kaleb Hermes 2021-04-14 19:54:02 -04:00 committed by GitHub
parent 6b06943c32
commit 1912f7dea2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 68 additions and 0 deletions

View file

@ -56,6 +56,7 @@ mixin DeserializeCommandFactory {
case 'tap': return Tap.deserialize(params, finderFactory);
case 'waitFor': return WaitFor.deserialize(params, finderFactory);
case 'waitForAbsent': return WaitForAbsent.deserialize(params, finderFactory);
case 'waitForTappable': return WaitForTappable.deserialize(params, finderFactory);
case 'waitForCondition': return WaitForCondition.deserialize(params);
case 'waitUntilNoTransientCallbacks': return WaitForCondition.deserialize(params);
case 'waitUntilNoPendingFrame': return WaitForCondition.deserialize(params);

View file

@ -80,6 +80,24 @@ class WaitForAbsent extends CommandWithTarget {
String get kind => 'waitForAbsent';
}
/// A Flutter Driver command that waits until [finder] can be tapped.
class WaitForTappable extends CommandWithTarget {
/// Creates a command that waits for the widget identified by [finder] to
/// be tappable within the [timeout] amiount of time.
///
/// If [timeout] is not specified, the command defuts to no timeout.
WaitForTappable(SerializableFinder finder, {Duration? timeout})
: super(finder, timeout: timeout);
/// Deserialized this command from the value generated by [serialize].
WaitForTappable.deserialize(
Map<String, String> json, DeserializeFinderFactory finderFactory)
: super.deserialize(json, finderFactory);
@override
String get kind => 'waitForTappable';
}
/// Base class for Flutter Driver finders, objects that describe how the driver
/// should search for elements.
abstract class SerializableFinder {

View file

@ -169,6 +169,7 @@ mixin CommandHandlerFactory {
case 'tap': return _tap(command, prober, finderFactory);
case 'waitFor': return _waitFor(command, finderFactory);
case 'waitForAbsent': return _waitForAbsent(command, finderFactory);
case 'waitForTappable': return _waitForTappable(command, finderFactory);
case 'waitForCondition': return _waitForCondition(command);
case 'waitUntilNoTransientCallbacks': return _waitUntilNoTransientCallbacks(command);
case 'waitUntilNoPendingFrame': return _waitUntilNoPendingFrame(command);
@ -236,6 +237,14 @@ mixin CommandHandlerFactory {
return Result.empty;
}
Future<Result> _waitForTappable(Command command, CreateFinderFactory finderFactory) async {
final WaitForTappable waitForTappableCommand = command as WaitForTappable;
await waitForElement(
finderFactory.createFinder(waitForTappableCommand.finder).hitTestable(),
);
return Result.empty;
}
Future<Result> _waitForCondition(Command command) async {
assert(command != null);
final WaitForCondition waitForConditionCommand = command as WaitForCondition;

View file

@ -220,6 +220,11 @@ abstract class FlutterDriver {
await sendCommand(WaitForAbsent(finder, timeout: timeout));
}
/// Waits until [finder] is tappable.
Future<void> waitForTappable(SerializableFinder finder, { Duration? timeout }) async {
await sendCommand(WaitForTappable(finder, timeout: timeout));
}
/// Waits until the given [waitCondition] is satisfied.
Future<void> waitForCondition(SerializableWaitCondition waitCondition, {Duration? timeout}) async {
await sendCommand(WaitForCondition(waitCondition, timeout: timeout));

View file

@ -1130,6 +1130,41 @@ void main() {
});
});
group('waitForTappable', () {
late FlutterDriverExtension driverExtension;
Future<Map<String, dynamic>> waitForTappable() async {
final SerializableFinder finder = ByValueKey('widgetOne');
final Map<String, String> arguments = WaitForTappable(finder).serialize();
final Map<String, dynamic> result = await driverExtension.call(arguments);
return result;
}
final Widget testWidget = MaterialApp(
home: Material(
child: Column(children: const<Widget> [
Text('Hello ', key: Key('widgetOne')),
SizedBox(
height: 0,
width: 0,
child: Text('World!', key: Key('widgetTwo')),
)
],
),
),
);
testWidgets('returns true when widget is tappable', (
WidgetTester tester) async {
driverExtension = FlutterDriverExtension((String? arg) async => '', true, false);
await tester.pumpWidget(testWidget);
final Map<String, dynamic> waitForTappableResult = await waitForTappable();
expect(waitForTappableResult['isError'], isFalse);
});
});
group('waitUntilFrameSync', () {
late FlutterDriverExtension driverExtension;
Map<String, dynamic>? result;