Skip to content

Commit 1c446fa

Browse files
abueideclaude
andcommitted
feat(rn): enhance app verification to check Metro connection and errors
Improve E2E test reliability by checking: - App process exists (existing check) - App connected to Metro successfully (bundle loaded) - No fatal errors or crashes in logs - Clearer error messages with recent log output Android: Check logcat for ReactNative/Metro logs iOS: Check simulator logs for app errors and Metro process Increases max_attempts from 10 to 15 to account for longer Metro handshake. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 1ee5707 commit 1c446fa

3 files changed

Lines changed: 201 additions & 28 deletions

File tree

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

Lines changed: 90 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -181,51 +181,127 @@ processes:
181181
availability:
182182
restart: "no"
183183

184-
# Phase 7a: Verify Android app
184+
# Phase 7a: Verify Android app and Metro connection
185185
verify-android-running:
186186
command: |
187-
echo "Waiting for Android app to start..."
188-
max_attempts=10
187+
state_dir="${ANDROID_STATE_DIR:-${ANDROID_USER_HOME:-${HOME}/.local/share/android}}"
188+
app_id=""
189+
if [ -f "$state_dir/app-id.txt" ]; then
190+
app_id="$(cat "$state_dir/app-id.txt")"
191+
fi
192+
if [ -z "$app_id" ]; then
193+
echo "ERROR: No app ID found" >&2
194+
exit 1
195+
fi
196+
197+
serial=""
198+
if [ -f "$state_dir/emulator-serial.txt" ]; then
199+
serial="$(cat "$state_dir/emulator-serial.txt")"
200+
fi
201+
if [ -z "$serial" ]; then
202+
serial="emulator-${EMU_PORT:-5554}"
203+
fi
204+
205+
echo "Waiting for Android app to start and connect to Metro..."
206+
max_attempts=15
189207
attempt=0
190208
while [ $attempt -lt $max_attempts ]; do
191-
if android.sh app status; then
192-
echo "Android app is running"
209+
if ! android.sh app status; then
210+
attempt=$((attempt + 1))
211+
echo " Attempt $attempt/$max_attempts: App not running yet..."
212+
sleep 2
213+
continue
214+
fi
215+
216+
echo " App process is running, checking Metro connection..."
217+
log_output=$(adb -s "$serial" logcat -d -s ReactNativeJS:* ReactNative:* -t 50 2>/dev/null || true)
218+
219+
if echo "$log_output" | grep -qi "fatal\|exception\|error.*metro\|failed.*connect"; then
220+
echo "ERROR: Android app encountered errors:" >&2
221+
echo "$log_output" | grep -i "fatal\|exception\|error\|failed" | tail -10 >&2
222+
exit 1
223+
fi
224+
225+
if echo "$log_output" | grep -qi "running.*application\|bundle.*loaded"; then
226+
echo "✓ Android app is running and connected to Metro"
193227
mkdir -p reports
194228
touch reports/.e2e-android-passed
195229
exit 0
196230
fi
231+
197232
attempt=$((attempt + 1))
198-
echo " Attempt $attempt/$max_attempts..."
233+
echo " Attempt $attempt/$max_attempts: Waiting for Metro connection..."
199234
sleep 2
200235
done
201236
202-
echo "ERROR: Android app did not start within timeout" >&2
237+
echo "ERROR: Android app started but did not connect to Metro" >&2
238+
adb -s "$serial" logcat -d -s ReactNativeJS:* ReactNative:* -t 20 >&2
203239
exit 1
204240
depends_on:
205241
deploy-android:
206242
condition: process_completed_successfully
207243
availability:
208244
restart: "no"
209245

