Files
Client/tool/screenshots_ios.sh
T
MineTecandClaude Opus 5.5 c5592f117b 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>
2026-09-29 16:58:29 +02:00

123 lines
4.6 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
#
# App-Store-Screenshots über den Demo-Login aufnehmen – iOS-Gegenstück zu
# tool/screenshots.sh.
#
# Fährt denselben integration_test-Lauf (integration_test/screenshot_test.dart)
# per flutter drive auf je einem iOS-Simulator pro Formfaktor: iPhone 6,5″
# (iPhone 14 Plus, 1284×2778) und iPad 13″ (iPad Pro 13-inch, 2064×2752). Die
# Simulatoren liefern die Frames direkt in der Zielauflösung, eine
# Größenumstellung wie per `adb shell wm size` ist nicht nötig. Fehlt ein
# Simulator, wird er mit gleichnamigem Gerätetyp angelegt.
#
# Ablage:
# - kanonisch (versioniert): materials/screenshots/{ios/6-5-inch,ipados/13-inch}/
# - Kopie für den Upload: ios/fastlane/screenshots/de-DE/<profil>_<name>.jpg
# (deliver ordnet die Bilder anhand der Pixelgröße dem Gerät zu; das Präfix
# verhindert nur Namenskollisionen zwischen iPhone und iPad.)
# Danach: `cd ios && fastlane upload_screenshots`.
#
# Voraussetzungen:
# - Xcode mit iOS-Simulator-Runtime; Simulatoren (Namen per IPHONE_SIM/IPAD_SIM
# überschreibbar; Name = Gerätetyp aus `xcrun simctl list devicetypes`)
# - flutter im PATH
#
# Achtung: Pro Simulator werden App und Schlüsselbund zurückgesetzt, damit der
# Lauf garantiert mit dem Demo-Login startet und keine echte Sitzung zeigt.
# Deshalb eigene Simulatoren verwenden, nicht den für die Entwicklung.
#
# Aufruf (vom Client-Projektwurzelverzeichnis):
# tool/screenshots_ios.sh # debug-Build
# BUILD_MODE=profile tool/screenshots_ios.sh
# PROFILES="iphone" tool/screenshots_ios.sh # nur eine Größe
set -euo pipefail
cd "$(dirname "$0")/.."
BUILD_MODE="${BUILD_MODE:-debug}"
FASTLANE_DIR="ios/fastlane/screenshots/de-DE"
BUNDLE_ID="eu.mhsl.marianum.mobile.client"
IPHONE_SIM="${IPHONE_SIM:-iPhone 14 Plus}"
IPAD_SIM="${IPAD_SIM:-iPad Pro 13-inch (M5)}"
PROFILES="${PROFILES:-iphone ipad}"
# UDID des ersten verfügbaren Simulators mit exakt diesem Namen.
sim_udid() {
xcrun simctl list devices available -j |
/usr/bin/python3 -c '
import json, sys
name = sys.argv[1]
for devices in json.load(sys.stdin)["devices"].values():
for d in devices:
if d["name"] == name:
print(d["udid"]); sys.exit(0)
sys.exit(1)' "$1"
}
BOOTED_BY_US=()
cleanup() {
for udid in ${BOOTED_BY_US[@]+"${BOOTED_BY_US[@]}"}; do
xcrun simctl status_bar "$udid" clear >/dev/null 2>&1 || true
xcrun simctl shutdown "$udid" >/dev/null 2>&1 || true
done
}
trap cleanup EXIT
mkdir -p "$FASTLANE_DIR"
for profile in $PROFILES; do
case "$profile" in
iphone) sim="$IPHONE_SIM"; materials_dir="materials/screenshots/ios/6-5-inch" ;;
ipad) sim="$IPAD_SIM"; materials_dir="materials/screenshots/ipados/13-inch" ;;
*) echo "Unbekanntes Profil '$profile' (erlaubt: iphone ipad)" >&2; exit 1 ;;
esac
udid="$(sim_udid "$sim")" || {
echo "Simulator '$sim' fehlt, lege ihn an…"
udid="$(xcrun simctl create "$sim" "$sim")"
}
echo ""
echo "=== Profil '$profile' ($sim, $udid) -> $materials_dir ==="
mkdir -p "$materials_dir"
rm -f "$materials_dir"/*.png "$FASTLANE_DIR/${profile}_"*.jpg
if ! xcrun simctl list devices | grep -q "$udid) (Booted)"; then
xcrun simctl boot "$udid"
BOOTED_BY_US+=("$udid")
fi
xcrun simctl bootstatus "$udid" -b >/dev/null
# Apple-typische Statusleiste: 9:41, volles WLAN/Netz, Akku voll.
xcrun simctl status_bar "$udid" override \
--time "9:41" --dataNetwork wifi --wifiMode active --wifiBars 3 \
--cellularMode active --cellularBars 4 --operatorName "" \
--batteryState charged --batteryLevel 100
# Frische, ausgeloggte Sitzung: App löschen und Schlüsselbund leeren
# (flutter_secure_storage überlebt auf iOS eine Deinstallation).
xcrun simctl uninstall "$udid" "$BUNDLE_ID" >/dev/null 2>&1 || true
xcrun simctl keychain "$udid" reset >/dev/null 2>&1 || true
SCREENSHOT_OUT_DIR="$materials_dir" flutter drive \
-d "$udid" \
--driver=test_driver/integration_test.dart \
--target=integration_test/screenshot_test.dart \
--"$BUILD_MODE" \
--no-dds
# Kanonische Bilder mit Profil-Präfix in den Fastlane-Upload-Ordner spiegeln.
# Als JPEG, weil App Store Connect Screenshots mit Alpha-Kanal ablehnt und
# takeScreenshot RGBA-PNGs liefert.
for f in "$materials_dir"/*.png; do
sips -s format jpeg -s formatOptions best "$f" \
--out "$FASTLANE_DIR/${profile}_$(basename "${f%.png}").jpg" >/dev/null
done
echo "Profil '$profile' fertig: $(ls -1 "$materials_dir"/*.png 2>/dev/null | wc -l | tr -d ' ') Screenshots"
done
echo ""
echo "Kanonische Screenshots: materials/screenshots/{ios/6-5-inch,ipados/13-inch}/"
echo "Upload: cd ios && fastlane upload_screenshots"