diff --git a/client/test/golden/app_shell_golden_test.dart b/client/test/golden/app_shell_golden_test.dart new file mode 100644 index 0000000..71c8cbb --- /dev/null +++ b/client/test/golden/app_shell_golden_test.dart @@ -0,0 +1,101 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:go_router/go_router.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:jiu_client/core/auth/auth_state.dart'; +import 'package:jiu_client/core/theme/themes.dart'; +import 'package:jiu_client/models/shop.dart'; +import 'package:jiu_client/providers/shop_provider.dart'; +import 'package:jiu_client/providers/license_provider.dart'; +import 'package:jiu_client/providers/update_provider.dart'; +import 'package:jiu_client/providers/connectivity_provider.dart'; +import 'package:jiu_client/providers/session_heartbeat.dart'; +import 'package:jiu_client/screens/shell/app_shell.dart'; + +/// design-distill 阶段4:app 外壳(顶栏 + 侧栏 + 内容区)golden × 三主题。 +/// 锁住导航 chrome 随主题换色——这是最显眼的主题面,之前各屏 golden 都不含外壳。 +/// 需 MaterialApp.router(外壳依赖 StatefulNavigationShell),故为自定义 golden。 +/// 更新基准:flutter test --update-goldens test/golden/app_shell_golden_test.dart + +class _FakeAuth extends AuthNotifier { + _FakeAuth() { + state = const AuthState( + user: AuthUser( + accessToken: 't', refreshToken: 'r', id: 1, username: 'wang', + realName: '王经理', shopNo: 'DBZB-001', shopId: 1, role: 'admin'), + ); + } +} + +class _FakeUpdate extends UpdateNotifier { + @override + Future build() async => null; +} + +class _FakeLicense extends LicenseNotifier { + @override + Future build() async => null; +} + +const _shop = ShopInfo( + id: 1, code: 'DBZB-001', name: '鼎昌酒行', + address: '浙江省杭州市', phone: '0571-88886666', managerName: '王经理'); + +List _overrides() => [ + authStateProvider.overrideWith((ref) => _FakeAuth()), + shopInfoProvider.overrideWith((ref) => _shop), + licenseProvider.overrideWith(() => _FakeLicense()), + updateProvider.overrideWith(() => _FakeUpdate()), + // 跳过联网首检 / 不启动心跳,避免后台 Timer 泄漏 + connectivityProvider + .overrideWith((ref) => ConnectivityNotifier(skipInit: true)), + sessionHeartbeatProvider.overrideWith((ref) => SessionHeartbeat(ref)), + appVersionProvider.overrideWith((ref) => 'v1.0.72'), + isReadonlyProvider.overrideWithValue(false), + ]; + +GoRouter _router() => GoRouter( + initialLocation: '/inventory', + routes: [ + StatefulShellRoute.indexedStack( + builder: (ctx, state, shell) => AppShell(navigationShell: shell), + branches: [ + StatefulShellBranch(routes: [ + GoRoute( + path: '/inventory', + builder: (_, __) => const SizedBox.expand()), + ]), + ], + ), + ], + ); + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + SharedPreferences.setMockInitialValues({}); + + for (final theme in const ['a', 'b', 'c']) { + testWidgets('app shell · theme $theme', (tester) async { + tester.view.physicalSize = const Size(2560, 1600); + tester.view.devicePixelRatio = 2.0; + addTearDown(tester.view.resetPhysicalSize); + addTearDown(tester.view.resetDevicePixelRatio); + + await tester.pumpWidget(ProviderScope( + overrides: _overrides(), + child: MaterialApp.router( + debugShowCheckedModeBanner: false, + theme: buildTheme(theme), + routerConfig: _router(), + ), + )); + await tester.pumpAndSettle(); + + await expectLater( + find.byType(MaterialApp), + matchesGoldenFile('goldens/app_shell_$theme.png'), + ); + }); + } +} diff --git a/client/test/golden/goldens/app_shell_a.png b/client/test/golden/goldens/app_shell_a.png new file mode 100644 index 0000000..30d2d72 Binary files /dev/null and b/client/test/golden/goldens/app_shell_a.png differ diff --git a/client/test/golden/goldens/app_shell_b.png b/client/test/golden/goldens/app_shell_b.png new file mode 100644 index 0000000..dbd4e3c Binary files /dev/null and b/client/test/golden/goldens/app_shell_b.png differ diff --git a/client/test/golden/goldens/app_shell_c.png b/client/test/golden/goldens/app_shell_c.png new file mode 100644 index 0000000..6e359e7 Binary files /dev/null and b/client/test/golden/goldens/app_shell_c.png differ