waitFor method
Future<Finder>
waitFor(
- dynamic testableId, {
- required CancelToken cancelToken,
- required TestController tester,
- Duration? timeout,
inherited
Waits for a widget with a key that has testableId
as the value.
Implementation
@protected
Future<test.Finder> waitFor(
dynamic testableId, {
required CancelToken cancelToken,
required TestController tester,
Duration? timeout,
}) async {
timeout ??= tester.delays.defaultTimeout;
final controller = StreamController<void>.broadcast();
final name = "waitFor('$testableId')";
try {
final waiter = () async {
final end =
DateTime.now().millisecondsSinceEpoch + timeout!.inMilliseconds;
test.Finder? finder;
var found = false;
while (found != true && DateTime.now().millisecondsSinceEpoch < end) {
try {
finder = test.find.byKey(_TestableKey(testableId));
final items = finder.evaluate();
final item = items.first;
if (item.widget is! Testable) {
finder = test.find.descendant(
of: finder,
matching: find.byType(Testable),
);
finder.evaluate().first;
}
found = true;
} catch (e) {
if (cancelToken.cancelled == true) {
throw Exception('[CANCELLED]: step was cancelled by the test');
}
await Future.delayed(const Duration(milliseconds: 100));
}
}
if (found != true) {
throw Exception('testableId: [$testableId] -- Timeout exceeded.');
}
return finder!;
};
final sleeper = sleep(
timeout,
cancelStream: controller.stream,
error: true,
message: '[$name]: ${timeout.inSeconds} seconds',
tester: tester,
);
final result = await waiter();
if (cancelToken.cancelled == true) {
throw Exception('[CANCELLED]: step was cancelled by the test');
}
controller.add(null);
await sleeper;
if (cancelToken.cancelled == true) {
throw Exception('[CANCELLED]: step was cancelled by the test');
}
try {
final finder = result.evaluate().first;
if (finder.widget is Testable) {
final element = finder as StatefulElement;
final state = element.state;
if (state is TestableState) {
_console('flash: [$testableId]', Level.FINEST);
await state.flash();
_console('flash complete: [$testableId]', Level.FINEST);
}
}
} catch (e) {
// no-op
}
return result;
} catch (e) {
log(
'ERROR: [$name] -- $e',
tester: tester,
);
rethrow;
} finally {
await controller.close();
}
}