// Copyright 2014 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.

import 'dart:ui' as ui;

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/src/physics/utils.dart' show nearEqual;
import 'package:flutter_test/flutter_test.dart';

const Color _kScrollbarColor = Color(0xFF123456);
const double _kThickness = 2.5;
const double _kMinThumbExtent = 18.0;
const Duration _kScrollbarFadeDuration = Duration(milliseconds: 300);
const Duration _kScrollbarTimeToFade = Duration(milliseconds: 600);

ScrollbarPainter _buildPainter({
  TextDirection textDirection = TextDirection.ltr,
  EdgeInsetsGeometry padding = EdgeInsets.zero,
  Color color = _kScrollbarColor,
  double thickness = _kThickness,
  double mainAxisMargin = 0.0,
  double crossAxisMargin = 0.0,
  Radius? radius,
  Radius? trackRadius,
  double minLength = _kMinThumbExtent,
  double? minOverscrollLength,
  ScrollbarOrientation? scrollbarOrientation,
  required ScrollMetrics scrollMetrics,
}) {
  return ScrollbarPainter(
    color: color,
    textDirection: textDirection,
    thickness: thickness,
    padding: padding,
    mainAxisMargin: mainAxisMargin,
    crossAxisMargin: crossAxisMargin,
    radius: radius,
    trackRadius: trackRadius,
    minLength: minLength,
    minOverscrollLength: minOverscrollLength ?? minLength,
    fadeoutOpacityAnimation: kAlwaysCompleteAnimation,
    scrollbarOrientation: scrollbarOrientation,
  )..update(scrollMetrics, scrollMetrics.axisDirection);
}

class _DrawRectOnceCanvas extends Fake implements Canvas {
  List<Rect> rects = <Rect>[];
  List<RRect> rrects = <RRect>[];

  @override
  void drawRect(Rect rect, Paint paint) {
    rects.add(rect);
  }

  @override
  void drawRRect(ui.RRect rrect, ui.Paint paint) {
    rrects.add(rrect);
  }

  @override
  void drawLine(Offset p1, Offset p2, Paint paint) {}
}

