Files
biz_xfj_cloud/test/sub_screen/customer_display_widget_test.dart
T
dzc 8cfbbd768e feat:"收银"页面副屏的支付成功状态。
feat:"收银"弹框增加重新识别功能。
2026-08-14 18:41:13 +08:00

250 lines
8.2 KiB
Dart

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<void>(
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<void>(
builder: (innerContext) => _NestedSettingState(
onPreview: () => Navigator.of(
innerContext,
rootNavigator: true,
).push<void>(
GetPageRoute<void>(
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<String, dynamic> _comboProductEvent() {
return {
'sysType': 'CANTEEN',
'payUser': null,
'totalPrice': 6400,
'amountMealPrice': 0,
'shopList': <Map<String, dynamic>>[
{
'productName': '中餐A',
'productPrice': 5200,
'nature': 'DEFAULT',
'productNumber': 1,
'productWidget': 0,
'totalPrice': 5200,
'isCombo': true,
'comboItems': <Map<String, dynamic>>[
{'name': '蒜香黑虎虾', 'quantity': 1},
{'name': '口蘑炒牛肉', 'quantity': 1},
{'name': '清炒有机西兰花', 'quantity': 1},
],
},
{
'productName': '例汤',
'productPrice': 1200,
'nature': 'DEFAULT',
'productNumber': 1,
'productWidget': 0,
'totalPrice': 1200,
'isCombo': false,
},
],
};
}