@@ -16,6 +16,7 @@ import { repairBudgetAvailable } from '../domain/reusable-action.js';
1616import { snapshotEnvelopeFailed } from './device-batch.js' ;
1717import { resolveBundleId } from '../project-config.js' ;
1818import { isAgentDeviceRunnerSentinel } from './runner-leak-recovery.js' ;
19+ import { stopFastRunner } from '../fast-runner-session.js' ;
1920const execFile = promisify ( execFileCb ) ;
2021/**
2122 * GH #105 / B153: bring the target app to foreground BEFORE taking the
@@ -24,12 +25,31 @@ const execFile = promisify(execFileCb);
2425 * no testIDs of its own. That yields the misleading "snapshot returned 0
2526 * testIDs" failure on a perfectly healthy app.
2627 *
28+ * **Live-smoke-test discovery (GH #105 follow-up):** `simctl launch` alone
29+ * loses the focus race when the agent-device fast-runner (spawned by the
30+ * prior `maestro_run`) is still alive — `XCUIApplication.activate()` inside
31+ * the runner re-foregrounds the runner before the snapshot lands. The fix
32+ * is to `stopFastRunner()` FIRST so there's nothing competing for focus,
33+ * THEN `simctl launch` the test-app. The next `runAgentDevice(snapshot)`
34+ * will lazily re-spawn the fast-runner, which is fine because by then
35+ * agent-device knows which bundle to attach to (it inherits the foreground
36+ * app's XCUIApplication).
37+ *
2738 * Best-effort: silent failure means we still fall through to the snapshot,
2839 * which can still detect the runner-leak sentinel and surface a useful
2940 * error. iOS uses `simctl launch booted <bundleId>`; Android uses `am start`
3041 * via adb.
3142 */
3243async function bringTargetAppToForeground ( platform , bundleId ) {
44+ // Kill the fast-runner FIRST so it can't re-grab focus the moment we
45+ // simctl-launch the test-app. Equivalent step exists in cdp_restart
46+ // hardReset (PR #161); this is its single-tool counterpart inside the
47+ // repair path so users don't have to call cdp_restart manually after
48+ // a SELECTOR_NOT_FOUND.
49+ try {
50+ stopFastRunner ( ) ;
51+ }
52+ catch { /* best-effort — fast-runner may already be dead */ }
3353 try {
3454 if ( platform === 'android' ) {
3555 await execFile ( 'adb' , [ 'shell' , 'monkey' , '-p' , bundleId , '-c' , 'android.intent.category.LAUNCHER' , '1' ] , { timeout : 5000 , encoding : 'utf8' } ) ;
0 commit comments