Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions maestro/helpers/helpers.sh
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,17 @@ stop_recording() {

# A wedged XCUITest driver escapes as UnknownFailure to main, so a flow-level `retry:` can never
# catch it. Bound the wall clock here, then reset the device and retry once.
#
# Backstop only — the fatal-exception check in run_maestro catches the common hang within seconds.
# Must cover a cold driver bootstrap after a simulator reset (up to ~170s in CI on top of a ~35s
# flow, MAESTRO_DRIVER_STARTUP_TIMEOUT allows 240s), so it can't go much lower than this.
MAESTRO_FLOW_TIMEOUT="${MAESTRO_FLOW_TIMEOUT:-300}"

MAESTRO_FLOW_TIMEOUT="${MAESTRO_FLOW_TIMEOUT:-480}"
# Once main dies Maestro prints this and then idles (non-daemon threads keep the JVM alive) until
# the watchdog fires — in CI that was another ~4.5-6 min per hang. Nothing recovers after it.
MAESTRO_FATAL_PATTERN='Exception in thread "main"'
# Grace period after the fatal line so the stack trace reaches the log before we kill the JVM.
MAESTRO_FATAL_GRACE=10

# Outside maestro's 0-1 range and below the 128+N signal range.
MAESTRO_INFRA_EXIT=90
Expand Down Expand Up @@ -125,10 +134,17 @@ run_maestro() {
local waited=0
while [ "$waited" -lt "$MAESTRO_FLOW_TIMEOUT" ]; do
kill -0 "$maestro_pid" 2>/dev/null || exit 0
if [ -n "$log_file" ] && grep -qF "$MAESTRO_FATAL_PATTERN" "$log_file" 2>/dev/null; then
sleep "$MAESTRO_FATAL_GRACE"
kill -0 "$maestro_pid" 2>/dev/null || exit 0
echo "::warning::maestro main thread died on $(basename "$flow") after ${waited}s — killing the lingering JVM (hung driver)"
break
fi
sleep 5
waited=$((waited + 5))
done
echo "::warning::maestro exceeded ${MAESTRO_FLOW_TIMEOUT}s on $(basename "$flow") — killing it (hung driver)"
[ "$waited" -ge "$MAESTRO_FLOW_TIMEOUT" ] &&
echo "::warning::maestro exceeded ${MAESTRO_FLOW_TIMEOUT}s on $(basename "$flow") — killing it (hung driver)"
kill -TERM "$maestro_pid" 2>/dev/null || true
sleep 10
kill -9 "$maestro_pid" 2>/dev/null || true
Expand Down
20 changes: 20 additions & 0 deletions maestro/helpers/prepare_ios.sh
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,25 @@ reduce_motion() {
|| echo "::warning::Could not set ReduceMotionReduceSlideTransitionsEnabled"
}

# Every XCUITest hang in CI (`XCTPerformOnMainRunLoop work timed out`) came right after an
# inputText, i.e. with the software keyboard up. Keep the keyboard as plain as possible: no
# first-use "slide to type" overlay (a freshly booted/reset simulator shows it on the first
# keyboard), no prediction bar, no autocorrect/spellcheck popups. Same domain Appium writes.
configure_keyboard() {
echo "Configuring iOS Simulator keyboard..."
if [ -z "$SIMULATOR_DEVICE_ID" ]; then
echo "Error: SIMULATOR_DEVICE_ID not set"
return 1
fi
xcrun simctl spawn "$SIMULATOR_DEVICE_ID" defaults write com.apple.keyboard.preferences DidShowContinuousPathIntroduction -bool true \
|| echo "::warning::Could not set keyboard preference DidShowContinuousPathIntroduction"
local key
for key in KeyboardPrediction KeyboardShowPredictionBar KeyboardAutocorrection KeyboardCheckSpelling KeyboardAutocapitalization KeyboardContinuousPathEnabled; do
xcrun simctl spawn "$SIMULATOR_DEVICE_ID" defaults write com.apple.keyboard.preferences "$key" -bool false \
|| echo "::warning::Could not set keyboard preference $key"
done
}

set_status_bar() {
echo "Setting status bar on iOS Simulator..."
if [ -z "$SIMULATOR_DEVICE_ID" ]; then
Expand Down Expand Up @@ -147,6 +166,7 @@ report_slim_state() {
start_simulator
report_slim_state
reduce_motion
configure_keyboard
set_status_bar
install_ios_app
verify_installed_app
Binary file modified maestro/images/expected/android/image_url.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ appId: "${APP_ID}"
- tapOn:
id: "container1"
- inputText: "11"
# iOS: dismiss the keyboard first — every XCUITest hang in CI (viewHierarchy timing out) came with
# the keyboard up. Android-only hideKeyboard is a Back press, so it stays iOS-scoped.
- runFlow:
when:
platform: ios
commands:
- hideKeyboard
- tapOn: "Show confirmation "
- assertVisible: "Yolo"
- assertVisible: "11"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ appId: "${APP_ID}"
- inputText:
text: "Maestro"
- pressKey: Enter
# Dismiss the keyboard before reading the hierarchy — every XCUITest hang in CI (viewHierarchy
# timing out) came with the keyboard up.
- hideKeyboard
- assertVisible:
text: "Maestro"
index: 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ appId: "${APP_ID}"
- inputText:
text: "Title 5"
- pressKey: Enter
# iOS: dismiss the keyboard before reading the hierarchy — every XCUITest hang in CI (viewHierarchy
# timing out) came with the keyboard up. Android-only hideKeyboard is a Back press, so it stays iOS-scoped.
- runFlow:
when:
platform: ios
commands:
- hideKeyboard
- assertVisible:
text: "Title 5"
index: 1
Expand All @@ -30,5 +37,10 @@ appId: "${APP_ID}"
- inputText:
text: "Title 100"
- pressKey: Enter
- runFlow:
when:
platform: ios
commands:
- hideKeyboard
- assertVisible:
text: "No results found"
Loading