dragUntilVisible method

Future<PatrolFinder> dragUntilVisible({
  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. Alignment alignment = Alignment.center,
  9. bool enablePatrolLog = true,
})
inherited

Repeatedly drags view by moveStep until finder finds at least one visible 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:

  • 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 perform 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.dragUntilExists, which scrolls to existing widget, not a visible one.

Implementation

Future<PatrolFinder> dragUntilVisible({
  required Finder finder,
  required Finder view,
  required Offset moveStep,
  int maxIteration = defaultScrollMaxIteration,
  Duration? settleBetweenScrollsTimeout,
  Duration? dragDuration,
  SettlePolicy? settlePolicy,
  Alignment alignment = Alignment.center,
  bool enablePatrolLog = true,
}) {
  return TestAsyncUtils.guard(
    () => wrapWithPatrolLog<PatrolFinder>(
      action: 'dragUntilVisible',
      finder: view,
      color: AnsiCodes.blue,
      enablePatrolLog: enablePatrolLog,
      function: () async {
        final viewPatrolFinder = (await waitUntilVisible(
          PatrolFinder(finder: view, tester: this),
          enablePatrolLog: false,
        )).first;

        dragDuration ??= config.dragDuration;
        settleBetweenScrollsTimeout ??= config.settleBetweenScrollsTimeout;

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

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

        return PatrolFinder(finder: hitTestableFinder.first, tester: this);
      },
    ),
  );
}