@@ -22,6 +22,28 @@ void main() {
2222 IntegrationTestWidgetsFlutterBinding .ensureInitialized ();
2323 GoogleMapsFlutterPlatform .instance.enableDebugInspection ();
2424
25+ // Repeatedly checks an asynchronous value against a test condition, waiting
26+ // one frame between each check, returing the value if it passes the predicate
27+ // before [maxTries] is reached.
28+ //
29+ // Returns null if the predicate is never satisfied.
30+ //
31+ // This is useful for cases where the Maps SDK has some internally
32+ // asynchronous operation that we don't have visibility into (e.g., native UI
33+ // animations).
34+ Future <T ?> waitForValueMatchingPredicate <T >(WidgetTester tester,
35+ Future <T > Function () getValue, bool Function (T ) predicate,
36+ {int maxTries = 100 }) async {
37+ for (int i = 0 ; i < maxTries; i++ ) {
38+ final T value = await getValue ();
39+ if (predicate (value)) {
40+ return value;
41+ }
42+ await tester.pump ();
43+ }
44+ return null ;
45+ }
46+
2547 testWidgets ('testCompassToggle' , (WidgetTester tester) async {
2648 final Key key = GlobalKey ();
2749 final Completer <int > mapIdCompleter = Completer <int >();
@@ -481,12 +503,13 @@ void main() {
481503 final GoogleMapController mapController =
482504 await mapControllerCompleter.future;
483505
506+ // Wait for the visible region to be non-zero.
484507 final LatLngBounds firstVisibleRegion =
485- await mapController. getVisibleRegion ();
486-
487- expect (firstVisibleRegion, isNotNull);
488- expect (firstVisibleRegion.southwest, isNotNull);
489- expect (firstVisibleRegion.northeast, isNotNull) ;
508+ await waitForValueMatchingPredicate < LatLngBounds >(
509+ tester,
510+ () => mapController. getVisibleRegion (),
511+ ( LatLngBounds bounds) => bounds != zeroLatLngBounds) ??
512+ zeroLatLngBounds ;
490513 expect (firstVisibleRegion, isNot (zeroLatLngBounds));
491514 expect (firstVisibleRegion.contains (_kInitialMapCenter), isTrue);
492515
@@ -517,9 +540,6 @@ void main() {
517540 final LatLngBounds secondVisibleRegion =
518541 await mapController.getVisibleRegion ();
519542
520- expect (secondVisibleRegion, isNotNull);
521- expect (secondVisibleRegion.southwest, isNotNull);
522- expect (secondVisibleRegion.northeast, isNotNull);
523543 expect (secondVisibleRegion, isNot (zeroLatLngBounds));
524544
525545 expect (firstVisibleRegion, isNot (secondVisibleRegion));
@@ -906,7 +926,13 @@ void main() {
906926 expect (iwVisibleStatus, false );
907927
908928 await controller.showMarkerInfoWindow (marker.markerId);
909- iwVisibleStatus = await controller.isMarkerInfoWindowShown (marker.markerId);
929+ // The Maps SDK doesn't always return true for whether it is shown
930+ // immediately after showing it, so wait for it to report as shown.
931+ iwVisibleStatus = await waitForValueMatchingPredicate <bool >(
932+ tester,
933+ () => controller.isMarkerInfoWindowShown (marker.markerId),
934+ (bool visible) => visible) ??
935+ false ;
910936 expect (iwVisibleStatus, true );
911937
912938 await controller.hideMarkerInfoWindow (marker.markerId);
0 commit comments