// Author: fruit.com.cn import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:fruitshorts/pages/player/widgets/seek_progress_bar.dart'; import 'package:video_player/video_player.dart'; void main() { testWidgets('tapping the progress bar does not hide the overlay', ( tester, ) async { final harness = await _pumpHarness(tester); await tester.tap(find.byType(Slider)); await tester.pumpAndSettle(); expect(find.byKey(const Key('scrub-overlay')), findsOneWidget); expect(harness.scrubStarts, 0); expect(harness.seeks, 0); expect(_sliderTheme(tester).trackHeight, 2); }); testWidgets('horizontal drag hides the overlay and thickens the track', ( tester, ) async { final harness = await _pumpHarness(tester); final slider = find.byType(Slider); final gesture = await tester.startGesture(tester.getCenter(slider)); await gesture.moveBy(const Offset(24, 0)); await tester.pump(); expect(find.byKey(const Key('scrub-overlay')), findsNothing); expect(harness.scrubStarts, 1); expect(_sliderTheme(tester).trackHeight, 6); expect( (_sliderTheme(tester).thumbShape! as RoundSliderThumbShape) .enabledThumbRadius, 8, ); await gesture.moveBy(const Offset(72, 0)); await tester.pump(); await gesture.up(); await tester.pumpAndSettle(); }); testWidgets('releasing restores the overlay and idle track height', ( tester, ) async { final harness = await _pumpHarness(tester); final gesture = await tester.startGesture( tester.getCenter(find.byType(Slider)), ); await gesture.moveBy(const Offset(32, 0)); await tester.pump(); await gesture.moveBy(const Offset(64, 0)); await tester.pump(); await gesture.up(); await tester.pumpAndSettle(); expect(find.byKey(const Key('scrub-overlay')), findsOneWidget); expect(harness.scrubEnds, 1); expect(harness.seeks, 1); expect(_sliderTheme(tester).trackHeight, 2); expect( (_sliderTheme(tester).thumbShape! as RoundSliderThumbShape) .enabledThumbRadius, 6, ); }); } Future<_HarnessState> _pumpHarness(WidgetTester tester) async { final controller = ValueNotifier( const VideoPlayerValue( duration: Duration(minutes: 2), position: Duration(seconds: 20), isInitialized: true, ), ); addTearDown(controller.dispose); final key = GlobalKey<_HarnessState>(); await tester.pumpWidget( MaterialApp( home: Scaffold( body: _Harness(key: key, controller: controller), ), ), ); await tester.pumpAndSettle(); return key.currentState!; } SliderThemeData _sliderTheme(WidgetTester tester) { return tester .widget( find .ancestor( of: find.byType(Slider), matching: find.byType(SliderTheme), ) .first, ) .data; } class _Harness extends StatefulWidget { const _Harness({super.key, required this.controller}); final ValueNotifier controller; @override State<_Harness> createState() => _HarnessState(); } class _HarnessState extends State<_Harness> { bool visible = true; int scrubStarts = 0; int scrubEnds = 0; int seeks = 0; @override Widget build(BuildContext context) { return Column( children: [ if (visible) const Text('Overlay', key: Key('scrub-overlay')), SizedBox( width: 320, height: 80, child: SeekProgressBar( valueListenable: widget.controller, semanticsLabel: 'Progress', onScrubStart: () => setState(() { visible = false; scrubStarts++; }), onScrubEnd: () => setState(() { visible = true; scrubEnds++; }), onSeek: (_) async { seeks++; }, ), ), ], ); } }