Command line interface for Percy visual testing platform that enables developers to capture, upload, and manage visual snapshots for web applications.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Specialized commands for visual testing of native mobile applications with Percy's app testing platform. These commands provide Percy's visual testing capabilities for iOS and Android applications.
Execute command with Percy environment configured for native app visual testing. Similar to percy exec but optimized for mobile app testing workflows.
/**
* Execute command with Percy for native apps
* Starts Percy in app mode, runs command, then stops Percy
* Optimized for mobile app testing with native SDKs
*
* Usage: percy app exec -- <command>
*
* Arguments:
* command Command to execute (required, after --)
*
* Configuration:
* projectType: 'app' Native app project type
* server: true Percy server enabled
* skipDiscovery: true Asset discovery disabled (not needed for apps)
*
* Environment variables set:
* PERCY_SERVER_ADDRESS Local Percy server URL
* PERCY_BUILD_ID Current build identifier
* PERCY_BUILD_URL Percy dashboard URL for build
* PERCY_LOGLEVEL Current logging level
*/
percy app exec -- <command>Usage Examples:
# iOS testing with XCTest
percy app exec -- xcodebuild test -project MyApp.xcodeproj -scheme MyAppTests
# Android testing with Espresso
percy app exec -- ./gradlew connectedAndroidTest
# React Native testing
percy app exec -- npm run test:e2e:ios
percy app exec -- npm run test:e2e:android
# Flutter testing
percy app exec -- flutter test integration_test/Start Percy process specifically configured for native app testing. Creates a build and starts the server in app mode.
/**
* Start Percy process for native applications
* Initializes Percy server in app mode for mobile testing
* Must be paired with 'percy app stop' to finalize build
*
* Usage: percy app start
*
* Configuration:
* projectType: 'app' Native app project type
* server: true Percy server enabled
* skipDiscovery: true Asset discovery disabled
*/
percy app startUsage Examples:
# Start Percy for app testing
percy app start
# Run your app tests (Percy server available for native SDKs)
xcodebuild test -project MyApp.xcodeproj -scheme MyAppTests
# Stop Percy when done
percy app stopStop the Percy app process and finalize the build. Uploads any remaining snapshots and marks the build as complete.
/**
* Stop Percy app process and finalize build
* Uploads pending snapshots and marks build as complete
* Should be called after 'percy app start' and test execution
*
* Usage: percy app stop
*/
percy app stopUsage Examples:
# Stop Percy app process
percy app stop
# Use in scripts
percy app start
./run-app-tests.sh
percy app stopCheck if Percy app process is running and responsive. Useful for debugging and health checks in app testing environments.
/**
* Check if Percy app process is running
* Tests connectivity to local Percy server in app mode
*
* Usage: percy app ping
*
* Exit codes:
* 0 - Percy app is running and responsive
* 1 - Percy app is not running or not responsive
*/
percy app pingUsage Examples:
# Check if Percy app is running
percy app ping
echo $? # 0 if running, 1 if not
# Use in conditional scripts
if percy app ping; then
echo "Percy app is running"
else
echo "Percy app is not running"
percy app start
fiPercy app commands work with the Percy iOS SDK to capture screenshots during XCTest execution:
// In your XCTest files
import Percy
class MyAppUITests: XCTestCase {
func testHomeScreen() {
let app = XCUIApplication()
app.launch()
// Navigate to home screen
app.buttons["Home"].tap()
// Capture Percy snapshot
Percy.screenshot(name: "Home Screen")
}
func testProfileScreen() {
let app = XCUIApplication()
app.launch()
// Navigate to profile
app.tabBars.buttons["Profile"].tap()
// Capture with options
Percy.screenshot(name: "Profile Screen", options: [
"widths": [375, 414]
])
}
}# Run tests with Percy
percy app exec -- xcodebuild test \
-project MyApp.xcodeproj \
-scheme MyAppUITests \
-destination 'platform=iOS Simulator,name=iPhone 13'Integration with Android Espresso tests using Percy Android SDK:
// In your Android test files
import io.percy.espresso.Percy
@RunWith(AndroidJUnit4::class)
class MainActivityTest {
@get:Rule
val activityRule = ActivityTestRule(MainActivity::class.java)
@Test
fun testHomeScreen() {
// Navigate to home screen
onView(withId(R.id.home_button)).perform(click())
// Capture Percy snapshot
Percy.screenshot(activityRule.activity, "Home Screen")
}
@Test
fun testProfileScreen() {
// Navigate to profile
onView(withId(R.id.profile_tab)).perform(click())
// Capture with options
val options = mutableMapOf<String, Any>()
options["widths"] = listOf(375, 414)
Percy.screenshot(activityRule.activity, "Profile Screen", options)
}
}# Run Android tests with Percy
percy app exec -- ./gradlew connectedAndroidTestIntegration with React Native testing frameworks:
// detox-tests.js (Detox example)
import { device, element, by } from 'detox';
import { percyScreenshot } from '@percy/detox';
describe('React Native App', () => {
beforeAll(async () => {
await device.launchApp();
});
it('should display home screen correctly', async () => {
await element(by.id('home-screen')).waitToBeVisible();
// Capture Percy snapshot
await percyScreenshot(device, 'Home Screen');
});
it('should display profile screen correctly', async () => {
await element(by.id('profile-tab')).tap();
await element(by.id('profile-screen')).waitToBeVisible();
// Capture with options
await percyScreenshot(device, 'Profile Screen', {
widths: [375, 414]
});
});
});# Run Detox tests with Percy
percy app exec -- detox test --configuration ios.sim.debugIntegration with Flutter integration tests:
// integration_test/app_test.dart
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:percy_flutter/percy_flutter.dart';
import 'package:myapp/main.dart' as app;
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
group('App Screenshots', () {
testWidgets('Home screen', (WidgetTester tester) async {
app.main();
await tester.pumpAndSettle();
// Navigate to home
await tester.tap(find.text('Home'));
await tester.pumpAndSettle();
// Capture Percy snapshot
await PercyFlutter.screenshot('Home Screen');
});
testWidgets('Profile screen', (WidgetTester tester) async {
app.main();
await tester.pumpAndSettle();
// Navigate to profile
await tester.tap(find.text('Profile'));
await tester.pumpAndSettle();
// Capture with options
await PercyFlutter.screenshot('Profile Screen',
widths: [375, 414]);
});
});
}# Run Flutter integration tests with Percy
percy app exec -- flutter test integration_test/Percy app commands use specialized configuration optimized for mobile testing:
# .percy.yml for app projects
version: 2
app:
projectType: 'app'
server: true
skipDiscovery: true
snapshot:
widths: [375, 414, 768] # Common mobile widths
minHeight: 667App commands set specific environment variables:
# Set by Percy app commands
PERCY_SERVER_ADDRESS # Local Percy server URL
PERCY_BUILD_ID # Current build identifier
PERCY_BUILD_URL # Percy dashboard URL for build
PERCY_LOGLEVEL # Current logging level
# App-specific configuration
PERCY_PROJECT_TYPE=app # Identifies as app project
PERCY_SKIP_DISCOVERY=true # Disables web asset discovery# Test on specific iOS simulator
percy app exec -- xcodebuild test \
-project MyApp.xcodeproj \
-scheme MyAppUITests \
-destination 'platform=iOS Simulator,name=iPhone 13 Pro'
# Test on multiple simulators
percy app exec -- xcodebuild test \
-project MyApp.xcodeproj \
-scheme MyAppUITests \
-destination 'platform=iOS Simulator,name=iPhone 13' \
-destination 'platform=iOS Simulator,name=iPad Air'# Test on specific Android emulator
percy app exec -- ./gradlew connectedAndroidTest
# Test with specific device configuration
percy app exec -- ./gradlew connectedAndroidTest \
-Pandroid.testInstrumentationRunnerArguments.size=medium# iOS physical device testing
percy app exec -- xcodebuild test \
-project MyApp.xcodeproj \
-scheme MyAppUITests \
-destination 'platform=iOS,name=My iPhone'
# Android physical device testing
percy app exec -- ./gradlew connectedAndroidTest \
-Pandroid.testInstrumentationRunnerArguments.device=physical# .github/workflows/app-visual-tests.yml
name: App Visual Tests
on: [push, pull_request]
jobs:
ios-tests:
runs-on: macos-latest
steps:
- uses: actions/checkout@v2
- name: Setup iOS Simulator
run: |
xcrun simctl boot "iPhone 13"
- name: Run Percy iOS tests
env:
PERCY_TOKEN: ${{ secrets.PERCY_TOKEN }}
run: |
percy app exec -- xcodebuild test \
-project MyApp.xcodeproj \
-scheme MyAppUITests \
-destination 'platform=iOS Simulator,name=iPhone 13'
android-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup Android Emulator
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: 29
script: |
export PERCY_TOKEN=${{ secrets.PERCY_TOKEN }}
percy app exec -- ./gradlew connectedAndroidTestpipeline {
agent any
environment {
PERCY_TOKEN = credentials('percy-token')
}
stages {
stage('iOS Tests') {
steps {
sh '''
percy app exec -- xcodebuild test \
-project MyApp.xcodeproj \
-scheme MyAppUITests \
-destination 'platform=iOS Simulator,name=iPhone 13'
'''
}
}
stage('Android Tests') {
steps {
sh '''
percy app exec -- ./gradlew connectedAndroidTest
'''
}
}
}
}# Handle simulator/emulator startup issues
if ! xcrun simctl list | grep -q "iPhone 13 (Booted)"; then
echo "Starting iOS Simulator..."
xcrun simctl boot "iPhone 13"
sleep 10
fi
percy app exec -- xcodebuild test -project MyApp.xcodeproj -scheme MyAppUITests
# Handle Android emulator issues
adb wait-for-device
adb shell input keyevent 82 # Unlock device
percy app exec -- ./gradlew connectedAndroidTest# Enable debug logging
PERCY_LOGLEVEL=debug percy app exec -- npm run test:e2e
# Check Percy server status
percy app ping || {
echo "Percy app server not responding"
percy app stop
percy app start
}
# Verify SDK integration
# Check that native SDK calls are reaching Percy server
tail -f ~/.percy/logs/percy.log# Organize tests by feature
percy app exec -- xcodebuild test \
-project MyApp.xcodeproj \
-scheme AuthenticationTests
percy app exec -- xcodebuild test \
-project MyApp.xcodeproj \
-scheme NavigationTests
percy app exec -- xcodebuild test \
-project MyApp.xcodeproj \
-scheme ProfileTests// Use descriptive, hierarchical names
Percy.screenshot(name: "Login - Empty Form")
Percy.screenshot(name: "Login - With Errors")
Percy.screenshot(name: "Login - Success")
Percy.screenshot(name: "Profile - View Mode")
Percy.screenshot(name: "Profile - Edit Mode")
Percy.screenshot(name: "Profile - Saving State")# Run tests in parallel where possible
percy app exec -- xcodebuild test \
-project MyApp.xcodeproj \
-scheme MyAppUITests \
-parallel-testing-enabled YES
# Use specific test classes to reduce runtime
percy app exec -- xcodebuild test \
-project MyApp.xcodeproj \
-scheme MyAppUITests \
-only-testing:MyAppUITests/LoginTestsInstall with Tessl CLI
npx tessl i tessl/npm-percy--cli