Skip to content

Commit d6905ce

Browse files
committed
Fingers crossed
1 parent 1a7feb5 commit d6905ce

File tree

1 file changed

+87
-105
lines changed

1 file changed

+87
-105
lines changed

scripts/run-ios-ui-tests.sh

Lines changed: 87 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
Absolutely—here’s a complete scripts/run-ios-ui-tests.sh that drops in as-is. It keeps your watchdog, artifacts, PR comment, screenshot decode, etc., but replaces the fragile runtime/device selection with a robust block that won’t abort under set -euo pipefail, and it uses the UDID we just created (no flaky “resolve by name” step). It also emits simulator listings into artifacts for debugging.
2+
13
#!/usr/bin/env bash
24
# Run Codename One iOS UI tests on the simulator and compare screenshots
35
set -euo pipefail
@@ -160,76 +162,96 @@ else
160162
ri_log "Scheme file not found for env injection: $SCHEME_FILE"
161163
fi
162164

163-
# --- begin: pick latest available iOS runtime + an iPhone device type (JSON-based) ---
165+
# --- begin: pick latest available iOS runtime + an iPhone device type (robust, non-fatal probing) ---
164166
require_cmd() { command -v "$1" >/dev/null 2>&1 || { ri_log "FATAL: '$1' not found"; exit 3; }; }
165167
require_cmd xcrun
166-
require_cmd python3
167168

168-
# Allow manual override from env if you want to pin a specific runtime/device on a given runner:
169-
# IOS_RUNTIME_ID="com.apple.CoreSimulator.SimRuntime.iOS-18-5"
170-
# IOS_DEVICE_TYPE="com.apple.CoreSimulator.SimDeviceType.iPhone-16"
171169
RUNTIME_ID="${IOS_RUNTIME_ID:-}"
172170
DEVICE_TYPE="${IOS_DEVICE_TYPE:-}"
171+
RUNTIMES_JSON=""; DEVICETYPES_JSON=""
173172

