@@ -160,76 +160,96 @@ else
160160 ri_log " Scheme file not found for env injection: $SCHEME_FILE "
161161fi
162162
163- # --- begin: pick latest available iOS runtime + an iPhone device type (JSON-based ) ---
163+ # --- begin: pick latest available iOS runtime + an iPhone device type (robust, non-fatal probing ) ---
164164require_cmd () { command -v " $1 " > /dev/null 2>&1 || { ri_log " FATAL: '$1 ' not found" ; exit 3; }; }
165165require_cmd xcrun
166- require_cmd python3
167166
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"
171167RUNTIME_ID=" ${IOS_RUNTIME_ID:- } "
172168DEVICE_TYPE=" ${IOS_DEVICE_TYPE:- } "
169+ RUNTIMES_JSON=" " ; DEVICETYPES_JSON=" "
173170
174- if [ -z " $RUNTIME_ID " ]; then
175- RUNTIME_ID=" $( xcrun simctl list runtimes --json 2> /dev/null | python3 - << 'PY '
171+ # Don’t let set -e kill us while probing/parsing
172+ set +e
173+
174+ # Try JSON first (if python3 exists)
175+ if command -v python3 > /dev/null 2>&1 ; then
176+ RUNTIMES_JSON=" $( xcrun simctl list runtimes --json 2> /dev/null || true) "
177+ DEVICETYPES_JSON=" $( xcrun simctl list devicetypes --json 2> /dev/null || true) "
178+ if [ -z " $RUNTIME_ID " ] && [ -n " $RUNTIMES_JSON " ]; then
179+ RUNTIME_ID=" $( printf ' %s' " $RUNTIMES_JSON " | python3 - << 'PY ' || true
176180import json, sys
177- try:
178- data=json.load(sys.stdin)
179- except Exception:
180- sys.exit(1)
181+ try: data=json.load(sys.stdin)
182+ except: sys.exit(0)
181183c=[]
182184for r in data.get("runtimes", []):
183- # Newer Xcodes use platform == "iOS"; older had name strings. Check both.
184185 plat = r.get("platform") or r.get("name","")
185186 if "iOS" not in str(plat): continue
186187 if not r.get("isAvailable", False): continue
187188 ident = r.get("identifier") or ""
188189 ver = r.get("version") or ""
189- # Turn version into a sortable tuple
190190 parts=[]
191191 for p in str(ver).split("."):
192192 try: parts.append(int(p))
193193 except: parts.append(0)
194194 c.append((parts, ident))
195- if not c:
196- sys.exit(2)
197- c.sort()
198- print(c[-1][1])
195+ if c:
196+ c.sort()
197+ print(c[-1][1])
199198PY
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 '
199+ ) "
200+ fi
201+ if [ -z " $DEVICE_TYPE " ] && [ -n " $DEVICETYPES_JSON " ]; then
202+ DEVICE_TYPE=" $( printf ' %s' " $DEVICETYPES_JSON " | python3 - << 'PY ' || true
211203import 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"]
204+ try: d=json.load(sys.stdin)
205+ except: sys.exit(0)
206+ prefs = ["iPhone 16 Pro Max","iPhone 16 Pro","iPhone 16",
207+ "iPhone 15 Pro Max","iPhone 15 Pro","iPhone 15","iPhone"]
208+ dts = d.get("devicetypes", [])
219209for pref in prefs:
220210 for dt in dts:
221211 if pref in (dt.get("name") or ""):
222212 print(dt.get("identifier","")); sys.exit(0)
223- if dts:
224- print(dts[0].get("identifier","")); sys.exit(0)
225- sys.exit(2)
213+ for dt in dts:
214+ if "iPhone" in (dt.get("name") or ""):
215+ print(dt.get("identifier","")); sys.exit(0)
216+ if dts: print(dts[0].get("identifier",""))
226217PY
227- ) "
218+ ) "
219+ fi
228220fi
229221
222+ # Fallback to text parsing if needed
223+ if [ -z " $RUNTIME_ID " ]; then
224+ RUNTIME_ID=" $( xcrun simctl list runtimes 2> /dev/null | awk '
225+ $0 ~ /iOS/ && $0 ~ /(Available|installed)/ {
226+ id=$NF; gsub(/[()]/,"",id); last=id
227+ } END { if (last!="") print last }
228+ ' || true) "
229+ fi
230+ if [ -z " $DEVICE_TYPE " ]; then
231+ DEVICE_TYPE=" $( xcrun simctl list devicetypes 2> /dev/null | awk -F ' [()]' '
232+ /iPhone/ && /identifier/ { print $2; found=1; exit }
233+ END { if (!found) print "" }
234+ ' || true) "
235+ fi
236+
237+ set -e
238+
239+ # Emit debug to artifacts
240+ if [ -n " ${ARTIFACTS_DIR:- } " ]; then
241+ printf ' %s\n' " ${RUNTIMES_JSON:- } " > " $ARTIFACTS_DIR /sim-runtimes.json" 2> /dev/null || true
242+ printf ' %s\n' " ${DEVICETYPES_JSON:- } " > " $ARTIFACTS_DIR /sim-devicetypes.json" 2> /dev/null || true
243+ xcrun simctl list runtimes > " $ARTIFACTS_DIR /sim-runtimes.txt" 2>&1 || true
244+ xcrun simctl list devicetypes > " $ARTIFACTS_DIR /sim-devicetypes.txt" 2>&1 || true
245+ fi
246+
247+ if [ -z " $RUNTIME_ID " ]; then
248+ ri_log " FATAL: No *available* iOS simulator runtime found on this runner"
249+ exit 3
250+ fi
230251if [ -z " $DEVICE_TYPE " ]; then
231252 ri_log " FATAL: Could not determine an iPhone device type"
232- xcrun simctl list devicetypes || true
233253 exit 3
234254fi
235255
@@ -249,7 +269,7 @@ if ! xcrun simctl bootstatus "$SIM_UDID" -b -t 180; then
249269fi
250270ri_log " Simulator booted: $SIM_UDID "
251271SIM_DESTINATION=" id=$SIM_UDID "
252- # --- end: pick latest available iOS runtime + an iPhone device type (JSON-based ) ---
272+ # --- end: pick latest available iOS runtime + an iPhone device type (robust, non-fatal probing ) ---
253273
254274ri_log " Running UI tests on destination '$SIM_DESTINATION '"
255275
@@ -286,7 +306,7 @@ if [ -n "$AUT_APP" ] && [ -d "$AUT_APP" ]; then
286306 export CN1_AUT_BUNDLE_ID=" $AUT_BUNDLE_ID "
287307 ri_log " Exported CN1_AUT_BUNDLE_ID=$AUT_BUNDLE_ID "
288308 # Inject AUT bundle id into the scheme, if a placeholder exists
289- if [ -f " $SCHEME_FILE " ] && [ -n " $AUT_BUNDLE_ID " ] ; then
309+ if [ -f " $SCHEME_FILE " ]; then
290310 if sed --version > /dev/null 2>&1 ; then
291311 sed -i -e " s|__CN1_AUT_BUNDLE_ID__|$AUT_BUNDLE_ID |g" " $SCHEME_FILE "
292312 else
@@ -296,64 +316,27 @@ if [ -n "$AUT_APP" ] && [ -d "$AUT_APP" ]; then
296316 fi
297317 fi
298318
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"
319+ # Start syslog capture for this simulator
320+ SIM_SYSLOG=" $ARTIFACTS_DIR /simulator-syslog.txt"
321+ ri_log " Capturing simulator syslog at $SIM_SYSLOG "
322+ ( xcrun simctl spawn " $SIM_UDID " log stream --style syslog --level debug \
323+ || xcrun simctl spawn " $SIM_UDID " log stream --style compact ) > " $SIM_SYSLOG " 2>&1 &
324+ SYSLOG_PID=$!
325+
326+ # Start video recording
327+ RUN_VIDEO=" $ARTIFACTS_DIR /run.mp4"
328+ ri_log " Recording simulator video to $RUN_VIDEO "
329+ ( xcrun simctl io " $SIM_UDID " recordVideo " $RUN_VIDEO " & echo $! > " $SCREENSHOT_TMP_DIR /video.pid" ) || true
330+ VIDEO_PID=" $( cat " $SCREENSHOT_TMP_DIR /video.pid" 2> /dev/null || true) "
331+
332+ # Warm-launch for pre-XCTest telemetry
333+ if [ -n " ${AUT_BUNDLE_ID:- } " ]; then
334+ ri_log " Warm-launching $AUT_BUNDLE_ID "
335+ xcrun simctl terminate " $SIM_UDID " " $AUT_BUNDLE_ID " > /dev/null 2>&1 || true
336+ LAUNCH_OUT=" $( xcrun simctl launch " $SIM_UDID " " $AUT_BUNDLE_ID " --args -AppleLocale en_US -AppleLanguages " (en)" 2>&1 || true) "
337+ ri_log " simctl launch output: $LAUNCH_OUT "
338+ ri_log " Simulator screenshot (pre-XCTest)"
339+ xcrun simctl io " $SIM_UDID " screenshot " $ARTIFACTS_DIR /pre-xctest.png" || true
357340 fi
358341fi
359342
@@ -409,10 +392,8 @@ else
409392fi
410393# --- End: xcresult JSON export ---
411394
412-
413-
414395ri_log " Final simulator screenshot"
415- xcrun simctl io booted screenshot " $ARTIFACTS_DIR /final.png" || true
396+ xcrun simctl io " $SIM_UDID " screenshot " $ARTIFACTS_DIR /final.png" || true
416397# --- End: Stop video + final screenshots ---
417398
418399set +o pipefail
@@ -572,5 +553,4 @@ if ! cn1ss_post_pr_comment "$COMMENT_FILE" "$SCREENSHOT_PREVIEW_DIR"; then
572553 comment_rc=$?
573554fi
574555
575- exit $comment_rc
576-
556+ exit $comment_rc
0 commit comments