import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:get/get.dart'; import 'package:pj_supermarket_cloud/sub_screen/common/models/customer_display_models.dart'; import 'package:pj_supermarket_cloud/sub_screen/common/utils/customer_display_coordinator.dart'; import 'package:pj_supermarket_cloud/sub_screen/page/customer_display.dart'; import 'package:pj_supermarket_cloud/sub_screen/page/customer_preview.dart'; void main() { for (final size in [const Size(1920, 1080), const Size(1280, 720)]) { testWidgets('${size.width.toInt()}x${size.height.toInt()} 六种状态无布局异常', (tester) async { tester.view.physicalSize = size; tester.view.devicePixelRatio = 1; addTearDown(tester.view.resetPhysicalSize); addTearDown(tester.view.resetDevicePixelRatio); for (final scenario in CustomerDisplayScenario.values) { final coordinator = CustomerDisplayCoordinator( initialState: CustomerDisplayState.demo(scenario), ); await tester.pumpWidget( MaterialApp( debugShowCheckedModeBanner: false, home: CustomerDisplayPage(coordinator: coordinator), ), ); await tester.pump(); final scenarioKey = scenario == CustomerDisplayScenario.idle ? const ValueKey('customer-welcome-page') : ValueKey('customer-scenario-${scenario.name}'); expect(find.byKey(scenarioKey), findsOneWidget); expect(tester.takeException(), isNull); if (scenario == CustomerDisplayScenario.idle) { expect(find.text('终端服务已就绪'), findsOneWidget); expect(find.text('等待添加商品'), findsNothing); } else { expect(find.text('张*明,您好'), findsOneWidget); expect(find.text('张小明'), findsNothing); expect(find.text('¥ 46.70'), findsOneWidget); expect(find.text('¥ 3.00'), findsOneWidget); expect(find.text('¥ 49.70'), findsOneWidget); expect(find.text('biz-xfj-customer-preview'), findsNothing); } if (scenario == CustomerDisplayScenario.success) { expect(find.text('本次购买商品'), findsOneWidget); expect(find.text('请核对商品信息'), findsNothing); expect(find.byKey(const ValueKey('customer-payment-success')), findsOneWidget); expect(find.byKey(const ValueKey('customer-success-countdown')), findsOneWidget); expect(find.text('请带好您的商品'), findsOneWidget); } await tester.pumpWidget(const SizedBox.shrink()); coordinator.dispose(); } }); } testWidgets('悬浮按钮和系统返回请求都能退出全屏预览', (tester) async { await tester.pumpWidget(const _PreviewNavigationHarness()); await tester.tap(find.text('打开预览')); await tester.pumpAndSettle(); expect(find.text('退出预览'), findsOneWidget); await tester.tap(find.text('退出预览')); await tester.pumpAndSettle(); expect(find.text('打开预览'), findsOneWidget); await tester.tap(find.text('打开预览')); await tester.pumpAndSettle(); await tester.binding.handlePopRoute(); await tester.pumpAndSettle(); expect(find.text('打开预览'), findsOneWidget); }); testWidgets('从内层终端设置打开预览后返回原设置状态', (tester) async { await tester.pumpWidget(const _NestedPreviewNavigationHarness()); await tester.tap(find.text('商品核对')); await tester.tap(find.text('全屏预览')); await tester.pumpAndSettle(); expect(find.text('退出预览'), findsOneWidget); await tester.tap(find.text('退出预览')); await tester.pumpAndSettle(); expect(find.text('商品核对:已选中'), findsOneWidget); }); testWidgets('套餐副屏展开组成并区分套餐与单品', (tester) async { tester.view.physicalSize = const Size(1280, 720); tester.view.devicePixelRatio = 1; addTearDown(tester.view.resetPhysicalSize); addTearDown(tester.view.resetDevicePixelRatio); final coordinator = CustomerDisplayCoordinator(); addTearDown(coordinator.dispose); coordinator.handleAction('updateCard', _comboProductEvent()); await tester.pumpWidget( MaterialApp( debugShowCheckedModeBanner: false, home: CustomerDisplayPage(coordinator: coordinator), ), ); await tester.pump(); expect(find.text('套餐'), findsOneWidget); expect(find.text('单品'), findsOneWidget); expect(find.text('中餐A'), findsOneWidget); expect(find.text('蒜香黑虎虾'), findsOneWidget); expect(find.text('口蘑炒牛肉'), findsOneWidget); expect(find.text('清炒有机西兰花'), findsOneWidget); expect(find.byKey(const ValueKey('combo-details-中餐A')), findsOneWidget); expect(find.text('明细不单独计价'), findsOneWidget); expect(tester.takeException(), isNull); }); } class _PreviewNavigationHarness extends StatelessWidget { const _PreviewNavigationHarness(); @override Widget build(BuildContext context) { return MaterialApp( home: Builder( builder: (context) => Scaffold( body: Center( child: ElevatedButton( onPressed: () => Navigator.of(context).push( MaterialPageRoute( builder: (_) => const CustomerDisplayPreviewPage( arguments: {'scenario': 'paying'}, ), ), ), child: const Text('打开预览'), ), ), ), ), ); } } class _NestedPreviewNavigationHarness extends StatelessWidget { const _NestedPreviewNavigationHarness(); @override Widget build(BuildContext context) { return GetMaterialApp( home: Navigator( onGenerateRoute: (_) => MaterialPageRoute( builder: (innerContext) => _NestedSettingState( onPreview: () => Navigator.of( innerContext, rootNavigator: true, ).push( GetPageRoute( routeName: '/customer', settings: const RouteSettings( name: '/customer', arguments: {'scenario': 'review'}, ), page: () => const CustomerDisplayPreviewPage( arguments: {'scenario': 'review'}, ), transition: Transition.noTransition, transitionDuration: Duration.zero, ), ), ), ), ), ); } } class _NestedSettingState extends StatefulWidget { const _NestedSettingState({required this.onPreview}); final VoidCallback onPreview; @override State<_NestedSettingState> createState() => _NestedSettingStateState(); } class _NestedSettingStateState extends State<_NestedSettingState> { bool _selected = false; @override Widget build(BuildContext context) { return Scaffold( body: Column( children: [ TextButton( onPressed: () => setState(() => _selected = true), child: const Text('商品核对'), ), ElevatedButton( onPressed: widget.onPreview, child: const Text('全屏预览'), ), if (_selected) const Text('商品核对:已选中'), ], ), ); } } Map _comboProductEvent() { return { 'sysType': 'CANTEEN', 'payUser': null, 'totalPrice': 6400, 'amountMealPrice': 0, 'shopList': >[ { 'productName': '中餐A', 'productPrice': 5200, 'nature': 'DEFAULT', 'productNumber': 1, 'productWidget': 0, 'totalPrice': 5200, 'isCombo': true, 'comboItems': >[ {'name': '蒜香黑虎虾', 'quantity': 1}, {'name': '口蘑炒牛肉', 'quantity': 1}, {'name': '清炒有机西兰花', 'quantity': 1}, ], }, { 'productName': '例汤', 'productPrice': 1200, 'nature': 'DEFAULT', 'productNumber': 1, 'productWidget': 0, 'totalPrice': 1200, 'isCombo': false, }, ], }; }