// 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 'package:flutter/cupertino.dart'; import 'package:flutter_test/flutter_test.dart'; const Color _kScrollbarColor = Color(0x59000000); // The `y` offset has to be larger than `ScrollDragController._bigThresholdBreakDistance` // to prevent [motionStartDistanceThreshold] from affecting the actual drag distance. const Offset _kGestureOffset = Offset(0, -25); const Radius _kScrollbarRadius = Radius.circular(1.5); void main() { testWidgets('Paints iOS spec', (WidgetTester tester) async { await tester.pumpWidget( const Directionality( textDirection: TextDirection.ltr, child: MediaQuery( data: MediaQueryData(), child: CupertinoScrollbar( child: SingleChildScrollView( child: SizedBox(width: 4000.0, height: 4000.0), ), ), ), ), ); expect(find.byType(CupertinoScrollbar), isNot(paints..rrect())); final TestGesture gesture = await tester.startGesture(tester.getCenter(find.byType(SingleChildScrollView))); await gesture.moveBy(_kGestureOffset); // Move back to original position. await gesture.moveBy(Offset.zero.translate(-_kGestureOffset.dx, -_kGestureOffset.dy)); await tester.pump(); await tester.pump(const Duration(milliseconds: 500)); expect(find.byType(CupertinoScrollbar), paints..rrect( color: _kScrollbarColor, rrect: RRect.fromRectAndRadius( const Rect.fromLTWH( 800.0 - 3 - 3, // Screen width - margin - thickness. 3.0, // Initial position is the top margin. 3, // Thickness. // Fraction in viewport * scrollbar height - top, bottom margin. 600.0 / 4000.0 * (600.0 - 2 * 3), ), _kScrollbarRadius, ), )); }); testWidgets('Paints iOS spec with nav bar', (WidgetTester tester) async { await tester.pumpWidget( CupertinoApp( home: MediaQuery( data: const MediaQueryData( padding: EdgeInsets.fromLTRB(0, 20, 0, 34), ), child: CupertinoPageScaffold( navigationBar: const CupertinoNavigationBar( middle: Text('Title'), backgroundColor: Color(0x11111111), ), child: CupertinoScrollbar( child: ListView( children: const <Widget>[SizedBox(width: 4000, height: 4000)], ), ), ), ), ), ); final TestGesture gesture = await tester.startGesture(tester.getCenter(find.byType(ListView))); await gesture.moveBy(_kGestureOffset); // Move back to original position. await gesture.moveBy(Offset(-_kGestureOffset.dx, -_kGestureOffset.dy)); await tester.pump(); await tester.pump(const Duration(milliseconds: 500)); expect(find.byType(CupertinoScrollbar), paints..rrect( color: _kScrollbarColor, rrect: RRect.fromRectAndRadius( const Rect.fromLTWH( 800.0 - 3 - 3, // Screen width - margin - thickness. 44 + 20 + 3.0, // nav bar height + top margin 3, // Thickness. // Fraction visible * (viewport size - padding - margin) // where Fraction visible = (viewport size - padding) / content size (600.0 - 34 - 44 - 20) / 4000.0 * (600.0 - 2 * 3 - 34 - 44 - 20), ), _kScrollbarRadius, ), )); }); testWidgets("should not paint when there isn't enough space", (WidgetTester tester) async { await tester.pumpWidget( CupertinoApp( home: MediaQuery( data: const MediaQueryData( padding: EdgeInsets.fromLTRB(0, 20, 0, 34), ), child: CupertinoPageScaffold( navigationBar: const CupertinoNavigationBar( middle: Text('Title'), backgroundColor: Color(0x11111111), ), child: CupertinoScrollbar( child: ListView( physics: const AlwaysScrollableScrollPhysics(parent: BouncingScrollPhysics()), children: const <Widget> [SizedBox(width: 10, height: 10)], ), ), ), ), ), ); final TestGesture gesture = await tester.startGesture(tester.getCenter(find.byType(ListView))); await gesture.moveBy(_kGestureOffset); // Move back to original position. await gesture.moveBy(Offset(-_kGestureOffset.dx, -_kGestureOffset.dy)); await tester.pump(); await tester.pump(const Duration(milliseconds: 500)); expect(find.byType(CupertinoScrollbar), isNot(paints..rrect())); // The scrollbar should not appear even when overscrolled. final TestGesture overscrollGesture = await tester.startGesture(tester.getCenter(find.byType(ListView))); await overscrollGesture.moveBy(_kGestureOffset); await tester.pump(); await tester.pump(const Duration(milliseconds: 500)); expect(find.byType(CupertinoScrollbar), isNot(paints..rrect())); }); }