174-
if [ -z "$RUNTIME_ID" ]; then
175-
RUNTIME_ID="$(xcrun simctl list runtimes --json 2>/dev/null | python3 - <<'PY'
173+
# Don’t let set -e kill us while probing/parsing
174+
set +e
175+
176+
# Try JSON first (if python3 exists)
177+
if command -v python3 >/dev/null 2>&1; then
178+
RUNTIMES_JSON="$(xcrun simctl list runtimes --json 2>/dev/null || true)"
179+
DEVICETYPES_JSON="$(xcrun simctl list devicetypes --json 2>/dev/null || true)"
180+
if [ -z "$RUNTIME_ID" ] && [ -n "$RUNTIMES_JSON" ]; then
181+
RUNTIME_ID="$(printf '%s' "$RUNTIMES_JSON" | python3 - <<'PY' || true
176182
import json, sys
177-
try:
178-
data=json.load(sys.stdin)
179-
except Exception:
180-
sys.exit(1)
183+
try: data=json.load(sys.stdin)
184+
except: sys.exit(0)
181185
c=[]
182186
for r in data.get("runtimes", []):
183-
# Newer Xcodes use platform == "iOS"; older had name strings. Check both.
184187
plat = r.get("platform") or r.get("name","")
185188
if "iOS" not in str(plat): continue
186189
if not r.get("isAvailable", False): continue
187190
ident = r.get("identifier") or ""
188191
ver = r.get("version") or ""
189-
# Turn version into a sortable tuple
190192
parts=[]
191193
for p in str(ver).split("."):
192194
try: parts.append(int(p))
193195
except: parts.append(0)
194196
c.append((parts, ident))
195-
if not c:
196-
sys.exit(2)
197-
c.sort()
198-
print(c[-1][1])
197+
if c:
198+
c.sort()
199+
print(c[-1][1])
199200
PY
200-
)"
201-
fi
202-
203-
if [ -z "$RUNTIME_ID" ]; then
204-
ri_log "FATAL: No *available* iOS simulator runtime found on this runner"
205-
xcrun simctl list runtimes || true
206-
exit 3
207-
fi
208-
209-
if [ -z "$DEVICE_TYPE" ]; then
210-
DEVICE_TYPE="$(xcrun simctl list devicetypes --json 2>/dev/null | python3 - <<'PY'
201+
)"
202+
fi
203+
if [ -z "$DEVICE_TYPE" ] && [ -n "$DEVICETYPES_JSON" ]; then
204+
DEVICE_TYPE="$(printf '%s' "$DEVICETYPES_JSON" | python3 - <<'PY' || true
211205
import json, sys
212-
try:
213-
data=json.load(sys.stdin)
214-
except Exception:
215-
sys.exit(1)
216-
dts=data.get("devicetypes",[])
217-
# prefer newest iPhone names if present, else any iPhone, else first available
218-
prefs = ["iPhone 16 Pro Max","iPhone 16 Pro","iPhone 16","iPhone 15 Pro Max","iPhone 15 Pro","iPhone 15","iPhone"]
206+
try: d=json.load(sys.stdin)
207+
except: sys.exit(0)
208+
prefs = ["iPhone 16 Pro Max","iPhone 16 Pro","iPhone 16",
209+
"iPhone 15 Pro Max","iPhone 15 Pro","iPhone 15","iPhone"]
210+
dts = d.get("devicetypes", [])
219211
for pref in prefs:
220212
for dt in dts:
221213
if pref in (dt.get("name") or ""):
222214
print(dt.get("identifier","")); sys.exit(0)
223-
if dts:
224-
print(dts[0].get("identifier","")); sys.exit(0)
225-
sys.exit(2)
215+
for dt in dts:
216+
if "iPhone" in (dt.get("name") or ""):
217+
print(dt.get("identifier","")); sys.exit(0)
218+
if dts: print(dts[0].get("identifier",""))
226219
PY
227-
)"
220+
)"
221+
fi
222+
fi
223+
224+
# Fallback to text parsing if needed
225+
if [ -z "$RUNTIME_ID" ]; then
226+
RUNTIME_ID="$(xcrun simctl list runtimes 2>/dev/null | awk '
227+
$0 ~ /iOS/ && $0 ~ /(Available|installed)/ {
228+
id=$NF; gsub(/[()]/,"",id); last=id
229+
} END { if (last!="") print last }
230+
' || true)"
231+
fi
232+
if [ -z "$DEVICE_TYPE" ]; then
233+
DEVICE_TYPE="$(xcrun simctl list devicetypes 2>/dev/null | awk -F '[()]' '
234+
/iPhone/ && /identifier/ { print $2; found=1; exit }
235+
END { if (!found) print "" }
236+
' || true)"
228237
fi
229238

239+
set -e
240+
241+
# Emit debug to artifacts
242+
if [ -n "${ARTIFACTS_DIR:-}" ]; then
243+
printf '%s\n' "${RUNTIMES_JSON:-}" > "$ARTIFACTS_DIR/sim-runtimes.json" 2>/dev/null || true
244+
printf '%s\n' "${DEVICETYPES_JSON:-}" > "$ARTIFACTS_DIR/sim-devicetypes.json" 2>/dev/null || true
245+
xcrun simctl list runtimes > "$ARTIFACTS_DIR/sim-runtimes.txt" 2>&1 || true
246+
xcrun simctl list devicetypes > "$ARTIFACTS_DIR/sim-devicetypes.txt" 2>&1 || true
247+
fi
248+
249+
if [ -z "$RUNTIME_ID" ]; then
250+
ri_log "FATAL: No *available* iOS simulator runtime found on this runner"
251+
exit 3
252+
fi
230253
if [ -z "$DEVICE_TYPE" ]; then
231254
ri_log "FATAL: Could not determine an iPhone device type"
232-
xcrun simctl list devicetypes || true
233255
exit 3
234256
fi
235257

@@ -249,7 +271,7 @@ if ! xcrun simctl bootstatus "$SIM_UDID" -b -t 180; then
249271
fi
250272
ri_log "Simulator booted: $SIM_UDID"
251273
SIM_DESTINATION="id=$SIM_UDID"
252-
# --- end: pick latest available iOS runtime + an iPhone device type (JSON-based) ---
274+
# --- end: pick latest available iOS runtime + an iPhone device type (robust, non-fatal probing) ---
253275

