Cross-platform screenshot automation tool for mobile apps using Appium.
Snappium automates the process of taking screenshots across multiple devices, languages, and orientations for mobile applications. It supports both iOS simulators and Android emulators, with action-driven configuration for flexible navigation workflows.
- Cross-Platform: Support for both iOS and Android apps
- Multi-Language: Automated language switching and locale configuration
- Action-Driven: Flexible navigation using configurable actions (tap, wait, capture)
- Sequential Execution: Jobs executed one at a time with proper device isolation and cleanup
- Rich Configuration: JSON-based configuration with schema validation and centralized defaults
- Graceful Shutdown: Proper cleanup of all managed processes on interruption (Ctrl+C)
- Failure Handling: Automatic artifact collection (page source, screenshots, device logs) with process cleanup
- Status Bar Control: Demo mode and status bar customization
- Artifact-Based: Uses pre-built app artifacts (no build integration)
- Comprehensive Logging: Colored console output with verbose mode
Ensure you have the following tools installed:
- .NET 9.0 SDK or later
- Node.js (for Appium)
- Appium with iOS and Android drivers:
npm install -g appium appium driver install uiautomator2 appium driver install xcuitest
- Xcode Command Line Tools (macOS only, for iOS):
xcode-select --install
- Android SDK with emulator support
- Java 11+ (for Android)
Clone the repository and install from source:
# Clone the repository
git clone https://github.com/QotoQot/Snappium.git
cd Snappium
# Pack the CLI tool
dotnet pack Snappium/Snappium.Cli/ -c Release
# Install globally from local source
dotnet tool install --global --add-source ./Snappium/Snappium.Cli/bin/Release Snappium.CliVerify installation:
snappium --helpStart with the sample configuration:
# Download sample configuration
curl -o screenshot_config.json https://raw.githubusercontent.com/QotoQot/Snappium/refs/heads/main/samples/screenshot_config.json
# Or create from scratch using the schema
curl -o schema.json https://raw.githubusercontent.com/QotoQot/Snappium/refs/heads/main/schema/screenshot_config.schema.jsonsnappium validate-config --config screenshot_config.jsonSee what screenshots will be generated:
snappium generate-matrix --config screenshot_config.jsonExecute a dry run to see the plan:
snappium run --config screenshot_config.json --dry-runRun for real:
snappium run --config screenshot_config.jsonSnappium uses a JSON configuration file that defines devices, languages, screenshots, and automation behavior.
{
"Devices": {
"Ios": [
{
"Name": "iPhone 15",
"Udid": null,
"Folder": "iPhone_15_6.1",
"PlatformVersion": "17.5"
}
],
"Android": [
{
"Name": "Pixel 7",
"Avd": "Pixel_7_API_34",
"Folder": "Phone_6.1",
"PlatformVersion": "14"
}
]
},
"Languages": ["en-US", "es-ES"],
"LocaleMapping": {
"en-US": {"Ios": "en_US", "Android": "en_US"},
"es-ES": {"Ios": "es_ES", "Android": "es_ES"}
},
"Artifacts": {
"Ios": {
"ArtifactGlob": "iOS/bin/Release/net9.0-ios/**/*.app",
"Package": "com.example.ios.app"
},
"Android": {
"ArtifactGlob": "Droid/bin/Release/net9.0-android/**/*.apk",
"Package": "com.example.app"
}
},
"Screenshots": [
{
"Name": "01_home",
"Orientation": "portrait",
"Actions": [
{
"WaitFor": {
"Selector": {"accessibility_id": "main-view"},
"TimeoutMs": 5000
}
},
{"Capture": {"Name": "01_home"}}
]
}
]
}Snappium supports various actions for navigation:
{
"Tap": {"accessibility_id": "button-id"}
}{
"Wait": {"Seconds": 2.5}
}{
"WaitFor": {
"Selector": {"accessibility_id": "continue-button"},
"TimeoutMs": 5000
}
}{
"Capture": {"Name": "screen_name"}
}Multiple selector strategies are supported:
accessibility_id: Accessibility identifierxpath: XPath expressionclass_chain: iOS class chain (iOS only)uiautomator: UiAutomator selector (Android only)id: Element ID
Execute screenshot automation:
snappium run --config screenshot_config.json [options]Options:
--platforms ios,android: Filter platforms--devices iPhone15,Pixel7: Filter devices--langs en-US,es-ES: Filter languages--screens home,settings: Filter screenshots--output ./Screenshots: Output directory--ios-app path/to/app.app: iOS app path override--android-app path/to/app.apk: Android app path override--base-port 4723: Appium base port--dry-run: Print plan without executing--verbose: Enable verbose logging
Validate configuration file:
snappium validate-config --config screenshot_config.jsonDisplay test matrix:
snappium generate-matrix --config screenshot_config.json [filters]Snappium requires pre-built app artifacts. Configure paths to your built apps:
{
"Artifacts": {
"Ios": {
"ArtifactGlob": "iOS/bin/Release/net9.0-ios/**/*.app",
"Package": "com.example.ios.app"
},
"Android": {
"ArtifactGlob": "Droid/bin/Release/net9.0-android/**/*.apk",
"Package": "com.example.app"
}
}
}Important: Build your apps before running Snappium. The tool will locate artifacts using the glob patterns and install them on devices using the specified package identifiers.
Configure demo status bars:
{
"StatusBar": {
"Ios": {
"Time": "9:41",
"WifiBars": 3,
"CellularBars": 4,
"BatteryState": "charged"
},
"Android": {
"DemoMode": true,
"Clock": "1200",
"Battery": 100,
"Wifi": "4"
}
}
}Snappium always performs fresh app installations between runs to ensure clean state. Apps are uninstalled and reinstalled for each language/device combination, eliminating configuration complexity and ensuring consistent results.
Validate screenshot dimensions:
{
"Validation": {
"EnforceImageSize": true,
"ExpectedSizes": {
"Ios": {
"iPhone_15_6.1": {
"Portrait": [393, 852],
"Landscape": [852, 393]
}
}
}
}
}Automatic failure debugging:
{
"FailureArtifacts": {
"SavePageSource": true,
"SaveScreenshot": true,
"SaveDeviceLogs": true,
"ArtifactsDir": "failure_artifacts"
}
}Automatically dismiss common popups:
{
"Dismissors": {
"Ios": [
{"AccessibilityId": "Allow"},
{"AccessibilityId": "OK"}
],
"Android": [
{"Id": "android:id/button1"}
]
}
}Configure port ranges for Appium servers and emulator management:
{
"ports": {
"basePort": 4723,
"portOffset": 10,
"emulatorStartPort": 5554,
"emulatorEndPort": 5600
}
}Port Settings:
basePort: Starting port for Appium servers (default: 4723)portOffset: Port spacing for sequential job execution (default: 10)emulatorStartPort: Starting port for Android emulator allocation (default: 5554)emulatorEndPort: Ending port for Android emulator allocation (default: 5600)
All default values are centrally managed and can be overridden in configuration or via command-line options.
Snappium generates:
- Screenshots: Organized by platform/device/language/screenshot
- Manifest JSON:
run_manifest.jsonwith detailed results - Summary Text:
run_summary.txtwith human-readable summary - Failure Artifacts: Page source, screenshots, and logs on failures
Example output structure:
Screenshots/
├── ios/
│ └── iPhone_15_6.1/
│ └── en-US/
│ ├── 01_home.png
│ └── 02_settings.png
├── android/
│ └── Phone_6.1/
│ └── en-US/
│ ├── 01_home.png
│ └── 02_settings.png
├── run_manifest.json
└── run_summary.txt
# Run only iOS devices in English
snappium run --config config.json --platforms ios --langs en-US# Run Android with multiple languages
snappium run --config config.json --platforms android --langs en-US,es-ES,de-DE# Run only specific screenshots
snappium run --config config.json --screens home,settings,profile# Run with detailed logging
snappium run --config config.json --verbose# Override artifact paths
snappium run --config config.json \
--ios-app ./iOS.app \
--android-app ./app-release.apk-
Graceful Shutdown
# Interrupt execution safely with Ctrl+C # Snappium will clean up all managed processes: # - Stop Appium servers # - Shutdown emulators/simulators # - Clean up temporary resources
-
Appium Server Conflicts
# Kill existing Appium processes pkill -f appium # Use custom port snappium run --config config.json --base-port 4724
-
iOS Simulator Issues
# Reset simulators xcrun simctl erase all # Boot specific simulator xcrun simctl boot "iPhone 15"
-
Android Emulator Issues
# List available AVDs emulator -list-avds # Start specific emulator emulator @Pixel_7_API_34
-
Missing Artifacts
# Build your apps first dotnet build -c Release # Check artifact paths match your configuration snappium validate-config --config config.json
Enable verbose logging for detailed output:
snappium run --config config.json --verboseThis shows:
- Colored console output with timestamps
- Shell command execution details
- Job-scoped logging with prefixes
- Enhanced error reporting
Validate your configuration:
snappium validate-config --config screenshot_config.jsonCommon validation errors:
- Invalid device folder names
- Missing required fields
- Invalid selector syntax
- Locale mapping mismatches
For more detailed information:
- Architecture Guide - Comprehensive overview of Snappium's system architecture, components, and orchestration flow
- Troubleshooting Guide - Detailed troubleshooting steps for common issues, setup problems, and debugging techniques
- Appium - Mobile automation framework
- Appium .NET Client - .NET bindings for Appium
- System.CommandLine - Command line parsing for .NET