Skip to content

Commit 39d87d9

Browse files
committed
[Flutter Espresso] Add the waitFor action.
1 parent b7fbe68 commit 39d87d9

File tree

4 files changed

+89
-1
lines changed

4 files changed

+89
-1
lines changed

packages/espresso/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
* Updates minimum supported SDK version to Flutter 3.13/Dart 3.1.
44
* Updates compileSdk version to 34.
5+
* Adds the waitFor action.
56

67
## 0.3.0+7
78

packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/FlutterActions.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import androidx.test.annotation.ExperimentalTestApi;
88
import androidx.test.espresso.flutter.api.WidgetAction;
9+
import androidx.test.espresso.flutter.common.Duration;
910
import java.util.concurrent.ExecutorService;
1011
import java.util.concurrent.Executors;
1112
import javax.annotation.Nonnull;
@@ -73,4 +74,14 @@ public static WidgetAction typeText(@Nonnull String stringToBeTyped) {
7374
public static WidgetAction scrollTo() {
7475
return new FlutterScrollToAction();
7576
}
77+
78+
/**
79+
* Returns an action that waits for up to a specified duration. This action can be useful when
80+
* waiting for a UI element or condition to become available before performing further Flutter
81+
* test actions.
82+
*/
83+
@Nonnull
84+
public static WidgetAction waitFor(@Nonnull Duration timeout) {
85+
return new FlutterWaitForAction(timeout);
86+
}
7687
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
package androidx.test.espresso.flutter.action;
5+
6+
import static com.google.common.base.Preconditions.checkNotNull;
7+
import static com.google.common.util.concurrent.Futures.immediateVoidFuture;
8+
9+
import android.os.SystemClock;
10+
import android.view.View;
11+
import androidx.annotation.NonNull;
12+
import androidx.annotation.Nullable;
13+
import androidx.test.espresso.UiController;
14+
import androidx.test.espresso.flutter.api.FlutterTestingProtocol;
15+
import androidx.test.espresso.flutter.api.WidgetAction;
16+
import androidx.test.espresso.flutter.api.WidgetMatcher;
17+
import androidx.test.espresso.flutter.common.Duration;
18+
import com.google.common.util.concurrent.ListenableFuture;
19+
20+
/** An action that waits for up to a specified duration. */
21+
public final class FlutterWaitForAction implements WidgetAction {
22+
private final Duration duration;
23+
private static final Duration WAIT_TIME_INTERVAL = Duration.ofMillis(50);
24+
25+
/**
26+
* Constructs with the given duration.
27+
*
28+
* @param duration amount of time to be waited up for.
29+
*/
30+
FlutterWaitForAction(@NonNull Duration duration) {
31+
this.duration = checkNotNull(duration);
32+
}
33+
34+
@Override
35+
@NonNull
36+
public ListenableFuture<Void> perform(
37+
@Nullable WidgetMatcher targetWidget,
38+
@NonNull View flutterView,
39+
@NonNull FlutterTestingProtocol flutterTestingProtocol,
40+
@NonNull UiController androidUiController) {
41+
long durationInMillis = duration.toMillis();
42+
long startInMillis = SystemClock.elapsedRealtime();
43+
long elapsedInMillis = 0;
44+
while (elapsedInMillis < durationInMillis) {
45+
androidUiController.loopMainThreadForAtLeast(WAIT_TIME_INTERVAL.toMillis());
46+
elapsedInMillis = SystemClock.elapsedRealtime() - startInMillis;
47+
}
48+
return immediateVoidFuture();
49+
}
50+
}

packages/espresso/android/src/main/java/androidx/test/espresso/flutter/common/Duration.java

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,12 @@
55
package androidx.test.espresso.flutter.common;
66

77
import static com.google.common.base.Preconditions.checkNotNull;
8+
import static java.util.concurrent.TimeUnit.MILLISECONDS;
9+
import static java.util.concurrent.TimeUnit.NANOSECONDS;
10+
import static java.util.concurrent.TimeUnit.SECONDS;
811

912
import java.util.concurrent.TimeUnit;
13+
import javax.annotation.Nonnull;
1014
import javax.annotation.Nullable;
1115

1216
/**
@@ -15,11 +19,24 @@
1519
*
1620
* <p>This class is immutable.
1721
*/
18-
public final class Duration {
22+
public final class Duration implements Comparable<Duration> {
1923

2024
private final long quantity;
2125
private final TimeUnit unit;
2226

27+
/** Constant for a duration of zero. */
28+
public static final Duration ZERO = new Duration(0, NANOSECONDS);
29+
30+
/** Returns a Duration that represents the given seconds. */
31+
public static Duration ofSeconds(long seconds) {
32+
return new Duration(seconds, SECONDS);
33+
}
34+
35+
/** Returns a Duration that represents the given milliseconds. */
36+
public static Duration ofMillis(long millis) {
37+
return new Duration(millis, MILLISECONDS);
38+
}
39+
2340
/**
2441
* Initializes a Duration instance.
2542
*
@@ -32,11 +49,13 @@ public Duration(long quantity, TimeUnit unit) {
3249
}
3350

3451
/** Returns the amount of time. */
52+
@Nullable
3553
public long getQuantity() {
3654
return quantity;
3755
}
3856

3957
/** Returns the time unit. */
58+
@Nonnull
4059
public TimeUnit getUnit() {
4160
return unit;
4261
}
@@ -50,6 +69,7 @@ public long toMillis() {
5069
* Returns a new Duration instance that adds this instance to the given {@code duration}. If the
5170
* given {@code duration} is null, this method simply returns this instance.
5271
*/
72+
@Nonnull
5373
public Duration plus(@Nullable Duration duration) {
5474
if (duration == null) {
5575
return this;
@@ -58,4 +78,10 @@ public Duration plus(@Nullable Duration duration) {
5878
long newQuantity = quantity + add;
5979
return new Duration(newQuantity, unit);
6080
}
81+
82+
@Override
83+
public int compareTo(@Nonnull Duration otherDuration) {
84+
long otherQuantity = unit.convert(otherDuration.quantity, otherDuration.unit);
85+
return Long.compare(quantity, otherQuantity);
86+
}
6187
}

0 commit comments

Comments
 (0)