254276
ri_log "Running UI tests on destination '$SIM_DESTINATION'"
255277

@@ -286,7 +308,7 @@ if [ -n "$AUT_APP" ] && [ -d "$AUT_APP" ]; then
286308
export CN1_AUT_BUNDLE_ID="$AUT_BUNDLE_ID"
287309
ri_log "Exported CN1_AUT_BUNDLE_ID=$AUT_BUNDLE_ID"
288310
# Inject AUT bundle id into the scheme, if a placeholder exists
289-
if [ -f "$SCHEME_FILE" ] && [ -n "$AUT_BUNDLE_ID" ]; then
311+
if [ -f "$SCHEME_FILE" ]; then
290312
if sed --version >/dev/null 2>&1; then
291313
sed -i -e "s|__CN1_AUT_BUNDLE_ID__|$AUT_BUNDLE_ID|g" "$SCHEME_FILE"
292314
else
@@ -296,64 +318,27 @@ if [ -n "$AUT_APP" ] && [ -d "$AUT_APP" ]; then
296318
fi
297319
fi
298320

299-
# Resolve a UDID for the chosen destination name (no regex groups to keep BSD awk happy)
300-
SIM_NAME="$(printf '%s\n' "$SIM_DESTINATION" | sed -n 's/.*name=\([^,]*\).*/\1/p')"
301-
SIM_UDID="$(
302-
xcrun simctl list devices available 2>/dev/null | \
303-
awk -v name="$SIM_NAME" '
304-
# Match a line that contains the selected device name followed by " ("
305-
index($0, name" (") && index($0, "[") {
306-
ud=$0
307-
sub(/^.*\[/,"",ud) # drop everything up to and including the first '['
308-
sub(/\].*$/,"",ud) # drop everything after the closing ']'
309-
if (length(ud)>0) { print ud; exit }
310-
}'
311-
)"
312-
313-
ri_log "Simulator devices (available):"
314-
xcrun simctl list devices available || true
315-
316-
if [ -n "$SIM_UDID" ]; then
317-
ri_log "Boot status for $SIM_UDID:"
318-
xcrun simctl bootstatus "$SIM_UDID" -b || true
319-
320-
ri_log "Processes in simulator:"
321-
xcrun simctl spawn "$SIM_UDID" launchctl print system | head -n 200 || true
322-
fi
323-
324-
if [ -n "$SIM_UDID" ]; then
325-
xcrun simctl bootstatus "$SIM_UDID" -b || xcrun simctl boot "$SIM_UDID"
326-
xcrun simctl install "$SIM_UDID" "$AUT_APP" || true
327-
if [ -n "$AUT_BUNDLE_ID" ]; then
328-
ri_log "Warm-launching $AUT_BUNDLE_ID"
329-
xcrun simctl terminate "$SIM_UDID" "$AUT_BUNDLE_ID" >/dev/null 2>&1 || true
330-
xcrun simctl launch "$SIM_UDID" "$AUT_BUNDLE_ID" --args -AppleLocale en_US -AppleLanguages "(en)" || true
331-
xcrun simctl io "$SIM_UDID" screenshot "$ARTIFACTS_DIR/pre-xctest.png" || true
332-
fi
333-
334-
# Start syslog capture for this simulator
335-
SIM_SYSLOG="$ARTIFACTS_DIR/simulator-syslog.txt"
336-
ri_log "Capturing simulator syslog at $SIM_SYSLOG"
337-
( xcrun simctl spawn "$SIM_UDID" log stream --style syslog --level debug \
338-
|| xcrun simctl spawn "$SIM_UDID" log stream --style compact ) > "$SIM_SYSLOG" 2>&1 &
339-
SYSLOG_PID=$!
340-
341-
# Start video recording
342-
RUN_VIDEO="$ARTIFACTS_DIR/run.mp4"
343-
ri_log "Recording simulator video to $RUN_VIDEO"
344-
( xcrun simctl io "$SIM_UDID" recordVideo "$RUN_VIDEO" & echo $! > "$SCREENSHOT_TMP_DIR/video.pid" ) || true
345-
VIDEO_PID="$(cat "$SCREENSHOT_TMP_DIR/video.pid" 2>/dev/null || true)"
346-
347-
if [ -n "$AUT_BUNDLE_ID" ] && [ -n "$SIM_UDID" ]; then
348-
ri_log "Warm-launching $AUT_BUNDLE_ID"
349-
xcrun simctl terminate "$SIM_UDID" "$AUT_BUNDLE_ID" >/dev/null 2>&1 || true
350-
LAUNCH_OUT="$(xcrun simctl launch "$SIM_UDID" "$AUT_BUNDLE_ID" --args -AppleLocale en_US -AppleLanguages "(en)" 2>&1 || true)"
351-
ri_log "simctl launch output: $LAUNCH_OUT"
352-
ri_log "Simulator screenshot (pre-XCTest)"
353-
xcrun simctl io "$SIM_UDID" screenshot "$ARTIFACTS_DIR/pre-xctest.png" || true
354-
fi
355-
else
356-
ri_log "WARN: Could not resolve simulator UDID for '$SIM_NAME'; skipping warm launch"
321+
# Start syslog capture for this simulator
322+
SIM_SYSLOG="$ARTIFACTS_DIR/simulator-syslog.txt"
323+
ri_log "Capturing simulator syslog at $SIM_SYSLOG"
324+
( xcrun simctl spawn "$SIM_UDID" log stream --style syslog --level debug \
325+
|| xcrun simctl spawn "$SIM_UDID" log stream --style compact ) > "$SIM_SYSLOG" 2>&1 &
326+
SYSLOG_PID=$!
327+
328+
# Start video recording
329+
RUN_VIDEO="$ARTIFACTS_DIR/run.mp4"
330+
ri_log "Recording simulator video to $RUN_VIDEO"
331+
( xcrun simctl io "$SIM_UDID" recordVideo "$RUN_VIDEO" & echo $! > "$SCREENSHOT_TMP_DIR/video.pid" ) || true
332+
VIDEO_PID="$(cat "$SCREENSHOT_TMP_DIR/video.pid" 2>/dev/null || true)"
333+
334+
# Warm-launch for pre-XCTest telemetry
335+
if [ -n "${AUT_BUNDLE_ID:-}" ]; then
336+
ri_log "Warm-launching $AUT_BUNDLE_ID"
337+
xcrun simctl terminate "$SIM_UDID" "$AUT_BUNDLE_ID" >/dev/null 2>&1 || true
338+
LAUNCH_OUT="$(xcrun simctl launch "$SIM_UDID" "$AUT_BUNDLE_ID" --args -AppleLocale en_US -AppleLanguages "(en)" 2>&1 || true)"
339+
ri_log "simctl launch output: $LAUNCH_OUT"
340+
ri_log "Simulator screenshot (pre-XCTest)"
341+
xcrun simctl io "$SIM_UDID" screenshot "$ARTIFACTS_DIR/pre-xctest.png" || true
357342
fi
358343
fi
359344

@@ -409,10 +394,8 @@ else
409394
fi
410395
# --- End: xcresult JSON export ---
411396

412-
413-
414397
ri_log "Final simulator screenshot"
415-
xcrun simctl io booted screenshot "$ARTIFACTS_DIR/final.png" || true
398+
xcrun simctl io "$SIM_UDID" screenshot "$ARTIFACTS_DIR/final.png" || true
416399
# --- End: Stop video + final screenshots ---
417400

418401
set +o pipefail
@@ -572,5 +555,4 @@ if ! cn1ss_post_pr_comment "$COMMENT_FILE" "$SCREENSHOT_PREVIEW_DIR"; then
572555
comment_rc=$?
573556
fi
574557

575-
exit $comment_rc
576-
558+
exit $comment_rc

0 commit comments

Comments
 (0)