added automated App Store screenshots via iOS simulators and fastlane deliver

tool/screenshots_ios.sh runs the existing demo-login integration test on
iPhone 6.5" (iPhone 14 Plus) and iPad 13" simulators, stores the canonical PNGs
under materials/screenshots and mirrors alpha-free JPEGs to
ios/fastlane/screenshots for `fastlane upload_screenshots`.

Fixed the demo router answering timetable/custom-events with a week, which
crashed the inline iOS widget refresh after a demo login. The screenshot test
now skips the one-time Talk notification dialog and waits longer for the app
shell on cold simulators.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-29 16:58:29 +02:00
co-authored by Claude Opus 5.5
parent ada4d6a77c
commit c5592f117b
38 changed files with 241 additions and 2 deletions
+21 -2
View File
@@ -17,7 +17,8 @@ import 'package:marianum_mobile/view/pages/talk/widgets/chat_tile.dart';
/// Stundenplan (hell + dunkel), Talk-Liste, Talk-Chat, Dateien, „Mehr"-Bereich
/// und Einstellungen. Ausgeführt über `flutter drive` mit
/// test_driver/integration_test.dart, orchestriert von tool/screenshots.sh
/// (Phone / 7″ / 10″).
/// (Android: Phone / 7″ / 10″) bzw. tool/screenshots_ios.sh (iPhone 6,5″ /
/// iPad 13″).
///
/// Kein Netzwerk: der Demo-Modus beantwortet allen Backend-Verkehr aus
/// Fixtures, daher ist der Lauf deterministisch.
@@ -42,11 +43,13 @@ Future<void> main() async {
_log('Login');
await _login(tester);
// Großzügig: auf einem frisch angelegten iOS-Simulator dauert der erste
// Post-Login-Aufbau deutlich länger als 20s.
_log('warte auf App-Shell');
await _pumpUntil(
tester,
find.byType(App),
timeout: const Duration(seconds: 20),
timeout: const Duration(seconds: 60),
);
_log('warte auf Post-Login-Splash-Ende');
await _pumpUntilGone(
@@ -64,6 +67,12 @@ Future<void> main() async {
await binding.convertFlutterSurfaceToImage();
}
// Den einmaligen Benachrichtigungs-Dialog beim ersten Talk-Besuch
// unterdrücken. Auf Android erteilt tool/screenshots.sh die Permission
// vorab, auf iOS lässt sie sich im Simulator nicht vorab erteilen – der
// Dialog würde sonst über der Talk-Liste liegen.
_markTalkPermissionPromptShown(tester);
// 1 + 2: Stundenplan in beiden Themes.
await _goTo(tester, Modules.timetable);
_setTheme(tester, ThemeMode.light);
@@ -129,6 +138,16 @@ void _setTheme(WidgetTester tester, ThemeMode mode) {
context.read<SettingsCubit>().val(write: true).appTheme = mode;
}
void _markTalkPermissionPromptShown(WidgetTester tester) {
final context = tester.element(find.byType(App));
context
.read<SettingsCubit>()
.val(write: true)
.notificationSettings
.talkPermissionPromptShown =
true;
}
/// Navigiert zu [module] – über den Bottom-Tab, wenn er in der Leiste liegt,
/// sonst als Vollbild-Push. Größenunabhängig, da die Tab-Anzahl je Gerät variiert.
Future<void> _goTo(WidgetTester tester, Modules module) async {