Skip to content

Commit 0eea123

Browse files
abueideclaude
andcommitted
fix(rn): separate emulator launch from readiness verification
Split emulator/simulator processes into launch and verify steps to fix deployment when devices are already running. Problem: When an emulator/simulator was already running, deploy tasks failed because they depended on launch process health, but the launch process would exit immediately if device was already up. Solution: - launch-emulator/launch-simulator: Checks if device is running, starts if needed, then exits (may skip if already running) - verify-emulator-ready/verify-simulator-ready: Always runs, waits for device to be ready regardless of how it started - Deploy tasks now depend on verify-*-ready instead of launch health This enables iteration in dev mode where devices persist between test runs. Changes: - test-suite-android-e2e.yaml: Split android-emulator into launch + verify - test-suite-ios-e2e.yaml: Split ios-simulator into launch + verify - test-suite-all-e2e.yaml: Split both platforms into launch + verify - Updated device lock files from test runs Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent 3d5f7be commit 0eea123

5 files changed

Lines changed: 132 additions & 20 deletions

File tree

examples/react-native/devbox.d/android/devices/devices.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,5 @@
1414
}
1515
],
1616
"checksum": "8df4d3393b61fbbb08e45cf8762f95c521316938e514527916e4fce88a849d57",
17-
"generated_at": "2026-02-20T01:46:34Z"
17+
"generated_at": "2026-02-20T01:50:04Z"
1818
}

examples/react-native/devbox.d/ios/devices/devices.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,5 @@
1010
}
1111
],
1212
"checksum": "4d5276f203d7ad62860bfc067f76194df53be449d4aa8a3b2d069855ec1f3232",
13-
"generated_at": "2026-02-20T01:46:35Z"
13+
"generated_at": "2026-02-20T01:50:05Z"
1414
}

examples/react-native/tests/test-suite-all-e2e.yaml

Lines changed: 65 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,18 +56,24 @@ processes:
5656
availability:
5757
restart: "no"
5858

59-
# Phase 4a: Start Android emulator
60-
android-emulator:
59+
# Phase 4a: Launch Android emulator if not running
60+
launch-emulator:
6161
depends_on:
6262
sync-avds:
6363
condition: process_completed_successfully
6464
environment:
6565
- "ANDROID_EMULATOR_FOREGROUND=1"
6666
command: |
6767
set -e
68-
echo "[ANDROID-EMULATOR] Starting emulator..."
6968
device="${ANDROID_DEFAULT_DEVICE:-max}"
7069
70+
# Check if emulator already running
71+
if android.sh emulator ready 2>/dev/null; then
72+
echo "Emulator already running, skipping launch"
73+
exit 0
74+
fi
75+
76+
echo "[ANDROID-EMULATOR] Starting emulator..."
7177
if [ "${DEVBOX_PURE_SHELL:-}" = "1" ]; then
7278
# Pure mode: foreground
7379
echo "Starting fresh Android emulator (pure mode): $device"
@@ -90,10 +96,39 @@ processes:
9096
success_threshold: 1
9197
failure_threshold: 24
9298

93-
# Phase 4b: Start iOS simulator (parallel with Android)
94-
ios-simulator:
99+
# Phase 4b: Verify Android emulator ready
100+
verify-emulator-ready:
101+
command: |
102+
echo "Verifying emulator is ready..."
103+
max_wait=120
104+
elapsed=0
105+
while ! android.sh emulator ready 2>/dev/null; do
106+
sleep 3
107+
elapsed=$((elapsed + 3))
108+
if [ $elapsed -ge $max_wait ]; then
109+
echo "ERROR: Emulator not ready within ${max_wait}s" >&2
110+
exit 1
111+
fi
112+
done
113+
echo "✓ Emulator ready"
114+
depends_on:
115+
launch-emulator:
116+
condition: process_completed
117+
availability:
118+
restart: "no"
119+
120+
# Phase 4c: Launch iOS simulator if not running
121+
launch-simulator:
95122
command: |
96123
set -e
124+
125+
# Check if simulator already running
126+
if ios.sh simulator ready 2>/dev/null; then
127+
echo "Simulator already running, skipping launch"
128+
exit 0
129+
fi
130+
131+
echo "Starting iOS simulator..."
97132
if [ "${DEVBOX_PURE_SHELL:-}" = "1" ]; then
98133
# Pure mode: foreground
99134
ios.sh simulator start --pure ${IOS_DEVICE}
@@ -116,6 +151,27 @@ processes:
116151
success_threshold: 1
117152
failure_threshold: 12
118153

