Claude
Skills
Sign in
Back

automating-screenshots

Included with Lifetime
$97 forever

Fastlane snapshot and screengrab for automated App Store and Play Store screenshots. Use when setting up screenshot automation, configuring device sizes, or generating localised screenshots.

General

What this skill does


# Fastlane Screenshot Automation Reference

## Plugin Tools

Before setting up screenshot automation, check your environment:

```bash
# List available simulators/emulators and check fastlane
cd /path/to/expo-toolkit && npm run list-devices

# Or with flags
node tools/list-devices.js --ios          # iOS only
node tools/list-devices.js --android      # Android only
node tools/list-devices.js --json         # JSON output
```

This shows:
- Available iOS simulators with App Store screenshot sizes highlighted
- Available Android emulators
- Fastlane installation status

## Tools Overview

Fastlane is a suite of tools for automating mobile app development workflows:

| Tool | Platform | Purpose |
|------|----------|---------|
| `snapshot` | iOS | Automated screenshots |
| `screengrab` | Android | Automated screenshots |
| `frameit` | Both | Add device frames to screenshots |
| `deliver` | iOS | Upload to App Store Connect |
| `supply` | Android | Upload to Play Console |
| `match` | iOS | Code signing management |
| `pilot` | iOS | TestFlight management |

## Installation

### Via Homebrew (Recommended)

```bash
brew install fastlane
```

### Via RubyGems

```bash
sudo gem install fastlane -NV
```

### Verify Installation

```bash
fastlane --version
```

## Project Setup

### Initialise Fastlane

```bash
# In your project root
fastlane init
```

This creates:
- `fastlane/Fastfile` - Lane definitions
- `fastlane/Appfile` - App configuration

### Directory Structure

```
your-project/
├── ios/
│   └── fastlane/
│       ├── Fastfile
│       ├── Appfile
│       ├── Snapfile
│       └── screenshots/
├── android/
│   └── fastlane/
│       ├── Fastfile
│       ├── Appfile
│       ├── Screengrabfile
│       └── screenshots/
└── ...
```

## iOS Screenshot Automation (Snapshot)

### Initialise Snapshot

```bash
cd ios
fastlane snapshot init
```

Creates:
- `fastlane/Snapfile` - Snapshot configuration
- `fastlane/SnapshotHelper.swift` - UI test helper

### Snapfile Configuration

```ruby
# fastlane/Snapfile

# Simulators to use for screenshots
devices([
  "iPhone 15 Pro Max",    # 6.7" display
  "iPhone 14 Plus",       # 6.5" display
  "iPhone 8 Plus",        # 5.5" display
  "iPad Pro (12.9-inch) (6th generation)"  # If iPad support
])

# Languages for localised screenshots
languages([
  "en-GB",
  "en-US",
  "de-DE",
  "fr-FR",
  "ja",
  "zh-Hans"
])

# Output directory
output_directory("./fastlane/screenshots")

# Clear previous screenshots
clear_previous_screenshots(true)

# Xcode scheme (must have UI tests)
scheme("YourAppUITests")

# Workspace (for CocoaPods projects)
workspace("../YourApp.xcworkspace")

# Or project (if not using CocoaPods)
# project("../YourApp.xcodeproj")

# Override status bar (clean screenshots)
override_status_bar(true)

# Launch arguments (optional)
launch_arguments(["-screenshots"])

# Number of concurrent simulators
concurrent_simulators(true)

# Stop on first error
stop_after_first_error(false)

# Skip opening HTML summary
skip_open_summary(false)
```

### SnapshotHelper Setup

1. Add `SnapshotHelper.swift` to your UI Test target
2. Import in your test file
3. Call `setupSnapshot(app)` in setUp

### UI Test for Screenshots

Create `YourAppUITests/ScreenshotTests.swift`:

