Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/espresso/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

* Updates minimum supported SDK version to Flutter 3.13/Dart 3.1.
* Updates compileSdk version to 34.
* Adds the waitFor action.

## 0.3.0+7

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import androidx.test.annotation.ExperimentalTestApi;
import androidx.test.espresso.flutter.api.WidgetAction;
import androidx.test.espresso.flutter.common.Duration;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.annotation.Nonnull;
Expand Down Expand Up @@ -73,4 +74,14 @@ public static WidgetAction typeText(@Nonnull String stringToBeTyped) {
public static WidgetAction scrollTo() {
return new FlutterScrollToAction();
}

/**
* Returns an action that waits for up to a specified duration. This action can be useful when
* waiting for a UI element or condition to become available before performing further Flutter
* test actions.
*/
@Nonnull
public static WidgetAction waitFor(@Nonnull Duration timeout) {
return new FlutterWaitForAction(timeout);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright 2013 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.
package androidx.test.espresso.flutter.action;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.util.concurrent.Futures.immediateVoidFuture;

import android.os.SystemClock;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.test.espresso.UiController;
import androidx.test.espresso.flutter.api.FlutterTestingProtocol;
import androidx.test.espresso.flutter.api.WidgetAction;
import androidx.test.espresso.flutter.api.WidgetMatcher;
import androidx.test.espresso.flutter.common.Duration;
import com.google.common.util.concurrent.ListenableFuture;

/** An action that waits for up to a specified duration. */
public final class FlutterWaitForAction implements WidgetAction {
private final Duration duration;
private static final Duration WAIT_TIME_INTERVAL = Duration.ofMillis(50);

/**
* Constructs with the given duration.
*
* @param duration amount of time to be waited up for.
*/
FlutterWaitForAction(@NonNull Duration duration) {
this.duration = checkNotNull(duration);
}

@Override
@NonNull
public ListenableFuture<Void> perform(
@Nullable WidgetMatcher targetWidget,
@NonNull View flutterView,
@NonNull FlutterTestingProtocol flutterTestingProtocol,
@NonNull UiController androidUiController) {
long durationInMillis = duration.toMillis();
long startInMillis = SystemClock.elapsedRealtime();
long elapsedInMillis = 0;
while (elapsedInMillis < durationInMillis) {
androidUiController.loopMainThreadForAtLeast(WAIT_TIME_INTERVAL.toMillis());
elapsedInMillis = SystemClock.elapsedRealtime() - startInMillis;
}
return immediateVoidFuture();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@
package androidx.test.espresso.flutter.common;

import static com.google.common.base.Preconditions.checkNotNull;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;

import java.util.concurrent.TimeUnit;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;

/**
Expand All @@ -15,11 +19,24 @@
*
* <p>This class is immutable.
*/
public final class Duration {
public final class Duration implements Comparable<Duration> {

private final long quantity;
private final TimeUnit unit;

/** Constant for a duration of zero. */
public static final Duration ZERO = new Duration(0, NANOSECONDS);

/** Returns a Duration that represents the given seconds. */
public static Duration ofSeconds(long seconds) {
return new Duration(seconds, SECONDS);
}

/** Returns a Duration that represents the given milliseconds. */
public static Duration ofMillis(long millis) {
return new Duration(millis, MILLISECONDS);
}

/**
* Initializes a Duration instance.
*
Expand All @@ -32,11 +49,13 @@ public Duration(long quantity, TimeUnit unit) {
}

/** Returns the amount of time. */
@Nullable
public long getQuantity() {
return quantity;
}

/** Returns the time unit. */
@Nonnull
public TimeUnit getUnit() {
return unit;
}
Expand All @@ -50,6 +69,7 @@ public long toMillis() {
* Returns a new Duration instance that adds this instance to the given {@code duration}. If the
* given {@code duration} is null, this method simply returns this instance.
*/
@Nonnull
public Duration plus(@Nullable Duration duration) {
if (duration == null) {
return this;
Expand All @@ -58,4 +78,10 @@ public Duration plus(@Nullable Duration duration) {
long newQuantity = quantity + add;
return new Duration(newQuantity, unit);
}

@Override
public int compareTo(@Nonnull Duration otherDuration) {
long otherQuantity = unit.convert(otherDuration.quantity, otherDuration.unit);
return Long.compare(quantity, otherQuantity);
}
}