automating-screenshots
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.
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
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.