Skip to content

Commit 178c605

Browse files
committed
feat(mobile): pipeline screenshot store (Maestro + CI macOS + compositing)
- Flow Maestro screenshots.yaml: login demo -> 5 schermate (dashboard, timeline, documenti, domande medico, self-care) - Workflow GitHub Actions store-screenshots (runner macos-15): simulator iPhone 16 Pro Max 6.9pollici, build EAS profilo store-screenshots (ios.simulator), lingua IT forzata, artifact PNG raw - eas.json: profilo store-screenshots (APP_VARIANT=preview -> bundle id app.accanto.mobile.preview) - Script PS store-screenshots.ps1: capture-android (adb), compose-ios (canvas 1320x2868/1284x2778), frames marketing (System.Drawing, frames.config.json per locale) - Script PS seed-demo-account.ps1: popola account demo via API (cerchio Famiglia Rossi, timeline, domande, documenti PDF) + estensione deadline 2FA via psql (reviewer Apple senza 2FA) - Script bash delete-circle.sh: hard delete transazionale cerchio demo (dry-run di default) - VS Code tasks per la pipeline; docs store/screenshots aggiornate
1 parent 0fa4e57 commit 178c605

12 files changed

Lines changed: 1207 additions & 23 deletions

File tree

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
name: store-screenshots
2+
3+
# Genera gli screenshot App Store iOS su un runner macOS (non serve un Mac locale).
4+
# Esecuzione manuale: Actions → store-screenshots → Run workflow.
5+
# Gli artifact `ios-raw-screenshots` vanno scaricati in
6+
# mobile/store/screenshots/_raw/ios/ e poi composti con:
7+
# pwsh mobile/scripts/store-screenshots.ps1 -Mode compose-ios
8+
#
9+
# Prerequisiti (una tantum):
10+
# - secret EAS_TOKEN (expo.dev → account → access tokens)
11+
# - variabili/secret MAESTRO_EMAIL + MAESTRO_PASSWORD di un account demo
12+
# con dati pre-popolati (cerchio "Famiglia Rossi", timeline, documenti...)
13+
14+
on:
15+
workflow_dispatch:
16+
17+
jobs:
18+
ios-screenshots:
19+
runs-on: macos-15
20+
defaults:
21+
run:
22+
working-directory: mobile
23+
env:
24+
EXPO_TOKEN: ${{ secrets.EAS_TOKEN }}
25+
# Il profilo store-screenshots (eas.json) usa APP_VARIANT=preview ->
26+
# bundle id app.accanto.mobile.preview (vedi app.config.ts resolveVariant).
27+
MAESTRO_APP_ID: app.accanto.mobile.preview
28+
MAESTRO_EMAIL: ${{ secrets.MAESTRO_EMAIL }}
29+
MAESTRO_PASSWORD: ${{ secrets.MAESTRO_PASSWORD }}
30+
steps:
31+
- uses: actions/checkout@v4
32+
33+
- uses: actions/setup-node@v4
34+
with:
35+
node-version: 20
36+
cache: npm
37+
cache-dependency-path: mobile/package-lock.json
38+
39+
- name: Install dependencies
40+
run: npm ci
41+
42+
- name: Install Maestro
43+
run: curl -Ls https://get.maestro.mobile.dev | bash
44+
# Maestro CLI si installa in $HOME/.maestro/bin
45+
46+
- name: Boot iPhone 16 Pro Max simulator (6.9")
47+
run: |
48+
UDID=$(xcrun simctl create "store-shot" "iPhone 16 Pro Max" 2>/dev/null || true)
49+
if [ -z "$UDID" ]; then
50+
# fallback se il device type non e' disponibile sull'immagine
51+
UDID=$(xcrun simctl create "store-shot" "iPhone 15 Pro Max")
52+
fi
53+
echo "SIM_UDID=$UDID" >> "$GITHUB_ENV"
54+
xcrun simctl boot "$UDID"
55+
xcrun simctl bootstatus "$UDID" -b
56+
57+
# Il flow Maestro naviga per testi VISIBILI in italiano ("Il tuo spazio",
58+
# "Diario", ...). Il simulator su runner macOS parte in inglese: senza
59+
# questo step l'app userebbe EN (se l'account demo non ha lingua salvata)
60+
# e le asserzioni fallirebbero. Forza IT a livello di simulator.
61+
- name: Set simulator language to Italian
62+
run: |
63+
xcrun simctl spawn "$SIM_UDID" defaults write "Apple Global Domain" AppleLanguages -array it
64+
xcrun simctl spawn "$SIM_UDID" defaults write "Apple Global Domain" AppleLocale -string it_IT
65+
66+
- name: Build iOS app (simulator profile) on EAS
67+
run: npx eas-cli build --platform ios --profile store-screenshots --non-interactive --wait --local 2>&1 | tee eas-build.log
68+
# Profilo `store-screenshots` (eas.json): ios.simulator=true -> produce
69+
# un .app installabile sul simulator. --local compila sul runner
70+
# (Xcode presente su macos-15), nessuna attesa della coda EAS remota.
71+
72+
- name: Install app on simulator
73+
run: |
74+
APP=$(find . -name "*.app" -maxdepth 3 | head -n1)
75+
if [ -z "$APP" ]; then
76+
TAR=$(find . -name "*.tar.gz" -maxdepth 2 | head -n1)
77+
tar -xzf "$TAR" -C /tmp/app
78+
APP=$(find /tmp/app -name "*.app" | head -n1)
79+
fi
80+
xcrun simctl install "$SIM_UDID" "$APP"
81+
82+
- name: Run Maestro screenshot flow
83+
run: |
84+
export PATH="$HOME/.maestro/bin:$PATH"
85+
maestro test --output store/screenshots/_raw/ios .maestro/screenshots.yaml
86+
87+
- name: Flatten raw screenshots
88+
run: |
89+
# maestro salva in una sottocartella con timestamp: sposta i PNG in _raw/ios
90+
find store/screenshots/_raw/ios -name "*.png" -exec mv {} store/screenshots/_raw/ios/ \;
91+
ls -la store/screenshots/_raw/ios
92+
93+
- uses: actions/upload-artifact@v4
94+
with:
95+
name: ios-raw-screenshots
96+
path: mobile/store/screenshots/_raw/ios/*.png
97+
retention-days: 30

.gitignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@ Thumbs.db
44

55
# IDE
66
.vs/
7-
.vscode/
7+
# Escludiamo .vscode/ ma NON i task condivisi (pipeline screenshot store, ecc.).
8+
# Serve de-escludere sia la cartella sia il file: git non ri-includes un file
9+
# se la sua directory parent e' ignorata.
10+
.vscode/*
11+
!.vscode/tasks.json
812
.idea/
913
*.user
1014
*.suo

.vscode/tasks.json

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
{
2+
"version": "2.0.0",
3+
"tasks": [
4+
{
5+
"label": "Store screenshots: Android (capture)",
6+
"type": "shell",
7+
"command": "pwsh",
8+
"args": [
9+
"-NoProfile",
10+
"-File",
11+
"${workspaceFolder}/mobile/scripts/store-screenshots.ps1",
12+
"-Mode",
13+
"capture-android"
14+
],
15+
"options": {
16+
"cwd": "${workspaceFolder}/mobile"
17+
},
18+
"problemMatcher": [],
19+
"presentation": {
20+
"reveal": "always",
21+
"panel": "dedicated"
22+
},
23+
"detail": "Cattura le 5 schermate dall'emulatore Android attivo via adb (guidata, premi INVIO per schermata)."
24+
},
25+
{
26+
"label": "Store screenshots: iOS (compose canvas)",
27+
"type": "shell",
28+
"command": "pwsh",
29+
"args": [
30+
"-NoProfile",
31+
"-File",
32+
"${workspaceFolder}/mobile/scripts/store-screenshots.ps1",
33+
"-Mode",
34+
"compose-ios"
35+
],
36+
"options": {
37+
"cwd": "${workspaceFolder}/mobile"
38+
},
39+
"problemMatcher": [],
40+
"presentation": {
41+
"reveal": "always",
42+
"panel": "dedicated"
43+
},
44+
"detail": "Composizione canvas App Store (1320x2868 + 1284x2778) dai PNG raw in store/screenshots/_raw/ios (artifact del workflow store-screenshots)."
45+
},
46+
{
47+
"label": "Store screenshots: marketing frames (all locales)",
48+
"type": "shell",
49+
"command": "pwsh",
50+
"args": [
51+
"-NoProfile",
52+
"-File",
53+
"${workspaceFolder}/mobile/scripts/store-screenshots.ps1",
54+
"-Mode",
55+
"frames",
56+
"-Locales",
57+
"it-IT,en-US,es-ES"
58+
],
59+
"options": {
60+
"cwd": "${workspaceFolder}/mobile"
61+
},
62+
"problemMatcher": [],
63+
"presentation": {
64+
"reveal": "always",
65+
"panel": "dedicated"
66+
},
67+
"detail": "Compositore frame marketing (sfondo brand + titolo/sottotitolo + screenshot arrotondato) per tutte le locali in frames.config.json."
68+
},
69+
{
70+
"label": "Store screenshots: Maestro flow (Android emulator)",
71+
"type": "shell",
72+
"command": "maestro",
73+
"args": [
74+
"test",
75+
".maestro/screenshots.yaml"
76+
],
77+
"options": {
78+
"cwd": "${workspaceFolder}/mobile"
79+
},
80+
"problemMatcher": [],
81+
"presentation": {
82+
"reveal": "always",
83+
"panel": "dedicated"
84+
},
85+
"detail": "Cattura automatica delle 5 schermate con Maestro sull'emulatore attivo (richiede MAESTRO_APP_ID/EMAIL/PASSWORD in env)."
86+
}
87+
]
88+
}

mobile/.maestro/screenshots.yaml

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# Screenshot flow: login con account demo → cattura le 5 schermate store.
2+
#
3+
# Uso locale (Android emulator):
4+
# $env:MAESTRO_APP_ID = "app.accanto.mobile.preview" # dipende dalla build installata (.dev/.preview/prod)
5+
# $env:MAESTRO_EMAIL = "demo@accanto.care" # account con dati demo pre-popolati
6+
# $env:MAESTRO_PASSWORD = "***"
7+
# maestro test .maestro/screenshots.yaml
8+
# Gli screenshot finiscono in ~/.maestro/tests/ (vedi `maestro test --output`).
9+
#
10+
# Uso in CI (iOS simulator, vedi .github/workflows/store-screenshots.yml):
11+
# maestro test --output screenshots/raw .maestro/screenshots.yaml
12+
#
13+
# N.B.: i nomi file prodotti da takeScreenshot sono quelli qui sotto; gli
14+
# script in scripts/store/ li raccolgono e li rinominano/ridimensionano
15+
# secondo le specifiche in store/screenshots/README.md.
16+
appId: ${MAESTRO_APP_ID}
17+
env:
18+
EMAIL: ${MAESTRO_EMAIL}
19+
PASSWORD: ${MAESTRO_PASSWORD}
20+
---
21+
- launchApp:
22+
clearState: true
23+
24+
# ---- Login (riusa gli id di login.yaml) ---------------------------------
25+
- assertVisible:
26+
id: "login-email"
27+
- tapOn:
28+
id: "login-email"
29+
- inputText: ${EMAIL}
30+
- tapOn:
31+
id: "login-password"
32+
- inputText: ${PASSWORD}
33+
- tapOn:
34+
id: "login-submit"
35+
36+
# Attende che RootNavigator switchi su AppStack e mostri la dashboard.
37+
- extendedWaitUntil:
38+
visible: "Il tuo spazio"
39+
timeout: 15000
40+
41+
# ---- 01 · Dashboard -------------------------------------------------------
42+
- takeScreenshot: 01-dashboard
43+
44+
# ---- 02 · Timeline (dentro il primo cerchio) -----------------------------
45+
# Il primo cerchio attivo della dashboard: tap sulla card (testo = nome
46+
# cerchio dell'account demo). Se il nome cambia, aggiorna anche qui.
47+
- tapOn: "Famiglia Rossi"
48+
- extendedWaitUntil:
49+
visible: "Diario"
50+
timeout: 10000
51+
- takeScreenshot: 02-timeline
52+
53+
# ---- 03 · Documents -------------------------------------------------------
54+
- tapOn: "Documenti"
55+
- takeScreenshot: 03-documents
56+
57+
# ---- 04 · DoctorQuestions -------------------------------------------------
58+
- tapOn: "Domande"
59+
- takeScreenshot: 04-doctor-questions
60+
61+
# ---- 05 · SelfCare (dal drawer) ------------------------------------------
62+
# Torna alla dashboard e apri il drawer dall'hamburger ("Apri menu").
63+
- back
64+
- back
65+
- tapOn: "Apri menu"
66+
- tapOn: "Prenditi cura di te"
67+
- extendedWaitUntil:
68+
visible: "Cura di te"
69+
timeout: 10000
70+
- takeScreenshot: 05-self-care

mobile/eas.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,22 @@
3939
"buildType": "apk"
4040
}
4141
},
42+
"store-screenshots": {
43+
"distribution": "internal",
44+
"channel": "preview",
45+
"env": {
46+
"EXPO_PUBLIC_API_BASE_URL": "https://api.staging.accanto.care",
47+
"EXPO_PUBLIC_WEB_BASE_URL": "https://staging.accanto.care",
48+
"APP_VARIANT": "preview"
49+
},
50+
"ios": {
51+
"simulator": true
52+
},
53+
"android": {
54+
"buildType": "apk",
55+
"gradleCommand": ":app:assembleRelease"
56+
}
57+
},
4258
"production": {
4359
"channel": "production",
4460
"autoIncrement": true,

0 commit comments

Comments
 (0)