Skip to content

Simulator: launch and terminate natively (simctl), not through XCTest - #138

Merged
ayman3000 merged 1 commit into
mainfrom
sim-native-lifecycle
Oct 10, 2026
Merged

ayman3000 merged 1 commit into
mainfrom
sim-native-lifecycle

Conversation

@ayman3000

Copy link
Copy Markdown
Owner

Root cause (from the hung driver session's own log, 2026-10-10): the app wasn't installed on the device, and XCUIApplication.launch() doesn't fail fast — it records the failure, then waits for accessibility (120 s), takes a spindump, then waits for idle: ~4 minutes inside one request. The driver serves requests serially, so its health checks hung, the host replaced the driver (3× in 10 min) and resent the launch.

Fix:

  • SimLifecycle (host, CoreSimulator via simctl): installed check (get_app_container, ~0.3 s), terminate, launch (instant; pid or reason). SimClient.launch/terminate use it; not_installed / launch_failed errors name the next step. The driver only attaches to the running app for UI work.
  • Transport-failure resend after a driver relaunch only when the request never reached the driver or is idempotent (a timed-out tap is not repeated).

Verified: unit tests (lifecycle: not installed fails at once with no HTTP; terminate-first order; simctl failure message; resend policy). Live: SAK_LIVE_TESTS=1 SAK_SIM_TESTS=1 SimLiveTests 4/4 pass on iOS 26.1 with native launch (driver reads/finds/taps/navigates an app it didn't launch). Manual: installed probe 0.2–0.3 s; launch of Quakely instant. Full swift test green.

🤖 Generated with Claude Code

Root cause of the 2026-10-10 hangs, from the driver's own log: the app was
not installed on the device, and XCUIApplication.launch() does not fail
fast — it records the failure, then waits for accessibility (120 s), takes
a spindump and waits for idle: 4 minutes inside one request. The driver
serves requests one at a time, so its health checks hung too and the host
replaced it, then resent the launch.

Lifecycle now runs on the host through CoreSimulator: an installed check
(simctl get_app_container, ~0.3 s), terminate, launch (instant, returns
the pid or the reason). The driver only attaches to the running app for UI
work — the live suite (Settings: launch, find, tap, navigate) passes that
way. A transport failure is resent after a driver relaunch only when the
request never reached the driver or is safe to repeat (a timed-out tap
must not tap twice).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@ayman3000
ayman3000 merged commit 0acc546 into main Oct 10, 2026
1 check passed
@ayman3000
ayman3000 deleted the sim-native-lifecycle branch October 10, 2026 19:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant