@aarwitz/tapp 0.16.5 → 0.17.0-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -19,7 +19,7 @@ PROJECT_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
19
19
  # accidentally reuse stale markers). TAPP_HOME redirects all writable output otherwise —
20
20
  # set by the `tapp` CLI when running as an installed npm package, where the package dir
21
21
  # must stay read-only. Unset (repo dev flow), everything lands in the repo as before.
22
- TAPP_RUNTIME_HOME="${TAPP_HOME:-${AUTOTAP_HOME:-}}"
22
+ TAPP_RUNTIME_HOME="${TAPP_HOME:-}"
23
23
  if [[ -n "${TAPP_CAPTURE_DIR:-}" ]]; then
24
24
  CAPTURE_DIR="$TAPP_CAPTURE_DIR"
25
25
  elif [[ -n "$TAPP_RUNTIME_HOME" ]]; then
@@ -262,58 +262,92 @@ case "$MODE" in
262
262
  echo "Running autonomous exploration ($MAX_ACTIONS actions, timeout: ${EXPLORE_TIMEOUT}s, app: $APP_BUNDLE)..."
263
263
  ensure_harness_built "$SIM_NAME"
264
264
 
265
- # Start video recording in background
266
- cleanup_stale_recorders "$UDID"
267
- RECORD_PID=""
268
- if xcrun simctl io "$UDID" recordVideo --codec=h264 "$CAPTURE_DIR/exploration.mov" & then
269
- RECORD_PID=$!
270
- fi
271
- sleep 0.5
272
- if ! kill -0 "$RECORD_PID" 2>/dev/null; then
273
- echo "WARNING: Could not start simulator video recording. Continuing without video." >&2
274
- RECORD_PID=""
265
+ # XCUITest can block inside `app.launch()` until the outer watchdog when the target dies in its
266
+ # initializer, producing a misleading timeout after minutes. For an ordinary unconfigured
267
+ # launch, probe the target directly first and verify that the returned PID survives a short
268
+ # settle window. (Configured launch args/env skip this probe because simctl would not reproduce
269
+ # that launch contract.) The harness still performs its own fresh launch for healthy apps.
270
+ PREFLIGHT_CRASH=0
271
+ PREFLIGHT_OUTPUT=""
272
+ if [[ -z "${OCQA_APP_LAUNCH_ARGS_JSON:-}" && -z "${OCQA_APP_LAUNCH_ENV_JSON:-}" ]]; then
273
+ xcrun simctl terminate "$UDID" "$APP_BUNDLE" >/dev/null 2>&1 || true
274
+ PREFLIGHT_OUTPUT="$(xcrun simctl launch "$UDID" "$APP_BUNDLE" 2>&1 || true)"
275
+ PREFLIGHT_PID="$(echo "$PREFLIGHT_OUTPUT" | sed -n 's/.*: \([0-9][0-9]*\)$/\1/p' | tail -1)"
276
+ if [[ -n "$PREFLIGHT_PID" ]]; then
277
+ sleep 2
278
+ if ! kill -0 "$PREFLIGHT_PID" 2>/dev/null; then PREFLIGHT_CRASH=1; fi
279
+ fi
280
+ xcrun simctl terminate "$UDID" "$APP_BUNDLE" >/dev/null 2>&1 || true
275
281
  fi
276
282
 
277
- # Run exploration with watchdog timeout to avoid silent hangs.
278
283
  local_output_file="$CAPTURE_DIR/harness-output.txt"
279
- run_harness_test "testAutonomousExploration" "$SIM_NAME" "$APP_BUNDLE" "$MAX_ACTIONS" "$EXPLORE_TIMEOUT" > "$local_output_file" 2>&1 &
280
- HARNESS_PID=$!
281
-
282
- START_TS=$(date +%s)
283
284
  TIMED_OUT=0
