CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-percy--cli

Command line interface for Percy visual testing platform that enables developers to capture, upload, and manage visual snapshots for web applications.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

app-snapshots.mddocs/

App Snapshots

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.

Capabilities

Percy App Exec

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/

Percy App Start

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 start

Usage 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 stop

Percy App Stop

Stop 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 stop

Usage Examples:

# Stop Percy app process
percy app stop

# Use in scripts
percy app start
./run-app-tests.sh
percy app stop

Percy App Ping

Check 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 ping

Usage 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
fi

Native SDK Integration

iOS Integration (Swift/Objective-C)

Percy 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'

Android Integration (Java/Kotlin)

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 connectedAndroidTest

React Native Integration

Integration 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.debug

Flutter Integration

Integration 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/

Configuration

App-Specific Settings

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: 667

Environment Variables

App 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

Device and Simulator Support

iOS Simulators

# 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'

Android Emulators

# Test on specific Android emulator
percy app exec -- ./gradlew connectedAndroidTest

# Test with specific device configuration
percy app exec -- ./gradlew connectedAndroidTest \
  -Pandroid.testInstrumentationRunnerArguments.size=medium

Physical Devices

# 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

CI/CD Integration

GitHub Actions

# .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 connectedAndroidTest

Jenkins Pipeline

pipeline {
    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
                '''
            }
        }
    }
}

Error Handling

Common Issues

# 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

Debugging

# 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

Best Practices

Test Organization

# 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

Screenshot Naming

// 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")

Performance Optimization

# 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/LoginTests

Install with Tessl CLI

npx tessl i tessl/npm-percy--cli

docs

app-snapshots.md

build-management.md

configuration.md

core-operations.md

image-uploads.md

index.md

programmatic-api.md

static-snapshots.md

tile.json