```swift
import XCTest

class ScreenshotTests: XCTestCase {

    var app: XCUIApplication!

    override func setUpWithError() throws {
        continueAfterFailure = false
        app = XCUIApplication()
        setupSnapshot(app)
        app.launch()
    }

    override func tearDownWithError() throws {
        app = nil
    }

    func testTakeScreenshots() throws {
        // Wait for app to load
        sleep(2)

        // 1. Home Screen
        snapshot("01_HomeScreen")

        // 2. Navigate to feature
        app.buttons["FeatureButton"].tap()
        sleep(1)
        snapshot("02_FeatureScreen")

        // 3. Navigate to another screen
        app.tabBars.buttons["Settings"].tap()
        sleep(1)
        snapshot("03_SettingsScreen")

        // 4. Show detail view
        app.cells["ProfileCell"].tap()
        sleep(1)
        snapshot("04_ProfileScreen")

        // 5. Dark mode (if applicable)
        // Toggle dark mode and capture
        snapshot("05_DarkModeScreen")
    }
}
```

### Running Snapshot

```bash
cd ios

# Run all screenshots
fastlane snapshot

# Specific device only
fastlane snapshot --devices "iPhone 15 Pro Max"

# Specific language only
fastlane snapshot --languages "en-GB"

# Skip building (if already built)
fastlane snapshot --skip_build
```

## Android Screenshot Automation (Screengrab)

### Initialise Screengrab

```bash
cd android
fastlane screengrab init
```

Creates:
- `fastlane/Screengrabfile` - Configuration

### Screengrabfile Configuration

```ruby
# fastlane/Screengrabfile

# Package name
app_package_name("com.yourcompany.yourapp")

# Test instrumentation runner
use_tests_in_classes(["com.yourcompany.yourapp.ScreenshotTests"])

# APK paths
app_apk_path("app/build/outputs/apk/debug/app-debug.apk")
tests_apk_path("app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk")

# Locales for screenshots
locales([
  "en-US",
  "en-GB",
  "de-DE",
  "fr-FR",
  "ja-JP",
  "zh-CN"
])

# Output directory
output_directory("./fastlane/screenshots")

# Clear previous screenshots
clear_previous_screenshots(true)

# Exit on test failure
exit_on_test_failure(false)

# ADB path (optional)
# adb_path("/usr/local/bin/adb")

# Ending locale
ending_locale("en-US")

# Specific device serial (optional)
# specific_device("emulator-5554")

# Skip open summary
skip_open_summary(false)
```

### Add Screengrab Dependency

In `app/build.gradle`:

```groovy
dependencies {
    // ...
    androidTestImplementation 'tools.fastlane:screengrab:2.1.1'
}
```

### Instrumented Test for Screenshots

Create `app/src/androidTest/java/com/yourcompany/yourapp/ScreenshotTests.kt`:

```kotlin
package com.yourcompany.yourapp

import androidx.test.core.app.ActivityScenario
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Before
import org.junit.ClassRule
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import tools.fastlane.screengrab.Screengrab
import tools.fastlane.screengrab.UiAutomatorScreenshotStrategy
import tools.fastlane.screengrab.locale.LocaleTestRule

@RunWith(AndroidJUnit4::class)
class ScreenshotTests {

    companion object {
        @get:ClassRule
        @JvmStatic
        val localeTestRule = LocaleTestRule()
    }

    @Before
    fun setUp() {
        Screengrab.setDefaultScreenshotStrategy(UiAutomatorScreenshotStrategy())
    }

    @Test
    fun takeScreenshots() {
        ActivityScenario.launch(MainActivity::class.java)

        // Wait for app to load
        Thread.sleep(2000)

        // 1. Home Screen
        Screengrab.screenshot("01_HomeScreen")

        // 2. Navigate to feature
        onView(withId(R.id.feature_button)).perform(click())
        Thread.sleep(1000)
        Screengrab.screenshot("02_FeatureScreen")

        // 3. Navigate to settings
        onView(withId(R.id.settings_tab)).perform(click())
        Thread.sleep(1000)
        Screengrab.screenshot("03_SettingsScreen")

        // 4. Show profile
        onView(withText("Profile")).perform(click())
        Thread.sleep(1000)
        Screengrab.screenshot("04_ProfileScreen")
    }
}
```

### Running Screengrab

```bash
cd android

# Build APKs first
./gradlew assembleDebug assembleAndroidTest

# Run screenshots
fastlane screengrab

# Specific locale
fastlane screengrab --locales "en-GB"
```

## Framing Screenshots (Frameit)

Add device frames and marketing text to screenshots.

### Basic Usage

```bash
# In screenshots directory
fastlane frameit
```

### Configuration (frameit.json)

Create `fastlane/

Related in General