Skip to content

Commit d891ff8

Browse files
authored
MPT-15220: Appium tests for Welcome screen (#24)
* Create Appium baseline tests expanded package.json with appium related entries added test/ folder to app/ to support appium testing added related github workflow files * Fix appium testing workflow moved template yml from folder to workflow root * Pipeline fix and Reportportal integration prep added changes for workflow files testing via appium edited wdio.conf to prepare for reportportal integration * Linting fixes and main update * More linting changes * Add pull_request trigger to test workflow * moved workflow inputs to env * add restore node cache step to workflow test job * setting template workflow job default working dir * updating template workflow node cache path * updated template workflow node cache path * worflow update XCUITest step * changed template workflow appium version * test workflow app path change * defined outputs for test workflow * template workflow app_path fix * test workflow input rename * workflow diagnostic step * template workflow debug * workflow change to download app archive * workflow app url update * workflow artifact changes * moved download step to caller workflow from template * editing test workflow test-ios fields * workflow input/env fix * changed workflow download file name * fixed workflow upload step to upload folder * changed workflow to build for simulator * workflow artifact name change on upload * workflow app name * disabled workflow upload/download * app path change for workflow * set env for workflow job verify-and-install-ios * re-add workflow up and download * workflow upload path fix * workflow change * workflow upload fixes * workflow simulator name change * workflow change for iphone udid * workflow change to find correct simulator * workflow cache pathing change * workflow XCUITest update * workflow simplified xcuitest install * workflow update appium discover time * workflow fix for cache pathing * wdio conf changed to use appium through hostname * template workflow update to log variables * template workflow update * added wdio port int parsing from env variable * appium url change * template workflow and wdio configuration updates * workflow guards for simulator run * moved install app to template workflow * workflow fixes for templates * workflow timeout fixes * install template change * workflow changes moving templates under the same job * changing templates to step based * step template workflow changes * added testing readme * workflow debug trigger * simulator hanging fix * Fix Appium WebDriver connection using verified network URL - Extract working network URL from Appium server logs - Use verified URL for WebDriver connections instead of localhost - Add connection testing before running actual tests - Enhanced debug output to show all available connection URLs This should resolve the UND_ERR_HEADERS_TIMEOUT error by using the network interface URL that Appium reports as working. * appium url workflow fix * Add debugging output for zip path resolution * Fix release step working directory to match other build steps - Add working-directory: ./app to release step - Remove 'app/' prefix from zip file path since we're now in app directory - Update find command to search from current directory (.) - This ensures consistent path resolution across all build steps * Fix workflow permissions for release creation - Change from contents: read to contents: write - Add actions: read permission for artifact access - This allows the workflow to create GitHub releases * workflow updates for simulator stability * workflow updates to ensure simulator availability * workflow updates * workflow default switched to release * forcing release default for workflow * changed download_url default for example workflow * added testing script and workflow changes * feat: enhance iOS testing workflow with skip-build option and remove branch triggers - Add --skip-build/-s option to run-local-test.sh for fast iteration - Support reusing existing builds to avoid 5-8 minute rebuild times - Add validation to prevent conflicting build options - Update APPIUM_IOS_TESTING.md with comprehensive workflow documentation - Remove branch triggers from iOS workflow files (manual trigger only) - Add appium log files to .gitignore Performance improvements: - Full build: ~6-8 minutes - Skip build: ~10 seconds - No flags: ~5 seconds * refactor: move testing dependencies to devDependencies - Move all Appium and WebDriverIO related packages to devDependencies - Move @reportportal/agent-js-webdriverio to devDependencies - Move wdio to devDependencies - Testing functionality preserved as scripts use npx - CI/CD workflows unaffected as they use npm ci + npx commands * PR comments resolution * fix: add missing @types/node dependency for CI compatibility - Add @types/node@^20.17.10 to devDependencies - Regenerate package-lock.json to resolve CI npm ci failures - Fix package.json/package-lock.json sync issue in GitHub Actions
1 parent 26ad92e commit d891ff8

25 files changed

+25373
-7702
lines changed
Lines changed: 300 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,300 @@
1+
name: 'iOS App Install and Setup'
2+
description: 'Download, install, and setup iOS app on simulator'
3+
inputs:
4+
artifact_name:
5+
description: 'Name of the iOS app artifact to download'
6+
required: false
7+
download_url:
8+
description: 'Direct download URL for the iOS app bundle'
9+
required: false
10+
ios_version:
11+
description: 'iOS version for simulator'
12+
required: false
13+
default: '26.0'
14+
device_name:
15+
description: 'iOS simulator device name'
16+
required: false
17+
default: 'iPhone 16'
18+
outputs:
19+
device_udid:
20+
description: 'UUID of the booted iOS simulator'
21+
value: ${{ steps.boot-simulator.outputs.device_udid }}
22+
bundle_id:
23+
description: 'Bundle ID of the installed app'
24+
value: ${{ steps.install-app.outputs.bundle_id }}
25+
app_path:
26+
description: 'Path to the installed app bundle'
27+
value: ${{ steps.verify-app.outputs.app_path }}
28+
29+
runs:
30+
using: 'composite'
31+
steps:
32+
- name: Download iOS app from artifact
33+
if: inputs.artifact_name != ''
34+
uses: actions/download-artifact@v4
35+
with:
36+
name: ${{ inputs.artifact_name }}
37+
path: ./downloaded-app
38+
39+
- name: Download iOS app from URL
40+
if: inputs.download_url != ''
41+
shell: bash
42+
run: |
43+
echo "📥 Downloading iOS app from URL..."
44+
echo "URL: ${{ inputs.download_url }}"
45+
46+
# Create download directory
47+
mkdir -p ./downloaded-app
48+
49+
# Download the file
50+
curl -L -o ./downloaded-app/app_bundle.zip "${{ inputs.download_url }}"
51+
52+
# Verify download
53+
if [ ! -f "./downloaded-app/app_bundle.zip" ]; then
54+
echo "❌ ERROR: Download failed"
55+
exit 1
56+
fi
57+
58+
# Check file size
59+
FILE_SIZE=$(stat -f%z "./downloaded-app/app_bundle.zip" 2>/dev/null || stat -c%s "./downloaded-app/app_bundle.zip")
60+
echo "✅ Downloaded app bundle (${FILE_SIZE} bytes)"
61+
62+
- name: Verify download method
63+
shell: bash
64+
run: |
65+
if [ -z "${{ inputs.artifact_name }}" ] && [ -z "${{ inputs.download_url }}" ]; then
66+
echo "❌ ERROR: Either artifact_name or download_url must be provided"
67+
exit 1
68+
fi
69+
70+
if [ -n "${{ inputs.artifact_name }}" ] && [ -n "${{ inputs.download_url }}" ]; then
71+
echo "⚠️ WARNING: Both artifact_name and download_url provided, using artifact_name"
72+
fi
73+
74+
- name: Unzip app bundle
75+
shell: bash
76+
run: |
77+
echo "📦 Extracting app bundle..."
78+
79+
# Find and extract the zip file
80+
if [ -f "./downloaded-app/app_bundle.zip" ]; then
81+
unzip "./downloaded-app/app_bundle.zip" -d ./downloaded-app/
82+
echo "✅ App bundle extracted"
83+
else
84+
echo "❌ ERROR: app_bundle.zip not found in ./downloaded-app"
85+
echo "Contents of ./downloaded-app:"
86+
ls -la ./downloaded-app/
87+
exit 1
88+
fi
89+
90+
- name: Verify app bundle
91+
id: verify-app
92+
shell: bash
93+
run: |
94+
echo "🔍 Verifying .app bundle..."
95+
96+
APP_PATH=$(find ./downloaded-app -name "*.app" -type d -maxdepth 2 | head -n 1)
97+
98+
echo "Contents of ./downloaded-app:"
99+
ls -la ./downloaded-app/
100+
101+
if [ -z "$APP_PATH" ]; then
102+
echo "❌ ERROR: .app bundle not found"
103+
echo "Searching for .app files:"
104+
find ./downloaded-app -name "*.app" -type d
105+
exit 1
106+
fi
107+
108+
if [ ! -f "$APP_PATH/Info.plist" ]; then
109+
echo "❌ ERROR: Invalid .app bundle - missing Info.plist"
110+
exit 1
111+
fi
112+
113+
# Extract bundle ID for verification
114+
BUNDLE_ID=$(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "$APP_PATH/Info.plist")
115+
echo "📱 Found valid app bundle: $(basename "$APP_PATH")"
116+
echo "📋 Bundle ID: $BUNDLE_ID"
117+
118+
echo "app_path=$APP_PATH" >> $GITHUB_OUTPUT
119+
echo "APP_PATH=$APP_PATH" >> $GITHUB_ENV
120+
echo "VERIFIED_BUNDLE_ID=$BUNDLE_ID" >> $GITHUB_ENV
121+
122+
- name: List available iOS simulators
123+
shell: bash
124+
run: |
125+
echo "📱 Available iOS Simulators:"
126+
xcrun simctl list devices available
127+
128+
- name: Find and boot iOS Simulator
129+
id: boot-simulator
130+
shell: bash
131+
run: |
132+
set -e
133+
DEVICE_NAME="${{ inputs.device_name }}"
134+
PLATFORM_VERSION="${{ inputs.ios_version }}"
135+
136+
echo "🔍 Looking for: $DEVICE_NAME with iOS $PLATFORM_VERSION"
137+
138+
# Use Python with JSON output for reliable parsing
139+
UDID=$(xcrun simctl list devices available -j | python3 -c "
140+
import json
141+
import sys
142+
143+
data = json.load(sys.stdin)
144+
target_device = '$DEVICE_NAME'
145+
target_version = '$PLATFORM_VERSION'
146+
147+
# Format the version for comparison (e.g., '26.0' -> 'iOS-26-0')
148+
formatted_version = 'iOS-' + target_version.replace(' ', '-').replace('.', '-')
149+
150+
for runtime_key, devices in data.get('devices', {}).items():
151+
# Extract and format the runtime version from the key
152+
# Runtime keys look like: 'com.apple.CoreSimulator.SimRuntime.iOS-26-0'
153+
if formatted_version in runtime_key:
154+
for device in devices:
155+
if device.get('name') == target_device and device.get('isAvailable', False):
156+
print(device['udid'])
157+
sys.exit(0)
158+
159+
# If we get here, device wasn't found
160+
sys.exit(1)
161+
" 2>/dev/null)
162+
163+
if [ -z "$UDID" ]; then
164+
echo "❌ ERROR: Could not find $DEVICE_NAME with iOS $PLATFORM_VERSION"
165+
echo ""
166+
echo "Available simulators:"
167+
xcrun simctl list devices available
168+
echo ""
169+
echo "Debugging - Runtime keys:"
170+
xcrun simctl list devices available -j | python3 -c "
171+
import json
172+
import sys
173+
data = json.load(sys.stdin)
174+
for key in data.get('devices', {}).keys():
175+
print(key)
176+
"
177+
exit 1
178+
fi
179+
180+
echo "DEVICE_UDID=$UDID" >> $GITHUB_ENV
181+
echo "device_udid=$UDID" >> $GITHUB_OUTPUT
182+
echo "✅ Found simulator: $DEVICE_NAME ($UDID)"
183+
184+
# Boot the simulator with timeout protection
185+
echo "🚀 Booting simulator..."
186+
xcrun simctl boot $UDID 2>/dev/null || echo "Simulator already booted or boot command completed"
187+
188+
# Wait for boot to complete with timeout and fallback strategy
189+
echo "⏳ Waiting for simulator to boot (timeout: 180 seconds)..."
190+
191+
BOOT_TIMEOUT=180
192+
BOOT_SUCCESS=false
193+
194+
for i in $(seq 1 $BOOT_TIMEOUT); do
195+
# Check if simulator is booted
196+
SIMULATOR_STATUS=$(xcrun simctl list devices | grep "$UDID" | head -1)
197+
if echo "$SIMULATOR_STATUS" | grep -q "(Booted)"; then
198+
BOOT_SUCCESS=true
199+
echo "✅ Simulator booted successfully after ${i} seconds"
200+
break
201+
fi
202+
203+
# Progress indicator every 10 seconds
204+
if [ $((i % 10)) -eq 0 ]; then
205+
echo "⏳ Still waiting... (${i}/${BOOT_TIMEOUT} seconds)"
206+
echo "Current status: $SIMULATOR_STATUS"
207+
fi
208+
209+
sleep 1
210+
done
211+
212+
if [ "$BOOT_SUCCESS" = false ]; then
213+
echo "❌ ERROR: Simulator failed to boot within $BOOT_TIMEOUT seconds"
214+
echo "Final status: $(xcrun simctl list devices | grep "$UDID" | head -1)"
215+
echo ""
216+
echo "🔧 Attempting recovery..."
217+
218+
# Try to shutdown and reboot once
219+
echo "🔄 Shutting down simulator..."
220+
xcrun simctl shutdown $UDID || true
221+
sleep 5
222+
223+
echo "🚀 Attempting second boot..."
224+
xcrun simctl boot $UDID
225+
226+
# Give it one more chance with shorter timeout
227+
echo "⏳ Final boot attempt (60 seconds timeout)..."
228+
FINAL_TIMEOUT=60
229+
FINAL_SUCCESS=false
230+
231+
for i in $(seq 1 $FINAL_TIMEOUT); do
232+
SIMULATOR_STATUS=$(xcrun simctl list devices | grep "$UDID" | head -1)
233+
if echo "$SIMULATOR_STATUS" | grep -q "(Booted)"; then
234+
FINAL_SUCCESS=true
235+
echo "✅ Simulator recovered and booted after ${i} seconds"
236+
break
237+
fi
238+
sleep 1
239+
done
240+
241+
if [ "$FINAL_SUCCESS" = false ]; then
242+
echo "❌ FATAL: Simulator boot failed completely"
243+
echo "This might be a CI environment issue with iOS simulators"
244+
exit 1
245+
fi
246+
fi
247+
248+
# Double-check simulator status and ensure it's ready for testing
249+
echo "🔍 Final verification that simulator is ready..."
250+
SIMULATOR_STATUS=$(xcrun simctl list devices | grep "$UDID" | head -1)
251+
echo "Simulator status: $SIMULATOR_STATUS"
252+
253+
if echo "$SIMULATOR_STATUS" | grep -q "(Booted)"; then
254+
echo "✅ Simulator is booted and ready for testing"
255+
else
256+
echo "❌ ERROR: Simulator failed to reach booted state"
257+
echo "Current status: $SIMULATOR_STATUS"
258+
exit 1
259+
fi
260+
261+
- name: Install app on simulator
262+
id: install-app
263+
shell: bash
264+
run: |
265+
echo "📲 Installing app on simulator..."
266+
echo "Device UDID: ${{ env.DEVICE_UDID }}"
267+
echo "App path: ${{ env.APP_PATH }}"
268+
269+
# Install the app
270+
xcrun simctl install "${{ env.DEVICE_UDID }}" "${{ env.APP_PATH }}"
271+
272+
# Extract and output bundle ID
273+
BUNDLE_ID=$(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "${{ env.APP_PATH }}/Info.plist")
274+
echo "BUNDLE_ID=${BUNDLE_ID}" >> $GITHUB_ENV
275+
echo "bundle_id=${BUNDLE_ID}" >> $GITHUB_OUTPUT
276+
277+
echo "✅ App installed successfully"
278+
echo "📋 Bundle ID: ${BUNDLE_ID}"
279+
280+
- name: Launch and verify app
281+
shell: bash
282+
run: |
283+
echo "🚀 Launching app..."
284+
xcrun simctl launch "${{ env.DEVICE_UDID }}" "${{ env.BUNDLE_ID }}"
285+
286+
echo "⏳ Waiting for app to initialize..."
287+
sleep 5
288+
289+
# Verify app is installed and accessible for testing
290+
echo "🔍 Final app verification before testing..."
291+
if xcrun simctl listapps "${{ env.DEVICE_UDID }}" | grep -q "${{ env.BUNDLE_ID }}"; then
292+
echo "✅ App ${{ env.BUNDLE_ID }} is installed and available for Appium testing"
293+
else
294+
echo "❌ ERROR: App not found after installation"
295+
echo "Installed apps:"
296+
xcrun simctl listapps "${{ env.DEVICE_UDID }}"
297+
exit 1
298+
fi
299+
300+
echo "🎯 App launched successfully and ready for testing"

0 commit comments

Comments
 (0)