154+
# Phase 4d: Verify iOS simulator ready
155+
verify-simulator-ready:
156+
command: |
157+
echo "Verifying simulator is ready..."
158+
max_wait=60
159+
elapsed=0
160+
while ! ios.sh simulator ready 2>/dev/null; do
161+
sleep 2
162+
elapsed=$((elapsed + 2))
163+
if [ $elapsed -ge $max_wait ]; then
164+
echo "ERROR: Simulator not ready within ${max_wait}s" >&2
165+
exit 1
166+
fi
167+
done
168+
echo "✓ Simulator ready"
169+
depends_on:
170+
launch-simulator:
171+
condition: process_completed
172+
availability:
173+
restart: "no"
174+
119175
# Phase 5: Start Metro bundler (shared by both platforms)
120176
metro-bundler:
121177
command: "metro.sh start all"
@@ -183,8 +239,8 @@ processes:
183239
depends_on:
184240
build-android:
185241
condition: process_completed_successfully
186-
android-emulator:
187-
condition: process_healthy
242+
verify-emulator-ready:
243+
condition: process_completed_successfully
188244
metro-bundler:
189245
condition: process_healthy
190246
availability:
@@ -199,8 +255,8 @@ processes:
199255
depends_on:
200256
build-ios:
201257
condition: process_completed_successfully
202-
ios-simulator:
203-
condition: process_healthy
258+
verify-simulator-ready:
259+
condition: process_completed_successfully
204260
metro-bundler:
205261
condition: process_healthy
206262
availability:

examples/react-native/tests/test-suite-android-e2e.yaml

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,18 +35,24 @@ processes:
3535
availability:
3636
restart: "no"
3737

38-
# Phase 4: Start emulator
39-
android-emulator:
38+
# Phase 4a: Launch emulator if not running
39+
launch-emulator:
4040
depends_on:
4141
sync-avds:
4242
condition: process_completed_successfully
4343
environment:
4444
- "ANDROID_EMULATOR_FOREGROUND=1"
4545
command: |
4646
set -e
47-
echo "[ANDROID-EMULATOR] Starting emulator..."
4847
device="${ANDROID_DEFAULT_DEVICE:-max}"
4948
49+
# Check if emulator already running
50+
if android.sh emulator ready 2>/dev/null; then
51+
echo "Emulator already running, skipping launch"
52+
exit 0
53+
fi
54+
55+
echo "[ANDROID-EMULATOR] Starting emulator..."
5056
if [ "${DEVBOX_PURE_SHELL:-}" = "1" ]; then
5157
# Pure mode: foreground, process-compose manages lifecycle
5258
echo "Starting fresh Android emulator (pure mode): $device"
@@ -69,6 +75,27 @@ processes:
6975
success_threshold: 1
7076
failure_threshold: 24
7177

78+
# Phase 4b: Verify emulator ready
79+
verify-emulator-ready:
80+
command: |
81+
echo "Verifying emulator is ready..."
82+
max_wait=120
83+
elapsed=0
84+
while ! android.sh emulator ready 2>/dev/null; do
85+
sleep 3
86+
elapsed=$((elapsed + 3))
87+
if [ $elapsed -ge $max_wait ]; then
88+
echo "ERROR: Emulator not ready within ${max_wait}s" >&2
89+
exit 1
90+
fi
91+
done
92+
echo "✓ Emulator ready"
93+
depends_on:
94+
launch-emulator:
95+
condition: process_completed
96+
availability:
97+
restart: "no"
98+
7299
# Phase 5: Start Metro bundler
73100
metro-bundler:
74101
command: "metro.sh start android"
@@ -113,8 +140,8 @@ processes:
113140
depends_on:
114141
build-android:
115142
condition: process_completed_successfully
116-
android-emulator:
117-
condition: process_healthy
143+
verify-emulator-ready:
144+
condition: process_completed_successfully
118145
metro-bundler:
119146
condition: process_healthy
120147
availability:

examples/react-native/tests/test-suite-ios-e2e.yaml

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,18 @@ processes:
3939
availability:
4040
restart: "no"
4141

42-
# Phase 4: Start simulator
43-
ios-simulator:
42+
# Phase 4a: Launch simulator if not running
43+
launch-simulator:
4444
command: |
4545
set -e
46+
47+
# Check if simulator already running
48+
if ios.sh simulator ready 2>/dev/null; then
49+
echo "Simulator already running, skipping launch"
50+
exit 0
51+
fi
52+
53+
echo "Starting iOS simulator..."
4654
if [ "${DEVBOX_PURE_SHELL:-}" = "1" ]; then
4755
# Pure mode: foreground, process-compose manages lifecycle
4856
ios.sh simulator start --pure ${IOS_DEVICE}
@@ -65,6 +73,27 @@ processes:
6573
success_threshold: 1
6674
failure_threshold: 12
6775

76+
# Phase 4b: Verify simulator ready
77+
verify-simulator-ready:
78+
command: |
79+
echo "Verifying simulator is ready..."
80+
max_wait=60
81+
elapsed=0
82+
while ! ios.sh simulator ready 2>/dev/null; do
83+
sleep 2
84+
elapsed=$((elapsed + 2))
85+
if [ $elapsed -ge $max_wait ]; then
86+
echo "ERROR: Simulator not ready within ${max_wait}s" >&2
87+
exit 1
88+
fi
89+
done
90+
echo "✓ Simulator ready"
91+
depends_on:
92+
launch-simulator:
93+
condition: process_completed
94+
availability:
95+
restart: "no"
96+
6897
# Phase 5: Start Metro bundler
6998
metro-bundler:
7099
command: "metro.sh start ios"
@@ -114,8 +143,8 @@ processes:
114143
depends_on:
115144
build-ios:
116145
condition: process_completed_successfully
117-
ios-simulator:
118-
condition: process_healthy
146+
verify-simulator-ready:
147+
condition: process_completed_successfully
119148
metro-bundler:
120149
condition: process_healthy
121150
availability:

0 commit comments

Comments
 (0)