162 lines
4.7 KiB
Dart
162 lines
4.7 KiB
Dart
// Author: fruit.com.cn
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:video_player/video_player.dart';
|
|
|
|
import 'package:fruitshorts/pages/player/widgets/player_video_surface.dart';
|
|
|
|
void main() {
|
|
testWidgets('should_keep_fallback_visible_before_video_is_ready', (
|
|
tester,
|
|
) async {
|
|
await _pumpSurface(tester);
|
|
|
|
expect(_fallbackColor(tester), Colors.black);
|
|
expect(find.byKey(const Key('player-fallback-cover')), findsNothing);
|
|
expect(find.byKey(const Key('player-fallback-scrim')), findsNothing);
|
|
expect(_opacity(tester), 0);
|
|
expect(find.byKey(const Key('player-debug-video')), findsNothing);
|
|
});
|
|
|
|
testWidgets('should_fade_video_in_within_200ms_after_first_frame', (
|
|
tester,
|
|
) async {
|
|
final controller = await _pumpSurface(tester);
|
|
expect(_opacity(tester), 0);
|
|
|
|
controller.value = const VideoPlayerValue(
|
|
duration: Duration(minutes: 1),
|
|
size: Size(1280, 720),
|
|
position: Duration(milliseconds: 1),
|
|
isInitialized: true,
|
|
isPlaying: true,
|
|
);
|
|
await tester.pump();
|
|
|
|
expect(_opacity(tester), 1);
|
|
expect(
|
|
tester
|
|
.widget<AnimatedOpacity>(
|
|
find.byKey(const Key('player-video-opacity')),
|
|
)
|
|
.duration,
|
|
const Duration(milliseconds: 200),
|
|
);
|
|
await tester.pump(const Duration(milliseconds: 100));
|
|
final halfway = _fadeValue(tester);
|
|
expect(halfway, greaterThan(0));
|
|
expect(halfway, lessThan(1));
|
|
await tester.pump(const Duration(milliseconds: 100));
|
|
expect(_fadeValue(tester), 1);
|
|
expect(_fallbackColor(tester), Colors.black);
|
|
expect(find.byKey(const Key('player-fallback-cover')), findsNothing);
|
|
expect(find.byKey(const Key('player-debug-video')), findsNothing);
|
|
});
|
|
|
|
testWidgets('should_show_video_error_above_retained_fallback', (
|
|
tester,
|
|
) async {
|
|
await _pumpSurface(
|
|
tester,
|
|
value: const VideoPlayerValue.erroneous('No route to host'),
|
|
);
|
|
|
|
expect(find.byKey(const Key('player-video-error')), findsOneWidget);
|
|
expect(find.text('No route to host'), findsOneWidget);
|
|
expect(_fallbackColor(tester), Colors.black);
|
|
expect(find.byKey(const Key('player-fallback-cover')), findsNothing);
|
|
expect(_opacity(tester), 0);
|
|
expect(find.byKey(const Key('player-debug-video')), findsNothing);
|
|
});
|
|
|
|
testWidgets('should_cover_new_video_only_while_handoff_is_held', (
|
|
tester,
|
|
) async {
|
|
final current = VideoPlayerController.networkUrl(
|
|
Uri.parse('http://192.168.31.187:8081/files/720.m3u8'),
|
|
);
|
|
final previous = VideoPlayerController.networkUrl(
|
|
Uri.parse('http://192.168.31.187:8081/files/360.m3u8'),
|
|
);
|
|
addTearDown(current.dispose);
|
|
addTearDown(previous.dispose);
|
|
const ready = VideoPlayerValue(
|
|
duration: Duration(minutes: 1),
|
|
size: Size(1280, 720),
|
|
position: Duration(seconds: 3),
|
|
isInitialized: true,
|
|
isPlaying: true,
|
|
);
|
|
current.value = ready;
|
|
previous.value = ready;
|
|
|
|
Future<void> pump(VideoPlayerController? handoff) {
|
|
return tester.pumpWidget(
|
|
MaterialApp(
|
|
home: Scaffold(
|
|
body: PlayerVideoSurface(
|
|
controller: current,
|
|
handoff: handoff,
|
|
videoUrl: current.dataSource,
|
|
theater: false,
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
await pump(previous);
|
|
expect(find.byKey(const Key('player-video-handoff')), findsOneWidget);
|
|
expect(_opacity(tester), 1);
|
|
|
|
await pump(null);
|
|
expect(find.byKey(const Key('player-video-handoff')), findsNothing);
|
|
expect(find.byType(VideoPlayer), findsOneWidget);
|
|
});
|
|
}
|
|
|
|
Future<VideoPlayerController> _pumpSurface(
|
|
WidgetTester tester, {
|
|
VideoPlayerValue? value,
|
|
}) async {
|
|
final controller = VideoPlayerController.networkUrl(
|
|
Uri.parse('http://192.168.31.187:8081/files/video.mp4'),
|
|
);
|
|
addTearDown(controller.dispose);
|
|
if (value != null) controller.value = value;
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: Scaffold(
|
|
body: PlayerVideoSurface(
|
|
controller: controller,
|
|
videoUrl: controller.dataSource,
|
|
theater: false,
|
|
),
|
|
),
|
|
),
|
|
);
|
|
await tester.pump();
|
|
return controller;
|
|
}
|
|
|
|
Color _fallbackColor(WidgetTester tester) {
|
|
return tester
|
|
.widget<ColoredBox>(find.byKey(const Key('player-fallback-background')))
|
|
.color;
|
|
}
|
|
|
|
double _opacity(WidgetTester tester) {
|
|
return tester
|
|
.widget<AnimatedOpacity>(find.byKey(const Key('player-video-opacity')))
|
|
.opacity;
|
|
}
|
|
|
|
double _fadeValue(WidgetTester tester) {
|
|
final fade = find.descendant(
|
|
of: find.byKey(const Key('player-video-opacity')),
|
|
matching: find.byType(FadeTransition),
|
|
);
|
|
return tester.widget<FadeTransition>(fade).opacity.value;
|
|
}
|