JJ_MKVMaker/integration_test/field_places_shot_test.dart

76 lines
3.4 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import 'dart:io';
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:jj_mkvmaker/app/i18n_controller.dart';
import 'package:jj_mkvmaker/ui/explorer/marks_bar.dart' show PatternDialog;
import 'package:jj_mkvmaker/ui/schedule_editor.dart';
import 'package:jj_mkvmaker/ui/theme.dart';
import 'package:path/path.dart' as p;
/// W JjField (관리자 10/24): 글 칸을 모을 때 캡처가 없던 곳을 찍는다 - 패턴으로 고르기 창 · 동기화 일정 창 (cron 글 칸의 도움 글).
/// 412 · 960 × ko · ja. 모으기 전 판과 뒤 판을 같은 이름으로 찍어 견준다 (JJ_SHOT_DIR)
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
// 글 칸 커서가 깜빡여 캡처가 실행마다 달라지지 않게 (시험 쪽에서만)
EditableText.debugDeterministicCursor = true;
final out = Platform.environment['JJ_SHOT_DIR'] ?? p.join(Directory.systemTemp.path, 'jj_shots_field');
for (final (w, h) in [(412, 900), (960, 700)]) {
for (final lang in ['ko', 'ja']) {
testWidgets('글 칸 자리 $lang ${w}x$h', (t) async {
t.view.physicalSize = Size(w.toDouble(), h.toDouble());
t.view.devicePixelRatio = 1;
addTearDown(t.view.reset);
await t.runAsync(() => i18n.apply(lang, save: false));
addTearDown(() => i18n.apply('ko', save: false));
final key = GlobalKey();
final nav = GlobalKey<NavigatorState>();
await t.pumpWidget(RepaintBoundary(
key: key,
child: MaterialApp(
theme: buildTheme(), debugShowCheckedModeBanner: false, navigatorKey: nav, home: const Scaffold(body: SizedBox.expand())),
));
Future<void> settle() async {
for (var i = 0; i < 6; i++) {
await t.runAsync(() => Future<void>.delayed(const Duration(milliseconds: 40)));
await t.pump(const Duration(milliseconds: 100));
}
}
Future<void> shot(String name) async {
expect(t.takeException(), isNull, reason: '$name 넘침');
final b = key.currentContext!.findRenderObject()! as RenderRepaintBoundary;
final img = await t.runAsync(() => b.toImage());
final bytes = await t.runAsync(() => img!.toByteData(format: ui.ImageByteFormat.png));
Directory(out).createSync(recursive: true);
File(p.join(out, 'field_${name}_${lang}_$w.png')).writeAsBytesSync(bytes!.buffer.asUint8List());
}
// 1. 패턴으로 고르기
final pattern = showDialog<String>(context: nav.currentContext!, builder: (_) => const PatternDialog());
await settle();
await shot('pattern');
Navigator.of(nav.currentContext!).pop();
await settle();
await pattern;
// 2. 동기화 일정 (시간 지정 - cron 글 칸과 도움 글이 보이게)
final schedule = editSchedule(nav.currentContext!, const ['0 9-17 * * 1-5']);
await settle();
final scroll = find.byType(Scrollable).last;
await t.scrollUntilVisible(find.byIcon(Icons.check), 200, scrollable: scroll);
await settle();
await shot('schedule');
Navigator.of(nav.currentContext!).pop();
await settle();
await schedule;
});
}
}
}