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>
123 lines
4.6 KiB
Bash
Executable File
123 lines
4.6 KiB
Bash
Executable File
#!/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"
|