284
- while kill -0 "$HARNESS_PID" 2>/dev/null; do
285
- NOW_TS=$(date +%s)
286
- ELAPSED=$((NOW_TS - START_TS))
287
- if [[ "$ELAPSED" -ge "$EXPLORE_TIMEOUT" ]]; then
288
- TIMED_OUT=1
289
- kill -TERM "$HARNESS_PID" 2>/dev/null || true
290
- sleep 2
291
- kill -KILL "$HARNESS_PID" 2>/dev/null || true
292
- break
285
+ RECORD_PID=""
286
+ if [[ "$PREFLIGHT_CRASH" -eq 1 ]]; then
287
+ OUTPUT="OCQA_ISSUE:{\"type\":\"crash\",\"severity\":\"critical\",\"title\":\"App crashed during launch preflight\",\"screen\":\"Launch\",\"step\":0}
288
+ OCQA_COMPLETE:{\"actions\":0,\"states\":0,\"issues\":1,\"screens\":\"\",\"outcome\":\"launch_crash\"}"
289
+ printf '%s\n%s\n' "$PREFLIGHT_OUTPUT" "$OUTPUT" > "$local_output_file"
290
+ echo "WARNING: Target process exited during launch preflight; recorded a crash instead of waiting for the exploration timeout." >&2
291
+ else
292
+
293
+ # Start video recording in background
294
+ cleanup_stale_recorders "$UDID"
295
+ if xcrun simctl io "$UDID" recordVideo --codec=h264 "$CAPTURE_DIR/exploration.mov" & then
296
+ RECORD_PID=$!
297
+ fi
298
+ sleep 0.5
299
+ if ! kill -0 "$RECORD_PID" 2>/dev/null; then
300
+ echo "WARNING: Could not start simulator video recording. Continuing without video." >&2
301
+ RECORD_PID=""
293
302
  fi
294
- sleep 2
295
- done
296
303
 
297
- wait "$HARNESS_PID" 2>/dev/null || true
298
- OUTPUT="$(cat "$local_output_file" 2>/dev/null || true)"
304
+ # Run exploration with watchdog timeout to avoid silent hangs.
305
+ run_harness_test "testAutonomousExploration" "$SIM_NAME" "$APP_BUNDLE" "$MAX_ACTIONS" "$EXPLORE_TIMEOUT" > "$local_output_file" 2>&1 &
306
+ HARNESS_PID=$!
307
+
308
+ START_TS=$(date +%s)
309
+ while kill -0 "$HARNESS_PID" 2>/dev/null; do
310
+ NOW_TS=$(date +%s)
311
+ ELAPSED=$((NOW_TS - START_TS))
312
+ if [[ "$ELAPSED" -ge "$EXPLORE_TIMEOUT" ]]; then
313
+ TIMED_OUT=1
314
+ kill -TERM "$HARNESS_PID" 2>/dev/null || true
315
+ sleep 2
316
+ kill -KILL "$HARNESS_PID" 2>/dev/null || true
317
+ break
318
+ fi
319
+ sleep 2
320
+ done
321
+
322
+ wait "$HARNESS_PID" 2>/dev/null || true
323
+ OUTPUT="$(cat "$local_output_file" 2>/dev/null || true)"
299
324
 
300
- # Stop recording
301
- if [[ -n "$RECORD_PID" ]]; then
302
- kill -INT "$RECORD_PID" 2>/dev/null || true
303
- wait "$RECORD_PID" 2>/dev/null || true
325
+ # Stop recording
326
+ if [[ -n "$RECORD_PID" ]]; then
327
+ kill -INT "$RECORD_PID" 2>/dev/null || true
328
+ wait "$RECORD_PID" 2>/dev/null || true
329
+ fi
330
+ sleep 1
304
331
  fi
305
- sleep 1
306
332
 
307
333
  # Parse OCQA_ markers
308
334
  echo "$OUTPUT" | grep "^OCQA_" > "$CAPTURE_DIR/ocqa-markers.txt" || true
309
335
  if [[ "$TIMED_OUT" -eq 1 ]]; then
310
- echo "OCQA_ISSUE:{\"type\":\"explore_timeout\",\"severity\":\"high\",\"title\":\"Exploration timed out\",\"timeoutSeconds\":$EXPLORE_TIMEOUT}" >> "$CAPTURE_DIR/ocqa-markers.txt"
311
- echo "OCQA_COMPLETE:{\"actions\":0,\"states\":0,\"issues\":1,\"screens\":\"\",\"timedOut\":true,\"timeoutSeconds\":$EXPLORE_TIMEOUT}" >> "$CAPTURE_DIR/ocqa-markers.txt"
312
- echo "WARNING: Exploration hit timeout after ${EXPLORE_TIMEOUT}s" >&2
336
+ # The caller's wall-clock budget expiring means the evidence is partial; it is not proof that
337
+ # the app itself is slow or hung. Preserve observed coverage in the terminal marker and let
338
+ # report.js classify the run as inconclusive instead of inventing an app finding.
339
+ TIMED_ACTIONS="$(echo "$OUTPUT" | sed -n 's/^OCQA_PROGRESS:{"action":\([0-9][0-9]*\).*/\1/p' | tail -1)"
340
+ TIMED_STATES="$(echo "$OUTPUT" | sed -n 's/^OCQA_PROGRESS:.*"states":\([0-9][0-9]*\).*/\1/p' | tail -1)"
341
+ TIMED_ISSUES="$(echo "$OUTPUT" | grep -c '^OCQA_ISSUE:' || true)"
342
+ TIMED_ACTIONS="${TIMED_ACTIONS:-0}"
343
+ TIMED_STATES="${TIMED_STATES:-0}"
344
+ TIMED_ISSUES="${TIMED_ISSUES:-0}"
345
+ echo "OCQA_COMPLETE:{\"actions\":$TIMED_ACTIONS,\"states\":$TIMED_STATES,\"issues\":$TIMED_ISSUES,\"screens\":\"\",\"timedOut\":true,\"timeoutSeconds\":$EXPLORE_TIMEOUT}" >> "$CAPTURE_DIR/ocqa-markers.txt"
346
+ echo "WARNING: Exploration reached its ${EXPLORE_TIMEOUT}s time budget; evidence is partial" >&2
313
347
  fi
314
348
  echo "$OUTPUT" > "$CAPTURE_DIR/full-output.txt"
315
349
 
316
- COMPLETE_LINE=$(echo "$OUTPUT" | grep "OCQA_COMPLETE" | tail -1)
350
+ COMPLETE_LINE=$(grep "OCQA_COMPLETE" "$CAPTURE_DIR/ocqa-markers.txt" | tail -1 || true)
317
351
  if [[ -n "$COMPLETE_LINE" ]]; then
318
352
  echo ""
319
353
  echo "Exploration complete: $COMPLETE_LINE"
@@ -26,7 +26,7 @@ UDID="$(xcrun simctl list devices booted -j 2>/dev/null | python3 -c 'import sys
26
26
  [ -z "$UDID" ] && { echo "❌ No booted simulator."; exit 2; }
27
27
  # When run through the installed `tapp` CLI, the harness cache lives under TAPP_HOME.
28
28
  XCTR=""
29
- TAPP_RUNTIME_HOME="${TAPP_HOME:-${AUTOTAP_HOME:-}}"
29
+ TAPP_RUNTIME_HOME="${TAPP_HOME:-}"
30
30
  [ -n "$TAPP_RUNTIME_HOME" ] && XCTR="$(find "$TAPP_RUNTIME_HOME/harness-derived/Build/Products" -name '*.xctestrun' 2>/dev/null | head -1)"
31
31
  [ -z "$XCTR" ] && XCTR="$(find "$HOME/Library/Developer/Xcode/DerivedData/OCQAHarness-"*/Build/Products -name '*.xctestrun' 2>/dev/null | head -1)"
32
32
  [ -z "$XCTR" ] && XCTR="$(find /tmp/tapp-harness-derived/Build/Products -name '*.xctestrun' 2>/dev/null | head -1)"