160 lines
7.3 KiB
Dart
160 lines
7.3 KiB
Dart
// 화면 점검용 캡처 (일반 시험이 아니다). 폰 크기(360×800)로 주요 화면을 그려 test_ux/shots/*.png 로 남긴다.
|
||
// flutter test test_ux/shots_test.dart --update-goldens
|
||
import 'dart:io';
|
||
|
||
import 'package:flutter/material.dart';
|
||
import 'package:flutter/services.dart';
|
||
import 'package:flutter_test/flutter_test.dart';
|
||
import 'package:friendly_map/modules/app/app.dart';
|
||
import 'package:friendly_map/modules/core/core.dart';
|
||
import 'package:friendly_map/modules/platform/platform.dart';
|
||
import 'package:friendly_map/modules/storage/storage.dart';
|
||
import 'package:friendly_map/modules/transport/transport.dart';
|
||
import 'package:friendly_map/modules/ui/src/screens/chat_room_screen.dart';
|
||
import 'package:friendly_map/modules/ui/src/screens/contact_import_screen.dart';
|
||
import 'package:friendly_map/modules/ui/src/screens/group_detail_screen.dart';
|
||
import 'package:friendly_map/modules/ui/src/screens/person_screen.dart';
|
||
import 'package:friendly_map/modules/ui/src/screens/requests_screen.dart';
|
||
import 'package:friendly_map/modules/ui/src/screens/settings_screen.dart';
|
||
import 'package:friendly_map/modules/ui/ui.dart';
|
||
|
||
import '../test/support/app_device.dart';
|
||
import '../test/support/fake_cipher.dart';
|
||
import '../test/support/storage_contract.dart' show FakeProbe;
|
||
import '../test/widget_test.dart' show FakeBootstrap;
|
||
|
||
class _Contacts implements ContactsProvider {
|
||
@override
|
||
Future<bool> requestPermission() async => true;
|
||
@override
|
||
Future<List<DeviceContact>> all() async => const [
|
||
DeviceContact(id: '1', name: '김민수', phones: ['010-3333-4444'], labels: ['가족']),
|
||
DeviceContact(id: '2', name: '이영희', phones: ['010-5555-6666'], labels: ['고등학교 동창']),
|
||
DeviceContact(id: '3', name: '박철수', phones: ['010-7777-8888'], labels: ['회사']),
|
||
DeviceContact(id: '4', name: '최지은', phones: ['010-1212-3434']),
|
||
DeviceContact(id: '5', name: '정우성', phones: ['02-555-1234']),
|
||
];
|
||
}
|
||
|
||
Future<void> _font(String family, String path) async {
|
||
final bytes = File(path).readAsBytesSync();
|
||
await (FontLoader(family)..addFont(Future.value(ByteData.view(Uint8List.fromList(bytes).buffer)))).load();
|
||
}
|
||
|
||
void main() {
|
||
late AppDevice me, minsu;
|
||
late FriendlyApp app;
|
||
|
||
setUpAll(() async {
|
||
await _font('Roboto', 'build/ux/kr.ttf');
|
||
await _font('MaterialIcons', '/sdks/flutter/bin/cache/artifacts/material_fonts/MaterialIcons-Regular.otf');
|
||
});
|
||
|
||
Future<void> seed(WidgetTester tester) async {
|
||
await tester.runAsync(() async {
|
||
final hub = MemoryHub();
|
||
me = await AppDevice.create(hub, '010-1111-2222', '+821011112222', '이미영', contacts: _Contacts());
|
||
minsu = await AppDevice.create(hub, '010-3333-4444', '+821033334444', '김민수');
|
||
app = me.app;
|
||
await app.friends.add(minsu.phone, minsu.name);
|
||
await AppDevice.settleAll();
|
||
await minsu.app.friends.accept(me.phone);
|
||
await AppDevice.settleAll();
|
||
for (final (p, n) in [('+821055556666', '이영희'), ('+821077778888', '박철수'), ('+821012123434', '최지은')]) {
|
||
await app.friends.add(p, n);
|
||
}
|
||
final people = {for (final p in await app.friends.people()) p.name: p.id};
|
||
await app.relate.into(people['이영희']!, 'school.high');
|
||
final hb = (await app.groups.add('한빛전자', CardKinds.company, parent: CardKinds.company))!;
|
||
final team = (await app.groups.add('결제팀', CardKinds.company, parent: hb.id))!;
|
||
await app.relate.into(people['박철수']!, team.id);
|
||
await app.relate.into(people['김민수']!, team.id);
|
||
final room = (await app.chats.openDirect(people['김민수']!, CardKinds.personal))!;
|
||
await app.chats.send(room.id, '안녕하세요, 내일 회의 몇 시죠?');
|
||
await app.work.assign(room.id, '결제 API 정리', assigneeId: people['김민수'], due: DateTime(2026, 10, 30));
|
||
await app.work.urgent(room.id, '결제 서버가 멈췄어요');
|
||
// 김민수가 새 폰으로 다시 연결을 청함
|
||
final again = await AppDevice.create(hub, '010-3333-4444', '+821033334444', '김민수 새폰');
|
||
await again.app.friends.add(me.phone, '이미영');
|
||
await AppDevice.settleAll();
|
||
});
|
||
}
|
||
|
||
Future<void> open(WidgetTester tester) async {
|
||
tester.view.physicalSize = const Size(1080, 2400);
|
||
tester.view.devicePixelRatio = 3;
|
||
addTearDown(tester.view.reset);
|
||
await seed(tester);
|
||
await tester.pumpWidget(FriendlyMapApp(bootstrap: FakeBootstrap(keys: true, app: app)));
|
||
await tester.pumpAndSettle();
|
||
}
|
||
|
||
Future<void> shot(WidgetTester tester, String name) async {
|
||
await tester.runAsync(() => Future<void>.delayed(const Duration(milliseconds: 30)));
|
||
await tester.pumpAndSettle();
|
||
await expectLater(find.byType(MaterialApp), matchesGoldenFile('shots/$name.png'));
|
||
}
|
||
|
||
Future<void> push(WidgetTester tester, Widget page) async {
|
||
tester.state<NavigatorState>(find.byType(Navigator).first).push(MaterialPageRoute<void>(builder: (_) => page));
|
||
await tester.pumpAndSettle();
|
||
}
|
||
|
||
Future<void> tab(WidgetTester tester, String label) async {
|
||
await tester.tap(find.descendant(of: find.byType(NavigationBar), matching: find.text(label)));
|
||
await tester.pumpAndSettle();
|
||
}
|
||
|
||
testWidgets('처음 시작', (tester) async {
|
||
tester.view.physicalSize = const Size(1080, 2400);
|
||
tester.view.devicePixelRatio = 3;
|
||
addTearDown(tester.view.reset);
|
||
final fresh = FriendlyApp(AppDeps(storage: Storage.memory(), transport: MemoryTransport('+82100', MemoryHub()), cipher: FakeCipher('K'), identity: FakeIdentity('K'), probe: FakeProbe(10)));
|
||
await tester.pumpWidget(FriendlyMapApp(bootstrap: FakeBootstrap(app: fresh)));
|
||
await tester.pumpAndSettle();
|
||
await shot(tester, '00_onboarding');
|
||
});
|
||
|
||
testWidgets('아래 메뉴 다섯 칸', (tester) async {
|
||
await open(tester);
|
||
await shot(tester, '01_chats');
|
||
await tab(tester, '관계');
|
||
await shot(tester, '02_relations');
|
||
await tab(tester, '업무');
|
||
await shot(tester, '03_tasks');
|
||
await tab(tester, '명함');
|
||
await shot(tester, '04_cards');
|
||
await tab(tester, '나');
|
||
await shot(tester, '05_me');
|
||
});
|
||
|
||
testWidgets('요청 · 그룹 · 설정', (tester) async {
|
||
await open(tester);
|
||
await push(tester, const RequestsScreen());
|
||
await shot(tester, '10_requests');
|
||
await push(tester, const GroupDetailScreen(groupId: CardKinds.school));
|
||
await shot(tester, '11_group_school');
|
||
await push(tester, const GroupDetailScreen(groupId: CardKinds.company));
|
||
await shot(tester, '12_group_company');
|
||
await push(tester, const SettingsScreen());
|
||
await shot(tester, '13_settings');
|
||
});
|
||
|
||
testWidgets('주소록 · 사람 · 대화', (tester) async {
|
||
await open(tester);
|
||
await push(tester, const ContactImportScreen());
|
||
await shot(tester, '20_contacts');
|
||
final people = {for (final p in (await tester.runAsync(() => app.friends.people()))!) p.name: p.id};
|
||
await push(tester, PersonScreen(personId: people['김민수']!));
|
||
await shot(tester, '21_person');
|
||
await tester.tap(find.text('관계'));
|
||
await tester.pumpAndSettle();
|
||
await shot(tester, '22_relate');
|
||
await tester.tapAt(const Offset(10, 10));
|
||
await tester.pumpAndSettle();
|
||
final rooms = (await tester.runAsync(() => app.chats.summaries()))!;
|
||
await push(tester, ChatRoomScreen(roomId: rooms.first.room.id));
|
||
await shot(tester, '23_chat_room');
|
||
});
|
||
}
|