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:image/image.dart' as img; import 'package:integration_test/integration_test.dart'; import 'package:jj_mkvmaker/app/i18n_controller.dart'; import 'package:jj_mkvmaker/ui/ai_upscale/upscale_compare.dart'; import 'package:jj_mkvmaker/ui/android_file_browser.dart'; import 'package:jj_mkvmaker/ui/theme.dart'; import 'package:path/path.dart' as p; import 'support/temp_dir.dart'; /// W JjTitleBar (관리자 10/24): 위 막대를 모을 때 캡처가 없던 곳을 찍는다 - AI 올리기 비교 (원본 · 올린 것 고르기) · /// 앱 안 폴더 고르기 (새 폴더 · 고르기 단추). 둘 다 넓은 단추가 있어 좁으면 제목 아래 줄로 간다. 412 · 960 × ko · ja (JJ_SHOT_DIR) void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); final out = Platform.environment['JJ_SHOT_DIR'] ?? p.join(Directory.systemTemp.path, 'jj_shots_titlebar'); 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 tmp = testFixedTempDir('jj_titlebar_fixed'); final a = p.join(tmp.path, 'a.png'), b = p.join(tmp.path, 'b.png'); File(a).writeAsBytesSync(img.encodePng(img.Image(width: 4, height: 4))); File(b).writeAsBytesSync(img.encodePng(img.Image(width: 16, height: 16))); Directory(p.join(tmp.path, '영상')).createSync(); Directory(p.join(tmp.path, '사진')).createSync(); pinTestTimes(tmp); final key = GlobalKey(); final nav = GlobalKey(); await t.pumpWidget(RepaintBoundary( key: key, child: MaterialApp( theme: buildTheme(), debugShowCheckedModeBanner: false, navigatorKey: nav, home: const Scaffold(body: SizedBox.expand())), )); Future settle() async { for (var i = 0; i < 8; i++) { await t.runAsync(() => Future.delayed(const Duration(milliseconds: 60))); await t.pump(const Duration(milliseconds: 100)); } } Future shot(String name) async { expect(t.takeException(), isNull, reason: '$name 넘침'); final r = key.currentContext!.findRenderObject()! as RenderRepaintBoundary; final im = await t.runAsync(() => r.toImage()); final bytes = await t.runAsync(() => im!.toByteData(format: ui.ImageByteFormat.png)); Directory(out).createSync(recursive: true); File(p.join(out, 'titlebar_${name}_${lang}_$w.png')).writeAsBytesSync(bytes!.buffer.asUint8List()); } // 1. AI 올리기 비교 final compare = nav.currentState!.push( MaterialPageRoute(builder: (_) => UpscaleCompareView(original: a, upscaled: b, title: 'IMG_0001 (4배) - 바다에서 찍은 사진.png'))); await settle(); await shot('upscale_compare'); nav.currentState!.pop(false); await settle(); await compare; // 2. 앱 안 폴더 고르기 final folder = showAndroidFolderBrowser(nav.currentContext!, title: '저장할 폴더', initialDirectory: tmp.path); await settle(); await shot('folder_browser'); nav.currentState!.pop(); await settle(); await folder; }); } } }