scrollbar_paint_test.dart 4.66 KB
Newer Older
Ian Hickson's avatar
Ian Hickson committed
1
// Copyright 2014 The Flutter Authors. All rights reserved.
2 3 4 5
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:flutter/material.dart';
6
import 'package:flutter_test/flutter_test.dart';
7

8 9
const Color _kAndroidThumbIdleColor = Color(0xffbcbcbc);

10 11 12
Widget _buildSingleChildScrollViewWithScrollbar({
  TextDirection textDirection = TextDirection.ltr,
  EdgeInsets padding = EdgeInsets.zero,
13
  Widget? child,
14
}) {
15 16 17 18
  return Directionality(
    textDirection: textDirection,
    child: MediaQuery(
      data: MediaQueryData(padding: padding),
19
      child: Scrollbar(
20
        child: SingleChildScrollView(child: child),
21
      ),
22 23 24 25 26
    ),
  );
}

void main() {
27
  testWidgets('Viewport basic test (LTR)', (WidgetTester tester) async {
28 29
    await tester.pumpWidget(_buildSingleChildScrollViewWithScrollbar(
      child: const SizedBox(width: 4000.0, height: 4000.0),
30
    ));
31
    expect(find.byType(Scrollbar), isNot(paints..rect()));
32
    await tester.fling(find.byType(SingleChildScrollView), const Offset(0.0, -10.0), 10.0);
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
    expect(
      find.byType(Scrollbar),
      paints
        ..rect(
          rect: const Rect.fromLTRB(796.0, 0.0, 800.0, 600.0),
          color: const Color(0x00000000),
        )
        ..line(
          p1: const Offset(796.0, 0.0),
          p2: const Offset(796.0, 600.0),
          strokeWidth: 1.0,
          color: const Color(0x00000000),
        )
        ..rect(
          rect: const Rect.fromLTRB(796.0, 1.5, 800.0, 91.5),
48
          color: _kAndroidThumbIdleColor,
49 50
        ),
    );
51 52
  });

53
  testWidgets('Viewport basic test (RTL)', (WidgetTester tester) async {
54
    await tester.pumpWidget(_buildSingleChildScrollViewWithScrollbar(
55
      textDirection: TextDirection.rtl,
56
      child: const SizedBox(width: 4000.0, height: 4000.0),
57 58 59
    ));
    expect(find.byType(Scrollbar), isNot(paints..rect()));
    await tester.fling(find.byType(SingleChildScrollView), const Offset(0.0, -10.0), 10.0);
60 61 62 63 64 65 66 67
    expect(
      find.byType(Scrollbar),
      paints
        ..rect(
          rect: const Rect.fromLTRB(0.0, 0.0, 4.0, 600.0),
          color: const Color(0x00000000),
        )
        ..line(
68 69
          p1: const Offset(4.0, 0.0),
          p2: const Offset(4.0, 600.0),
70 71 72 73 74
          strokeWidth: 1.0,
          color: const Color(0x00000000),
        )
        ..rect(
          rect: const Rect.fromLTRB(0.0, 1.5, 4.0, 91.5),
75
          color: _kAndroidThumbIdleColor,
76 77
        ),
    );
78
  });
79

80
  testWidgets('works with MaterialApp and Scaffold', (WidgetTester tester) async {
81 82 83
    await tester.pumpWidget(MaterialApp(
      home: MediaQuery(
        data: const MediaQueryData(
84
          padding: EdgeInsets.fromLTRB(0, 20, 0, 34),
85 86 87 88 89
        ),
        child: Scaffold(
          appBar: AppBar(title: const Text('Title')),
          body: Scrollbar(
            child: ListView(
90
              children: const <Widget>[SizedBox(width: 4000, height: 4000)],
91 92 93 94 95 96 97 98 99 100 101 102 103
            ),
          ),
        ),
      ),
    ));

    final TestGesture gesture = await tester.startGesture(tester.getCenter(find.byType(ListView)));
    // On Android it should not overscroll.
    await gesture.moveBy(const Offset(0, 100));
    // Trigger fade in animation.
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 500));

104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
    expect(
      find.byType(Scrollbar),
      paints
        ..rect(
          rect: const Rect.fromLTRB(796.0, 0.0, 800.0, 490.0),
          color: const Color(0x00000000),
        )
        ..line(
          p1: const Offset(796.0, 0.0),
          p2: const Offset(796.0, 490.0),
          strokeWidth: 1.0,
          color: const Color(0x00000000),
        )
        ..rect(
          rect: const Rect.fromLTWH(796.0, 0.0, 4.0, (600.0 - 56 - 34 - 20) / 4000 * (600 - 56 - 34 - 20)),
119
          color: _kAndroidThumbIdleColor,
120 121
        ),
    );
122
  });
123

124
  testWidgets("should not paint when there isn't enough space", (WidgetTester tester) async {
125 126 127
    await tester.pumpWidget(MaterialApp(
      home: MediaQuery(
        data: const MediaQueryData(
128
          padding: EdgeInsets.fromLTRB(0, 20, 0, 34),
129 130 131 132 133
        ),
        child: Scaffold(
          appBar: AppBar(title: const Text('Title')),
          body: Scrollbar(
            child: ListView(
134
              children: const <Widget>[SizedBox(width: 40, height: 40)],
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
            ),
          ),
        ),
      ),
    ));

    final TestGesture gesture = await tester.startGesture(tester.getCenter(find.byType(ListView)));
    // On Android it should not overscroll.
    await gesture.moveBy(const Offset(0, 100));
    // Trigger fade in animation.
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 500));

    expect(find.byType(Scrollbar), isNot(paints..rect()));
  });

151
}