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,
  8. bool enablePatrolLog = true,
})
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:

  • PatrolTesterConfig.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,
  bool enablePatrolLog = true,
}) {
  return TestAsyncUtils.guard(
    () => wrapWithPatrolLog<PatrolFinder>(
      action: 'dragUntilExists',
      finder: view,
      color: AnsiCodes.blue,
      enablePatrolLog: enablePatrolLog,
      function: () async {
        var viewPatrolFinder = PatrolFinder(finder: view, tester: this);
        await viewPatrolFinder.waitUntilVisible(enablePatrolLog: false);
        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);
      },
    ),
  );
}