refactor: remove screenshot scripts
This commit is contained in:
@@ -1,396 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Android Screenshot Automation Script
|
||||
# Starts emulators, runs Flutter app, executes maestro tests, and organizes screenshots
|
||||
|
||||
set -e # Exit on any error
|
||||
|
||||
# Configuration
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
||||
MAESTRO_DIR="$PROJECT_ROOT/maestro"
|
||||
FASTLANE_IMAGES_DIR="$PROJECT_ROOT/android/fastlane/metadata/android/en-GB/images"
|
||||
ENV_FILE="$PROJECT_ROOT/.env"
|
||||
|
||||
# Source common screenshot functions
|
||||
source "${SCRIPT_DIR}/screenshot_common.sh"
|
||||
|
||||
# Check if required tools are installed
|
||||
check_dependencies() {
|
||||
# Check common dependencies first
|
||||
if ! check_common_dependencies; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "Checking Android-specific dependencies..."
|
||||
|
||||
# Try to find emulator binary
|
||||
if ! command -v emulator &> /dev/null; then
|
||||
# Try common Android SDK locations
|
||||
POSSIBLE_PATHS=(
|
||||
"$ANDROID_HOME/emulator/emulator"
|
||||
"$ANDROID_SDK_ROOT/emulator/emulator"
|
||||
"~/Android/Sdk/emulator/emulator"
|
||||
"~/Library/Android/sdk/emulator/emulator"
|
||||
)
|
||||
|
||||
EMULATOR_PATH=""
|
||||
for path in "${POSSIBLE_PATHS[@]}"; do
|
||||
if [ -f "$path" ]; then
|
||||
EMULATOR_PATH="$path"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -z "$EMULATOR_PATH" ]; then
|
||||
log_error "Android emulator not found. Please ensure Android SDK is installed and ANDROID_HOME is set."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create an alias for emulator
|
||||
alias emulator="$EMULATOR_PATH"
|
||||
fi
|
||||
|
||||
log_success "All dependencies found"
|
||||
}
|
||||
|
||||
# Get list of available AVDs
|
||||
get_avds() {
|
||||
# Parse flutter emulators output to get Android emulator IDs
|
||||
flutter emulators 2>/dev/null | grep "android$" | awk '{print $1}'
|
||||
}
|
||||
|
||||
# Stop all running emulators
|
||||
stop_emulators() {
|
||||
log_info "Stopping any running emulators..."
|
||||
|
||||
# Get list of running emulators
|
||||
local running_emulators=$(adb devices | grep emulator | cut -f1)
|
||||
|
||||
if [ -n "$running_emulators" ]; then
|
||||
for emulator in $running_emulators; do
|
||||
log_info "Stopping emulator $emulator"
|
||||
adb -s "$emulator" emu kill 2>/dev/null || true
|
||||
done
|
||||
|
||||
# Wait for emulators to fully stop - check periodically
|
||||
log_info "Waiting for emulators to fully shut down..."
|
||||
local timeout=30 # 30 seconds timeout
|
||||
local elapsed=0
|
||||
|
||||
while [ $elapsed -lt $timeout ]; do
|
||||
local still_running=$(adb devices | grep emulator | cut -f1)
|
||||
if [ -z "$still_running" ]; then
|
||||
log_success "All emulators stopped"
|
||||
return 0
|
||||
fi
|
||||
sleep 2
|
||||
elapsed=$((elapsed + 2))
|
||||
|
||||
# Show progress every 6 seconds
|
||||
if [ $((elapsed % 6)) -eq 0 ]; then
|
||||
log_info "Still waiting for emulators to stop... (${elapsed}s elapsed)"
|
||||
fi
|
||||
done
|
||||
|
||||
log_warning "Timeout waiting for emulators to stop completely"
|
||||
else
|
||||
log_info "No emulators are currently running"
|
||||
fi
|
||||
}
|
||||
|
||||
# Start emulator and wait for it to be ready
|
||||
start_emulator() {
|
||||
local avd_name="$1"
|
||||
local device_type="$2"
|
||||
|
||||
log_info "Starting $device_type emulator: $avd_name"
|
||||
|
||||
# Double-check if any emulator is still running
|
||||
local running_emulators=$(adb devices | grep emulator | cut -f1)
|
||||
if [ -n "$running_emulators" ]; then
|
||||
log_warning "Emulator still running: $running_emulators"
|
||||
log_info "Forcing stop before starting new emulator..."
|
||||
stop_emulators
|
||||
fi
|
||||
|
||||
# Start emulator in background with proper output redirection
|
||||
log_info "Launching emulator..."
|
||||
flutter emulators --launch "$avd_name" > /dev/null 2>&1 &
|
||||
local emulator_pid=$!
|
||||
|
||||
log_info "Waiting for $device_type emulator to boot..."
|
||||
|
||||
# Wait for emulator to appear in adb devices
|
||||
local timeout=120 # 2 minutes timeout
|
||||
local elapsed=0
|
||||
|
||||
while [ $elapsed -lt $timeout ]; do
|
||||
if adb devices | grep -q "emulator.*device"; then
|
||||
log_success "$device_type emulator is ready"
|
||||
return 0
|
||||
fi
|
||||
sleep 2
|
||||
elapsed=$((elapsed + 2))
|
||||
|
||||
# Show progress every 10 seconds
|
||||
if [ $((elapsed % 10)) -eq 0 ]; then
|
||||
log_info "Still waiting... (${elapsed}s elapsed)"
|
||||
fi
|
||||
done
|
||||
|
||||
log_error "Timeout waiting for $device_type emulator to start"
|
||||
return 1
|
||||
}
|
||||
|
||||
# Detect device type based on screen size
|
||||
detect_device_type() {
|
||||
local device_id="$1"
|
||||
|
||||
# Get screen density and size
|
||||
local density=$(adb -s "$device_id" shell wm density | cut -d: -f2 | tr -d ' ')
|
||||
local size=$(adb -s "$device_id" shell wm size | cut -d: -f2 | tr -d ' ')
|
||||
|
||||
# Extract width and height
|
||||
local width=$(echo "$size" | cut -d'x' -f1)
|
||||
local height=$(echo "$size" | cut -d'x' -f2)
|
||||
|
||||
# Calculate diagonal in inches (approximate)
|
||||
local diagonal_pixels=$(echo "sqrt($width*$width + $height*$height)" | bc -l)
|
||||
local diagonal_inches=$(echo "$diagonal_pixels / $density" | bc -l)
|
||||
|
||||
# Convert to integer for comparison
|
||||
local diagonal_int=$(echo "$diagonal_inches" | cut -d'.' -f1)
|
||||
|
||||
if [ "$diagonal_int" -ge 9 ]; then
|
||||
echo "tablet"
|
||||
else
|
||||
echo "phone"
|
||||
fi
|
||||
}
|
||||
|
||||
# Run Flutter app on specified device
|
||||
run_flutter_app() {
|
||||
local device_id="$1"
|
||||
local device_type="$2"
|
||||
|
||||
log_info "Running Flutter app on $device_type ($device_id)"
|
||||
|
||||
cd "$PROJECT_ROOT"
|
||||
flutter run -d "$device_id" --hot &
|
||||
local flutter_pid=$!
|
||||
|
||||
# Wait for app to be installed and launched
|
||||
sleep 30
|
||||
|
||||
# Check if app is running
|
||||
if adb -s "$device_id" shell pm list packages | grep -q "com.edde746.plezy"; then
|
||||
log_success "Flutter app is running on $device_type"
|
||||
return 0
|
||||
else
|
||||
log_error "Failed to start Flutter app on $device_type"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Detect device type based on image dimensions
|
||||
detect_device_type() {
|
||||
local image_path="$1"
|
||||
|
||||
local dimensions=$(get_image_dimensions "$image_path")
|
||||
if [ -z "$dimensions" ]; then
|
||||
log_warning "Could not get dimensions for $image_path"
|
||||
echo "phone" # Default to phone
|
||||
return
|
||||
fi
|
||||
|
||||
local width=$(echo "$dimensions" | cut -d',' -f1)
|
||||
local height=$(echo "$dimensions" | cut -d',' -f2)
|
||||
|
||||
# Determine shorter and longer sides
|
||||
local shorter_side=$((width < height ? width : height))
|
||||
local longer_side=$((width > height ? width : height))
|
||||
|
||||
# Calculate diagonal using shell arithmetic (approximate)
|
||||
# For simplicity, we'll use the shorter side as the main criteria
|
||||
# Tablets typically have shorter side >= 1200px
|
||||
# Phones typically have shorter side < 1200px
|
||||
|
||||
if [ "$shorter_side" -ge 1200 ]; then
|
||||
echo "tablet"
|
||||
else
|
||||
echo "phone"
|
||||
fi
|
||||
}
|
||||
|
||||
# Organize screenshots into correct fastlane folders
|
||||
organize_screenshots() {
|
||||
log_info "Organizing screenshots using ffprobe analysis..."
|
||||
|
||||
# Create directories if they don't exist
|
||||
mkdir -p "$FASTLANE_IMAGES_DIR/phoneScreenshots"
|
||||
mkdir -p "$FASTLANE_IMAGES_DIR/sevenInchScreenshots"
|
||||
mkdir -p "$FASTLANE_IMAGES_DIR/tenInchScreenshots"
|
||||
|
||||
# Find all screenshot files generated by maestro
|
||||
local android_screenshots_dir="$MAESTRO_DIR/android"
|
||||
if [ ! -d "$android_screenshots_dir" ]; then
|
||||
log_warning "No Android screenshots directory found at $android_screenshots_dir"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local screenshots=($(find "$android_screenshots_dir" -name "*.png" | sort))
|
||||
|
||||
if [ ${#screenshots[@]} -eq 0 ]; then
|
||||
log_warning "No Android screenshots found in $android_screenshots_dir"
|
||||
return 1
|
||||
fi
|
||||
|
||||
log_info "Found ${#screenshots[@]} screenshots"
|
||||
|
||||
# Group screenshots by device type
|
||||
local phone_screenshots=()
|
||||
local tablet_screenshots=()
|
||||
|
||||
for screenshot in "${screenshots[@]}"; do
|
||||
local device_type=$(detect_device_type "$screenshot")
|
||||
log_image_info "$screenshot" "$device_type"
|
||||
|
||||
if [ "$device_type" = "tablet" ]; then
|
||||
tablet_screenshots+=("$screenshot")
|
||||
else
|
||||
phone_screenshots+=("$screenshot")
|
||||
fi
|
||||
done
|
||||
|
||||
# Copy and rename phone screenshots
|
||||
local phone_count=1
|
||||
for screenshot in "${phone_screenshots[@]}"; do
|
||||
if [ $phone_count -gt 4 ]; then
|
||||
break # Limit to 4 screenshots
|
||||
fi
|
||||
|
||||
local target_name="${phone_count}_en-GB.png"
|
||||
|
||||
# Copy to phone directory
|
||||
cp "$screenshot" "$FASTLANE_IMAGES_DIR/phoneScreenshots/$target_name"
|
||||
|
||||
# Copy to seven inch directory (phone screenshots go here too)
|
||||
cp "$screenshot" "$FASTLANE_IMAGES_DIR/sevenInchScreenshots/$target_name"
|
||||
|
||||
log_success "Copied phone screenshot $phone_count: $(basename "$screenshot")"
|
||||
phone_count=$((phone_count + 1))
|
||||
done
|
||||
|
||||
# Copy and rename tablet screenshots
|
||||
local tablet_count=1
|
||||
for screenshot in "${tablet_screenshots[@]}"; do
|
||||
if [ $tablet_count -gt 4 ]; then
|
||||
break # Limit to 4 screenshots
|
||||
fi
|
||||
|
||||
local target_name="${tablet_count}_en-GB.png"
|
||||
cp "$screenshot" "$FASTLANE_IMAGES_DIR/tenInchScreenshots/$target_name"
|
||||
|
||||
log_success "Copied tablet screenshot $tablet_count: $(basename "$screenshot")"
|
||||
tablet_count=$((tablet_count + 1))
|
||||
done
|
||||
|
||||
log_success "Organized $((phone_count-1)) phone screenshots and $((tablet_count-1)) tablet screenshots"
|
||||
}
|
||||
|
||||
# Cleanup function
|
||||
cleanup() {
|
||||
log_info "Cleaning up..."
|
||||
|
||||
# Kill any running Flutter processes
|
||||
pkill -f "flutter run" 2>/dev/null || true
|
||||
|
||||
# Stop emulators using our function
|
||||
stop_emulators
|
||||
|
||||
log_success "Cleanup completed"
|
||||
}
|
||||
|
||||
# Main execution
|
||||
main() {
|
||||
log_info "Starting Android screenshot automation..."
|
||||
|
||||
# Set up cleanup trap
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
# Clean up old screenshots at the very beginning
|
||||
clean_old_screenshots "android ios"
|
||||
|
||||
# Check dependencies
|
||||
check_dependencies
|
||||
|
||||
# Stop any running emulators first
|
||||
stop_emulators
|
||||
|
||||
# Get available AVDs
|
||||
log_info "Getting available Android Virtual Devices..."
|
||||
|
||||
# Store AVDs in an array, handling potential spaces in names
|
||||
local avds_raw=$(get_avds)
|
||||
if [ -z "$avds_raw" ]; then
|
||||
log_error "No Android Virtual Devices found. Please create AVDs first."
|
||||
log_info "Create AVDs using: flutter emulators --create"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Convert to array (each line is an AVD)
|
||||
IFS=$'\n' read -d '' -r -a avds <<< "$avds_raw" || true
|
||||
|
||||
log_info "Found ${#avds[@]} Android AVD(s): ${avds[*]}"
|
||||
|
||||
# For now, we'll use the first two AVDs as phone and tablet
|
||||
# In a real scenario, you'd want to specify which AVDs to use
|
||||
local phone_avd="${avds[0]}"
|
||||
local tablet_avd="${avds[1]:-${avds[0]}}" # Use first AVD if only one available
|
||||
|
||||
if [ ${#avds[@]} -eq 1 ]; then
|
||||
log_warning "Only one AVD available. Using it for both phone and tablet tests."
|
||||
fi
|
||||
|
||||
# Start phone emulator
|
||||
start_emulator "$phone_avd" "phone"
|
||||
|
||||
# Get device ID for phone
|
||||
local phone_device=$(adb devices | grep emulator | head -n1 | cut -f1)
|
||||
|
||||
# Run Flutter app on phone
|
||||
run_flutter_app "$phone_device" "phone"
|
||||
|
||||
# Run maestro tests for phone
|
||||
MAESTRO_DEVICE="$phone_device" run_maestro_tests
|
||||
|
||||
# If we have a different tablet AVD, start it
|
||||
if [ "$phone_avd" != "$tablet_avd" ]; then
|
||||
# Stop phone emulator
|
||||
log_info "Switching from phone to tablet emulator"
|
||||
stop_emulators
|
||||
|
||||
# Start tablet emulator
|
||||
start_emulator "$tablet_avd" "tablet"
|
||||
|
||||
# Get device ID for tablet
|
||||
local tablet_device=$(adb devices | grep emulator | head -n1 | cut -f1)
|
||||
|
||||
# Run Flutter app on tablet
|
||||
run_flutter_app "$tablet_device" "tablet"
|
||||
|
||||
# Run maestro tests for tablet
|
||||
MAESTRO_DEVICE="$tablet_device" run_maestro_tests
|
||||
fi
|
||||
|
||||
# Organize screenshots
|
||||
organize_screenshots
|
||||
|
||||
log_success "Android screenshot automation completed successfully!"
|
||||
}
|
||||
|
||||
# Run main function if script is executed directly
|
||||
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||
main "$@"
|
||||
fi
|
||||
@@ -1,421 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# iOS Screenshot Automation Script
|
||||
# Starts simulators, runs Flutter app, executes maestro tests, and organizes screenshots
|
||||
|
||||
set -e # Exit on any error
|
||||
|
||||
# Configuration
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
||||
MAESTRO_DIR="$PROJECT_ROOT/maestro"
|
||||
FASTLANE_SCREENSHOTS_DIR="$PROJECT_ROOT/ios/fastlane/screenshots/en-US"
|
||||
ENV_FILE="$PROJECT_ROOT/.env"
|
||||
|
||||
# Source common screenshot functions
|
||||
source "${SCRIPT_DIR}/screenshot_common.sh"
|
||||
|
||||
# Check if required tools are installed
|
||||
check_dependencies() {
|
||||
# Check common dependencies first
|
||||
if ! check_common_dependencies; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "Checking iOS-specific dependencies..."
|
||||
|
||||
if ! command -v xcrun &> /dev/null; then
|
||||
log_error "xcrun is not installed - Xcode is required"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_success "All dependencies found"
|
||||
}
|
||||
|
||||
# Get list of available iOS simulators
|
||||
get_simulators() {
|
||||
xcrun simctl list devices available -j | python3 -c "
|
||||
import sys, json
|
||||
data = json.load(sys.stdin)
|
||||
for runtime, devices in data['devices'].items():
|
||||
if 'iOS' in runtime and devices:
|
||||
for device in devices:
|
||||
if device['isAvailable']:
|
||||
print(f\"{device['udid']}|{device['name']}\")
|
||||
" 2>/dev/null || echo ""
|
||||
}
|
||||
|
||||
# Stop all running simulators
|
||||
stop_simulators() {
|
||||
log_info "Stopping any running simulators..."
|
||||
|
||||
# Get list of running simulators
|
||||
local running_simulators=$(xcrun simctl list devices | grep "Booted" | grep -oE "[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}" || echo "")
|
||||
|
||||
if [ -n "$running_simulators" ]; then
|
||||
while IFS= read -r simulator; do
|
||||
log_info "Stopping simulator $simulator"
|
||||
xcrun simctl shutdown "$simulator" 2>/dev/null || true
|
||||
done <<< "$running_simulators"
|
||||
|
||||
# Wait for simulators to fully stop
|
||||
log_info "Waiting for simulators to fully shut down..."
|
||||
sleep 3
|
||||
log_success "All simulators stopped"
|
||||
else
|
||||
log_info "No simulators are currently running"
|
||||
fi
|
||||
}
|
||||
|
||||
# Start simulator and wait for it to be ready
|
||||
start_simulator() {
|
||||
local simulator_udid="$1"
|
||||
local simulator_name="$2"
|
||||
local device_type="$3"
|
||||
|
||||
log_info "Starting $device_type simulator: $simulator_name"
|
||||
|
||||
# Double-check if any simulator is still running
|
||||
local running_simulators=$(xcrun simctl list devices | grep "Booted" | grep -oE "[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}" || echo "")
|
||||
if [ -n "$running_simulators" ]; then
|
||||
log_warning "Simulator still running"
|
||||
log_info "Forcing stop before starting new simulator..."
|
||||
stop_simulators
|
||||
fi
|
||||
|
||||
# Start simulator
|
||||
log_info "Launching simulator..."
|
||||
xcrun simctl boot "$simulator_udid" 2>/dev/null || log_warning "Simulator may already be booting"
|
||||
|
||||
log_info "Waiting for $device_type simulator to be ready..."
|
||||
|
||||
# Wait for simulator to boot
|
||||
local timeout=120 # 2 minutes timeout
|
||||
local elapsed=0
|
||||
|
||||
while [ $elapsed -lt $timeout ]; do
|
||||
local state=$(xcrun simctl list devices | grep "$simulator_udid" | grep -oE "(Booted|Shutdown)")
|
||||
if [ "$state" = "Booted" ]; then
|
||||
# Give it a bit more time to fully initialize
|
||||
sleep 5
|
||||
log_success "$device_type simulator is ready"
|
||||
return 0
|
||||
fi
|
||||
sleep 2
|
||||
elapsed=$((elapsed + 2))
|
||||
|
||||
# Show progress every 10 seconds
|
||||
if [ $((elapsed % 10)) -eq 0 ]; then
|
||||
log_info "Still waiting... (${elapsed}s elapsed)"
|
||||
fi
|
||||
done
|
||||
|
||||
log_error "Timeout waiting for $device_type simulator to start"
|
||||
return 1
|
||||
}
|
||||
|
||||
# Rotate simulator to landscape
|
||||
rotate_simulator_landscape() {
|
||||
local simulator_udid="$1"
|
||||
|
||||
log_info "Rotating simulator to landscape orientation..."
|
||||
|
||||
# Open Simulator app and bring it to front
|
||||
open -a Simulator
|
||||
sleep 2
|
||||
|
||||
# Use AppleScript to send rotation keyboard shortcut (Cmd+Left arrow rotates counterclockwise)
|
||||
# Key code 123 is left arrow
|
||||
osascript -e 'tell application "Simulator" to activate' \
|
||||
-e 'tell application "System Events" to key code 123 using command down'
|
||||
|
||||
sleep 2
|
||||
log_success "Simulator rotated to landscape"
|
||||
}
|
||||
|
||||
# Detect device type based on image dimensions for iOS
|
||||
detect_ios_device_type() {
|
||||
local image_path="$1"
|
||||
|
||||
local dimensions=$(get_image_dimensions "$image_path")
|
||||
if [ -z "$dimensions" ]; then
|
||||
log_warning "Could not get dimensions for $image_path"
|
||||
echo "iphone_6_5" # Default
|
||||
return
|
||||
fi
|
||||
|
||||
local width=$(echo "$dimensions" | cut -d',' -f1)
|
||||
local height=$(echo "$dimensions" | cut -d',' -f2)
|
||||
|
||||
# Determine shorter and longer sides (for portrait orientation)
|
||||
local shorter_side=$((width < height ? width : height))
|
||||
local longer_side=$((width > height ? width : height))
|
||||
|
||||
# iOS App Store screenshot sizes (based on shorter side in portrait)
|
||||
# Reference: https://help.apple.com/app-store-connect/#/devd274dd925
|
||||
|
||||
# iPad Pro 12.9" (3rd gen and later): 2048 x 2732
|
||||
if [ "$shorter_side" -ge 2000 ] && [ "$longer_side" -ge 2700 ]; then
|
||||
echo "ipad_pro_12_9_3rd_gen"
|
||||
# iPad Pro 12.9" (2nd gen): 2048 x 2732
|
||||
elif [ "$shorter_side" -ge 2000 ] && [ "$longer_side" -ge 2700 ]; then
|
||||
echo "ipad_pro_12_9_2nd_gen"
|
||||
# iPhone 6.9" display (iPhone Air Pro Max, 16 Pro Max, etc.): 1320 x 2868
|
||||
elif [ "$shorter_side" -ge 1300 ] && [ "$longer_side" -ge 2800 ]; then
|
||||
echo "iphone_6_9"
|
||||
# iPhone 6.7" display (iPhone 14 Pro Max, etc.): 1290 x 2796
|
||||
elif [ "$shorter_side" -ge 1250 ] && [ "$longer_side" -ge 2700 ]; then
|
||||
echo "iphone_6_7"
|
||||
# iPhone 6.3" display (iPhone 17, 16 Pro, 15 Pro, 14 Pro): 1206 x 2622
|
||||
elif [ "$shorter_side" -ge 1200 ] && [ "$shorter_side" -lt 1242 ] && [ "$longer_side" -ge 2600 ] && [ "$longer_side" -lt 2688 ]; then
|
||||
echo "iphone_6_3"
|
||||
# iPhone 6.5" display (iPhone 14 Plus, 13 Pro Max, 11 Pro Max, XS Max, etc.): 1242 x 2688 or 1284 x 2778
|
||||
elif [ "$shorter_side" -ge 1200 ] && [ "$longer_side" -ge 2600 ]; then
|
||||
echo "iphone_6_5"
|
||||
# iPhone 5.5" display (iPhone 8 Plus, etc.): 1242 x 2208
|
||||
elif [ "$shorter_side" -ge 1200 ] && [ "$longer_side" -ge 2200 ]; then
|
||||
echo "iphone_5_5"
|
||||
else
|
||||
# Default to 6.5" for unknown iPhone sizes
|
||||
echo "iphone_6_5"
|
||||
fi
|
||||
}
|
||||
|
||||
# Run Flutter app on specified device
|
||||
run_flutter_app() {
|
||||
local device_id="$1"
|
||||
local device_type="$2"
|
||||
|
||||
log_info "Running Flutter app on $device_type ($device_id)"
|
||||
|
||||
cd "$PROJECT_ROOT"
|
||||
flutter run -d "$device_id" --hot &
|
||||
local flutter_pid=$!
|
||||
|
||||
# Wait for app to be installed and launched
|
||||
log_info "Waiting for Flutter app to launch..."
|
||||
sleep 40 # iOS typically takes longer to launch
|
||||
|
||||
# Check if simulator is still running
|
||||
local state=$(xcrun simctl list devices | grep "$device_id" | grep -oE "(Booted|Shutdown)")
|
||||
if [ "$state" = "Booted" ]; then
|
||||
log_success "Flutter app should be running on $device_type"
|
||||
return 0
|
||||
else
|
||||
log_error "Simulator not running anymore"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Map device type to fastlane naming convention
|
||||
get_fastlane_device_name() {
|
||||
local device_type="$1"
|
||||
|
||||
case "$device_type" in
|
||||
ipad_pro_12_9_3rd_gen|ipad_pro_12_9_2nd_gen)
|
||||
echo "IPAD_PRO_3GEN_129"
|
||||
;;
|
||||
iphone_6_9)
|
||||
echo "IPHONE_69"
|
||||
;;
|
||||
iphone_6_7)
|
||||
echo "IPHONE_67"
|
||||
;;
|
||||
iphone_6_5)
|
||||
echo "IPHONE_65"
|
||||
;;
|
||||
iphone_6_3)
|
||||
echo "IPHONE_63"
|
||||
;;
|
||||
iphone_5_5)
|
||||
echo "IPHONE_55"
|
||||
;;
|
||||
*)
|
||||
echo "IPHONE_67" # Default to 6.7"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Organize screenshots into correct fastlane folders
|
||||
organize_screenshots() {
|
||||
log_info "Organizing screenshots using ffprobe analysis..."
|
||||
|
||||
# Ensure target directory exists
|
||||
mkdir -p "$FASTLANE_SCREENSHOTS_DIR"
|
||||
|
||||
# Find all screenshot files generated by maestro
|
||||
local ios_screenshots_dir="$MAESTRO_DIR/ios"
|
||||
if [ ! -d "$ios_screenshots_dir" ]; then
|
||||
log_warning "No iOS screenshots directory found at $ios_screenshots_dir"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local screenshots=($(find "$ios_screenshots_dir" -name "*.png" | sort))
|
||||
|
||||
if [ ${#screenshots[@]} -eq 0 ]; then
|
||||
log_warning "No iOS screenshots found in $ios_screenshots_dir"
|
||||
return 1
|
||||
fi
|
||||
|
||||
log_info "Found ${#screenshots[@]} screenshots"
|
||||
|
||||
# First pass: detect and log all device types
|
||||
local device_types=()
|
||||
for screenshot in "${screenshots[@]}"; do
|
||||
local device_type=$(detect_ios_device_type "$screenshot")
|
||||
log_image_info "$screenshot" "$device_type"
|
||||
|
||||
# Add to device_types if not already present
|
||||
local found=0
|
||||
for dt in "${device_types[@]}"; do
|
||||
if [ "$dt" = "$device_type" ]; then
|
||||
found=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [ $found -eq 0 ]; then
|
||||
device_types+=("$device_type")
|
||||
fi
|
||||
done
|
||||
|
||||
# Second pass: copy and rename screenshots for each device type
|
||||
for device_type in "${device_types[@]}"; do
|
||||
local fastlane_name=$(get_fastlane_device_name "$device_type")
|
||||
local count=0
|
||||
|
||||
for screenshot in "${screenshots[@]}"; do
|
||||
local detected_type=$(detect_ios_device_type "$screenshot")
|
||||
|
||||
# Only process screenshots matching this device type
|
||||
if [ "$detected_type" = "$device_type" ]; then
|
||||
# Format: {index}_APP_{DEVICE_TYPE}_{index}.png
|
||||
local target_name="${count}_APP_${fastlane_name}_${count}.png"
|
||||
cp "$screenshot" "$FASTLANE_SCREENSHOTS_DIR/$target_name"
|
||||
|
||||
log_success "Copied $device_type screenshot: $(basename "$screenshot") -> $target_name"
|
||||
count=$((count + 1))
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
log_success "Screenshot organization completed"
|
||||
}
|
||||
|
||||
# Cleanup function
|
||||
cleanup() {
|
||||
log_info "Cleaning up..."
|
||||
|
||||
# Kill any running Flutter processes
|
||||
pkill -f "flutter run" 2>/dev/null || true
|
||||
|
||||
# Stop simulators
|
||||
stop_simulators
|
||||
|
||||
log_success "Cleanup completed"
|
||||
}
|
||||
|
||||
# Main execution
|
||||
main() {
|
||||
log_info "Starting iOS screenshot automation..."
|
||||
|
||||
# Set up cleanup trap
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
# Clean up old screenshots at the very beginning
|
||||
clean_old_screenshots "ios"
|
||||
|
||||
# Clean up old fastlane screenshots to prevent mixing old/new with different naming
|
||||
log_info "Cleaning old fastlane screenshots..."
|
||||
if [ -d "$FASTLANE_SCREENSHOTS_DIR" ]; then
|
||||
rm -rf "$FASTLANE_SCREENSHOTS_DIR"/*
|
||||
log_success "Fastlane screenshots directory cleaned"
|
||||
fi
|
||||
|
||||
# Check dependencies
|
||||
check_dependencies
|
||||
|
||||
# Stop any running simulators first
|
||||
stop_simulators
|
||||
|
||||
# Get available simulators
|
||||
log_info "Getting available iOS Simulators..."
|
||||
|
||||
local simulators_raw=$(get_simulators)
|
||||
if [ -z "$simulators_raw" ]; then
|
||||
log_error "No iOS Simulators found. Please install simulators via Xcode."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Parse simulators into arrays
|
||||
declare -a simulator_udids
|
||||
declare -a simulator_names
|
||||
|
||||
while IFS='|' read -r udid name; do
|
||||
simulator_udids+=("$udid")
|
||||
simulator_names+=("$name")
|
||||
done <<< "$simulators_raw"
|
||||
|
||||
log_info "Found ${#simulator_udids[@]} iOS Simulator(s)"
|
||||
|
||||
# Find iPhone Air and iPad Pro 13" simulators
|
||||
local iphone_idx=-1
|
||||
local ipad_idx=-1
|
||||
|
||||
for i in "${!simulator_names[@]}"; do
|
||||
if [[ "${simulator_names[$i]}" =~ iPhone\ Air ]] && [ $iphone_idx -eq -1 ]; then
|
||||
iphone_idx=$i
|
||||
log_info "Found iPhone Air: ${simulator_names[$i]}"
|
||||
elif [[ "${simulator_names[$i]}" =~ iPad.*13 ]] && [ $ipad_idx -eq -1 ]; then
|
||||
ipad_idx=$i
|
||||
log_info "Found iPad Pro 13\": ${simulator_names[$i]}"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $iphone_idx -eq -1 ]; then
|
||||
log_error "iPhone Air simulator not found. Please create it in Xcode."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ $ipad_idx -eq -1 ]; then
|
||||
log_error "iPad Pro 13\" simulator not found. Please create it in Xcode."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "Using iPhone: ${simulator_names[$iphone_idx]}"
|
||||
log_info "Using iPad: ${simulator_names[$ipad_idx]}"
|
||||
|
||||
# Start iPhone Air simulator
|
||||
start_simulator "${simulator_udids[$iphone_idx]}" "${simulator_names[$iphone_idx]}" "iPhone Air"
|
||||
|
||||
# Run Flutter app on iPhone Air
|
||||
run_flutter_app "${simulator_udids[$iphone_idx]}" "iPhone Air"
|
||||
|
||||
# Run maestro tests for iPhone Air
|
||||
run_maestro_tests "${simulator_udids[$iphone_idx]}"
|
||||
|
||||
# Stop iPhone simulator and switch to iPad
|
||||
log_info "Switching from iPhone Air to iPad Pro 13\" simulator"
|
||||
stop_simulators
|
||||
|
||||
# Start iPad Pro 13" simulator
|
||||
start_simulator "${simulator_udids[$ipad_idx]}" "${simulator_names[$ipad_idx]}" "iPad Pro 13\""
|
||||
|
||||
# Rotate iPad to landscape
|
||||
# rotate_simulator_landscape "${simulator_udids[$ipad_idx]}"
|
||||
|
||||
# Run Flutter app on iPad
|
||||
run_flutter_app "${simulator_udids[$ipad_idx]}" "iPad Pro 13\""
|
||||
|
||||
# Run maestro tests for iPad
|
||||
run_maestro_tests "${simulator_udids[$ipad_idx]}"
|
||||
|
||||
# Organize screenshots
|
||||
organize_screenshots
|
||||
|
||||
log_success "iOS screenshot automation completed successfully!"
|
||||
}
|
||||
|
||||
# Run main function if script is executed directly
|
||||
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||
main "$@"
|
||||
fi
|
||||
@@ -1,184 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Screenshot Automation Common Functions
|
||||
# Shared functionality between Android and iOS screenshot scripts
|
||||
|
||||
# This script should be sourced, not executed directly
|
||||
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||
echo "This script should be sourced, not executed directly"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Configuration - these should be set before sourcing this file, but defaults provided
|
||||
SCRIPT_DIR="${SCRIPT_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)}"
|
||||
PROJECT_ROOT="${PROJECT_ROOT:-$(dirname "$SCRIPT_DIR")}"
|
||||
MAESTRO_DIR="${MAESTRO_DIR:-$PROJECT_ROOT/maestro}"
|
||||
ENV_FILE="${ENV_FILE:-$PROJECT_ROOT/.env}"
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Logging functions
|
||||
log_info() {
|
||||
echo -e "${BLUE}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
log_success() {
|
||||
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
||||
}
|
||||
|
||||
log_warning() {
|
||||
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
# Check common dependencies (flutter, maestro, dotenv, ffprobe)
|
||||
check_common_dependencies() {
|
||||
log_info "Checking common dependencies..."
|
||||
|
||||
local all_found=true
|
||||
|
||||
if ! command -v flutter &> /dev/null; then
|
||||
log_error "Flutter is not installed or not in PATH"
|
||||
all_found=false
|
||||
fi
|
||||
|
||||
if ! command -v maestro &> /dev/null; then
|
||||
log_error "Maestro is not installed or not in PATH"
|
||||
all_found=false
|
||||
fi
|
||||
|
||||
if ! command -v dotenv &> /dev/null; then
|
||||
log_error "dotenv is not installed or not in PATH"
|
||||
all_found=false
|
||||
fi
|
||||
|
||||
if ! command -v ffprobe &> /dev/null; then
|
||||
log_error "ffprobe is not installed or not in PATH (part of ffmpeg)"
|
||||
all_found=false
|
||||
fi
|
||||
|
||||
if [ "$all_found" = false ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
log_success "Common dependencies found"
|
||||
return 0
|
||||
}
|
||||
|
||||
# Get image dimensions using ffprobe
|
||||
get_image_dimensions() {
|
||||
local image_path="$1"
|
||||
ffprobe -v quiet -select_streams v:0 -show_entries stream=width,height -of csv=p=0 "$image_path" 2>/dev/null
|
||||
}
|
||||
|
||||
# Log image information for debugging
|
||||
log_image_info() {
|
||||
local image_path="$1"
|
||||
local device_type="$2"
|
||||
|
||||
local dimensions=$(get_image_dimensions "$image_path")
|
||||
local filename=$(basename "$image_path")
|
||||
|
||||
if [ -n "$dimensions" ]; then
|
||||
local width=$(echo "$dimensions" | cut -d',' -f1)
|
||||
local height=$(echo "$dimensions" | cut -d',' -f2)
|
||||
log_info "Screenshot: $filename - ${width}x${height} - $device_type"
|
||||
else
|
||||
log_warning "Could not analyze: $filename - assuming $device_type"
|
||||
fi
|
||||
}
|
||||
|
||||
# Clean up old maestro screenshots for specified platform(s)
|
||||
# Usage: clean_old_screenshots "android" or clean_old_screenshots "ios" or clean_old_screenshots "android ios"
|
||||
clean_old_screenshots() {
|
||||
local platforms="$1"
|
||||
|
||||
log_info "Cleaning up old screenshots..."
|
||||
|
||||
for platform in $platforms; do
|
||||
local platform_dir="$MAESTRO_DIR/$platform"
|
||||
|
||||
if [ -d "$platform_dir" ]; then
|
||||
local old_count=$(find "$platform_dir" -name "*.png" 2>/dev/null | wc -l)
|
||||
if [ "$old_count" -gt 0 ]; then
|
||||
log_info "Removing $old_count old screenshot(s) from maestro/$platform/"
|
||||
rm -f "$platform_dir"/*.png
|
||||
else
|
||||
log_info "No old screenshots found in maestro/$platform/"
|
||||
fi
|
||||
else
|
||||
log_info "No $platform screenshot directory found"
|
||||
fi
|
||||
done
|
||||
|
||||
log_success "Screenshot cleanup completed"
|
||||
}
|
||||
|
||||
# Execute maestro tests
|
||||
# Usage: run_maestro_tests [device_id]
|
||||
run_maestro_tests() {
|
||||
local device_id="${1:-}"
|
||||
|
||||
if [ -n "$device_id" ]; then
|
||||
log_info "Running maestro screenshot tests on device $device_id..."
|
||||
else
|
||||
log_info "Running maestro screenshot tests..."
|
||||
fi
|
||||
|
||||
# Check if .env file exists
|
||||
if [ ! -f "$ENV_FILE" ]; then
|
||||
log_error "Environment file not found at $ENV_FILE"
|
||||
log_info "Please create a .env file with required Maestro variables"
|
||||
return 1
|
||||
fi
|
||||
|
||||
log_info "Using environment file: $ENV_FILE"
|
||||
cd "$MAESTRO_DIR"
|
||||
|
||||
# Run maestro tests with optional device specification
|
||||
if [ -n "$device_id" ]; then
|
||||
log_info "Executing: MAESTRO_DEVICE=$device_id dotenv -f $ENV_FILE run maestro test screenshots.yaml"
|
||||
MAESTRO_DEVICE="$device_id" dotenv -f "$ENV_FILE" run maestro test screenshots.yaml
|
||||
else
|
||||
log_info "Executing: dotenv -f $ENV_FILE run maestro test screenshots.yaml"
|
||||
dotenv -f "$ENV_FILE" run maestro test screenshots.yaml
|
||||
fi
|
||||
|
||||
local maestro_exit_code=$?
|
||||
if [ $maestro_exit_code -eq 0 ]; then
|
||||
log_success "Maestro tests completed successfully"
|
||||
return 0
|
||||
else
|
||||
log_error "Maestro tests failed with exit code $maestro_exit_code"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Run Flutter app on specified device
|
||||
# Platform-specific validation should be done in the calling script
|
||||
run_flutter_app() {
|
||||
local device_id="$1"
|
||||
local device_type="$2"
|
||||
local wait_time="${3:-30}" # Optional wait time, default 30s
|
||||
|
||||
log_info "Running Flutter app on $device_type ($device_id)"
|
||||
|
||||
cd "$PROJECT_ROOT"
|
||||
flutter run -d "$device_id" --hot &
|
||||
local flutter_pid=$!
|
||||
|
||||
# Wait for app to be installed and launched
|
||||
log_info "Waiting for Flutter app to launch..."
|
||||
sleep "$wait_time"
|
||||
|
||||
log_success "Flutter app should be running on $device_type"
|
||||
return 0
|
||||
}
|
||||
Reference in New Issue
Block a user