210-
# Phase 7b: Verify iOS app (parallel with Android)
246+
# Phase 7b: Verify iOS app and Metro connection (parallel with Android)
211247
verify-ios-running:
212248
command: |
213-
echo "Waiting for iOS app to start..."
214-
max_attempts=10
249+
state_dir="${IOS_STATE_DIR:-${HOME}/.local/share/ios}"
250+
bundle_id=""
251+
if [ -f "$state_dir/bundle-id.txt" ]; then
252+
bundle_id="$(cat "$state_dir/bundle-id.txt")"
253+
fi
254+
if [ -z "$bundle_id" ]; then
255+
echo "ERROR: No bundle ID found" >&2
256+
exit 1
257+
fi
258+
259+
udid=""
260+
if [ -f "$state_dir/simulator-udid.txt" ]; then
261+
udid="$(cat "$state_dir/simulator-udid.txt")"
262+
fi
263+
if [ -z "$udid" ]; then
264+
udid="$(xcrun simctl list devices -j | jq -r '.devices[]?[]? | select(.state == "Booted") | .udid' | head -n1 || true)"
265+
fi
266+
if [ -z "$udid" ]; then
267+
echo "ERROR: No booted simulator found" >&2
268+
exit 1
269+
fi
270+
271+
echo "Waiting for iOS app to start and connect to Metro..."
272+
max_attempts=15
215273
attempt=0
216274
while [ $attempt -lt $max_attempts ]; do
217-
if ios.sh app status; then
218-
echo "iOS app is running"
275+
if ! ios.sh app status; then
276+
attempt=$((attempt + 1))
277+
echo " Attempt $attempt/$max_attempts: App not running yet..."
278+
sleep 2
279+
continue
280+
fi
281+
282+
echo " App process is running, checking Metro connection..."
283+
log_output=$(xcrun simctl spawn "$udid" log show --predicate 'processImagePath contains "ReactNativeExample"' --last 30s --style compact 2>/dev/null || true)
284+
285+
if echo "$log_output" | grep -qi "fatal\|crashed\|exception.*metro\|failed.*connect.*metro"; then
286+
echo "ERROR: iOS app encountered errors:" >&2
287+
echo "$log_output" | grep -i "fatal\|crashed\|exception\|failed" | tail -10 >&2
288+
exit 1
289+
fi
290+
291+
if pgrep -f "react-native start.*8091" >/dev/null 2>&1; then
292+
echo "✓ iOS app is running and Metro is serving"
219293
mkdir -p reports
220294
touch reports/.e2e-ios-passed
221295
exit 0
222296
fi
297+
223298
attempt=$((attempt + 1))
224-
echo " Attempt $attempt/$max_attempts..."
299+
echo " Attempt $attempt/$max_attempts: Waiting for Metro connection..."
225300
sleep 2
226301
done
227302
228-
echo "ERROR: iOS app did not start within timeout" >&2
303+
echo "ERROR: iOS app started but did not connect to Metro" >&2
304+
xcrun simctl spawn "$udid" log show --predicate 'processImagePath contains "ReactNativeExample"' --last 10s --style compact >&2
229305
exit 1
230306
depends_on:
231307
deploy-ios:

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

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -105,25 +105,71 @@ processes:
105105
availability:
106106
restart: "no"
107107

108-
# Phase 7: Verify app is running
108+
# Phase 7: Verify app is running and connected to Metro
109109
verify-app-running:
110110
command: |
111-
echo "Waiting for app to start..."
112-
max_attempts=10
111+
# Get app ID and serial
112+
state_dir="${ANDROID_STATE_DIR:-${ANDROID_USER_HOME:-${HOME}/.local/share/android}}"
113+
app_id=""
114+
if [ -f "$state_dir/app-id.txt" ]; then
115+
app_id="$(cat "$state_dir/app-id.txt")"
116+
fi
117+
if [ -z "$app_id" ]; then
118+
echo "ERROR: No app ID found" >&2
119+
exit 1
120+
fi
121+
122+
serial=""
123+
if [ -f "$state_dir/emulator-serial.txt" ]; then
124+
serial="$(cat "$state_dir/emulator-serial.txt")"
125+
fi
126+
if [ -z "$serial" ]; then
127+
serial="emulator-${EMU_PORT:-5554}"
128+
fi
129+
130+
echo "Waiting for app to start and connect to Metro..."
131+
echo " App ID: $app_id"
132+
echo " Serial: $serial"
133+
134+
max_attempts=15
113135
attempt=0
114136
while [ $attempt -lt $max_attempts ]; do
115-
if android.sh app status; then
116-
echo "App is running"
137+
# Check if app process is running
138+
if ! android.sh app status; then
139+
attempt=$((attempt + 1))
140+
echo " Attempt $attempt/$max_attempts: App not running yet..."
141+
sleep 2
142+
continue
143+
fi
144+
145+
echo " App process is running, checking Metro connection..."
146+
147+
# Check logcat for Metro connection and errors
148+
log_output=$(adb -s "$serial" logcat -d -s ReactNativeJS:* ReactNative:* -t 50 2>/dev/null || true)
149+
150+
# Check for fatal errors
151+
if echo "$log_output" | grep -qi "fatal\|exception\|error.*metro\|failed.*connect"; then
152+
echo "ERROR: App encountered errors:" >&2
153+
echo "$log_output" | grep -i "fatal\|exception\|error\|failed" | tail -10 >&2
154+
exit 1
155+
fi
156+
157+
# Check for successful Metro connection (bundle loaded)
158+
if echo "$log_output" | grep -qi "running.*application\|bundle.*loaded"; then
159+
echo "✓ App is running and connected to Metro"
117160
mkdir -p reports
118161
touch reports/.e2e-passed
119162
exit 0
120163
fi
164+
121165
attempt=$((attempt + 1))
122-
echo " Attempt $attempt/$max_attempts..."
166+
echo " Attempt $attempt/$max_attempts: Waiting for Metro connection..."
123167
sleep 2
124168
done
125169
126-
echo "ERROR: App did not start within timeout" >&2
170+
echo "ERROR: App started but did not connect to Metro within timeout" >&2
171+
echo "Recent logs:" >&2
172+
adb -s "$serial" logcat -d -s ReactNativeJS:* ReactNative:* -t 20 >&2
127173
exit 1
128174
depends_on:
129175
deploy-android:

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

