dragUntilExists method

Future<PatrolFinder> dragUntilExists({
  1. required Finder finder,
  2. required Finder view,
  3. required Offset moveStep,
  4. int maxIteration = defaultScrollMaxIteration,
  5. Duration? settleBetweenScrollsTimeout,
  6. Duration? dragDuration,
  7. SettlePolicy? settlePolicy,
})
inherited

Repeatedly drags view by moveStep until finder finds at least one existing widget.

Between each drag, calls pump, pumpAndSettle or pumpAndTrySettle, depending on chosen settlePolicy.

This is a reimplementation of WidgetController.dragUntilVisible that differs from the original in the following ways:

  • scrolls until until finder finds at least one existing widget

  • waits until view is visible

  • if the view finder finds more than 1 widget, it scrolls the first one instead of throwing a StateError

  • if the finder finder finds more than 1 widget, it scrolls to the first one instead of throwing a StateError

  • can drag any widget, not only a Scrollable

  • performed drag is slower (it takes some time to performe dragging gesture, half a second by default)

  • you can configure, which version of pumping is performed between each drag gesture (pump, pumpAndSettle or pumpAndTrySettle),

  • timeouts and durations, if null, are controlled by values in PatrolTester.config.

See also:

  • PatrolTester.config.settlePolicy, which controls the default settle behavior
  • PatrolTester.dragUntilVisible, which scrolls to visible widget, not only existing one.

Implementation

Future<PatrolFinder> dragUntilExists({
  required Finder finder,
  required Finder view,
  required Offset moveStep,
  int maxIteration = defaultScrollMaxIteration,
  Duration? settleBetweenScrollsTimeout,
  Duration? dragDuration,
  SettlePolicy? settlePolicy,
}) {
  return TestAsyncUtils.guard(() async {
    var viewPatrolFinder = PatrolFinder(finder: view, tester: this);
    await viewPatrolFinder.waitUntilVisible();
    viewPatrolFinder = viewPatrolFinder.hitTestable().first;
    dragDuration ??= config.dragDuration;
    settleBetweenScrollsTimeout ??= config.settleBetweenScrollsTimeout;

    var iterationsLeft = maxIteration;
    while (iterationsLeft > 0 && finder.evaluate().isEmpty) {
      await tester.timedDrag(
        viewPatrolFinder,
        moveStep,
        dragDuration!,
      );
      await _performPump(
        settlePolicy: settlePolicy,
        settleTimeout: settleBetweenScrollsTimeout,
      );
      iterationsLeft -= 1;
    }

    if (iterationsLeft <= 0) {
      throw WaitUntilExistsTimeoutException(
        finder: finder,
        // TODO: set reasonable duration or create new exception for this case
        duration: settleBetweenScrollsTimeout!,
      );
    }

    return PatrolFinder(finder: finder, tester: this);
  });
}