void main() {
  final testCanvas = _DrawRectOnceCanvas();
  ScrollbarPainter painter;

  Rect captureRect() => testCanvas.rects.removeLast();
  RRect captureRRect() => testCanvas.rrects.removeLast();

  tearDown(() {
    testCanvas.rects.clear();
    testCanvas.rrects.clear();
  });

  final ScrollMetrics defaultMetrics = FixedScrollMetrics(
    minScrollExtent: 0,
    maxScrollExtent: 0,
    pixels: 0,
    viewportDimension: 100,
    axisDirection: AxisDirection.down,
    devicePixelRatio: 3.0,
  );

  test('Scrollbar is not smaller than minLength with large scroll views, '
      'if minLength is small ', () {
    const minLen = 3.5;
    const size = Size(600, 10);
    final ScrollMetrics metrics = defaultMetrics.copyWith(
      maxScrollExtent: 100000,
      viewportDimension: size.height,
    );

    // When overscroll.
    painter = _buildPainter(minLength: minLen, minOverscrollLength: minLen, scrollMetrics: metrics);

    painter.paint(testCanvas, size);

    final Rect rect0 = captureRect();
    expect(rect0.top, 0);
    expect(rect0.left, size.width - _kThickness);
    expect(rect0.width, _kThickness);
    expect(rect0.height >= minLen, true);

    // When scroll normally.
    const newPixels = 1.0;

    painter.update(metrics.copyWith(pixels: newPixels), metrics.axisDirection);

    painter.paint(testCanvas, size);

    final Rect rect1 = captureRect();
    expect(rect1.left, size.width - _kThickness);
    expect(rect1.width, _kThickness);
    expect(rect1.height >= minLen, true);
  });

  test('When scrolling normally (no overscrolling), the size of the scrollbar stays the same, '
      'and it scrolls evenly', () {
    const double viewportDimension = 23;
    const double maxExtent = 100;
    final ScrollMetrics startingMetrics = defaultMetrics.copyWith(
      maxScrollExtent: maxExtent,
      viewportDimension: viewportDimension,
    );
    const size = Size(600, viewportDimension);
    const double minLen = 0;

    painter = _buildPainter(
      minLength: minLen,
      minOverscrollLength: minLen,
      scrollMetrics: defaultMetrics,
    );

    final metricsList = <ScrollMetrics>[
      startingMetrics.copyWith(pixels: 0.01),
      ...List<ScrollMetrics>.generate(
        (maxExtent / viewportDimension).round(),
        (int index) => startingMetrics.copyWith(pixels: (index + 1) * viewportDimension),
      ).where((ScrollMetrics metrics) => !metrics.outOfRange),
      startingMetrics.copyWith(pixels: maxExtent - 0.01),
    ];

    late double lastCoefficient;
    for (final metrics in metricsList) {
      painter.update(metrics, metrics.axisDirection);
      painter.paint(testCanvas, size);

      final Rect rect = captureRect();
      final double newCoefficient = metrics.pixels / rect.top;
      lastCoefficient = newCoefficient;

      expect(rect.top >= 0, true);
      expect(rect.bottom <= maxExtent, true);
      expect(rect.left, size.width - _kThickness);
      expect(rect.width, _kThickness);
      expect(
        nearEqual(
          rect.height,
          viewportDimension * viewportDimension / (viewportDimension + maxExtent),
          0.001,
        ),
        true,
      );
      expect(nearEqual(lastCoefficient, newCoefficient, 0.001), true);
    }
  });

  test('mainAxisMargin is respected', () {
    const double viewportDimension = 23;
    const double maxExtent = 100;
    final ScrollMetrics startingMetrics = defaultMetrics.copyWith(
      maxScrollExtent: maxExtent,
      viewportDimension: viewportDimension,
    );
    const size = Size(600, viewportDimension);
    const double minLen = 0;

    const margins = <double>[-10, 1, viewportDimension / 2 - 0.01];
    for (final margin in margins) {
      painter = _buildPainter(
        mainAxisMargin: margin,
        minLength: minLen,
        scrollMetrics: defaultMetrics,
      );

      // Overscroll to double.negativeInfinity (top).
      painter.update(
        startingMetrics.copyWith(pixels: double.negativeInfinity),
        startingMetrics.axisDirection,
      );

      painter.paint(testCanvas, size);
      expect(captureRect().top, margin);

      // Overscroll to double.infinity (down).
      painter.update(
        startingMetrics.copyWith(pixels: double.infinity),
        startingMetrics.axisDirection,
      );

      painter.paint(testCanvas, size);
      expect(size.height - captureRect().bottom, margin);
    }
  });

  test('crossAxisMargin & text direction are respected', () {
    const double viewportDimension = 23;
    const double maxExtent = 100;
    final ScrollMetrics startingMetrics = defaultMetrics.copyWith(
      maxScrollExtent: maxExtent,
      viewportDimension: viewportDimension,
    );
    const size = Size(600, viewportDimension);
    const double margin = 4;

    for (final TextDirection textDirection in TextDirection.values) {
      painter = _buildPainter(
        crossAxisMargin: margin,
        scrollMetrics: startingMetrics,
        textDirection: textDirection,
      );

      for (final AxisDirection direction in AxisDirection.values) {
        painter.update(startingMetrics.copyWith(axisDirection: direction), direction);

        painter.paint(testCanvas, size);
        final Rect rect = captureRect();

        switch (axisDirectionToAxis(direction)) {
          case Axis.vertical:
            expect(margin, switch (textDirection) {
              TextDirection.ltr => size.width - rect.right,
              TextDirection.rtl => rect.left,
            });
          case Axis.horizontal:
            expect(margin, size.height - rect.bottom);
        }
      }
    }
  });

  test('scrollbarOrientation are respected', () {
    const double viewportDimension = 23;
    const double maxExtent = 100;
    final ScrollMetrics startingMetrics = defaultMetrics.copyWith(
      maxScrollExtent: maxExtent,
      viewportDimension: viewportDimension,
    );
    const size = Size(600, viewportDimension);

    for (final ScrollbarOrientation scrollbarOrientation in ScrollbarOrientation.values) {
      final AxisDirection axisDirection;
      if (scrollbarOrientation == ScrollbarOrientation.left ||
          scrollbarOrientation == ScrollbarOrientation.right) {
        axisDirection = AxisDirection.down;
      } else {
        axisDirection = AxisDirection.right;
      }

      painter = _buildPainter(
        scrollMetrics: startingMetrics,
        scrollbarOrientation: scrollbarOrientation,
      );

      painter.update(startingMetrics.copyWith(axisDirection: axisDirection), axisDirection);

      painter.paint(testCanvas, size);
      final Rect rect = captureRect();

      switch (scrollbarOrientation) {
        case ScrollbarOrientation.left:
          expect(rect.left, 0);
          expect(rect.top, 0);
          expect(rect.right, _kThickness);
          expect(rect.bottom, _kMinThumbExtent);
        case ScrollbarOrientation.right:
          expect(rect.left, 600 - _kThickness);
          expect(rect.top, 0);
          expect(rect.right, 600);
          expect(rect.bottom, _kMinThumbExtent);
        case ScrollbarOrientation.top:
          expect(rect.left, 0);
          expect(rect.top, 0);
          expect(rect.right, _kMinThumbExtent);
          expect(rect.bottom, _kThickness);
        case ScrollbarOrientation.bottom:
          expect(rect.left, 0);
          expect(rect.top, 23 - _kThickness);
          expect(rect.right, _kMinThumbExtent);
          expect(rect.bottom, 23);
      }
    }
  });

  test('scrollbarOrientation default values are correct', () {
    const double viewportDimension = 23;
    const double maxExtent = 100;
    final ScrollMetrics startingMetrics = defaultMetrics.copyWith(
      maxScrollExtent: maxExtent,
      viewportDimension: viewportDimension,
    );
    const size = Size(600, viewportDimension);
    Rect rect;

    // Vertical scroll with TextDirection.ltr
    painter = _buildPainter(scrollMetrics: startingMetrics);
    painter.update(startingMetrics.copyWith(axisDirection: AxisDirection.down), AxisDirection.down);
    painter.paint(testCanvas, size);
    rect = captureRect();
    expect(rect.left, 600 - _kThickness);
    expect(rect.top, 0);
    expect(rect.right, 600);
    expect(rect.bottom, _kMinThumbExtent);

    // Vertical scroll with TextDirection.rtl
    painter = _buildPainter(scrollMetrics: startingMetrics, textDirection: TextDirection.rtl);
    painter.update(startingMetrics.copyWith(axisDirection: AxisDirection.down), AxisDirection.down);
    painter.paint(testCanvas, size);
    rect = captureRect();
    expect(rect.left, 0);
    expect(rect.top, 0);
    expect(rect.right, _kThickness);
    expect(rect.bottom, _kMinThumbExtent);

    // Horizontal scroll
    painter = _buildPainter(scrollMetrics: startingMetrics);
    painter.update(
      startingMetrics.copyWith(axisDirection: AxisDirection.right),
      AxisDirection.right,
    );
    painter.paint(testCanvas, size);
    rect = captureRect();
    expect(rect.left, 0);
    expect(rect.top, 23 - _kThickness);
    expect(rect.right, _kMinThumbExtent);
    expect(rect.bottom, 23);
  });

  group('Padding works for all scroll directions', () {
    const padding = EdgeInsets.fromLTRB(1, 2, 3, 4);
    const size = Size(60, 80);
    final ScrollMetrics metrics = defaultMetrics.copyWith(
      minScrollExtent: -100,
      maxScrollExtent: 240,
      axisDirection: AxisDirection.down,
    );

    final ScrollbarPainter painter = _buildPainter(padding: padding, scrollMetrics: metrics);

    testWidgets('down', (WidgetTester tester) async {
      painter.update(
        metrics.copyWith(viewportDimension: size.height, pixels: double.negativeInfinity),
        AxisDirection.down,
      );

      // Top overscroll.
      painter.paint(testCanvas, size);
      final Rect rect0 = captureRect();
      expect(rect0.top, padding.top);
      expect(size.width - rect0.right, padding.right);

      // Bottom overscroll.
      painter.update(
        metrics.copyWith(viewportDimension: size.height, pixels: double.infinity),
        AxisDirection.down,
      );

      painter.paint(testCanvas, size);
      final Rect rect1 = captureRect();
      expect(size.height - rect1.bottom, padding.bottom);
      expect(size.width - rect1.right, padding.right);
    });

    testWidgets('up', (WidgetTester tester) async {
      painter.update(
        metrics.copyWith(
          viewportDimension: size.height,
          pixels: double.infinity,
          axisDirection: AxisDirection.up,
        ),
        AxisDirection.up,
      );

      // Top overscroll.
      painter.paint(testCanvas, size);
      final Rect rect0 = captureRect();
      expect(rect0.top, padding.top);
      expect(size.width - rect0.right, padding.right);

      // Bottom overscroll.
      painter.update(
        metrics.copyWith(
          viewportDimension: size.height,
          pixels: double.negativeInfinity,
          axisDirection: AxisDirection.up,
        ),
        AxisDirection.up,
      );

      painter.paint(testCanvas, size);
      final Rect rect1 = captureRect();
      expect(size.height - rect1.bottom, padding.bottom);
      expect(size.width - rect1.right, padding.right);
    });

    testWidgets('left', (WidgetTester tester) async {
      painter.update(
        metrics.copyWith(
          viewportDimension: size.width,
          pixels: double.negativeInfinity,
          axisDirection: AxisDirection.left,
        ),
        AxisDirection.left,
      );

      // Right overscroll.
      painter.paint(testCanvas, size);
      final Rect rect0 = captureRect();
      expect(size.height - rect0.bottom, padding.bottom);
      expect(size.width - rect0.right, padding.right);

      // Left overscroll.
      painter.update(
        metrics.copyWith(
          viewportDimension: size.width,
          pixels: double.infinity,
          axisDirection: AxisDirection.left,
        ),
        AxisDirection.left,
      );

      painter.paint(testCanvas, size);
      final Rect rect1 = captureRect();
      expect(size.height - rect1.bottom, padding.bottom);
      expect(rect1.left, padding.left);
    });

    testWidgets('right', (WidgetTester tester) async {
      painter.update(
        metrics.copyWith(
          viewportDimension: size.width,
          pixels: double.infinity,
          axisDirection: AxisDirection.right,
        ),
        AxisDirection.right,
      );

      // Right overscroll.
      painter.paint(testCanvas, size);
      final Rect rect0 = captureRect();
      expect(size.height - rect0.bottom, padding.bottom);
      expect(size.width - rect0.right, padding.right);

      // Left overscroll.
      painter.update(
        metrics.copyWith(
          viewportDimension: size.width,
          pixels: double.negativeInfinity,
          axisDirection: AxisDirection.right,
        ),
        AxisDirection.right,
      );

      painter.paint(testCanvas, size);
      final Rect rect1 = captureRect();
      expect(size.height - rect1.bottom, padding.bottom);
      expect(rect1.left, padding.left);
    });
  });

  testWidgets('thumb resizes gradually on overscroll', (WidgetTester tester) async {
    const padding = EdgeInsets.fromLTRB(1, 2, 3, 4);
    const size = Size(60, 300);
    final double scrollExtent = size.height * 10;
    final ScrollMetrics metrics = defaultMetrics.copyWith(
      minScrollExtent: 0,
      maxScrollExtent: scrollExtent,
      axisDirection: AxisDirection.down,
      viewportDimension: size.height,
    );

    const minOverscrollLength = 8.0;
    final ScrollbarPainter painter = _buildPainter(
      padding: padding,
      scrollMetrics: metrics,
      minLength: 36.0,
      minOverscrollLength: 8.0,
    );

    // No overscroll gives a full sized thumb.
    painter.update(metrics.copyWith(pixels: 0.0), AxisDirection.down);
    painter.paint(testCanvas, size);
    final double fullThumbExtent = captureRect().height;
    expect(fullThumbExtent, greaterThan(_kMinThumbExtent));

    // Scrolling to the middle also gives a full sized thumb.
    painter.update(metrics.copyWith(pixels: scrollExtent / 2), AxisDirection.down);
    painter.paint(testCanvas, size);
    expect(captureRect().height, moreOrLessEquals(fullThumbExtent, epsilon: 1e-6));

    // Scrolling just to the very end also gives a full sized thumb.
    painter.update(metrics.copyWith(pixels: scrollExtent), AxisDirection.down);
    painter.paint(testCanvas, size);
    expect(captureRect().height, moreOrLessEquals(fullThumbExtent, epsilon: 1e-6));

    // Scrolling just past the end shrinks the thumb slightly.
    painter.update(metrics.copyWith(pixels: scrollExtent * 1.001), AxisDirection.down);
    painter.paint(testCanvas, size);
    expect(captureRect().height, moreOrLessEquals(fullThumbExtent, epsilon: 2.0));

    // Scrolling way past the end shrinks the thumb to minimum.
    painter.update(metrics.copyWith(pixels: double.infinity), AxisDirection.down);
    painter.paint(testCanvas, size);
    expect(captureRect().height, minOverscrollLength);
  });

  test('should scroll towards the right direction', () {
    const size = Size(60, 80);
    const double maxScrollExtent = 240;
    const double minScrollExtent = -100;
    final ScrollMetrics startingMetrics = defaultMetrics.copyWith(
      minScrollExtent: minScrollExtent,
      maxScrollExtent: maxScrollExtent,
      axisDirection: AxisDirection.down,
      viewportDimension: size.height,
    );

    for (final minLength in <double>[_kMinThumbExtent, double.infinity]) {
      // Disregard `minLength` and `minOverscrollLength` to keep
      // scroll direction correct, if needed
      painter = _buildPainter(
        minLength: minLength,
        minOverscrollLength: minLength,
        scrollMetrics: startingMetrics,
      );

      final Iterable<ScrollMetrics> metricsList = Iterable<ScrollMetrics>.generate(
        9999,
        (int index) => startingMetrics.copyWith(pixels: minScrollExtent + index * size.height / 3),
      ).takeWhile((ScrollMetrics metrics) => !metrics.outOfRange);

      Rect? previousRect;

      for (final metrics in metricsList) {
        painter.update(metrics, metrics.axisDirection);
        painter.paint(testCanvas, size);
        final Rect rect = captureRect();
        if (previousRect != null) {
          if (rect.height == size.height) {
            // Size of the scrollbar is too large for the view port
            expect(previousRect.top <= rect.top, true);
            expect(previousRect.bottom <= rect.bottom, true);
          } else {
            // The scrollbar can fit in the view port.
            expect(previousRect.top < rect.top, true);
            expect(previousRect.bottom < rect.bottom, true);
          }
        }

        previousRect = rect;
      }
    }
  });

  test('trackRadius and radius is respected', () {
    const minLen = 3.5;
    const size = Size(600, 10);
    final ScrollMetrics metrics = defaultMetrics.copyWith(
      maxScrollExtent: 100000,
      viewportDimension: size.height,
    );

    painter = _buildPainter(
      trackRadius: const Radius.circular(2.0),
      radius: const Radius.circular(3.0),
      minLength: minLen,
      minOverscrollLength: minLen,
      scrollMetrics: metrics,
    );

    painter.paint(testCanvas, size);

    final RRect thumbRRect = captureRRect(); // thumb
    expect(thumbRRect.blRadius, const Radius.circular(3.0));
    expect(thumbRRect.brRadius, const Radius.circular(3.0));
    expect(thumbRRect.tlRadius, const Radius.circular(3.0));
    expect(thumbRRect.trRadius, const Radius.circular(3.0));

    final RRect trackRRect = captureRRect(); // track
    expect(trackRRect.blRadius, const Radius.circular(2.0));
    expect(trackRRect.brRadius, const Radius.circular(2.0));
    expect(trackRRect.tlRadius, const Radius.circular(2.0));
    expect(trackRRect.trRadius, const Radius.circular(2.0));
  });

  testWidgets('ScrollbarPainter asserts if no TextDirection has been provided', (
    WidgetTester tester,
  ) async {
    final painter = ScrollbarPainter(
      color: _kScrollbarColor,
      fadeoutOpacityAnimation: kAlwaysCompleteAnimation,
    );
    const size = Size(60, 80);
    final ScrollMetrics scrollMetrics = defaultMetrics.copyWith(
      maxScrollExtent: 100000,
      viewportDimension: size.height,
    );
    painter.update(scrollMetrics, scrollMetrics.axisDirection);
    // Try to paint the scrollbar
    try {
      painter.paint(testCanvas, size);
    } on AssertionError catch (error) {
      expect(error.message, 'A TextDirection must be provided before a Scrollbar can be painted.');
    }
  });

  testWidgets('Tapping the track area pages the Scroll View', (WidgetTester tester) async {
    final scrollController = ScrollController();
    addTearDown(scrollController.dispose);
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: const MediaQueryData(),
          child: RawScrollbar(
            thumbVisibility: true,
            controller: scrollController,
            child: SingleChildScrollView(
              controller: scrollController,
              child: const SizedBox(width: 1000.0, height: 1000.0),
            ),
          ),
        ),
      ),
    );

    await tester.pumpAndSettle();
    expect(scrollController.offset, 0.0);
    expect(
      find.byType(RawScrollbar),
      paints
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0))
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 360.0), color: const Color(0x66BCBCBC)),
    );

    // Tap on the track area below the thumb.
    await tester.tapAt(const Offset(796.0, 550.0));
    await tester.pumpAndSettle();

    expect(scrollController.offset, 400.0);
    expect(
      find.byType(RawScrollbar),
      paints
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0))
        ..rect(
          rect: const Rect.fromLTRB(794.0, 240.0, 800.0, 600.0),
          color: const Color(0x66BCBCBC),
        ),
    );

    // Tap on the track area above the thumb.
    await tester.tapAt(const Offset(796.0, 50.0));
    await tester.pumpAndSettle();

    expect(scrollController.offset, 0.0);
    expect(
      find.byType(RawScrollbar),
      paints
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0))
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 360.0), color: const Color(0x66BCBCBC)),
    );
  });

  testWidgets('Scrollbar never goes away until finger lift', (WidgetTester tester) async {
    await tester.pumpWidget(
      const Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: MediaQueryData(),
          child: RawScrollbar(
            child: SingleChildScrollView(child: SizedBox(width: 4000.0, height: 4000.0)),
          ),
        ),
      ),
    );
    final TestGesture gesture = await tester.startGesture(
      tester.getCenter(find.byType(SingleChildScrollView)),
    );
    await gesture.moveBy(const Offset(0.0, -20.0));
    await tester.pump();
    // Scrollbar fully showing
    await tester.pump(const Duration(milliseconds: 500));
    expect(
      find.byType(RawScrollbar),
      paints
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0))
        ..rect(rect: const Rect.fromLTRB(794.0, 3.0, 800.0, 93.0), color: const Color(0x66BCBCBC)),
    );

    await tester.pump(const Duration(seconds: 3));
    await tester.pump(const Duration(seconds: 3));
    // Still there.
    expect(
      find.byType(RawScrollbar),
      paints
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0))
        ..rect(rect: const Rect.fromLTRB(794.0, 3.0, 800.0, 93.0), color: const Color(0x66BCBCBC)),
    );

    await gesture.up();
    await tester.pump(_kScrollbarTimeToFade);
    await tester.pump(_kScrollbarFadeDuration * 0.5);

    // Opacity going down now.
    expect(
      find.byType(RawScrollbar),
      paints
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0))
        ..rect(rect: const Rect.fromLTRB(794.0, 3.0, 800.0, 93.0), color: const Color(0x4fbcbcbc)),
    );
  });

  testWidgets('Scrollbar does not fade away while hovering', (WidgetTester tester) async {
    await tester.pumpWidget(
      const Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: MediaQueryData(),
          child: RawScrollbar(
            child: SingleChildScrollView(child: SizedBox(width: 4000.0, height: 4000.0)),
          ),
        ),
      ),
    );
    final TestGesture gesture = await tester.startGesture(
      tester.getCenter(find.byType(SingleChildScrollView)),
    );
    await gesture.moveBy(const Offset(0.0, -20.0));
    await tester.pump();
    // Scrollbar fully showing
    await tester.pump(const Duration(milliseconds: 500));
    expect(
      find.byType(RawScrollbar),
      paints
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0))
        ..rect(rect: const Rect.fromLTRB(794.0, 3.0, 800.0, 93.0), color: const Color(0x66BCBCBC)),
    );

    final testPointer = TestPointer(1, ui.PointerDeviceKind.mouse);
    // Hover over the thumb to prevent the scrollbar from fading out.
    testPointer.hover(const Offset(790.0, 5.0));
    await gesture.up();
    await tester.pump(const Duration(seconds: 3));

    // Still there.
    expect(
      find.byType(RawScrollbar),
      paints
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0))
        ..rect(rect: const Rect.fromLTRB(794.0, 3.0, 800.0, 93.0), color: const Color(0x66BCBCBC)),
    );
  });

  testWidgets('Scrollbar will fade back in when hovering over known track area', (
    WidgetTester tester,
  ) async {
    await tester.pumpWidget(
      const Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: MediaQueryData(),
          child: RawScrollbar(
            child: SingleChildScrollView(child: SizedBox(width: 4000.0, height: 4000.0)),
          ),
        ),
      ),
    );
    final TestGesture gesture = await tester.startGesture(
      tester.getCenter(find.byType(SingleChildScrollView)),
    );
    await gesture.moveBy(const Offset(0.0, -20.0));
    await tester.pump();
    // Scrollbar fully showing
    await tester.pump(const Duration(milliseconds: 500));
    expect(
      find.byType(RawScrollbar),
      paints
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0))
        ..rect(rect: const Rect.fromLTRB(794.0, 3.0, 800.0, 93.0), color: const Color(0x66BCBCBC)),
    );
    await gesture.up();
    await tester.pump(_kScrollbarTimeToFade);
    await tester.pump(_kScrollbarFadeDuration * 0.5);

    // Scrollbar is fading out
    expect(
      find.byType(RawScrollbar),
      paints
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0))
        ..rect(rect: const Rect.fromLTRB(794.0, 3.0, 800.0, 93.0), color: const Color(0x4fbcbcbc)),
    );

    // Hover over scrollbar with mouse to bring opacity back up
    final TestGesture mouseGesture = await tester.createGesture(kind: ui.PointerDeviceKind.mouse);
    await mouseGesture.addPointer();
    addTearDown(mouseGesture.removePointer);
    await mouseGesture.moveTo(const Offset(794.0, 5.0));
    await tester.pumpAndSettle();
    // Scrollbar should be visible
    expect(
      find.byType(RawScrollbar),
      paints
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0))
        ..rect(rect: const Rect.fromLTRB(794.0, 3.0, 800.0, 93.0), color: const Color(0x66BCBCBC)),
    );
  });

  testWidgets('Scrollbar will show on hover without needing to scroll first for metrics', (
    WidgetTester tester,
  ) async {
    await tester.pumpWidget(
      const Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: MediaQueryData(),
          child: RawScrollbar(
            child: SingleChildScrollView(child: SizedBox(width: 4000.0, height: 4000.0)),
          ),
        ),
      ),
    );
    await tester.pump();

    // Hover over scrollbar with mouse. Even though we have not scrolled, the
    // ScrollMetricsNotification will have informed the Scrollbar's hit testing.
    final TestGesture mouseGesture = await tester.createGesture(kind: ui.PointerDeviceKind.mouse);
    await mouseGesture.addPointer();
    addTearDown(mouseGesture.removePointer);
    await mouseGesture.moveTo(const Offset(794.0, 5.0));
    await tester.pumpAndSettle();
    // Scrollbar should have appeared in response to hover event.
    expect(
      find.byType(RawScrollbar),
      paints
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0))
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 90.0), color: const Color(0x66BCBCBC)),
    );
  });

  testWidgets('Scrollbar thumb can be dragged', (WidgetTester tester) async {
    final scrollController = ScrollController();
    addTearDown(scrollController.dispose);
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: const MediaQueryData(),
          child: PrimaryScrollController(
            controller: scrollController,
            child: RawScrollbar(
              thumbVisibility: true,
              controller: scrollController,
              child: const SingleChildScrollView(child: SizedBox(width: 4000.0, height: 4000.0)),
            ),
          ),
        ),
      ),
    );
    await tester.pumpAndSettle();
    expect(scrollController.offset, 0.0);
    expect(
      find.byType(RawScrollbar),
      paints
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0))
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 90.0), color: const Color(0x66BCBCBC)),
    );

    // Drag the thumb down to scroll down.
    const scrollAmount = 10.0;
    final TestGesture dragScrollbarGesture = await tester.startGesture(const Offset(797.0, 45.0));
    await tester.pumpAndSettle();
    await dragScrollbarGesture.moveBy(const Offset(0.0, scrollAmount));
    await tester.pumpAndSettle();
    await dragScrollbarGesture.up();
    await tester.pumpAndSettle();

    // The view has scrolled more than it would have by a swipe gesture of the
    // same distance.
    expect(scrollController.offset, greaterThan(scrollAmount * 2));
    expect(
      find.byType(RawScrollbar),
      paints
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0))
        ..rect(
          rect: const Rect.fromLTRB(794.0, 10.0, 800.0, 100.0),
          color: const Color(0x66BCBCBC),
        ),
    );
  });

  testWidgets('Scrollbar thumb cannot be dragged into overscroll if the physics do not allow', (
    WidgetTester tester,
  ) async {
    final scrollController = ScrollController();
    addTearDown(scrollController.dispose);
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: const MediaQueryData(),
          child: PrimaryScrollController(
            controller: scrollController,
            child: RawScrollbar(
              thumbVisibility: true,
              controller: scrollController,
              child: const SingleChildScrollView(child: SizedBox(width: 4000.0, height: 4000.0)),
            ),
          ),
        ),
      ),
    );
    await tester.pumpAndSettle();
    expect(scrollController.offset, 0.0);
    expect(
      find.byType(RawScrollbar),
      paints
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0))
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 90.0), color: const Color(0x66BCBCBC)),
    );

    // Try to drag the thumb into overscroll.
    const scrollAmount = -10.0;
    final TestGesture dragScrollbarGesture = await tester.startGesture(const Offset(797.0, 45.0));
    await tester.pumpAndSettle();
    await dragScrollbarGesture.moveBy(const Offset(0.0, scrollAmount));
    await tester.pumpAndSettle();

    // The physics should not have allowed us to enter overscroll.
    expect(scrollController.offset, 0.0);
    expect(
      find.byType(RawScrollbar),
      paints
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0))
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 90.0), color: const Color(0x66BCBCBC)),
    );
  });

  testWidgets(
    'Scrollbar thumb cannot be dragged into overscroll if the platform does not allow it',
    (WidgetTester tester) async {
      final scrollController = ScrollController();
      addTearDown(scrollController.dispose);
      await tester.pumpWidget(
        Directionality(
          textDirection: TextDirection.ltr,
          child: MediaQuery(
            data: const MediaQueryData(),
            child: ScrollConfiguration(
              // Don't apply a scrollbar automatically for this test.
              behavior: const ScrollBehavior().copyWith(
                scrollbars: false,
                physics: const AlwaysScrollableScrollPhysics(),
              ),
              child: PrimaryScrollController(
                controller: scrollController,
                child: RawScrollbar(
                  thumbVisibility: true,
                  controller: scrollController,
                  child: const SingleChildScrollView(
                    primary: true,
                    child: SizedBox(width: 4000.0, height: 4000.0),
                  ),
                ),
              ),
            ),
          ),
        ),
      );
      await tester.pumpAndSettle();
      expect(scrollController.offset, 0.0);
      expect(
        find.byType(RawScrollbar),
        paints
          ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0))
          ..rect(
            rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 90.0),
            color: const Color(0x66BCBCBC),
          ),
      );

      // Try to drag the thumb into overscroll.
      const scrollAmount = -10.0;
      final TestGesture dragScrollbarGesture = await tester.startGesture(const Offset(797.0, 45.0));
      await tester.pumpAndSettle();
      await dragScrollbarGesture.moveBy(const Offset(0.0, scrollAmount));
      await tester.pumpAndSettle();

      // The platform drag handling should not have allowed us to enter overscroll.
      expect(scrollController.offset, 0.0);
      expect(
        find.byType(RawScrollbar),
        paints
          ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0))
          ..rect(
            rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 90.0),
            color: const Color(0x66BCBCBC),
          ),
      );

      await dragScrollbarGesture.up();
      await tester.pumpAndSettle();
    },
    variant: const TargetPlatformVariant(<TargetPlatform>{
      TargetPlatform.macOS,
      TargetPlatform.linux,
      TargetPlatform.windows,
      TargetPlatform.fuchsia,
    }),
  );

  testWidgets(
    'Scrollbar thumb can be dragged into overscroll if the platform allows it',
    (WidgetTester tester) async {
      final scrollController = ScrollController();
      addTearDown(scrollController.dispose);
      await tester.pumpWidget(
        Directionality(
          textDirection: TextDirection.ltr,
          child: MediaQuery(
            data: const MediaQueryData(),
            child: ScrollConfiguration(
              // Don't apply a scrollbar automatically for this test.
              behavior: const ScrollBehavior().copyWith(
                scrollbars: false,
                physics: const AlwaysScrollableScrollPhysics(),
              ),
              child: PrimaryScrollController(
                controller: scrollController,
                child: RawScrollbar(
                  thumbVisibility: true,
                  controller: scrollController,
                  child: const SingleChildScrollView(
                    child: SizedBox(width: 4000.0, height: 4000.0),
                  ),
                ),
              ),
            ),
          ),
        ),
      );
      await tester.pumpAndSettle();
      expect(scrollController.offset, 0.0);
      expect(
        find.byType(RawScrollbar),
        paints
          ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0))
          ..rect(
            rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 90.0),
            color: const Color(0x66BCBCBC),
          ),
      );

      // Try to drag the thumb into overscroll.
      const scrollAmount = -10.0;
      final TestGesture dragScrollbarGesture = await tester.startGesture(const Offset(797.0, 45.0));
      await tester.pumpAndSettle();
      await dragScrollbarGesture.moveBy(const Offset(0.0, scrollAmount));
      await tester.pumpAndSettle();

      // The platform drag handling should have allowed us to enter overscroll.
      expect(scrollController.offset, lessThan(-66.0));
      expect(
        find.byType(RawScrollbar),
        paints
          ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0))
          ..rect(
            // The size of the scrollbar thumb shrinks when overscrolling
            rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 80.0),
            color: const Color(0x66BCBCBC),
          ),
      );

      await dragScrollbarGesture.up();
      await tester.pumpAndSettle();
    },
    variant: const TargetPlatformVariant(<TargetPlatform>{
      TargetPlatform.android,
      TargetPlatform.iOS,
    }),
  );

  // Regression test for https://github.com/flutter/flutter/issues/66444
  testWidgets("RawScrollbar doesn't show when scroll the inner scrollable widget", (
    WidgetTester tester,
  ) async {
    final GlobalKey key1 = GlobalKey();
    final GlobalKey key2 = GlobalKey();
    final GlobalKey outerKey = GlobalKey();
    final GlobalKey innerKey = GlobalKey();
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: const MediaQueryData(),
          child: RawScrollbar(
            key: key2,
            thumbColor: const Color(0x11111111),
            child: SingleChildScrollView(
              key: outerKey,
              child: SizedBox(
                height: 1000.0,
                width: double.infinity,
                child: Column(
                  children: <Widget>[
                    RawScrollbar(
                      key: key1,
                      thumbColor: const Color(0x22222222),
                      child: SizedBox(
                        height: 300.0,
                        width: double.infinity,
                        child: SingleChildScrollView(
                          key: innerKey,
                          child: const SizedBox(
                            key: Key('Inner scrollable'),
                            height: 1000.0,
                            width: double.infinity,
                          ),
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ),
        ),
      ),
    );

    // Drag the inner scrollable widget.
    await tester.drag(find.byKey(innerKey), const Offset(0.0, -25.0));
    await tester.pump();
    // Scrollbar fully showing.
    await tester.pump(const Duration(milliseconds: 500));

    expect(
      tester.renderObject(find.byKey(key2)),
      paintsExactlyCountTimes(#drawRect, 2), // Each bar will call [drawRect] twice.
    );

    expect(tester.renderObject(find.byKey(key1)), paintsExactlyCountTimes(#drawRect, 2));
  });

  testWidgets('Scrollbar hit test area adjusts for PointerDeviceKind', (WidgetTester tester) async {
    final scrollController = ScrollController();
    addTearDown(scrollController.dispose);
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: const MediaQueryData(),
          child: PrimaryScrollController(
            controller: scrollController,
            child: RawScrollbar(
              thumbVisibility: true,
              controller: scrollController,
              child: const SingleChildScrollView(child: SizedBox(width: 4000.0, height: 4000.0)),
            ),
          ),
        ),
      ),
    );
    await tester.pumpAndSettle();
    expect(scrollController.offset, 0.0);
    expect(
      find.byType(RawScrollbar),
      paints
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0))
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 90.0), color: const Color(0x66BCBCBC)),
    );

    // Drag the scrollbar just outside of the painted thumb with touch input.
    // The hit test area is padded to meet the minimum interactive size.
    const scrollAmount = 10.0;
    final TestGesture dragScrollbarGesture = await tester.startGesture(const Offset(790.0, 45.0));
    await tester.pumpAndSettle();
    await dragScrollbarGesture.moveBy(const Offset(0.0, scrollAmount));
    await tester.pumpAndSettle();

    // The scrollbar moved by scrollAmount, and the scrollOffset moved forward.
    expect(scrollController.offset, greaterThan(0.0));
    expect(
      find.byType(RawScrollbar),
      paints
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0))
        ..rect(
          rect: const Rect.fromLTRB(794.0, 10.0, 800.0, 100.0),
          color: const Color(0x66BCBCBC),
        ),
    );

    // Move back to reset.
    await dragScrollbarGesture.moveBy(const Offset(0.0, -scrollAmount));
    await tester.pumpAndSettle();
    await dragScrollbarGesture.up();
    expect(scrollController.offset, 0.0);
    expect(
      find.byType(RawScrollbar),
      paints
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0))
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 90.0), color: const Color(0x66BCBCBC)),
    );

    // The same should not be possible with a mouse since it is more precise,
    // the padding it not necessary.
    final TestGesture gesture = await tester.createGesture(kind: ui.PointerDeviceKind.mouse);
    await gesture.addPointer();
    await gesture.down(const Offset(790.0, 45.0));
    await tester.pump();
    await gesture.moveTo(const Offset(790.0, 55.0));
    await gesture.up();
    await tester.pumpAndSettle();
    // The scrollbar/scrollable should not have moved.
    expect(scrollController.offset, 0.0);
    expect(
      find.byType(RawScrollbar),
      paints
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0))
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 90.0), color: const Color(0x66BCBCBC)),
    );
  });

  testWidgets('hit test', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/99324
    final scrollController = ScrollController();
    addTearDown(scrollController.dispose);
    var onTap = false;
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: const MediaQueryData(),
          child: PrimaryScrollController(
            controller: scrollController,
            child: RawScrollbar(
              trackVisibility: true,
              thumbVisibility: true,
              controller: scrollController,
              child: SingleChildScrollView(
                child: GestureDetector(
                  onTap: () => onTap = true,
                  child: const SizedBox.square(
                    dimension: 4000.0,
                    child: ColoredBox(color: Color(0x00000000)),
                  ),
                ),
              ),
            ),
          ),
        ),
      ),
    );
    await tester.pumpAndSettle();
    expect(onTap, false);

    // Tap on track area.
    await tester.tapAt(const Offset(795.0, 550.0));
    await tester.pumpAndSettle();
    expect(onTap, false);

    // Tap on thumb area.
    await tester.tapAt(const Offset(795.0, 10.0));
    await tester.pumpAndSettle();
    expect(onTap, false);

    // Tap on content area.
    await tester.tapAt(const Offset(400.0, 300.0));
    await tester.pumpAndSettle();
    expect(onTap, true);
  });

  testWidgets('RawScrollbar.thumbVisibility asserts that a ScrollPosition is attached', (
    WidgetTester tester,
  ) async {
    final FlutterExceptionHandler? handler = FlutterError.onError;
    FlutterErrorDetails? error;
    FlutterError.onError = (FlutterErrorDetails details) {
      error = details;
    };
    final controller = ScrollController();
    addTearDown(controller.dispose);

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: const MediaQueryData(),
          child: RawScrollbar(
            thumbVisibility: true,
            controller: controller,
            thumbColor: const Color(0x11111111),
            child: const SingleChildScrollView(child: SizedBox(height: 1000.0, width: 50.0)),
          ),
        ),
      ),
    );
    await tester.pumpAndSettle();

    expect(error, isNotNull);
    final exception = error!.exception as AssertionError;
    expect(
      exception.message,
      contains("The Scrollbar's ScrollController has no ScrollPosition attached."),
    );

    FlutterError.onError = handler;
  });

  testWidgets('RawScrollbar.thumbVisibility asserts that a ScrollPosition is attached', (
    WidgetTester tester,
  ) async {
    final FlutterExceptionHandler? handler = FlutterError.onError;
    FlutterErrorDetails? error;
    FlutterError.onError = (FlutterErrorDetails details) {
      error = details;
    };
    final controller = ScrollController();
    addTearDown(controller.dispose);

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: const MediaQueryData(),
          child: RawScrollbar(
            thumbVisibility: true,
            controller: controller,
            thumbColor: const Color(0x11111111),
            child: const SingleChildScrollView(child: SizedBox(height: 1000.0, width: 50.0)),
          ),
        ),
      ),
    );
    await tester.pumpAndSettle();

    expect(error, isNotNull);
    final exception = error!.exception as AssertionError;
    expect(
      exception.message,
      contains("The Scrollbar's ScrollController has no ScrollPosition attached."),
    );

    FlutterError.onError = handler;
  });

  testWidgets('Interactive scrollbars should have a valid scroll controller', (
    WidgetTester tester,
  ) async {
    final primaryScrollController = ScrollController();
    addTearDown(primaryScrollController.dispose);
    final scrollController = ScrollController();
    addTearDown(scrollController.dispose);

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: const MediaQueryData(),
          child: PrimaryScrollController(
            controller: primaryScrollController,
            child: RawScrollbar(
              child: SingleChildScrollView(
                controller: scrollController,
                child: const SizedBox(height: 1000.0, width: 1000.0),
              ),
            ),
          ),
        ),
      ),
    );

    await tester.pumpAndSettle();

    var exception = tester.takeException() as AssertionError?;
    // The scrollbar is not visible and cannot be interacted with, so no assertion.
    expect(exception, isNull);
    // Scroll to trigger the scrollbar to come into view.
    final TestGesture gesture = await tester.startGesture(
      tester.getCenter(find.byType(SingleChildScrollView)),
    );
    await gesture.moveBy(const Offset(0.0, -20.0));
    exception = tester.takeException() as AssertionError;
    expect(exception, isAssertionError);
    expect(
      exception.message,
      '''
The Scrollbar's ScrollController has no ScrollPosition attached.
A Scrollbar cannot be painted without a ScrollPosition.
The Scrollbar attempted to use the PrimaryScrollController. This ScrollController should be associated with the ScrollView that the Scrollbar is being applied to.
If a ScrollController has not been provided, the PrimaryScrollController is used by default on mobile platforms for ScrollViews with an Axis.vertical scroll direction.
To use the PrimaryScrollController explicitly, set ScrollView.primary to true on the Scrollable widget.''',
    );
  });

  testWidgets('Scrollbars assert on multiple scroll positions', (WidgetTester tester) async {
    final scrollController = ScrollController();
    addTearDown(scrollController.dispose);
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: const MediaQueryData(),
          child: PrimaryScrollController(
            controller: scrollController,
            child: Row(
              children: <Widget>[
                RawScrollbar(
                  controller: scrollController,
                  child: const SingleChildScrollView(child: SizedBox(width: 10.0, height: 4000.0)),
                ),
                RawScrollbar(
                  controller: scrollController,
                  child: const SingleChildScrollView(child: SizedBox(width: 10.0, height: 4000.0)),
                ),
              ],
            ),
          ),
        ),
      ),
    );
    await tester.pumpAndSettle();

    var exception = tester.takeException() as AssertionError?;
    // The scrollbar is not visible and cannot be interacted with, so no assertion.
    expect(exception, isNull);
    // Scroll to trigger the scrollbar to come into view.
    final Finder scrollViews = find.byType(SingleChildScrollView);
    final TestGesture gesture = await tester.startGesture(tester.getCenter(scrollViews.first));
    await gesture.moveBy(const Offset(0.0, -20.0));
    exception = tester.takeException() as AssertionError;
    expect(exception, isAssertionError);
    expect(exception.message, '''
The provided ScrollController is attached to more than one ScrollPosition.
The Scrollbar requires a single ScrollPosition in order to be painted.
When the scrollbar is interactive, the associated ScrollController must only have one ScrollPosition attached.
The provided ScrollController cannot be shared by multiple ScrollView widgets.''');
  });

  testWidgets('Simultaneous dragging and pointer scrolling does not cause a crash', (
    WidgetTester tester,
  ) async {
    // Regression test for https://github.com/flutter/flutter/issues/70105
    final scrollController = ScrollController();
    addTearDown(scrollController.dispose);
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: const MediaQueryData(),
          child: PrimaryScrollController(
            controller: scrollController,
            child: RawScrollbar(
              thumbVisibility: true,
              controller: scrollController,
              child: const SingleChildScrollView(child: SizedBox(width: 4000.0, height: 4000.0)),
            ),
          ),
        ),
      ),
    );
    await tester.pumpAndSettle();
    expect(scrollController.offset, 0.0);
    expect(
      find.byType(RawScrollbar),
      paints
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0), color: const Color(0x00000000))
        ..line(
          p1: const Offset(794.0, 0.0),
          p2: const Offset(794.0, 600.0),
          strokeWidth: 1.0,
          color: const Color(0x00000000),
        )
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 90.0), color: const Color(0x66bcbcbc)),
    );

    // Drag the thumb down to scroll down.
    const scrollAmount = 10.0;
    final TestGesture dragScrollbarGesture = await tester.startGesture(const Offset(797.0, 45.0));
    await tester.pumpAndSettle();

    expect(
      find.byType(RawScrollbar),
      paints
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0), color: const Color(0x00000000))
        ..line(
          p1: const Offset(794.0, 0.0),
          p2: const Offset(794.0, 600.0),
          strokeWidth: 1.0,
          color: const Color(0x00000000),
        )
        ..rect(
          rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 90.0),
          // Drag color
          color: const Color(0x66bcbcbc),
        ),
    );

    await dragScrollbarGesture.moveBy(const Offset(0.0, scrollAmount));
    await tester.pumpAndSettle();
    expect(scrollController.offset, greaterThan(10.0));
    final double previousOffset = scrollController.offset;
    expect(
      find.byType(RawScrollbar),
      paints
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0), color: const Color(0x00000000))
        ..line(
          p1: const Offset(794.0, 0.0),
          p2: const Offset(794.0, 600.0),
          strokeWidth: 1.0,
          color: const Color(0x00000000),
        )
        ..rect(
          rect: const Rect.fromLTRB(794.0, 10.0, 800.0, 100.0),
          color: const Color(0x66bcbcbc),
        ),
    );

    // Execute a pointer scroll while dragging (drag gesture has not come up yet)
    final pointer = TestPointer(1, ui.PointerDeviceKind.mouse);
    pointer.hover(const Offset(798.0, 15.0));
    await tester.sendEventToBinding(pointer.scroll(const Offset(0.0, 20.0)));
    await tester.pumpAndSettle();

    if (!kIsWeb) {
      // Scrolling while holding the drag on the scrollbar and still hovered over
      // the scrollbar should not have changed the scroll offset.
      expect(pointer.location, const Offset(798.0, 15.0));
      expect(scrollController.offset, previousOffset);
      expect(
        find.byType(RawScrollbar),
        paints
          ..rect(
            rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0),
            color: const Color(0x00000000),
          )
          ..line(
            p1: const Offset(794.0, 0.0),
            p2: const Offset(794.0, 600.0),
            strokeWidth: 1.0,
            color: const Color(0x00000000),
          )
          ..rect(
            rect: const Rect.fromLTRB(794.0, 10.0, 800.0, 100.0),
            color: const Color(0x66bcbcbc),
          ),
      );
    } else {
      expect(pointer.location, const Offset(798.0, 15.0));
      expect(scrollController.offset, previousOffset + 20.0);
    }

    // Drag is still being held, move pointer to be hovering over another area
    // of the scrollable (not over the scrollbar) and execute another pointer scroll
    pointer.hover(tester.getCenter(find.byType(SingleChildScrollView)));
    await tester.sendEventToBinding(pointer.scroll(const Offset(0.0, -90.0)));
    await tester.pumpAndSettle();
    // Scrolling while holding the drag on the scrollbar changed the offset
    expect(pointer.location, const Offset(400.0, 300.0));
    expect(scrollController.offset, 0.0);
    expect(
      find.byType(RawScrollbar),
      paints
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0), color: const Color(0x00000000))
        ..line(
          p1: const Offset(794.0, 0.0),
          p2: const Offset(794.0, 600.0),
          strokeWidth: 1.0,
          color: const Color(0x00000000),
        )
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 90.0), color: const Color(0x66bcbcbc)),
    );

    await dragScrollbarGesture.up();
    await tester.pumpAndSettle();
    expect(scrollController.offset, 0.0);
    expect(
      find.byType(RawScrollbar),
      paints
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0), color: const Color(0x00000000))
        ..line(
          p1: const Offset(794.0, 0.0),
          p2: const Offset(794.0, 600.0),
          strokeWidth: 1.0,
          color: const Color(0x00000000),
        )
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 90.0), color: const Color(0x66bcbcbc)),
    );
  });

  testWidgets('Scrollbar thumb can be dragged in reverse', (WidgetTester tester) async {
    final scrollController = ScrollController();
    addTearDown(scrollController.dispose);
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: const MediaQueryData(),
          child: PrimaryScrollController(
            controller: scrollController,
            child: RawScrollbar(
              thumbVisibility: true,
              controller: scrollController,
              child: const SingleChildScrollView(
                reverse: true,
                child: SizedBox(width: 4000.0, height: 4000.0),
              ),
            ),
          ),
        ),
      ),
    );
    await tester.pumpAndSettle();
    expect(scrollController.offset, 0.0);
    expect(
      find.byType(RawScrollbar),
      paints
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0))
        ..rect(
          rect: const Rect.fromLTRB(794.0, 510.0, 800.0, 600.0),
          color: const Color(0x66BCBCBC),
        ),
    );

    // Drag the thumb up to scroll up.
    const scrollAmount = 10.0;
    final TestGesture dragScrollbarGesture = await tester.startGesture(const Offset(797.0, 550.0));
    await tester.pumpAndSettle();
    await dragScrollbarGesture.moveBy(const Offset(0.0, -scrollAmount));
    await tester.pumpAndSettle();
    await dragScrollbarGesture.up();
    await tester.pumpAndSettle();

    // The view has scrolled more than it would have by a swipe gesture of the
    // same distance.
    expect(scrollController.offset, greaterThan(scrollAmount * 2));
    expect(
      find.byType(RawScrollbar),
      paints
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0))
        ..rect(
          rect: const Rect.fromLTRB(794.0, 500.0, 800.0, 590.0),
          color: const Color(0x66BCBCBC),
        ),
    );
  });

  testWidgets('ScrollbarPainter asserts if scrollbarOrientation is used with wrong axisDirection', (
    WidgetTester tester,
  ) async {
    final painter = ScrollbarPainter(
      color: _kScrollbarColor,
      fadeoutOpacityAnimation: kAlwaysCompleteAnimation,
      textDirection: TextDirection.ltr,
      scrollbarOrientation: ScrollbarOrientation.left,
    );
    const size = Size(60, 80);
    final ScrollMetrics scrollMetrics = defaultMetrics.copyWith(
      maxScrollExtent: 100,
      viewportDimension: size.height,
      axisDirection: AxisDirection.right,
    );
    painter.update(scrollMetrics, scrollMetrics.axisDirection);

    expect(() => painter.paint(testCanvas, size), throwsA(isA<AssertionError>()));
  });

  testWidgets('RawScrollbar mainAxisMargin property works properly', (WidgetTester tester) async {
    final scrollController = ScrollController();
    addTearDown(scrollController.dispose);
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: const MediaQueryData(),
          child: RawScrollbar(
            mainAxisMargin: 10,
            thumbVisibility: true,
            controller: scrollController,
            child: SingleChildScrollView(
              controller: scrollController,
              child: const SizedBox(width: 1000.0, height: 1000.0),
            ),
          ),
        ),
      ),
    );

    await tester.pumpAndSettle();
    expect(scrollController.offset, 0.0);
    expect(
      find.byType(RawScrollbar),
      paints
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0))
        ..rect(rect: const Rect.fromLTRB(794.0, 10.0, 800.0, 358.0)),
    );
  });

  testWidgets('shape property of RawScrollbar can draw a BeveledRectangleBorder', (
    WidgetTester tester,
  ) async {
    final scrollController = ScrollController();
    addTearDown(scrollController.dispose);
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: const MediaQueryData(),
          child: RawScrollbar(
            shape: const BeveledRectangleBorder(
              borderRadius: BorderRadius.all(Radius.circular(8.0)),
            ),
            controller: scrollController,
            thumbVisibility: true,
            child: SingleChildScrollView(
              controller: scrollController,
              child: const SizedBox(height: 1000.0),
            ),
          ),
        ),
      ),
    );
    await tester.pumpAndSettle();
    expect(
      find.byType(RawScrollbar),
      paints
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0))
        ..path(
          includes: const <Offset>[Offset(797.0, 0.0), Offset(797.0, 18.0)],
          excludes: const <Offset>[Offset(796.0, 0.0), Offset(798.0, 0.0)],
        ),
    );
  });

  testWidgets('minThumbLength property of RawScrollbar is respected', (WidgetTester tester) async {
    final scrollController = ScrollController();
    addTearDown(scrollController.dispose);
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: const MediaQueryData(),
          child: RawScrollbar(
            controller: scrollController,
            minThumbLength: 21,
            minOverscrollLength: 8,
            thumbVisibility: true,
            child: SingleChildScrollView(
              controller: scrollController,
              child: const SizedBox(width: 1000.0, height: 50000.0),
            ),
          ),
        ),
      ),
    );
    await tester.pumpAndSettle();
    expect(
      find.byType(RawScrollbar),
      paints
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0)) // track
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 21.0)),
    ); // thumb
  });

  testWidgets('shape property of RawScrollbar can draw a CircleBorder', (
    WidgetTester tester,
  ) async {
    final scrollController = ScrollController();
    addTearDown(scrollController.dispose);
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: const MediaQueryData(),
          child: RawScrollbar(
            shape: const CircleBorder(side: BorderSide(width: 2.0)),
            thickness: 36.0,
            controller: scrollController,
            thumbVisibility: true,
            child: SingleChildScrollView(
              controller: scrollController,
              child: const SizedBox(height: 1000.0, width: 1000),
            ),
          ),
        ),
      ),
    );
    await tester.pumpAndSettle();

    expect(
      find.byType(RawScrollbar),
      paints
        // Scrollbar thumb background fill.
        ..circle(x: 782.0, y: 180.0, radius: 18.0, style: PaintingStyle.fill)
        // Scrollbar thumb border (stroke).
        ..circle(x: 782.0, y: 180.0, radius: 17.0, style: PaintingStyle.stroke, strokeWidth: 2.0),
    );
  });

  testWidgets('crossAxisMargin property of RawScrollbar is respected', (WidgetTester tester) async {
    final scrollController = ScrollController();
    addTearDown(scrollController.dispose);
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: const MediaQueryData(),
          child: RawScrollbar(
            controller: scrollController,
            crossAxisMargin: 30,
            thumbVisibility: true,
            child: SingleChildScrollView(
              controller: scrollController,
              child: const SizedBox(width: 1000.0, height: 1000.0),
            ),
          ),
        ),
      ),
    );
    await tester.pumpAndSettle();
    expect(
      find.byType(RawScrollbar),
      paints
        ..rect(rect: const Rect.fromLTRB(734.0, 0.0, 800.0, 600.0))
        ..rect(rect: const Rect.fromLTRB(764.0, 0.0, 770.0, 360.0)),
    );
  });

  testWidgets('shape property of RawScrollbar can draw a RoundedRectangleBorder', (
    WidgetTester tester,
  ) async {
    final scrollController = ScrollController();
    addTearDown(scrollController.dispose);
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: const MediaQueryData(),
          child: RawScrollbar(
            thickness: 20,
            shape: const RoundedRectangleBorder(
              borderRadius: BorderRadius.only(topLeft: Radius.circular(8)),
            ),
            controller: scrollController,
            thumbVisibility: true,
            child: SingleChildScrollView(
              controller: scrollController,
              child: const SizedBox(height: 1000.0, width: 1000.0),
            ),
          ),
        ),
      ),
    );
    await tester.pumpAndSettle();
    expect(
      find.byType(RawScrollbar),
      paints
        // Scrollbar track.
        ..rect(rect: const Rect.fromLTRB(780.0, 0.0, 800.0, 600.0))
        // Scrollbar thumb background fill.
        ..rrect(
          rrect: RRect.fromRectAndCorners(
            const Rect.fromLTRB(780.0, 0.0, 800.0, 360.0),
            topLeft: const Radius.circular(8.0),
          ),
        ),
    );
  });

  testWidgets('minOverscrollLength property of RawScrollbar is respected', (
    WidgetTester tester,
  ) async {
    final scrollController = ScrollController();
    addTearDown(scrollController.dispose);
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: const MediaQueryData(),
          child: RawScrollbar(
            controller: scrollController,
            thumbVisibility: true,
            minOverscrollLength: 8.0,
            minThumbLength: 36.0,
            child: SingleChildScrollView(
              physics: const BouncingScrollPhysics(),
              controller: scrollController,
              child: const SizedBox(height: 10000),
            ),
          ),
        ),
      ),
    );
    await tester.pumpAndSettle();
    final TestGesture gesture = await tester.startGesture(
      tester.getCenter(find.byType(RawScrollbar)),
    );
    await gesture.moveBy(const Offset(0, 1000));
    await tester.pump();
    expect(
      find.byType(RawScrollbar),
      paints
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0))
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 8.0)),
    );
  });

  testWidgets(
    'not passing any shape or radius to RawScrollbar will draw the usual rectangular thumb',
    (WidgetTester tester) async {
      final scrollController = ScrollController();
      addTearDown(scrollController.dispose);
      await tester.pumpWidget(
        Directionality(
          textDirection: TextDirection.ltr,
          child: MediaQuery(
            data: const MediaQueryData(),
            child: RawScrollbar(
              controller: scrollController,
              thumbVisibility: true,
              child: SingleChildScrollView(
                controller: scrollController,
                child: const SizedBox(height: 1000.0),
              ),
            ),
          ),
        ),
      );
      await tester.pumpAndSettle();

      expect(
        find.byType(RawScrollbar),
        paints
          ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0))
          ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 360.0)),
      );
    },
  );

  testWidgets('The bar can show or hide when the viewport size change', (
    WidgetTester tester,
  ) async {
    final scrollController = ScrollController();
    addTearDown(scrollController.dispose);
    Widget buildFrame(double height) {
      return Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: const MediaQueryData(),
          child: RawScrollbar(
            controller: scrollController,
            thumbVisibility: true,
            child: SingleChildScrollView(
              controller: scrollController,
              child: SizedBox(width: double.infinity, height: height),
            ),
          ),
        ),
      );
    }

    await tester.pumpWidget(buildFrame(600.0));
    await tester.pumpAndSettle();
    expect(find.byType(RawScrollbar), isNot(paints..rect())); // Not shown.

    await tester.pumpWidget(buildFrame(600.1));
    await tester.pumpAndSettle();
    expect(find.byType(RawScrollbar), paints..rect()); // Show the bar.

    await tester.pumpWidget(buildFrame(600.0));
    await tester.pumpAndSettle();
    expect(find.byType(RawScrollbar), isNot(paints..rect())); // Hide the bar.
  });

  testWidgets('The bar can show or hide when the view size change', (WidgetTester tester) async {
    addTearDown(tester.view.reset);

    final scrollController = ScrollController();
    addTearDown(scrollController.dispose);
    Widget buildFrame() {
      return Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: const MediaQueryData(),
          child: PrimaryScrollController(
            controller: scrollController,
            child: RawScrollbar(
              thumbVisibility: true,
              controller: scrollController,
              child: const SingleChildScrollView(
                child: SizedBox(width: double.infinity, height: 600.0),
              ),
            ),
          ),
        ),
      );
    }

    tester.view.physicalSize = const Size(800.0, 600.0);
    tester.view.devicePixelRatio = 1;

    await tester.pumpWidget(buildFrame());
    await tester.pumpAndSettle();
    expect(scrollController.offset, 0.0);
    expect(find.byType(RawScrollbar), isNot(paints..rect())); // Not shown.

    tester.view.physicalSize = const Size(800.0, 599.0);
    await tester.pumpAndSettle();
    expect(
      find.byType(RawScrollbar),
      paints
        ..rect()
        ..rect(),
    ); // Show the bar.

    tester.view.physicalSize = const Size(800.0, 600.0);
    await tester.pumpAndSettle();
    expect(find.byType(RawScrollbar), isNot(paints..rect())); // Not shown.
  });

  testWidgets(
    'Scrollbar will not flip axes based on notification is there is a scroll controller',
    (WidgetTester tester) async {
      // Regression test for https://github.com/flutter/flutter/issues/87697
      final verticalScrollController = ScrollController();
      addTearDown(verticalScrollController.dispose);
      final horizontalScrollController = ScrollController();
      addTearDown(horizontalScrollController.dispose);
      Widget buildFrame() {
        return Directionality(
          textDirection: TextDirection.ltr,
          child: MediaQuery(
            data: const MediaQueryData(),
            child: RawScrollbar(
              thumbVisibility: true,
              controller: verticalScrollController,
              // This scrollbar will receive scroll notifications from both nested
              // scroll views of opposite axes, but should stay on the vertical
              // axis that its scroll controller is associated with.
              notificationPredicate: (ScrollNotification notification) => notification.depth <= 1,
              child: SingleChildScrollView(
                controller: verticalScrollController,
                child: SingleChildScrollView(
                  scrollDirection: Axis.horizontal,
                  controller: horizontalScrollController,
                  child: const SizedBox(width: 1000.0, height: 1000.0),
                ),
              ),
            ),
          ),
        );
      }

      await tester.pumpWidget(buildFrame());
      await tester.pumpAndSettle();
      expect(verticalScrollController.offset, 0.0);
      expect(horizontalScrollController.offset, 0.0);
      expect(
        find.byType(RawScrollbar),
        paints
          ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0))
          ..rect(
            rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 360.0),
            color: const Color(0x66BCBCBC),
          ),
      );

      // Move the horizontal scroll view. The vertical scrollbar should not flip.
      horizontalScrollController.jumpTo(10.0);
      expect(verticalScrollController.offset, 0.0);
      expect(horizontalScrollController.offset, 10.0);
      expect(
        find.byType(RawScrollbar),
        paints
          ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0))
          ..rect(
            rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 360.0),
            color: const Color(0x66BCBCBC),
          ),
      );
    },
  );

  testWidgets('notificationPredicate depth test.', (WidgetTester tester) async {
    final scrollController = ScrollController();
    addTearDown(scrollController.dispose);
    final depths = <int>[];
    Widget buildFrame() {
      return Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: const MediaQueryData(),
          child: RawScrollbar(
            notificationPredicate: (ScrollNotification notification) {
              depths.add(notification.depth);
              return notification.depth == 0;
            },
            controller: scrollController,
            thumbVisibility: true,
            child: SingleChildScrollView(
              controller: scrollController,
              child: const SingleChildScrollView(),
            ),
          ),
        ),
      );
    }

    await tester.pumpWidget(buildFrame());
    await tester.pumpAndSettle();

    // `notificationPredicate` should be called twice with different `depth`
    // because there are two scrollable widgets.
    expect(depths.length, 2);
    expect(depths[0], 1);
    expect(depths[1], 0);
  });

  // Regression test for https://github.com/flutter/flutter/issues/92262
  testWidgets('Do not crash when resize from scrollable to non-scrollable.', (
    WidgetTester tester,
  ) async {
    final scrollController = ScrollController();
    addTearDown(scrollController.dispose);
    Widget buildFrame(double height) {
      return Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: const MediaQueryData(),
          child: RawScrollbar(
            controller: scrollController,
            interactive: true,
            thumbVisibility: true,
            child: SingleChildScrollView(
              controller: scrollController,
              child: Container(width: 100.0, height: height, color: const Color(0xFF000000)),
            ),
          ),
        ),
      );
    }

    await tester.pumpWidget(buildFrame(700.0));
    await tester.pumpAndSettle();

    await tester.pumpWidget(buildFrame(600.0));
    await tester.pumpAndSettle();

    // Try to drag the thumb.
    final TestGesture dragScrollbarGesture = await tester.startGesture(const Offset(798.0, 5.0));
    await tester.pumpAndSettle();
    await dragScrollbarGesture.moveBy(const Offset(0.0, 5.0));
    await tester.pumpAndSettle();
  });

  testWidgets(
    'Scrollbar thumb can be dragged when the scrollable widget has a negative minScrollExtent - desktop',
    (WidgetTester tester) async {
      // Regression test for https://github.com/flutter/flutter/issues/95840

      final scrollController = ScrollController();
      addTearDown(scrollController.dispose);
      final uniqueKey = UniqueKey();
      await tester.pumpWidget(
        Directionality(
          textDirection: TextDirection.ltr,
          child: MediaQuery(
            data: const MediaQueryData(),
            child: ScrollConfiguration(
              behavior: const ScrollBehavior().copyWith(scrollbars: false),
              child: PrimaryScrollController(
                controller: scrollController,
                child: RawScrollbar(
                  thumbVisibility: true,
                  controller: scrollController,
                  child: CustomScrollView(
                    primary: true,
                    center: uniqueKey,
                    slivers: <Widget>[
                      SliverToBoxAdapter(child: Container(height: 600.0)),
                      SliverToBoxAdapter(key: uniqueKey, child: Container(height: 600.0)),
                      SliverToBoxAdapter(child: Container(height: 600.0)),
                    ],
                  ),
                ),
              ),
            ),
          ),
        ),
      );
      await tester.pumpAndSettle();
      expect(scrollController.offset, 0.0);
      expect(
        find.byType(RawScrollbar),
        paints
          ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0))
          ..rect(
            rect: const Rect.fromLTRB(794.0, 200.0, 800.0, 400.0),
            color: const Color(0x66BCBCBC),
          ),
      );

      // Drag the thumb up to scroll up.
      const scrollAmount = -10.0;
      final TestGesture dragScrollbarGesture = await tester.startGesture(
        const Offset(797.0, 300.0),
      );
      await tester.pumpAndSettle();
      await dragScrollbarGesture.moveBy(const Offset(0.0, scrollAmount));
      await tester.pumpAndSettle();
      await dragScrollbarGesture.up();
      await tester.pumpAndSettle();

      // The view has scrolled more than it would have by a swipe gesture of the
      // same distance.
      expect(scrollController.offset, lessThan(scrollAmount * 2));
      expect(
        find.byType(RawScrollbar),
        paints
          ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0))
          ..rect(
            rect: const Rect.fromLTRB(794.0, 190.0, 800.0, 390.0),
            color: const Color(0x66BCBCBC),
          ),
      );
    },
    variant: TargetPlatformVariant.desktop(),
  );

  testWidgets(
    'Scrollbar thumb can be dragged when the scrollable widget has a negative minScrollExtent - mobile',
    (WidgetTester tester) async {
      // Regression test for https://github.com/flutter/flutter/issues/95840

      final scrollController = ScrollController();
      addTearDown(scrollController.dispose);
      final uniqueKey = UniqueKey();
      await tester.pumpWidget(
        Directionality(
          textDirection: TextDirection.ltr,
          child: MediaQuery(
            data: const MediaQueryData(),
            child: ScrollConfiguration(
              behavior: const ScrollBehavior().copyWith(scrollbars: false),
              child: PrimaryScrollController(
                controller: scrollController,
                child: RawScrollbar(
                  thumbVisibility: true,
                  controller: scrollController,
                  child: CustomScrollView(
                    center: uniqueKey,
                    slivers: <Widget>[
                      SliverToBoxAdapter(child: Container(height: 600.0)),
                      SliverToBoxAdapter(key: uniqueKey, child: Container(height: 600.0)),
                      SliverToBoxAdapter(child: Container(height: 600.0)),
                    ],
                  ),
                ),
              ),
            ),
          ),
        ),
      );
      await tester.pumpAndSettle();

      // Rectangle for the track of scrollbar.
      // The default thickness of thumb is 6.0, hence topLeft = 800.0 - 6.0 = 794.0
      const trackRect = Rect.fromLTRB(794.0, 0.0, 800.0, 600.0);

      expect(scrollController.offset, 0.0);
      expect(
        find.byType(RawScrollbar),
        paints
          ..rect(rect: trackRect)
          ..rect(
            rect: const Rect.fromLTRB(794.0, 200.0, 800.0, 400.0),
            color: const Color(0x66BCBCBC),
          ),
      );

      // Drag the thumb up to scroll up.
      const scrollAmount = -10.0;
      final TestGesture dragScrollbarGesture = await tester.startGesture(
        const Offset(797.0, 300.0),
      );
      await tester.pumpAndSettle();
      await dragScrollbarGesture.moveBy(const Offset(0.0, scrollAmount));
      await tester.pumpAndSettle();
      await dragScrollbarGesture.up();
      await tester.pumpAndSettle();

      // The view has scrolled more than it would have by a swipe gesture of the
      // same distance.
      expect(scrollController.offset, lessThan(scrollAmount * 2));
      expect(
        find.byType(RawScrollbar),
        paints
          ..rect(rect: trackRect) // Scrollbar track
          ..rect(
            rect: const Rect.fromLTRB(794.0, 190.0, 800.0, 390.0), // Scrollbar thumb
            color: const Color(0x66BCBCBC),
          ),
      );

      // Regression test for issue: https://github.com/flutter/flutter/issues/170246
      // First scroll to the top, then drag the thumb to scroll down.
      final double minScrollExtent = scrollController.position.minScrollExtent; // -600
      scrollController.jumpTo(minScrollExtent);
      await tester.pumpAndSettle();
      expect(scrollController.offset, minScrollExtent);
      const thumbRectBefore = Rect.fromLTRB(794.0, 0.0, 800.0, 200.0); // Scrollbar thumb
      expect(
        find.byType(RawScrollbar),
        paints
          ..rect(rect: trackRect)
          ..rect(rect: thumbRectBefore, color: const Color(0x66BCBCBC)),
      );

      // Drag the thumb to scroll down.
      const scrollDownAmount = 20.0;
      final Offset thumbCenter = thumbRectBefore.center;
      final TestGesture dragGesture = await tester.startGesture(thumbCenter);
      await tester.pumpAndSettle();
      await dragGesture.moveBy(const Offset(0.0, scrollDownAmount));
      await tester.pumpAndSettle();
      await dragGesture.up();
      await tester.pumpAndSettle();

      // The view should have scrolled by the amount dragged.
      expect(scrollController.offset - minScrollExtent, 1800 * scrollDownAmount / 600);
      expect(
        find.byType(RawScrollbar),
        paints
          ..rect(rect: trackRect)
          ..rect(
            rect: thumbRectBefore.shift(const Offset(0.0, scrollDownAmount)),
            color: const Color(0x66BCBCBC),
          ),
      );
    },
    variant: TargetPlatformVariant.mobile(),
  );

  test('ScrollbarPainter.shouldRepaint returns true when any of the properties changes', () {
    ScrollbarPainter createPainter({
      Color color = const Color(0xFF000000),
      Animation<double> fadeoutOpacityAnimation = kAlwaysCompleteAnimation,
      Color trackColor = const Color(0x00000000),
      Color trackBorderColor = const Color(0x00000000),
      TextDirection textDirection = TextDirection.ltr,
      double thickness = _kThickness,
      EdgeInsets padding = EdgeInsets.zero,
      double mainAxisMargin = 0.0,
      double crossAxisMargin = 0.0,
      Radius? radius,
      Radius? trackRadius,
      OutlinedBorder? shape,
      double minLength = _kMinThumbExtent,
      double? minOverscrollLength,
      ScrollbarOrientation scrollbarOrientation = ScrollbarOrientation.top,
    }) {
      return ScrollbarPainter(
        color: color,
        fadeoutOpacityAnimation: fadeoutOpacityAnimation,
        trackColor: trackColor,
        trackBorderColor: trackBorderColor,
        textDirection: textDirection,
        thickness: thickness,
        padding: padding,
        mainAxisMargin: mainAxisMargin,
        crossAxisMargin: crossAxisMargin,
        radius: radius,
        trackRadius: trackRadius,
        shape: shape,
        minLength: minLength,
        minOverscrollLength: minOverscrollLength,
        scrollbarOrientation: scrollbarOrientation,
      );
    }

    final ScrollbarPainter painter = createPainter();
    expect(painter.shouldRepaint(createPainter()), false);
    expect(painter.shouldRepaint(createPainter(color: const Color(0xFFFFFFFF))), true);
    expect(
      painter.shouldRepaint(createPainter(fadeoutOpacityAnimation: kAlwaysDismissedAnimation)),
      true,
    );
    expect(painter.shouldRepaint(createPainter(trackColor: const Color(0xFFFFFFFF))), true);
    expect(painter.shouldRepaint(createPainter(trackBorderColor: const Color(0xFFFFFFFF))), true);
    expect(painter.shouldRepaint(createPainter(textDirection: TextDirection.rtl)), true);
    expect(painter.shouldRepaint(createPainter(thickness: _kThickness + 1.0)), true);
    expect(painter.shouldRepaint(createPainter(padding: const EdgeInsets.all(1.0))), true);
    expect(painter.shouldRepaint(createPainter(mainAxisMargin: 1.0)), true);
    expect(painter.shouldRepaint(createPainter(crossAxisMargin: 1.0)), true);
    expect(painter.shouldRepaint(createPainter(radius: const Radius.circular(1.0))), true);
    expect(painter.shouldRepaint(createPainter(trackRadius: const Radius.circular(1.0))), true);
    expect(
      painter.shouldRepaint(createPainter(shape: const CircleBorder(side: BorderSide(width: 2.0)))),
      true,
    );
    expect(painter.shouldRepaint(createPainter(minLength: _kMinThumbExtent + 1.0)), true);
    expect(painter.shouldRepaint(createPainter(minOverscrollLength: 1.0)), true);
    expect(
      painter.shouldRepaint(createPainter(scrollbarOrientation: ScrollbarOrientation.bottom)),
      true,
    );
  });

  testWidgets('Scrollbar track can be drawn', (WidgetTester tester) async {
    final scrollController = ScrollController();
    addTearDown(scrollController.dispose);
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: const MediaQueryData(),
          child: PrimaryScrollController(
            controller: scrollController,
            child: RawScrollbar(
              thumbVisibility: true,
              trackVisibility: true,
              controller: scrollController,
              child: const SingleChildScrollView(child: SizedBox(width: 4000.0, height: 4000.0)),
            ),
          ),
        ),
      ),
    );
    await tester.pumpAndSettle();
    expect(scrollController.offset, 0.0);
    expect(
      find.byType(RawScrollbar),
      paints
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0), color: const Color(0x08000000))
        ..line(
          p1: const Offset(794.0, 0.0),
          p2: const Offset(794.0, 600.0),
          strokeWidth: 1.0,
          color: const Color(0x1a000000),
        )
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 90.0), color: const Color(0x66BCBCBC)),
    );
  });

  testWidgets('RawScrollbar correctly assigns colors', (WidgetTester tester) async {
    final scrollController = ScrollController();
    addTearDown(scrollController.dispose);
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: const MediaQueryData(),
          child: PrimaryScrollController(
            controller: scrollController,
            child: RawScrollbar(
              thumbVisibility: true,
              thumbColor: const Color(0xFFF44336),
              trackVisibility: true,
              trackColor: const Color(0xFF2196F3),
              trackBorderColor: const Color(0xFFFFEB3B),
              controller: scrollController,
              child: const SingleChildScrollView(child: SizedBox(width: 4000.0, height: 4000.0)),
            ),
          ),
        ),
      ),
    );
    await tester.pumpAndSettle();
    expect(scrollController.offset, 0.0);
    expect(
      find.byType(RawScrollbar),
      paints
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0), color: const Color(0xFF2196F3))
        ..line(
          p1: const Offset(794.0, 0.0),
          p2: const Offset(794.0, 600.0),
          strokeWidth: 1.0,
          color: const Color(0xFFFFEB3B),
        )
        ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 90.0), color: const Color(0xFFF44336)),
    );
  });

  testWidgets('trackRadius and radius properties of RawScrollbar can draw RoundedRectangularRect', (
    WidgetTester tester,
  ) async {
    final scrollController = ScrollController();
    addTearDown(scrollController.dispose);
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: const MediaQueryData(),
          child: PrimaryScrollController(
            controller: scrollController,
            child: RawScrollbar(
              thumbVisibility: true,
              trackVisibility: true,
              trackRadius: const Radius.circular(1.0),
              radius: const Radius.circular(2.0),
              controller: scrollController,
              child: const SingleChildScrollView(child: SizedBox(width: 4000.0, height: 4000.0)),
            ),
          ),
        ),
      ),
    );
    await tester.pumpAndSettle();
    expect(scrollController.offset, 0.0);
    expect(
      find.byType(RawScrollbar),
      paints
        ..rrect(
          rrect: RRect.fromLTRBR(794.0, 0.0, 800.0, 600.0, const Radius.circular(1.0)),
          color: const Color(0x08000000),
        )
        ..rrect(
          rrect: RRect.fromLTRBR(794.0, 0.0, 800.0, 90.0, const Radius.circular(2.0)),
          color: const Color(0x66bcbcbc),
        ),
    );
  });

  testWidgets('Scrollbar asserts that a visible track has a visible thumb', (
    WidgetTester tester,
  ) async {
    final scrollController = ScrollController();
    addTearDown(scrollController.dispose);
    Widget buildApp() {
      return Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: const MediaQueryData(),
          child: PrimaryScrollController(
            controller: scrollController,
            child: RawScrollbar(
              thumbVisibility: false,
              trackVisibility: true,
              controller: scrollController,
              child: const SingleChildScrollView(child: SizedBox(width: 4000.0, height: 4000.0)),
            ),
          ),
        ),
      );
    }

    expect(() => tester.pumpWidget(buildApp()), throwsAssertionError);
  });

  testWidgets('Skip the ScrollPosition check if the bar was unmounted', (
    WidgetTester tester,
  ) async {
    // Regression test for https://github.com/flutter/flutter/issues/103939
    final scrollController = ScrollController();
    addTearDown(scrollController.dispose);
    Widget buildApp(bool buildBar) {
      return Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: MediaQueryData(
            invertColors: buildBar, // Trigger a post frame check before unmount.
          ),
          child: PrimaryScrollController(
            controller: scrollController,
            child: LayoutBuilder(
              builder: (BuildContext context, BoxConstraints constraints) {
                Widget content = const SingleChildScrollView(
                  child: SizedBox(width: 4000.0, height: 4000.0),
                );
                if (buildBar) {
                  content = RawScrollbar(thumbVisibility: true, child: content);
                }
                return content;
              },
            ),
          ),
        ),
      );
    }

    await tester.pumpWidget(buildApp(true));

    await tester.pumpWidget(buildApp(false));

    // Go without throw.
  });

  testWidgets('Track offset respects MediaQuery padding', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/106834
    final scrollController = ScrollController();
    addTearDown(scrollController.dispose);
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: const MediaQueryData(padding: EdgeInsets.all(50.0)),
          child: RawScrollbar(
            controller: scrollController,
            minThumbLength: 21,
            minOverscrollLength: 8,
            thumbVisibility: true,
            child: SingleChildScrollView(
              controller: scrollController,
              child: const SizedBox(width: 1000.0, height: 50000.0),
            ),
          ),
        ),
      ),
    );
    await tester.pumpAndSettle();
    expect(
      find.byType(RawScrollbar),
      paints
        ..rect(rect: const Rect.fromLTRB(744.0, 50.0, 750.0, 550.0)) // track
        ..rect(rect: const Rect.fromLTRB(744.0, 50.0, 750.0, 71.0)), // thumb
    ); // thumb
  });

  testWidgets('RawScrollbar.padding replaces MediaQueryData.padding', (WidgetTester tester) async {
    final scrollController = ScrollController();
    addTearDown(scrollController.dispose);
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: const MediaQueryData(padding: EdgeInsets.all(50.0)),
          child: RawScrollbar(
            controller: scrollController,
            minThumbLength: 21,
            minOverscrollLength: 8,
            thumbVisibility: true,
            padding: const EdgeInsets.all(100),
            child: SingleChildScrollView(
              controller: scrollController,
              child: const SizedBox(width: 1000.0, height: 50000.0),
            ),
          ),
        ),
      ),
    );
    await tester.pumpAndSettle();
    expect(
      find.byType(RawScrollbar),
      paints
        ..rect(rect: const Rect.fromLTRB(694.0, 100.0, 700.0, 500.0)) // track
        ..rect(rect: const Rect.fromLTRB(694.0, 100.0, 700.0, 121.0)), // thumb
    ); // thumb
  });

  testWidgets('Scrollbar respect the NeverScrollableScrollPhysics physics', (
    WidgetTester tester,
  ) async {
    final scrollController = ScrollController();
    addTearDown(scrollController.dispose);
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: const MediaQueryData(),
          child: PrimaryScrollController(
            controller: scrollController,
            child: RawScrollbar(
              thumbVisibility: true,
              controller: scrollController,
              child: const SingleChildScrollView(
                physics: NeverScrollableScrollPhysics(),
                child: SizedBox(width: 4000.0, height: 4000.0),
              ),
            ),
          ),
        ),
      ),
    );
    await tester.pumpAndSettle();
    expect(scrollController.offset, 0.0);

    // Drag the thumb down to scroll down.
    const scrollAmount = 10.0;
    final TestGesture dragScrollbarGesture = await tester.startGesture(const Offset(797.0, 45.0));
    await tester.pumpAndSettle();
    await dragScrollbarGesture.moveBy(const Offset(0.0, scrollAmount));
    await tester.pumpAndSettle();
    await dragScrollbarGesture.up();
    await tester.pumpAndSettle();

    expect(scrollController.offset, 0.0);

    // Tap on the track area below the thumb.
    await tester.tapAt(const Offset(797.0, 550.0));
    await tester.pumpAndSettle();

    expect(scrollController.offset, 0.0);
  });

  testWidgets(
    'The thumb should follow the pointer when the scroll metrics changed during dragging',
    (WidgetTester tester) async {
      // Regression test for https://github.com/flutter/flutter/issues/112072
      final scrollController = ScrollController();
      addTearDown(scrollController.dispose);
      await tester.pumpWidget(
        Directionality(
          textDirection: TextDirection.ltr,
          child: MediaQuery(
            data: const MediaQueryData(),
            child: PrimaryScrollController(
              controller: scrollController,
              child: RawScrollbar(
                thumbVisibility: true,
                controller: scrollController,
                child: CustomScrollView(
                  controller: scrollController,
                  slivers: <Widget>[
                    SliverList.builder(
                      itemCount: 100,
                      itemBuilder: (BuildContext context, int index) {
                        final double height;
                        if (index < 10) {
                          height = 100;
                        } else {
                          height = 500;
                        }
                        return SizedBox(height: height, child: Text('$index'));
                      },
                    ),
                  ],
                ),
              ),
            ),
          ),
        ),
      );
      await tester.pumpAndSettle();
      expect(scrollController.offset, 0.0);

      // Drag the thumb down to scroll down.
      const double scrollAmount = 100;
      final TestGesture dragScrollbarGesture = await tester.startGesture(const Offset(797.0, 5.0));
      await tester.pumpAndSettle();
      await dragScrollbarGesture.moveBy(const Offset(0.0, scrollAmount));
      await tester.pumpAndSettle();

      await dragScrollbarGesture.moveBy(const Offset(0.0, scrollAmount));
      await tester.pumpAndSettle();

      await dragScrollbarGesture.up();
      await tester.pumpAndSettle();

      // The view has scrolled more than it would have by a swipe gesture of the
      // same distance.
      expect(scrollController.offset, greaterThan((100.0 * 10 + 500.0 * 90) / 3));
      expect(
        find.byType(RawScrollbar),
        paints
          ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0))
          ..rect(
            rect: const Rect.fromLTRB(794.0, 200.0, 800.0, 218.0),
            color: const Color(0x66BCBCBC),
          ),
      );
    },
  );

  testWidgets('The scrollable should not stutter when the scroll metrics shrink during dragging', (
    WidgetTester tester,
  ) async {
    // Regression test for https://github.com/flutter/flutter/issues/121574
    final scrollController = ScrollController();
    addTearDown(scrollController.dispose);
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: const MediaQueryData(),
          child: PrimaryScrollController(
            controller: scrollController,
            child: RawScrollbar(
              thumbVisibility: true,
              controller: scrollController,
              child: CustomScrollView(
                controller: scrollController,
                slivers: <Widget>[
                  SliverList.builder(
                    itemCount: 100,
                    itemBuilder: (BuildContext context, int index) {
                      final double height;
                      if (index < 10) {
                        height = 500;
                      } else {
                        height = 100;
                      }
                      return SizedBox(height: height, child: Text('$index'));
                    },
                  ),
                ],
              ),
            ),
          ),
        ),
      ),
    );
    await tester.pumpAndSettle();
    expect(scrollController.offset, 0.0);

    // Drag the thumb down to scroll down.
    const double scrollAmount = 100;
    final TestGesture dragScrollbarGesture = await tester.startGesture(const Offset(797.0, 5.0));
    await tester.pumpAndSettle();
    await dragScrollbarGesture.moveBy(const Offset(0.0, scrollAmount));
    await tester.pumpAndSettle();

    final double lastPosition = scrollController.offset;
    // The view has scrolled more than it would have by a swipe gesture of the
    // same distance.
    expect(lastPosition, greaterThan((100.0 * 10 + 500.0 * 90) / 6));

    await dragScrollbarGesture.moveBy(const Offset(0.0, scrollAmount));
    await tester.pumpAndSettle();

    await dragScrollbarGesture.up();
    await tester.pumpAndSettle();

    expect(scrollController.offset, greaterThan(lastPosition));
  });

  testWidgets('The bar supports mouse wheel event', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/pull/109659
    final scrollController = ScrollController();
    addTearDown(scrollController.dispose);
    Widget buildFrame() {
      return Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: const MediaQueryData(),
          child: PrimaryScrollController(
            controller: scrollController,
            child: RawScrollbar(
              thumbVisibility: true,
              controller: scrollController,
              child: const SingleChildScrollView(
                primary: true,
                child: SizedBox(width: double.infinity, height: 1200.0),
              ),
            ),
          ),
        ),
      );
    }

    await tester.pumpWidget(buildFrame());
    await tester.pumpAndSettle();
    expect(scrollController.offset, 0.0);

    // Execute a pointer scroll hover on the scroll bar
    final pointer = TestPointer(1, ui.PointerDeviceKind.mouse);
    pointer.hover(const Offset(798.0, 15.0));
    await tester.sendEventToBinding(pointer.scroll(const Offset(0.0, 30.0)));
    await tester.pumpAndSettle();

    expect(scrollController.offset, 30.0);

    // Execute a pointer scroll outside the scroll bar
    pointer.hover(const Offset(198.0, 15.0));
    await tester.sendEventToBinding(pointer.scroll(const Offset(0.0, 70.0)));
    await tester.pumpAndSettle();

    expect(scrollController.offset, 100.0);
  }, variant: TargetPlatformVariant.all());

  testWidgets(
    'Flinging a vertical scrollbar thumb does not cause a ballistic scroll - non-mobile platforms',
    (WidgetTester tester) async {
      final scrollController = ScrollController();
      addTearDown(scrollController.dispose);

      bool isMobilePlatform() {
        return const <TargetPlatform>{
          TargetPlatform.iOS,
          TargetPlatform.android,
        }.contains(debugDefaultTargetPlatformOverride);
      }

      Widget buildFrame({required bool reverse}) {
        return Directionality(
          textDirection: TextDirection.ltr,
          child: MediaQuery(
            data: const MediaQueryData(),
            child: PrimaryScrollController(
              controller: scrollController,
              child: RawScrollbar(
                thumbVisibility: true,
                controller: scrollController,
                child: CustomScrollView(
                  controller: scrollController,
                  reverse: reverse,
                  slivers: <Widget>[
                    SliverList.builder(
                      itemCount: 10,
                      itemBuilder: (BuildContext context, int index) {
                        return Container(
                          height: 100,
                          alignment: Alignment.center,
                          child: Text('$index'),
                        );
                      },
                    ),
                  ],
                ),
              ),
            ),
          ),
        );
      }

      await tester.pumpWidget(buildFrame(reverse: false));
      await tester.pumpAndSettle();
      expect(scrollController.offset, 0.0);

      // Try flinging downward. The flingFrom() method generates 50 moves of about 2
      // pixels and then a fling with the indicated velocity.
      await tester.flingFrom(const Offset(797.0, 45.0), const Offset(0, 60.0), 500.0);
      await tester.pumpAndSettle();

      if (isMobilePlatform()) {
        expect(
          scrollController.offset,
          greaterThan(100.0),
          reason: 'Ballistic scroll expected on $debugDefaultTargetPlatformOverride',
        );
      } else {
        expect(
          scrollController.offset,
          100.0,
          reason: 'Ballistic scroll not expected on $debugDefaultTargetPlatformOverride',
        );
      }

      // Tap at the top of the track to scroll back to the origin.
      await tester.tapAt(const Offset(797.0, 5.0));
      await tester.pumpAndSettle();
      expect(scrollController.offset, 0.0);

      // Drag the thumb to the bottom.
      await tester.dragFrom(const Offset(797.0, 45.0), const Offset(0, 1000.0));
      await tester.pumpAndSettle();
      expect(scrollController.offset, 400.0);

      // Try flinging upward.
      await tester.flingFrom(const Offset(797.0, 545.0), const Offset(0, -60), 500.0);
      await tester.pumpAndSettle();
      if (isMobilePlatform()) {
        expect(
          scrollController.offset,
          lessThan(300.0),
          reason: 'Ballistic scroll expected on $debugDefaultTargetPlatformOverride',
        );
      } else {
        expect(
          scrollController.offset,
          300.0,
          reason: 'Ballistic scroll not expected on $debugDefaultTargetPlatformOverride',
        );
      }

      // Tap at the top of the track to scroll back to the origin.
      await tester.tapAt(const Offset(797.0, 5.0));
      await tester.pumpAndSettle();
      expect(scrollController.offset, 0.0);

      // Same tests with reverse: true

      await tester.pumpWidget(buildFrame(reverse: true));
      await tester.pumpAndSettle();
      expect(scrollController.offset, 0.0);

      // Try flinging upward.
      await tester.flingFrom(const Offset(797.0, 545.0), const Offset(0, -60), 500.0);
      await tester.pumpAndSettle();
      if (isMobilePlatform()) {
        expect(
          scrollController.offset,
          greaterThan(100.0),
          reason: 'Ballistic scroll expected on $debugDefaultTargetPlatformOverride',
        );
      } else {
        expect(
          scrollController.offset,
          100.0,
          reason: 'Ballistic scroll not expected on $debugDefaultTargetPlatformOverride',
        );
      }

      // Tap at the top of the track to scroll to the limit
      await tester.tapAt(const Offset(797.0, 5.0));
      await tester.pumpAndSettle();
      expect(scrollController.offset, 400.0);

      // Try flinging downward.
      await tester.flingFrom(const Offset(797.0, 45.0), const Offset(0, 60.0), 500.0);
      await tester.pumpAndSettle();
      if (isMobilePlatform()) {
        expect(
          scrollController.offset,
          lessThan(300.0),
          reason: 'Ballistic scroll expected on $debugDefaultTargetPlatformOverride',
        );
      } else {
        expect(
          scrollController.offset,
          300.0,
          reason: 'Ballistic scroll not expected on $debugDefaultTargetPlatformOverride',
        );
      }
    },
    variant: TargetPlatformVariant.all(),
  );

  testWidgets(
    'Flinging a horizontal scrollbar thumb does not cause a ballistic scroll - non-mobile platforms',
    (WidgetTester tester) async {
      final scrollController = ScrollController();
      addTearDown(scrollController.dispose);

      bool isMobilePlatform() {
        return const <TargetPlatform>{
          TargetPlatform.iOS,
          TargetPlatform.android,
        }.contains(debugDefaultTargetPlatformOverride);
      }

      Widget buildFrame({required bool reverse}) {
        return Directionality(
          textDirection: TextDirection.ltr,
          child: MediaQuery(
            data: const MediaQueryData(),
            child: PrimaryScrollController(
              controller: scrollController,
              child: RawScrollbar(
                thumbVisibility: true,
                controller: scrollController,
                child: CustomScrollView(
                  controller: scrollController,
                  reverse: reverse,
                  scrollDirection: Axis.horizontal,
                  slivers: <Widget>[
                    SliverList.builder(
                      itemCount: 10,
                      itemBuilder: (BuildContext context, int index) {
                        return Container(
                          width: 100,
                          alignment: Alignment.center,
                          child: Text('$index'),
                        );
                      },
                    ),
                  ],
                ),
              ),
            ),
          ),
        );
      }

      await tester.pumpWidget(buildFrame(reverse: false));
      await tester.pumpAndSettle();
      expect(scrollController.offset, 0.0);

      // Try flinging to the right.
      await tester.flingFrom(const Offset(45.0, 597.0), const Offset(80, 0.0), 500.0);
      await tester.pumpAndSettle();
      if (isMobilePlatform()) {
        expect(
          scrollController.offset,
          greaterThan(100.0),
          reason: 'Ballistic scroll expected on $debugDefaultTargetPlatformOverride',
        );
      } else {
        expect(
          scrollController.offset,
          100.0,
          reason: 'Ballistic scroll not expected on $debugDefaultTargetPlatformOverride',
        );
      }

      // Tap at the end of the track to scroll to the limit.
      await tester.tapAt(const Offset(794.0, 597.0));
      await tester.pumpAndSettle();
      expect(scrollController.offset, 200.0);

      // Try flinging to the left.
      await tester.flingFrom(const Offset(794.0, 597.0), const Offset(-80, 0), 500.0);
      await tester.pumpAndSettle();
      if (isMobilePlatform()) {
        expect(
          scrollController.offset,
          lessThan(100.0),
          reason: 'Ballistic scroll expected on $debugDefaultTargetPlatformOverride',
        );
      } else {
        expect(
          scrollController.offset,
          100.0,
          reason: 'Ballistic scroll not expected on $debugDefaultTargetPlatformOverride',
        );
      }

      // Tap at the beginning of the track to scroll back to the origin.
      await tester.tapAt(const Offset(6.0, 597.0));
      await tester.pumpAndSettle();
      expect(scrollController.offset, 0.0);

      // Same tests with reverse: true

      await tester.pumpWidget(buildFrame(reverse: true));
      await tester.pumpAndSettle();
      expect(scrollController.offset, 0.0);

      // Try flinging to the left.
      await tester.flingFrom(const Offset(794.0, 597.0), const Offset(-80, 0), 500.0);
      await tester.pumpAndSettle();
      if (isMobilePlatform()) {
        expect(
          scrollController.offset,
          greaterThan(100.0),
          reason: 'Ballistic scroll expected on $debugDefaultTargetPlatformOverride',
        );
      } else {
        expect(
          scrollController.offset,
          100.0,
          reason: 'Ballistic scroll not expected on $debugDefaultTargetPlatformOverride',
        );
      }

      // Tap at the beginning of the track to scroll to the limit.
      await tester.tapAt(const Offset(6.0, 597.0));
      await tester.pumpAndSettle();
      expect(scrollController.offset, 200.0);

      // Try flinging to the right.
      await tester.flingFrom(const Offset(6.0, 597.0), const Offset(80, 0), 500.0);
      await tester.pumpAndSettle();

      if (isMobilePlatform()) {
        expect(
          scrollController.offset,
          lessThan(100.0),
          reason: 'Ballistic scroll expected on $debugDefaultTargetPlatformOverride',
        );
      } else {
        expect(
          scrollController.offset,
          100.0,
          reason: 'Ballistic scroll not expected on $debugDefaultTargetPlatformOverride',
        );
      }
    },
    variant: TargetPlatformVariant.all(),
  );

  testWidgets('Safe to drag trackpad when maxScrollExtent is 0 (scrollbar is not painted)', (
    WidgetTester tester,
  ) async {
    // Regression test for https://github.com/flutter/flutter/issues/149803
    final scrollController = ScrollController();
    addTearDown(scrollController.dispose);

    Widget buildFrame(double sizedBoxHeight) {
      return Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: const MediaQueryData(),
          child: RawScrollbar(
            controller: scrollController,
            child: SingleChildScrollView(
              controller: scrollController,
              child: SizedBox(width: 100.0, height: sizedBoxHeight),
            ),
          ),
        ),
      );
    }

    await tester.pumpWidget(buildFrame(100)); // Test viewport has height=600
    await tester.pumpAndSettle();
    expect(scrollController.offset, 0.0);
    expect(scrollController.position.maxScrollExtent, 0.0);

    await tester.trackpadFling(find.byType(SingleChildScrollView), const Offset(0, -100), 500);
    await tester.pumpAndSettle();
    expect(scrollController.offset, 0.0);

    await tester.trackpadFling(find.byType(SingleChildScrollView), const Offset(0, 100), 500);
    await tester.pumpAndSettle();
    expect(scrollController.offset, 0.0);

    await tester.pumpWidget(buildFrame(700));
    await tester.pumpAndSettle();
    expect(scrollController.offset, 0.0);
    expect(scrollController.position.maxScrollExtent, 100.0);

    await tester.trackpadFling(find.byType(SingleChildScrollView), const Offset(0, -100), 500);
    await tester.pumpAndSettle();
    expect(scrollController.offset, 100.0);

    await tester.trackpadFling(find.byType(SingleChildScrollView), const Offset(0, 100), 500);
    await tester.pumpAndSettle();
    expect(scrollController.offset, 0.0);
  });

  testWidgets(
    'Desktop trackpad drag direction: -X,-Y produces positive scroll offset changes',
    (WidgetTester tester) async {
      // Regression test for https://github.com/flutter/flutter/issues/149999.
      // This test doesn't strictly test the scrollbar: trackpad flings
      // that begin in the center of the scrollable are handled by the
      // scrollable, not the scrollbar. However: the scrollbar widget does
      // contain the scrollable and this test verifies that it doesn't
      // inadvertently handle thumb down/start/update/end gestures due
      // to trackpad pan/zoom events. Those callbacks are prevented by
      // the overrides of isPointerPanZoomAllowed in the scrollbar
      // gesture recognizers.

      final scrollController = ScrollController();
      addTearDown(scrollController.dispose);

      Widget buildFrame(Axis scrollDirection) {
        return Directionality(
          textDirection: TextDirection.ltr,
          child: MediaQuery(
            data: const MediaQueryData(),
            child: RawScrollbar(
              controller: scrollController,
              child: SingleChildScrollView(
                scrollDirection: scrollDirection,
                controller: scrollController,
                child: const SizedBox(width: 1600, height: 1200),
              ),
            ),
          ),
        );
      }

      // Vertical scrolling: -Y trackpad motion produces positive scroll offset change

      await tester.pumpWidget(buildFrame(Axis.vertical));
      expect(scrollController.offset, 0);
      expect(scrollController.position.maxScrollExtent, 600);

      await tester.trackpadFling(find.byType(SingleChildScrollView), const Offset(0, -600), 500);
      await tester.pumpAndSettle();
      expect(scrollController.offset, 600);

      await tester.trackpadFling(find.byType(SingleChildScrollView), const Offset(0, 600), 500);
      await tester.pumpAndSettle();
      expect(scrollController.offset, 0);

      // Overscroll is OK for (vertical) trackpad gestures.

      await tester.trackpadFling(find.byType(SingleChildScrollView), const Offset(0, -100), 500);
      await tester.pumpAndSettle();
      expect(scrollController.offset, greaterThan(100));
      scrollController.jumpTo(600);

      await tester.trackpadFling(find.byType(SingleChildScrollView), const Offset(0, 100), 500);
      await tester.pumpAndSettle();
      expect(scrollController.offset, lessThan(500));
      scrollController.jumpTo(0);

      // Horizontal scrolling: -X trackpad motion produces positive scroll offset change

      await tester.pumpWidget(buildFrame(Axis.horizontal));
      expect(scrollController.offset, 0);
      expect(scrollController.position.maxScrollExtent, 800);

      await tester.trackpadFling(find.byType(SingleChildScrollView), const Offset(-800, 0), 500);
      await tester.pumpAndSettle();
      expect(scrollController.offset, 800);

      await tester.trackpadFling(find.byType(SingleChildScrollView), const Offset(800, 0), 500);
      await tester.pumpAndSettle();
      expect(scrollController.offset, 0);

      // Overscroll is OK for (horizontal) trackpad gestures.

      await tester.trackpadFling(find.byType(SingleChildScrollView), const Offset(-100, 0), 500);
      await tester.pumpAndSettle();
      expect(scrollController.offset, greaterThan(100));
      scrollController.jumpTo(800);

      await tester.trackpadFling(find.byType(SingleChildScrollView), const Offset(100, 0), 500);
      await tester.pumpAndSettle();
      expect(scrollController.offset, lessThan(700));
      scrollController.jumpTo(0);
    },
    variant: const TargetPlatformVariant(<TargetPlatform>{
      TargetPlatform.macOS,
      TargetPlatform.linux,
      TargetPlatform.windows,
      TargetPlatform.fuchsia,
    }),
  );

  testWidgets(
    'Desktop trackpad, nested ListViews, no explicit scrollbars, horizontal drag succeeds',
    (WidgetTester tester) async {
      // Regression test for https://github.com/flutter/flutter/issues/150236.
      // This test is similar to "Desktop trackpad drag direction: -X,-Y...".
      // It's really only verifying that trackpad gestures are being handled
      // by the scrollable, not the scrollbar.

      final Key outerListViewKey = UniqueKey();
      final scrollControllerY = ScrollController();
      final scrollControllerX = ScrollController();
      addTearDown(scrollControllerY.dispose);
      addTearDown(scrollControllerX.dispose);

      await tester.pumpWidget(
        Directionality(
          textDirection: TextDirection.ltr,
          child: MediaQuery(
            data: const MediaQueryData(),
            child: ListView(
              key: outerListViewKey,
              controller: scrollControllerY,
              children: <Widget>[
                const SizedBox(width: 200, height: 200),
                SizedBox(
                  height: 200,
                  child: ListView(
                    // vertically centered within the 600 high viewport
                    scrollDirection: Axis.horizontal,
                    controller: scrollControllerX,
                    children: List<Widget>.generate(5, (int index) {
                      return SizedBox(width: 200, child: Center(child: Text('item $index')));
                    }),
                  ),
                ),
                const SizedBox(width: 200, height: 200),
                const SizedBox(width: 200, height: 200),
                const SizedBox(width: 200, height: 200),
              ],
            ),
          ),
        ),
      );

      Finder outerListView() => find.byKey(outerListViewKey);

      // 800x600 viewport content is 1000x1000
      expect(tester.getSize(outerListView()), const Size(800, 600));
      expect(scrollControllerY.offset, 0);
      expect(scrollControllerY.position.maxScrollExtent, 400);
      expect(scrollControllerX.offset, 0);
      expect(scrollControllerX.position.maxScrollExtent, 200);

      // Vertical scrolling: -Y trackpad motion produces positive scroll offset change
      await tester.trackpadFling(outerListView(), const Offset(0, -600), 500);
      await tester.pumpAndSettle();
      expect(scrollControllerY.offset, 400);
      await tester.trackpadFling(outerListView(), const Offset(0, 600), 500);
      await tester.pumpAndSettle();
      expect(scrollControllerY.offset, 0);

      // Horizontal scrolling: -X trackpad motion produces positive scroll offset change
      await tester.trackpadFling(outerListView(), const Offset(-800, 0), 500);
      await tester.pumpAndSettle();
      expect(scrollControllerX.offset, 200);
      await tester.trackpadFling(outerListView(), const Offset(800, 0), 500);
      await tester.pumpAndSettle();
      expect(scrollControllerX.offset, 0);
    },
    variant: const TargetPlatformVariant(<TargetPlatform>{
      TargetPlatform.macOS,
      TargetPlatform.linux,
      TargetPlatform.windows,
      TargetPlatform.fuchsia,
    }),
  );

  testWidgets(
    'Desktop trackpad, nested ListViews, no explicit scrollbars, horizontal drag succeeds',
    (WidgetTester tester) async {
      // Regression test for https://github.com/flutter/flutter/issues/150342

      final scrollController = ScrollController();
      addTearDown(scrollController.dispose);

      late Size childSize;
      late StateSetter rebuildScrollViewChild;

      Widget buildFrame(Axis scrollDirection) {
        return Directionality(
          textDirection: TextDirection.ltr,
          child: MediaQuery(
            data: const MediaQueryData(),
            child: RawScrollbar(
              controller: scrollController,
              child: SingleChildScrollView(
                controller: scrollController,
                scrollDirection: scrollDirection,
                child: StatefulBuilder(
                  builder: (BuildContext context, StateSetter setState) {
                    rebuildScrollViewChild = setState;
                    return SizedBox(width: childSize.width, height: childSize.height);
                  },
                ),
              ),
            ),
          ),
        );
      }

      RawGestureDetector getScrollbarGestureDetector() {
        return tester.widget<RawGestureDetector>(
          find
              .descendant(of: find.byType(RawScrollbar), matching: find.byType(RawGestureDetector))
              .first,
        );
      }

      // Vertical scrollDirection

      childSize = const Size(800, 600);
      await tester.pumpWidget(buildFrame(Axis.vertical));
      // Scrolling isn't possible, so there are no scrollbar gesture recognizers.
      expect(getScrollbarGestureDetector().gestures.length, 0);

      rebuildScrollViewChild(() {
        childSize = const Size(800, 800);
      });
      await tester.pumpAndSettle();
      // Scrolling is now possible, so there are scrollbar (thumb and track) gesture recognizers.
      expect(getScrollbarGestureDetector().gestures.length, greaterThan(1));

      // Horizontal scrollDirection

      childSize = const Size(800, 600);
      await tester.pumpWidget(buildFrame(Axis.horizontal));
      await tester.pumpAndSettle();
      // Scrolling isn't possible, so there are no scrollbar gesture recognizers.
      expect(getScrollbarGestureDetector().gestures.length, 0);

      rebuildScrollViewChild(() {
        childSize = const Size(1000, 600);
      });
      await tester.pumpAndSettle();
      // Scrolling is now possible, so there are scrollbar (thumb and track) gesture recognizers.
      expect(getScrollbarGestureDetector().gestures.length, greaterThan(1));
    },
  );

  testWidgets('Scrollbar gestures disabled when maxScrollExtent == minScrollExtent', (
    WidgetTester tester,
  ) async {
    // Test for the condition: maxScrollExtent > minScrollExtent
    // When maxScrollExtent == minScrollExtent, gestures should be disabled.
    final scrollController = ScrollController();
    addTearDown(scrollController.dispose);

    RawGestureDetector getScrollbarGestureDetector() {
      return tester.widget<RawGestureDetector>(
        find
            .descendant(of: find.byType(RawScrollbar), matching: find.byType(RawGestureDetector))
            .first,
      );
    }

    // Content that fits exactly (maxScrollExtent == minScrollExtent == 0.0)
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: const MediaQueryData(),
          child: RawScrollbar(
            interactive: true,
            controller: scrollController,
            child: SingleChildScrollView(
              controller: scrollController,
              child: const SizedBox(height: 600.0, width: 800.0),
            ),
          ),
        ),
      ),
    );
    await tester.pumpAndSettle();

    // When maxScrollExtent == minScrollExtent, gestures should be disabled.
    expect(getScrollbarGestureDetector().gestures.length, 0);
  });

  testWidgets('Scrollbar gestures enabled when maxScrollExtent > minScrollExtent by any amount', (
    WidgetTester tester,
  ) async {
    final scrollController = ScrollController();
    addTearDown(scrollController.dispose);

    RawGestureDetector getScrollbarGestureDetector() {
      return tester.widget<RawGestureDetector>(
        find
            .descendant(of: find.byType(RawScrollbar), matching: find.byType(RawGestureDetector))
            .first,
      );
    }

    // Use CustomScrollView with center to create negative minScrollExtent.
    final uniqueKey = UniqueKey();
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: const MediaQueryData(),
          child: ScrollConfiguration(
            behavior: const ScrollBehavior().copyWith(scrollbars: false),
            child: PrimaryScrollController(
              controller: scrollController,
              child: RawScrollbar(
                interactive: true,
                controller: scrollController,
                child: CustomScrollView(
                  center: uniqueKey,
                  slivers: <Widget>[
                    SliverToBoxAdapter(child: Container(height: 300.0)),
                    SliverToBoxAdapter(key: uniqueKey, child: Container(height: 300.0)),
                    SliverToBoxAdapter(child: Container(height: 300.0)),
                  ],
                ),
              ),
            ),
          ),
        ),
      ),
    );
    await tester.pumpAndSettle();

    expect(scrollController.position.minScrollExtent, lessThan(0.0));
    expect(
      scrollController.position.maxScrollExtent,
      greaterThan(scrollController.position.minScrollExtent),
    );

    expect(scrollController.position.maxScrollExtent, lessThanOrEqualTo(0.0));

    expect(getScrollbarGestureDetector().gestures.length, greaterThan(0));
  });

  testWidgets('Drag horizontal and vertical scrollbars', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/87697
    final verticalScrollController = ScrollController();
    addTearDown(verticalScrollController.dispose);
    final horizontalScrollController = ScrollController();
    addTearDown(horizontalScrollController.dispose);

    final GlobalKey key1 = GlobalKey();
    Widget buildFrame() {
      return Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: const MediaQueryData(),
          child: RawScrollbar(
            thumbVisibility: true,
            controller: verticalScrollController,
            child: RawScrollbar(
              thumbVisibility: true,
              controller: horizontalScrollController,
              key: key1,
              notificationPredicate: (ScrollNotification notification) => notification.depth == 1,
              child: SingleChildScrollView(
                controller: verticalScrollController,
                child: SingleChildScrollView(
                  scrollDirection: Axis.horizontal,
                  controller: horizontalScrollController,
                  child: const SizedBox(width: 1000.0, height: 1000.0),
                ),
              ),
            ),
          ),
        ),
      );
    }

    await tester.pumpWidget(buildFrame());
    await tester.pumpAndSettle();

    expect(verticalScrollController.offset, 0.0);
    expect(horizontalScrollController.offset, 0.0);

    const scrollAmount = 10.0;

    final TestGesture verticalScrollbarGesture = await tester.startGesture(
      const Offset(797.0, 45.0),
    );
    await tester.pumpAndSettle();
    await verticalScrollbarGesture.moveBy(const Offset(0.0, scrollAmount));
    await tester.pumpAndSettle();
    await verticalScrollbarGesture.up();
    await tester.pumpAndSettle();

    final TestGesture horizontalScrollbarGesture = await tester.startGesture(
      const Offset(45.0, 597.0),
    );
    await tester.pumpAndSettle();
    await horizontalScrollbarGesture.moveBy(const Offset(scrollAmount, 0.0));
    await tester.pumpAndSettle();
    await horizontalScrollbarGesture.up();
    await tester.pumpAndSettle();

    expect(verticalScrollController.offset, greaterThan(0.0));
    expect(horizontalScrollController.offset, greaterThan(0.0));
  });

  // Regression test for https://github.com/flutter/flutter/issues/141348.
  testWidgets(
    'Scrollbar should not shown due to precision error on desktop',
    (WidgetTester tester) async {
      Widget buildFrame(Size size) {
        tester.view.physicalSize = size;
        tester.view.devicePixelRatio = 1.0;
        addTearDown(tester.view.reset);
        return MaterialApp(
          home: Scaffold(
            body: Center(
              child: DatePickerDialog(
                initialDate: DateTime(2020, DateTime.may), // Month with six rows.
                firstDate: DateTime(2010),
                lastDate: DateTime(2030),
              ),
            ),
          ),
        );
      }

      const screenSizePortrait = Size(400, 600);
      await tester.pumpWidget(buildFrame(screenSizePortrait));
      await tester.pumpAndSettle();

      // Scrollbar is not shown.
      expect(find.byType(Scrollbar), findsOneWidget);
      expect(find.byType(Scrollbar), isNot(paints..rect()));

      // Scroll on the Scrollbar.
      final pointer = TestPointer(1, ui.PointerDeviceKind.mouse);
      pointer.hover(tester.getCenter(find.byType(Scrollbar)));
      await tester.sendEventToBinding(pointer.scroll(const Offset(0.0, 10.0)));
      await tester.pumpAndSettle();

      // Scrollbar is still not shown.
      expect(find.byType(Scrollbar), findsOneWidget);
      expect(find.byType(Scrollbar), isNot(paints..rect()));
    },
    variant: TargetPlatformVariant.desktop(),
  );

  test('with EdgeInsetsDirectional', () {
    const size = Size(60, 80);
    final ScrollMetrics metrics = defaultMetrics.copyWith(
      minScrollExtent: -100,
      maxScrollExtent: 240,
      axisDirection: AxisDirection.down,
    );

    final ScrollbarPainter ltrPainter = _buildPainter(
      padding: const EdgeInsetsDirectional.fromSTEB(1, 2, 3, 4),
      scrollMetrics: metrics,
    );

    ltrPainter.update(
      metrics.copyWith(viewportDimension: size.height, pixels: double.negativeInfinity),
      AxisDirection.down,
    );

    // Top overscroll.
    ltrPainter.paint(testCanvas, size);
    final Rect ltrRect0 = captureRect();
    expect(ltrRect0.top, 2);
    expect(size.width - ltrRect0.right, 3);

    // Bottom overscroll.
    ltrPainter.update(
      metrics.copyWith(viewportDimension: size.height, pixels: double.infinity),
      AxisDirection.down,
    );

    ltrPainter.paint(testCanvas, size);
    final Rect ltrRect1 = captureRect();
    expect(size.height - ltrRect1.bottom, 4);
    expect(size.width - ltrRect1.right, 3);

    final ScrollbarPainter rtlPainter = _buildPainter(
      padding: const EdgeInsetsDirectional.fromSTEB(1, 2, 3, 4),
      scrollMetrics: metrics,
      textDirection: TextDirection.rtl,
    );

    rtlPainter.update(
      metrics.copyWith(viewportDimension: size.height, pixels: double.negativeInfinity),
      AxisDirection.down,
    );

    // Top overscroll.
    rtlPainter.paint(testCanvas, size);
    final Rect rtlRect0 = captureRect();
    expect(rtlRect0.top, 2);
    expect(rtlRect0.left, 3);

    // Bottom overscroll.
    rtlPainter.update(
      metrics.copyWith(viewportDimension: size.height, pixels: double.infinity),
      AxisDirection.down,
    );

    rtlPainter.paint(testCanvas, size);
    final Rect rtlRect1 = captureRect();
    expect(size.height - rtlRect1.bottom, 4);
    expect(rtlRect1.left, 3);
  });

  testWidgets(
    'RawScrollbar does not assert when dynamically assigning controller with thumbVisibility true',
    (WidgetTester tester) async {
      // This test reproduces the issue from https://github.com/flutter/flutter/issues/172614
      // where dynamically assigning a controller and setting thumbVisibility to true
      // in the same frame caused an assertion failure.

      final scrollController = ScrollController();
      addTearDown(scrollController.dispose);

      var useController = false;
      var thumbVisible = false;
      var interactive = false;

      await tester.pumpWidget(
        StatefulBuilder(
          builder: (BuildContext context, StateSetter setState) {
            return Directionality(
              textDirection: TextDirection.ltr,
              child: MediaQuery(
                data: const MediaQueryData(),
                child: Column(
                  children: <Widget>[
                    ElevatedButton(
                      onPressed: () {
                        setState(() {
                          // This reproduces the exact scenario from the linked issue:
                          // Initially the controller is null, thumbVisibility is false, and interactive is false.
                          // Then, in the next frame, the controller is non-null, thumbVisibility is true, and interactive is true.
                          useController = true;
                          thumbVisible = true;
                          interactive = true;
                        });
                      },
                      child: const Text('Enable Scrollbar'),
                    ),
                    Expanded(
                      child: RawScrollbar(
                        controller: useController ? scrollController : null,
                        thumbVisibility: thumbVisible,
                        interactive: interactive,
                        child: SingleChildScrollView(
                          controller: useController ? scrollController : null,
                          child: const SizedBox(height: 2000.0, width: 100.0),
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            );
          },
        ),
      );

      await tester.pumpAndSettle();
      expect(find.byType(RawScrollbar), findsOneWidget);

      await tester.tap(find.text('Enable Scrollbar'));
      await tester.pumpAndSettle();

      // Verify scrollbar is now working properly and doesn't throw an assertion.
      final Finder scrollbarFinder = find.byType(RawScrollbar);
      expect(scrollbarFinder, findsOneWidget);
      expect(scrollController.offset, 0.0);

      // Test that scrolling works without assertions.
      await tester.drag(find.byType(SingleChildScrollView), const Offset(0.0, -100.0));
      await tester.pumpAndSettle();

      // Verify the scroll happened.
      expect(scrollController.offset, greaterThan(0.0));
    },
  );
}