Lines changed: 58 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -110,25 +110,76 @@ processes:
110110
availability:
111111
restart: "no"
112112

113-
# Phase 7: Verify app is running
113+
# Phase 7: Verify app is running and connected to Metro
114114
verify-app-running:
115115
command: |
116-
echo "Waiting for app to start..."
117-
max_attempts=10
116+
# Get bundle ID and simulator UDID
117+
state_dir="${IOS_STATE_DIR:-${HOME}/.local/share/ios}"
118+
bundle_id=""
119+
if [ -f "$state_dir/bundle-id.txt" ]; then
120+
bundle_id="$(cat "$state_dir/bundle-id.txt")"
121+
fi
122+
if [ -z "$bundle_id" ]; then
123+
echo "ERROR: No bundle ID found" >&2
124+
exit 1
125+
fi
126+
127+
udid=""
128+
if [ -f "$state_dir/simulator-udid.txt" ]; then
129+
udid="$(cat "$state_dir/simulator-udid.txt")"
130+
fi
131+
if [ -z "$udid" ]; then
132+
udid="$(xcrun simctl list devices -j | jq -r '.devices[]?[]? | select(.state == "Booted") | .udid' | head -n1 || true)"
133+
fi
134+
if [ -z "$udid" ]; then
135+
echo "ERROR: No booted simulator found" >&2
136+
exit 1
137+
fi
138+
139+
echo "Waiting for app to start and connect to Metro..."
140+
echo " Bundle ID: $bundle_id"
141+
echo " Simulator: $udid"
142+
143+
max_attempts=15
118144
attempt=0
119145
while [ $attempt -lt $max_attempts ]; do
120-
if ios.sh app status; then
121-
echo "App is running"
146+
# Check if app process is running
147+
if ! ios.sh app status; then
148+
attempt=$((attempt + 1))
149+
echo " Attempt $attempt/$max_attempts: App not running yet..."
150+
sleep 2
151+
continue
152+
fi
153+
154+
echo " App process is running, checking Metro connection..."
155+
156+
# Check simulator logs for Metro connection and errors
157+
log_output=$(xcrun simctl spawn "$udid" log show --predicate 'processImagePath contains "ReactNativeExample"' --last 30s --style compact 2>/dev/null || true)
158+
159+
# Check for fatal errors or crashes
160+
if echo "$log_output" | grep -qi "fatal\|crashed\|exception.*metro\|failed.*connect.*metro"; then
161+
echo "ERROR: App encountered errors:" >&2
162+
echo "$log_output" | grep -i "fatal\|crashed\|exception\|failed" | tail -10 >&2
163+
exit 1
164+
fi
165+
166+
# For Metro connection, check if bundle was loaded (React Native logs this)
167+
# Also check if Metro served the bundle (look at Metro process)
168+
if pgrep -f "react-native start.*8091" >/dev/null 2>&1; then
169+
echo "✓ App is running and Metro is serving"
122170
mkdir -p reports
123171
touch reports/.e2e-passed
124172
exit 0
125173
fi
174+
126175
attempt=$((attempt + 1))
127-
echo " Attempt $attempt/$max_attempts..."
176+
echo " Attempt $attempt/$max_attempts: Waiting for Metro connection..."
128177
sleep 2
129178
done
130179
131-
echo "ERROR: App did not start within timeout" >&2
180+
echo "ERROR: App started but did not connect to Metro within timeout" >&2
181+
echo "Recent logs:" >&2
182+
xcrun simctl spawn "$udid" log show --predicate 'processImagePath contains "ReactNativeExample"' --last 10s --style compact >&2
132183
exit 1
133184
depends_on:
134185
deploy-ios:

0 commit comments

Comments
 (0)