feat(ui): 校正首页发现详情播放器预览

This commit is contained in:
Zhou Weidong committed 2026-10-19 15:50:11 +08:00
1 parent 87db548591
commit 21d457fd98
13 files changed
+1218 -1684

No files matched your search

+15 -17
View File
@@ -39,44 +39,42 @@ void main() {
expect(find.text('Continue Watching'), findsNothing);
expect(find.byKey(const Key('home-all-dramas-title')), findsNothing);
expect(find.text('All'), findsOneWidget);
expect(find.text('Recommended'), findsOneWidget);
expect(find.text('For You'), findsNothing);
expect(
tester.getCenter(find.text('All')).dx,
lessThan(tester.getCenter(find.text('Hot')).dx),
);
final grid = tester.widget<SliverGrid>(
find.byKey(const Key('home-all-dramas-grid')),
);
final delegate =
grid.gridDelegate as SliverGridDelegateWithFixedCrossAxisCount;
expect(delegate.crossAxisCount, 2);
expect(delegate.crossAxisSpacing, 12);
expect(delegate.mainAxisSpacing, 14);
expect(delegate.childAspectRatio, closeTo(0.55, 0.001));
expect(delegate.crossAxisSpacing, 10);
expect(delegate.mainAxisSpacing, 10);
expect(delegate.mainAxisExtent, 164);
expect(
tester
.widget<SliverPadding>(
find.byKey(const Key('home-all-dramas-section')),
)
.padding,
const EdgeInsets.symmetric(horizontal: 16),
const EdgeInsets.symmetric(horizontal: 14),
);
expect(find.byType(GridView), findsNothing);
expect(find.byType(CustomScrollView), findsOneWidget);
expect(find.byType(RemoteImage), findsWidgets);
final cover = tester.widget<AspectRatio>(
find.byKey(const Key('home-drama-cover-city-lights-demo')),
expect(
tester
.getSize(find.byKey(const Key('home-drama-cover-city-lights-demo')))
.height,
120,
);
expect(cover.aspectRatio, closeTo(3 / 4.2, 0.001));
expect(
tester
.widget<Text>(
find.byKey(const Key('home-drama-title-city-lights-demo')),
)
.maxLines,
2,
1,
);
expect(
tester
@@ -100,14 +98,14 @@ void main() {
await tester.tap(find.byKey(const Key('tab-discover')));
await tester.pumpAndSettle();
expect(find.text('The Signal'), findsOneWidget);
expect(find.text('City Lights & Velvet Nights'), findsOneWidget);
expect(find.text('The Signal'), findsWidgets);
expect(find.text('City Lights & Velvet Nights'), findsWidgets);
await tester.tap(find.text('Romance'));
await tester.pumpAndSettle();
expect(find.text('The Signal'), findsNothing);
expect(find.text('City Lights & Velvet Nights'), findsOneWidget);
expect(find.text('City Lights & Velvet Nights'), findsWidgets);
expect(
find.byKey(const Key('home-drama-card-the-signal-demo')),
findsNothing,
@@ -182,7 +180,7 @@ void main() {
await tester.pumpAndSettle();
expect(find.byKey(const Key('home-all-dramas-title')), findsNothing);
expect(find.text('City Lights & Velvet Nights'), findsOneWidget);
expect(find.text('City Lights & Velvet Nights'), findsWidgets);
expect(tester.takeException(), isNull);
});
+13 -34
View File
@@ -21,7 +21,7 @@ import '../support/fake_haptics.dart';
import '../support/fake_interaction_repositories.dart';
void main() {
testWidgets('should_render_hero_cta_synopsis_and_two_column_episode_grid', (
testWidgets('should_render_preview_hero_cta_synopsis_and_episode_chips', (
tester,
) async {
tester.view.physicalSize = const Size(390, 844);
@@ -32,45 +32,24 @@ void main() {
await tester.pumpWidget(_host(_detailDrama()));
await tester.pumpAndSettle();
final hero = tester.widget<AspectRatio>(
find.byKey(const Key('detail-hero')),
);
expect(hero.aspectRatio, closeTo(16 / 9, 0.001));
expect(tester.getSize(find.byKey(const Key('detail-hero'))).height, 190);
expect(find.byKey(const Key('detail-cta')), findsOneWidget);
expect(find.byKey(const Key('detail-favorite')), findsOneWidget);
expect(find.byKey(const Key('detail-download')), findsOneWidget);
expect(find.byKey(const Key('detail-episodes-range')), findsOneWidget);
expect(tester.getSize(find.byKey(const Key('detail-cta'))).height, 40);
expect(find.byKey(const Key('detail-episode-chip-1')), findsOneWidget);
expect(
tester.getSize(find.byKey(const Key('detail-episode-chip-1'))),
const Size(46, 44),
);
expect(find.byKey(const Key('detail-episode-chip-8')), findsOneWidget);
final synopsis = tester.widget<Text>(
find.byKey(const Key('detail-synopsis')),
);
expect(synopsis.maxLines, 2);
await tester.tap(find.byKey(const Key('detail-synopsis-toggle')));
await tester.pumpAndSettle();
expect(
tester.widget<Text>(find.byKey(const Key('detail-synopsis'))).maxLines,
100,
);
expect(synopsis.style?.fontSize, 11);
expect(synopsis.style?.height, 1.6);
final grid = tester.widget<SliverGrid>(
find.descendant(
of: find.byKey(const Key('detail-episode-grid')),
matching: find.byType(SliverGrid),
),
);
final delegate =
grid.gridDelegate as SliverGridDelegateWithFixedCrossAxisCount;
expect(delegate.crossAxisCount, 2);
expect(find.byKey(const Key('detail-episode-card-1')), findsOneWidget);
expect(
tester.getSize(find.byKey(const Key('detail-episode-thumb-1'))),
const Size(96, 64),
);
await tester.tap(find.byKey(const Key('detail-more')));
await tester.pumpAndSettle();
expect(find.byKey(const Key('detail-favorite')), findsOneWidget);
expect(find.byKey(const Key('detail-download')), findsOneWidget);
expect(find.byKey(const Key('detail-share')), findsOneWidget);
expect(find.byKey(const Key('detail-report')), findsOneWidget);
expect(tester.takeException(), isNull);
});
@@ -90,7 +69,7 @@ void main() {
);
await tester.pumpAndSettle();
expect(find.byKey(const Key('detail-episode-card-3')), findsOneWidget);
expect(find.byKey(const Key('detail-episode-chip-8')), findsOneWidget);
expect(tester.takeException(), isNull);
});
}
+64
View File
@@ -0,0 +1,64 @@
// Author: fruit.com.cn
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:shared_preferences_platform_interface/in_memory_shared_preferences_async.dart';
import 'package:shared_preferences_platform_interface/shared_preferences_async_platform_interface.dart';
import 'package:fruitshorts/app.dart';
import 'package:fruitshorts/core/data/repositories/favorite_repository.dart';
import 'package:fruitshorts/core/data/repositories/playback_repository.dart';
import 'package:fruitshorts/core/data/repositories/watch_history_repository.dart';
import '../support/fake_catalog.dart';
import '../support/fake_category.dart';
import '../support/fake_haptics.dart';
import '../support/fake_interaction_repositories.dart';
import '../support/fake_notice_repository.dart';
import '../support/widget_player.dart';
void main() {
testWidgets('should_render_preview_home_card_without_hot_or_follow_avatar', (
tester,
) async {
SharedPreferencesAsyncPlatform.instance =
InMemorySharedPreferencesAsync.empty();
tester.view.physicalSize = const Size(390, 844);
tester.view.devicePixelRatio = 1;
addTearDown(tester.view.resetPhysicalSize);
addTearDown(tester.view.resetDevicePixelRatio);
final catalog = FakeCatalogRepository();
await tester.pumpWidget(
LumaDramaApp(
playerFactory: createWidgetPlayer,
catalogRepository: catalog,
categoryRepository: FakeCategoryRepository(catalog: catalog),
watchHistoryRepository: InMemoryWatchHistoryRepository(),
favoriteRepository: InMemoryFavoriteRepository(cards: catalog.dramas),
playbackRepository: FakePlaybackRepository(),
commentRepository: FakeCommentRepository(),
interactionRepository: FakeInteractionRepository(),
noticeRepository: FakeNoticeRepository(),
haptics: FakeHaptics(),
),
);
await tester.pumpAndSettle();
await tester.tap(find.byKey(const Key('tab-home')));
await tester.pumpAndSettle();
expect(find.byKey(const Key('home-feed-title')), findsOneWidget);
expect(find.byKey(const Key('home-feed-info-card')), findsOneWidget);
expect(find.byKey(const Key('home-feed-episode')), findsOneWidget);
expect(find.byKey(const Key('home-feed-follow-series')), findsOneWidget);
expect(find.byKey(const Key('home-feed-episodes')), findsOneWidget);
expect(
tester.getSize(find.byKey(const Key('home-feed-follow-series'))).height,
34,
);
expect(find.text('HOT'), findsNothing);
expect(find.textContaining('Season'), findsNothing);
expect(find.byKey(const Key('home-feed-follow')), findsNothing);
expect(tester.takeException(), isNull);
});
}
+18 -9
View File
@@ -29,11 +29,15 @@ void main() {
await _pumpApp(tester);
await tester.tap(find.byKey(const Key('tab-discover')));
await tester.pumpAndSettle();
await tester.tap(find.text('City Lights & Velvet Nights'));
await tester.tap(find.byKey(const Key('home-drama-card-city-lights-demo')));
await tester.pumpAndSettle();
_expectFullscreenOverlay();
expect(find.byType(PageView), findsOneWidget);
await tester.tap(find.byKey(const Key('player-more')));
await tester.pumpAndSettle();
expect(find.byKey(const Key('player-more-download')), findsOneWidget);
expect(find.byKey(const Key('player-more-pip')), findsOneWidget);
expect(tester.takeException(), isNull);
});
@@ -57,24 +61,29 @@ void main() {
await tester.tap(find.byKey(const Key('detail-episode-chip-2')));
await tester.pumpAndSettle();
_expectFullscreenOverlay();
expect(find.text('Episode 2 · Playing now'), findsOneWidget);
expect(
tester.widget<Text>(find.byKey(const Key('player-title'))).data,
contains('Episode 2'),
);
expect(tester.takeException(), isNull);
});
}
void _expectFullscreenOverlay() {
expect(find.byKey(const Key('rail-like')), findsOneWidget);
expect(find.byKey(const Key('rail-save')), findsOneWidget);
expect(find.byKey(const Key('rail-comments')), findsOneWidget);
expect(find.byKey(const Key('rail-share')), findsOneWidget);
expect(find.byTooltip('Picture in picture'), findsOneWidget);
expect(find.byTooltip('Clear screen'), findsOneWidget);
expect(find.byKey(const Key('player-back')), findsOneWidget);
expect(find.byKey(const Key('player-title')), findsOneWidget);
expect(find.byKey(const Key('player-more')), findsOneWidget);
expect(find.byKey(const Key('player-play-toggle')), findsOneWidget);
expect(find.byKey(const Key('player-episodes')), findsOneWidget);
expect(find.byKey(const Key('player-comments')), findsOneWidget);
expect(find.byKey(const Key('player-next')), findsOneWidget);
expect(find.byType(Slider), findsOneWidget);
expect(find.byKey(const Key('rail-like')), findsNothing);
expect(find.byKey(const Key('rail-save')), findsNothing);
expect(find.byKey(const Key('card-player-video-frame')), findsNothing);
expect(find.byKey(const Key('card-player-progress')), findsNothing);
expect(find.byKey(const Key('card-player-next')), findsNothing);
expect(find.byKey(const Key('player-title')), findsNothing);
}
Future<void> _pumpApp(WidgetTester tester) async {
+35 -27
View File
@@ -110,17 +110,19 @@ void main() {
await tester.tap(find.byKey(const Key('tab-home')));
await tester.pumpAndSettle();
expect(find.text('The Signal'), findsOneWidget);
expect(find.byType(Slider), findsOneWidget);
expect(find.byType(Slider), findsNothing);
expect(find.text('Home'), findsWidgets);
expect(find.textContaining('Playing now'), findsOneWidget);
expect(find.text('Recommended'), findsNothing);
expect(find.text('Following'), findsNothing);
expect(find.byTooltip('Episodes'), findsWidgets);
expect(find.byTooltip('Clear screen'), findsOneWidget);
expect(find.byTooltip('Picture in picture'), findsNothing);
await tester.tap(find.byTooltip('More'));
expect(find.byKey(const Key('home-feed-title')), findsOneWidget);
expect(find.byKey(const Key('home-feed-info-card')), findsOneWidget);
expect(find.byKey(const Key('rail-like')), findsOneWidget);
expect(find.byKey(const Key('rail-comments')), findsOneWidget);
expect(find.byKey(const Key('rail-share')), findsOneWidget);
expect(find.byKey(const Key('rail-save')), findsOneWidget);
await tester.tap(find.byKey(const Key('home-feed-more')));
await tester.pumpAndSettle();
expect(find.text('Picture in picture'), findsOneWidget);
expect(find.byKey(const Key('home-feed-download')), findsOneWidget);
expect(find.byKey(const Key('home-feed-pip')), findsOneWidget);
expect(find.byKey(const Key('home-feed-clear')), findsOneWidget);
await tester.binding.handlePopRoute();
await tester.pumpAndSettle();
expect(find.text('Watch Full'), findsNothing);
@@ -139,14 +141,16 @@ void main() {
await tester.pumpAndSettle();
await tester.tap(find.byKey(const Key('tab-home')));
await tester.pumpAndSettle();
await tester.tap(find.byTooltip('Clear screen'));
await tester.tap(find.byKey(const Key('home-feed-more')));
await tester.pumpAndSettle();
await tester.tap(find.byKey(const Key('home-feed-clear')));
await tester.pumpAndSettle();
expect(find.byKey(const Key('home-tabs-bar')), findsNothing);
expect(find.byTooltip('Exit clear screen'), findsOneWidget);
await tester.tap(find.byTooltip('Exit clear screen'));
await tester.pumpAndSettle();
expect(find.byKey(const Key('home-tabs-bar')), findsOneWidget);
expect(find.byTooltip('Clear screen'), findsOneWidget);
expect(find.byKey(const Key('home-feed-more')), findsOneWidget);
expect(tester.takeException(), isNull);
});
@@ -233,12 +237,11 @@ void main() {
expect(find.text('我的'), findsWidgets);
await tester.drag(find.byType(ListView), const Offset(0, 700));
await tester.pumpAndSettle();
expect(find.text('我的账户'), findsOneWidget);
expect(find.byKey(const Key('mine-wallet')), findsOneWidget);
expect(find.text('首页'), findsOneWidget);
await tester.tap(find.text('找剧'));
await tester.tap(find.text('发现'));
await tester.pumpAndSettle();
expect(find.text('全部'), findsOneWidget);
expect(find.text('热门'), findsOneWidget);
expect(find.text('推荐'), findsOneWidget);
});
testWidgets(
@@ -259,7 +262,9 @@ void main() {
expect(find.text('City Lights & Velvet Nights'), findsOneWidget);
await tester.tap(find.byKey(const Key('tab-discover')));
await tester.pumpAndSettle();
await tester.tap(find.text('City Lights & Velvet Nights'));
await tester.tap(
find.byKey(const Key('home-drama-card-city-lights-demo')),
);
await tester.pumpAndSettle();
expect(find.byType(Slider), findsOneWidget);
expect(tester.takeException(), isNull);
@@ -324,7 +329,7 @@ void main() {
await tester.tap(find.byKey(const Key('tab-discover')));
await tester.pumpAndSettle();
expect(find.text('All'), findsOneWidget);
expect(find.text('Recommended'), findsOneWidget);
expect(find.byKey(const Key('home-all-dramas-grid')), findsOneWidget);
expect(find.byKey(const Key('discover-profile')), findsOneWidget);
expect(
@@ -341,7 +346,7 @@ void main() {
),
findsOneWidget,
);
expect(find.byTooltip('Search'), findsNothing);
expect(find.byTooltip('Search'), findsOneWidget);
expect(tester.takeException(), isNull);
await tester.tap(find.byKey(const Key('tab-my')));
@@ -372,7 +377,7 @@ void main() {
await tester.tap(find.byKey(const Key('tab-discover')));
await tester.pumpAndSettle();
expect(find.byKey(const Key('home-all-dramas-grid')), findsOneWidget);
expect(find.byTooltip('Search'), findsNothing);
expect(find.byTooltip('Search'), findsOneWidget);
expect(
Navigator.of(
tester.element(find.byKey(const Key('home-all-dramas-grid'))),
@@ -396,7 +401,7 @@ void main() {
await tester.tap(find.byKey(const Key('tab-discover')));
await tester.pumpAndSettle();
expect(find.byKey(const Key('home-all-dramas-grid')), findsOneWidget);
expect(find.byTooltip('Search'), findsNothing);
expect(find.byTooltip('Search'), findsOneWidget);
expect(
Navigator.of(
tester.element(find.byKey(const Key('home-all-dramas-grid'))),
@@ -440,12 +445,17 @@ void main() {
await tester.tap(find.byKey(const Key('tab-discover')));
await tester.pumpAndSettle();
await tester.tap(find.text('City Lights & Velvet Nights'));
await tester.tap(
find.byKey(const Key('home-drama-card-city-lights-demo')),
);
await tester.pumpAndSettle();
expect(find.byType(Slider), findsOneWidget);
await tester.drag(find.byType(PageView), const Offset(0, -550));
await tester.pumpAndSettle();
expect(find.text('Episode 2 · Playing now'), findsOneWidget);
expect(
tester.widget<Text>(find.byKey(const Key('player-title'))).data,
contains('Episode 2'),
);
expect(find.textContaining('City Lights & Velvet Nights'), findsWidgets);
},
);
@@ -507,9 +517,9 @@ void main() {
await tester.pumpAndSettle();
final keys = [
const Key('rail-like'),
const Key('rail-save'),
const Key('rail-comments'),
const Key('rail-share'),
const Key('rail-save'),
];
final tops = keys
.map((key) => tester.getTopLeft(find.byKey(key)).dy)
@@ -644,10 +654,8 @@ void main() {
await tester.pumpAndSettle();
await tester.tap(find.byKey(const Key('tab-my')));
await tester.pumpAndSettle();
await tester.scrollUntilVisible(
find.byKey(const Key('mine-library-tab-1')),
300,
);
await tester.drag(find.byType(ListView), const Offset(0, -320));
await tester.pumpAndSettle();
await tester.tap(find.byKey(const Key('mine-library-tab-1')));
await tester.pumpAndSettle();
expect(find.text('The Signal'), findsOneWidget);