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

5 6
// @dart = 2.8

7 8
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/material.dart';
9
import 'package:flutter/gestures.dart' show DragStartBehavior;
10

11 12
const TextStyle testFont = TextStyle(
  color: Color(0xFF00FF00),
13 14 15
  fontFamily: 'Ahem',
);

16
Future<void> pumpTest(WidgetTester tester, TargetPlatform platform) async {
17 18 19
  await tester.pumpWidget(Container());
  await tester.pumpWidget(MaterialApp(
    theme: ThemeData(
20
      platform: platform,
21
    ),
22
    home: Container(
23
      color: const Color(0xFF111111),
24
      child: ListView.builder(
25
        dragStartBehavior: DragStartBehavior.down,
26
        itemBuilder: (BuildContext context, int index) {
27
          return Text('$index', style: testFont);
28 29
        },
      ),
30 31 32 33 34 35 36 37
    ),
  ));
}

const double dragOffset = 213.82;

void main() {
  testWidgets('Flings on different platforms', (WidgetTester tester) async {
38
    double getCurrentOffset() {
Adam Barth's avatar
Adam Barth committed
39
      return tester.state<ScrollableState>(find.byType(Scrollable)).position.pixels;
40 41
    }

42
    await pumpTest(tester, TargetPlatform.android);
43 44
    await tester.fling(find.byType(ListView), const Offset(0.0, -dragOffset), 1000.0);
    expect(getCurrentOffset(), dragOffset);
45
    await tester.pump(); // trigger fling
46
    expect(getCurrentOffset(), dragOffset);
47
    await tester.pump(const Duration(seconds: 5));
Dan Field's avatar
Dan Field committed
48
    final double androidResult = getCurrentOffset();
49

50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
    await pumpTest(tester, TargetPlatform.linux);
    await tester.fling(find.byType(ListView), const Offset(0.0, -dragOffset), 1000.0);
    expect(getCurrentOffset(), dragOffset);
    await tester.pump(); // trigger fling
    expect(getCurrentOffset(), dragOffset);
    await tester.pump(const Duration(seconds: 5));
    final double linuxResult = getCurrentOffset();

    await pumpTest(tester, TargetPlatform.windows);
    await tester.fling(find.byType(ListView), const Offset(0.0, -dragOffset), 1000.0);
    expect(getCurrentOffset(), dragOffset);
    await tester.pump(); // trigger fling
    expect(getCurrentOffset(), dragOffset);
    await tester.pump(const Duration(seconds: 5));
    final double windowsResult = getCurrentOffset();

66
    await pumpTest(tester, TargetPlatform.iOS);
67
    await tester.fling(find.byType(ListView), const Offset(0.0, -dragOffset), 1000.0);
68 69
    // Scroll starts ease into the scroll on iOS.
    expect(getCurrentOffset(), moreOrLessEquals(210.71026666666666));
70
    await tester.pump(); // trigger fling
71
    expect(getCurrentOffset(), moreOrLessEquals(210.71026666666666));
72
    await tester.pump(const Duration(seconds: 5));
Dan Field's avatar
Dan Field committed
73
    final double iOSResult = getCurrentOffset();
74

Dan Field's avatar
Dan Field committed
75 76 77 78 79 80 81 82 83 84 85
    await pumpTest(tester, TargetPlatform.macOS);
    await tester.fling(find.byType(ListView), const Offset(0.0, -dragOffset), 1000.0);
    // Scroll starts ease into the scroll on iOS.
    expect(getCurrentOffset(), moreOrLessEquals(210.71026666666666));
    await tester.pump(); // trigger fling
    expect(getCurrentOffset(), moreOrLessEquals(210.71026666666666));
    await tester.pump(const Duration(seconds: 5));
    final double macOSResult = getCurrentOffset();

    expect(androidResult, lessThan(iOSResult)); // iOS is slipperier than Android
    expect(androidResult, lessThan(macOSResult)); // macOS is slipperier than Android
86 87 88 89 90 91 92 93
    expect(linuxResult, lessThan(iOSResult)); // iOS is slipperier than Linux
    expect(linuxResult, lessThan(macOSResult)); // macOS is slipperier than Linux
    expect(windowsResult, lessThan(iOSResult)); // iOS is slipperier than Windows
    expect(windowsResult, lessThan(macOSResult)); // macOS is slipperier than Windows
    expect(windowsResult, equals(androidResult));
    expect(windowsResult, equals(androidResult));
    expect(linuxResult, equals(androidResult));
    expect(linuxResult, equals(androidResult));
94
  });
95 96

  testWidgets('fling and tap to stop', (WidgetTester tester) async {
97
    final List<String> log = <String>[];
98
    await tester.pumpWidget(
99
      Directionality(
100
        textDirection: TextDirection.ltr,
101 102 103 104 105 106 107
        child: ListView(
          dragStartBehavior: DragStartBehavior.down,
          children: List<Widget>.generate(250, (int i) => GestureDetector(
            onTap: () { log.add('tap $i'); },
            child: Text('$i', style: testFont),
          )),
        ),
108 109
      ),
    );
110 111

    expect(log, equals(<String>[]));
Adam Barth's avatar
Adam Barth committed
112
    await tester.tap(find.byType(Scrollable));
113
    await tester.pump(const Duration(milliseconds: 50));
114
    expect(log, equals(<String>['tap 21']));
Adam Barth's avatar
Adam Barth committed
115
    await tester.fling(find.byType(Scrollable), const Offset(0.0, -200.0), 1000.0);
116
    await tester.pump(const Duration(milliseconds: 50));
117 118
    expect(log, equals(<String>['tap 21']));
    await tester.tap(find.byType(Scrollable)); // should stop the fling but not tap anything
119
    await tester.pump(const Duration(milliseconds: 50));
120
    expect(log, equals(<String>['tap 21']));
Adam Barth's avatar
Adam Barth committed
121
    await tester.tap(find.byType(Scrollable));
122
    await tester.pump(const Duration(milliseconds: 50));
123
    expect(log, equals(<String>['tap 21', 'tap 35']));
124
  });
125 126

  testWidgets('fling and wait and tap', (WidgetTester tester) async {
127
    final List<String> log = <String>[];
128
    await tester.pumpWidget(
129
      Directionality(
130
        textDirection: TextDirection.ltr,
131 132 133 134 135 136 137
        child: ListView(
          dragStartBehavior: DragStartBehavior.down,
          children: List<Widget>.generate(250, (int i) => GestureDetector(
            onTap: () { log.add('tap $i'); },
            child: Text('$i', style: testFont),
          )),
        ),
138 139
      ),
    );
140 141

    expect(log, equals(<String>[]));
Adam Barth's avatar
Adam Barth committed
142
    await tester.tap(find.byType(Scrollable));
143
    await tester.pump(const Duration(milliseconds: 50));
144
    expect(log, equals(<String>['tap 21']));
Adam Barth's avatar
Adam Barth committed
145
    await tester.fling(find.byType(Scrollable), const Offset(0.0, -200.0), 1000.0);
146
    await tester.pump(const Duration(milliseconds: 50));
147 148 149
    expect(log, equals(<String>['tap 21']));
    await tester.pump(const Duration(seconds: 50)); // long wait, so the fling will have ended at the end of it
    expect(log, equals(<String>['tap 21']));
Adam Barth's avatar
Adam Barth committed
150
    await tester.tap(find.byType(Scrollable));
151
    await tester.pump(const Duration(milliseconds: 50));
152
    expect(log, equals(<String>['tap 21', 'tap 48']));
153
  });
154
}