###### Automate taking localized screenshots of your iOS, tvOS, and watchOS apps on every device
Features • UI Tests • Quick Start • Usage • Tips • How?
------- # Features - Create hundreds of screenshots in multiple languages on all simulators - Take screenshots in multiple device simulators concurrently to cut down execution time (Xcode 9 only) - Configure it once, store the configuration in git - Do something else, while the computer takes the screenshots for you - Integrates with [_fastlane_](https://fastlane.tools) and [_deliver_](https://docs.fastlane.tools/actions/deliver/) - Generates a beautiful web page, which shows all screenshots on all devices. This is perfect to send to QA or the marketing team - _snapshot_ automatically waits for network requests to be finished before taking a screenshot (we don't want loading images in the App Store screenshots) After _snapshot_ successfully created new screenshots, it will generate a beautiful HTML file to get a quick overview of all screens: ![img/actions/htmlPagePreviewFade.jpg](/img/actions/htmlPagePreviewFade.jpg) ## Why? This tool automatically switches the language and device type and runs UI Tests for every combination. ### Why should I automate this process? - It takes **hours** to take screenshots - You get a great overview of all your screens, running on all available simulators without the need to manually start it hundreds of times - Easy verification for translators (without an iDevice) that translations do make sense in real App context - Easy verification that localizations fit into labels on all screen dimensions - It is an integration test: You can test for UI elements and other things inside your scripts - Be so nice, and provide new screenshots with every App Store update. Your customers deserve it - You realize, there is a spelling mistake in one of the screens? Well, just correct it and re-run the script # UI Tests ## Getting started This project uses Apple's newly announced UI Tests. We will not go into detail on how to write scripts. Here a few links to get started: - [WWDC 2015 Introduction to UI Tests](https://developer.apple.com/videos/play/wwdc2015-406/) - [A first look into UI Tests](http://www.mokacoding.com/blog/xcode-7-ui-testing/) - [UI Testing in Xcode 7](http://masilotti.com/ui-testing-xcode-7/) - [HSTestingBackchannel : ‘Cheat’ by communicating directly with your app](https://github.com/ConfusedVorlon/HSTestingBackchannel) - [Automating App Store screenshots using fastlane snapshot and frameit](https://tisunov.github.io/2015/11/06/automating-app-store-screenshots-generation-with-fastlane-snapshot-and-sketch.html) # Quick Start - Create a new UI Test target in your Xcode project ([top part of this article](https://krausefx.com/blog/run-xcode-7-ui-tests-from-the-command-line)) - Run `fastlane snapshot init` in your project folder - Add the ./SnapshotHelper.swift to your UI Test target (You can move the file anywhere you want) - (Xcode 8 only) add the ./SnapshotHelperXcode8.swift to your UI Test target - (Objective C only) add the bridging header to your test class: - `#import "MYUITests-Swift.h"` (The bridging header is named after your test target with `-Swift.h` appended.) - In your UI Test class, click the `Record` button on the bottom left and record your interaction - To take a snapshot, call the following between interactions - Swift: `snapshot("01LoginScreen")` - Objective C: `[Snapshot snapshot:@"01LoginScreen" timeWaitingForIdle:10];` - Add the following code to your `setUp()` method: **Swift:** ```swift let app = XCUIApplication() setupSnapshot(app) app.launch() ``` **Objective C:** ```objective-c XCUIApplication *app = [[XCUIApplication alloc] init]; [Snapshot setupSnapshot:app waitForAnimations:NO]; [app launch]; ``` _Make sure you only have one `launch` call in your test class, as Xcode adds one automatically on new test files._ ![img/actions/snapshot.gif](/img/actions/snapshot.gif) You can try the _snapshot_ [example project](https://github.com/fastlane/fastlane/tree/master/snapshot/example) by cloning this repo. To quick start your UI tests, you can use the UI Test recorder. You only have to interact with the simulator, and Xcode will generate the UI Test code for you. You can find the red record button on the bottom of the screen (more information in [this blog post](https://krausefx.com/blog/run-xcode-7-ui-tests-from-the-command-line)) # Usage ```no-highlight fastlane snapshot ``` Your screenshots will be stored in the `./screenshots/` folder by default (or `./fastlane/screenshots` if you're using [_fastlane_](https://fastlane.tools)) New with Xcode 9, *snapshot* can run multiple simulators concurrently. This is the default behavior in order to take your screenshots as quickly as possible. This can be disabled to run each device, one at a time, by setting the `:concurrent_simulators` option to `false`. **Note:** While running *snapshot* with Xcode 9, the simulators will not be visibly spawned. So, while you won't see the simulators running your tests, they will, in fact, be taking your screenshots. If any error occurs while running the snapshot script on a device, that device will not have any screenshots, and _snapshot_ will continue with the next device or language. To stop the flow after the first error, run ```no-highlight fastlane snapshot --stop_after_first_error ``` Also by default, _snapshot_ will open the HTML after all is done. This can be skipped with the following command ```no-highlight fastlane snapshot --stop_after_first_error --skip_open_summary ``` There are a lot of options available that define how to build your app, for example ```no-highlight fastlane snapshot --scheme "UITests" --configuration "Release" --sdk "iphonesimulator" ``` Reinstall the app before running _snapshot_ ```no-highlight fastlane snapshot --reinstall_app --app_identifier "tools.fastlane.app" ``` By default _snapshot_ automatically retries running UI Tests if they fail. This is due to randomly failing UI Tests (e.g. [#2517](https://github.com/fastlane/fastlane/issues/2517)). You can adapt this number using ```no-highlight fastlane snapshot --number_of_retries 3 ``` Add photos and/or videos to the simulator before running _snapshot_ ```no-highlight fastlane snapshot --add_photos MyTestApp/Assets/demo.jpg --add_videos MyTestApp/Assets/demo.mp4 ``` For a list for all available options run ```no-highlight fastlane action snapshot ``` After running _snapshot_ you will get a nice summary: ## Snapfile All of the available options can also be stored in a configuration file called the `Snapfile`. Since most values will not change often for your project, it is recommended to store them there: First make sure to have a `Snapfile` (you get it for free when running `fastlane snapshot init`) The `Snapfile` can contain all the options that are also available on `fastlane action snapshot` ```ruby-skip-tests scheme("UITests") devices([ "iPad (7th generation)", "iPad Air (3rd generation)", "iPad Pro (11-inch)", "iPad Pro (12.9-inch) (3rd generation)", "iPad Pro (9.7-inch)", "iPhone 11", "iPhone 11 Pro", "iPhone 11 Pro Max", "iPhone 8", "iPhone 8 Plus" ]) languages([ "en-US", "de-DE", "es-ES", ["pt", "pt_BR"] # Portuguese with Brazilian locale ]) launch_arguments(["-username Felix"]) # The directory in which the screenshots should be stored output_directory('./screenshots') clear_previous_screenshots(true) override_status_bar(true) add_photos(["MyTestApp/Assets/demo.jpg"]) ``` ### Completely reset all simulators You can run this command in the terminal to delete and re-create all iOS and tvOS simulators: ```no-highlight fastlane snapshot reset_simulators ``` **Warning**: This will delete **all** your simulators and replace by new ones! This is useful, if you run into weird problems when running _snapshot_. You can use the environment variable `SNAPSHOT_FORCE_DELETE` to stop asking for confirmation before deleting. ```no-highlight SNAPSHOT_FORCE_DELETE=1 fastlane snapshot reset_simulators ``` ## Update snapshot helpers Some updates require the helper files to be updated. _snapshot_ will automatically warn you and tell you how to update. Basically you can run ```no-highlight fastlane snapshot update ``` to update your `SnapshotHelper.swift` files. In case you modified your `SnapshotHelper.swift` and want to manually update the file, check out [SnapshotHelper.swift](https://github.com/fastlane/fastlane/blob/master/snapshot/lib/assets/SnapshotHelper.swift). ## Launch Arguments You can provide additional arguments to your app on launch. These strings will be available in your app (e.g. not in the testing target) through `ProcessInfo.processInfo.arguments`. Alternatively, use user-default syntax (`-key value`) and they will be available as key-value pairs in `UserDefaults.standard`. ```ruby-skip-tests launch_arguments([ "-firstName Felix -lastName Krause" ]) ``` ```swift name.text = UserDefaults.standard.string(forKey: "firstName") // name.text = "Felix" ``` _snapshot_ includes `-FASTLANE_SNAPSHOT YES`, which will set a temporary user default for the key `FASTLANE_SNAPSHOT`, you may use this to detect when the app is run by _snapshot_. ```swift if UserDefaults.standard.bool(forKey: "FASTLANE_SNAPSHOT") { // runtime check that we are in snapshot mode } ``` Specify multiple argument strings and _snapshot_ will generate screenshots for each combination of arguments, devices, and languages. This is useful for comparing the same screenshots with different feature flags, dynamic text sizes, and different data sets. ```ruby-skip-tests # Snapfile for A/B Test Comparison launch_arguments([ "-secretFeatureEnabled YES", "-secretFeatureEnabled NO" ]) ``` ## Xcode Environment Variables _snapshot_ includes `FASTLANE_SNAPSHOT=YES` and `FASTLANE_LANGUAGE=