228 lines
7.2 KiB
Dart
228 lines
7.2 KiB
Dart
import 'package:ducafe_ui_core/ducafe_ui_core.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:forui/forui.dart';
|
|
import 'package:get/get.dart';
|
|
|
|
import 'package:pj_supermarket_cloud/common/index.dart';
|
|
|
|
/// 注册终端设备弹框在多档横屏尺寸和放大主题下的布局回归测试。
|
|
void main() {
|
|
setUp(AppDeviceStatusTool.resetForTest);
|
|
|
|
for (final viewportSize in const [
|
|
Size(800, 450),
|
|
Size(800, 600),
|
|
Size(1280, 720),
|
|
]) {
|
|
testWidgets(
|
|
'${viewportSize.width.toInt()}x${viewportSize.height.toInt()}大字号下设备弹框无布局溢出',
|
|
(tester) async {
|
|
tester.view.devicePixelRatio = 1;
|
|
tester.view.physicalSize = viewportSize;
|
|
addTearDown(tester.view.reset);
|
|
final adminSession = Get.put(TerminalAdminSessionControl());
|
|
Get.put(
|
|
TerminalDeviceStatusControl(
|
|
loadHiddenDevices: () async => <TerminalDeviceType>{},
|
|
saveHiddenDevices: (_) async {},
|
|
),
|
|
);
|
|
adminSession.unlock();
|
|
|
|
await tester.pumpWidget(_terminalDeviceStatusTestApp());
|
|
await tester.pump();
|
|
expect(
|
|
MediaQuery.sizeOf(tester.element(find.byType(Scaffold))),
|
|
viewportSize,
|
|
);
|
|
await tester.tap(
|
|
find.byKey(const ValueKey('terminal-device-status-group')),
|
|
);
|
|
await tester.pumpAndSettle();
|
|
|
|
expect(
|
|
find.byKey(const ValueKey('terminal-device-status-dialog')),
|
|
findsOneWidget,
|
|
);
|
|
expect(
|
|
find.byKey(const ValueKey('terminal-device-status-table')),
|
|
findsOneWidget,
|
|
);
|
|
for (final device in TerminalDeviceType.values) {
|
|
expect(
|
|
find.byKey(
|
|
ValueKey('terminal-device-status-visibility-${device.code}'),
|
|
),
|
|
findsOneWidget,
|
|
);
|
|
}
|
|
expect(
|
|
find.byKey(const ValueKey('terminal-device-status-row-打印机')),
|
|
findsOneWidget,
|
|
);
|
|
for (final deviceName in const ['打印机', '电子秤', '读卡器', '副屏', '摄像头']) {
|
|
expect(
|
|
find.byKey(ValueKey('terminal-device-status-row-$deviceName')),
|
|
findsOneWidget,
|
|
);
|
|
}
|
|
final printerBottom = tester
|
|
.getBottomLeft(
|
|
find.byKey(const ValueKey('terminal-device-status-row-打印机')),
|
|
)
|
|
.dy;
|
|
final scaleTop = tester
|
|
.getTopLeft(
|
|
find.byKey(const ValueKey('terminal-device-status-row-电子秤')),
|
|
)
|
|
.dy;
|
|
expect(
|
|
scaleTop - printerBottom,
|
|
inInclusiveRange(5, 9),
|
|
reason: '设备行之间应保留适中的 6-8dp 间距,既可分组又不恢复成松散大卡片',
|
|
);
|
|
final printerRow =
|
|
find.byKey(const ValueKey('terminal-device-status-row-打印机'));
|
|
final printerRowSize = tester.getSize(printerRow);
|
|
expect(
|
|
printerRowSize.height,
|
|
greaterThanOrEqualTo(68),
|
|
reason: '设备行需要提供足够的阅读高度,不能再次压缩成过薄表格',
|
|
);
|
|
final printerLabel = tester.widget<Text>(
|
|
find.descendant(of: printerRow, matching: find.text('打印机')).first,
|
|
);
|
|
expect(
|
|
printerLabel.style?.fontSize,
|
|
greaterThanOrEqualTo(16),
|
|
reason: '设备名称必须保持实体终端可连续识别的字号',
|
|
);
|
|
final printerStatusWidth = tester
|
|
.getSize(
|
|
find.byKey(
|
|
const ValueKey('terminal-device-status-label-打印机'),
|
|
),
|
|
)
|
|
.width;
|
|
expect(
|
|
printerStatusWidth,
|
|
lessThan(printerRowSize.width * 0.25),
|
|
reason: '运行状态应按图标和文案自然宽度展示,不能铺满整列形成色条',
|
|
);
|
|
final tableHeight = tester
|
|
.getSize(
|
|
find.byKey(const ValueKey('terminal-device-status-table')),
|
|
)
|
|
.height;
|
|
expect(
|
|
tableHeight,
|
|
greaterThanOrEqualTo(400),
|
|
reason: '设备表需要恢复可读行高和行距,不能集中挤在弹框顶部',
|
|
);
|
|
final layoutException = tester.takeException();
|
|
await tester.tap(
|
|
find.byKey(const ValueKey('terminal-device-status-close-icon')),
|
|
);
|
|
await tester.pumpAndSettle();
|
|
adminSession.lock();
|
|
await tester.pumpWidget(const SizedBox.shrink());
|
|
await tester.pump();
|
|
Get.reset();
|
|
expect(layoutException, isNull);
|
|
});
|
|
}
|
|
|
|
testWidgets('设备状态弹框开关只隐藏对应顶部设备并保存完整集合', (tester) async {
|
|
tester.view.devicePixelRatio = 1;
|
|
tester.view.physicalSize = const Size(1280, 720);
|
|
addTearDown(tester.view.reset);
|
|
final adminSession = Get.put(TerminalAdminSessionControl());
|
|
final saved = <Set<TerminalDeviceType>>[];
|
|
final visibilityControl = Get.put(
|
|
TerminalDeviceStatusControl(
|
|
loadHiddenDevices: () async => <TerminalDeviceType>{},
|
|
saveHiddenDevices: (hiddenDevices) async =>
|
|
saved.add(Set<TerminalDeviceType>.from(hiddenDevices)),
|
|
),
|
|
);
|
|
adminSession.unlock();
|
|
|
|
await tester.pumpWidget(_terminalDeviceStatusTestApp());
|
|
await tester.tap(
|
|
find.byKey(const ValueKey('terminal-device-status-group')),
|
|
);
|
|
await tester.pumpAndSettle();
|
|
await tester.tap(
|
|
find.byKey(
|
|
const ValueKey('terminal-device-status-visibility-printer'),
|
|
),
|
|
);
|
|
await tester.pump();
|
|
|
|
expect(
|
|
visibilityControl.isHeaderDeviceVisible(TerminalDeviceType.printer),
|
|
isFalse,
|
|
);
|
|
expect(
|
|
visibilityControl.isHeaderDeviceVisible(TerminalDeviceType.camera),
|
|
isTrue,
|
|
);
|
|
expect(saved, [
|
|
<TerminalDeviceType>{TerminalDeviceType.printer}
|
|
]);
|
|
expect(
|
|
find.byKey(const ValueKey('terminal-status-打印机-missing')),
|
|
findsNothing,
|
|
);
|
|
expect(
|
|
find.byKey(const ValueKey('terminal-status-摄像头-missing')),
|
|
findsOneWidget,
|
|
);
|
|
expect(
|
|
find.byKey(const ValueKey('terminal-device-status-row-打印机')),
|
|
findsOneWidget,
|
|
reason: '隐藏顶部图标后详情行仍需保留,用户才能在弹框内重新开启',
|
|
);
|
|
expect(
|
|
tester
|
|
.widget<FSwitch>(
|
|
find.byKey(
|
|
const ValueKey('terminal-device-status-visibility-printer'),
|
|
),
|
|
)
|
|
.value,
|
|
isFalse,
|
|
);
|
|
|
|
adminSession.lock();
|
|
await tester.pumpWidget(const SizedBox.shrink());
|
|
await tester.pump();
|
|
Get.reset();
|
|
});
|
|
}
|
|
|
|
/// 构建与真机问题一致的横屏、大字号主题环境,用于捕获弹框运行时布局溢出。
|
|
Widget _terminalDeviceStatusTestApp() {
|
|
final baseTheme = FThemes.zinc.light;
|
|
final terminalTheme = FThemeData.inherit(
|
|
colorScheme: baseTheme.colorScheme,
|
|
typography: baseTheme.typography.scale(sizeScalar: 1.4),
|
|
style: baseTheme.style,
|
|
);
|
|
return ScreenUtilInit(
|
|
designSize: const Size(1920, 1080),
|
|
minTextAdapt: true,
|
|
splitScreenMode: true,
|
|
builder: (_, __) => MaterialApp(
|
|
builder: (_, child) => FTheme(data: terminalTheme, child: child!),
|
|
home: const Scaffold(
|
|
body: Align(
|
|
alignment: Alignment.topRight,
|
|
child: TerminalDeviceStatus(),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|