Spotlight on fastlane: snapshot

Friday, 11 March 2016

Spotlight on fastlane: snapshot

Fastlane is an open source tool set that saves you time by automating your iOS and Android release process. In this blog post, we’ll explore how you can leverage snapshot — a tool that generates localized screenshots of your iOS app. Snapshot can be used as a stand-alone tool or as part of a streamlined workflow within fastlane.

Generating iOS screenshots has always been a laborious process. If your app supports iOS 7+ and is available in 10 languages, you’re looking at 8 different devices for a total of 80 unique combinations. Taking two screenshots per device-language pair would require you to generate 160 screenshots! Snapshot automates this process by leveraging Apple’s new UI testing features that were made available in Xcode 7.

Let’s take a look at how you can easily get started with fastlane and snapshot in a brownfield project. I’ll be using Cannonball — an open source iOS app that enables you to create and share poems on Twitter.

If you want to follow along, head over to GitHub, clone the repository and onboard the app using the Fabric Mac plugin available via fabric.io. Then, follow this guide to install fastlane.

To initialize fastlane, run the following command in a terminal inside Cannonball’s project directory:

$ fastlane init

Fastlane introduces the concept of lanes and each lane represents a workflow that executes a series of steps. Steps refer to execution of tools like snapshot, third-party integrations with products like Slack, or your own custom shell scripts. The lanes are defined in a configuration file called a Fastfile. Replace the contents of the default Fastfile (generated by the init command) with the following:

lane :appstore do
  snapshot
end

appstore is the name of the lane, which you’ll use later to have fastlane execute the contents of the Fastfile. You can have multiple lanes for App Store builds, beta builds, or anything you’d like.

Like its parent tool fastlane, snapshot can be configured via command-line arguments or via a configuration file called a Snapfile.

To generate a default Snapfile, run the following command inside Cannonball’s project directory:

$ snapshot init

Replace the generated Snapfile’s contents with the following:

devices([
  "iPhone 6"
])

languages([
  "en-US"
])

clear_previous_screenshots true

This will generate a single iPhone 6 screenshot using the en-US locale. clear_previous_screenshots is a snapshot command that will remove the previously generated screenshots before generating new ones.

Add a new iOS UI Testing Bundle target to Cannonball.

Spotlight on fastlane: snapshot

File > New > Target

Spotlight on fastlane: snapshot

iOS > Test > iOS UI Testing Bundle > Next > Enter ‘CannonballUITests’ as the Product Name > Finish

Once that’s done, add the SnapshotHelper.swift file to the newly created UI Test target. The file is found inside the fastlane directory which itself is inside Cannonball’s project directory.

Open the CannonballUITests.swift and replace the contents of the setUp() method with the following:

super.setUp()
let app = XCUIApplication()
setupSnapshot(app)
app.launch()

Now, while CannonballUITests.swift is still open, click the red Record button found in the bottom left of the window.

Spotlight on fastlane: snapshot

To take a screenshot of the main view, click on the Skip button at the bottom of the app’s authentication view.

Spotlight on fastlane: snapshot

This generates the following line inside the testExample() method:

XCUIApplication().buttons["Skip"].tap()

To take a screenshot, add the following line in testExample():

snapshot("01MainScreen")

The resulting CannonballUITests.swift file looks like this:

import XCTest

class CannonballUITests: XCTestCase {

  override func setUp() {
    super.setUp()

    let app = XCUIApplication()
    setupSnapshot(app)
    app.launch()
  }

  func testExample() {
    XCUIApplication().buttons["Skip"].tap()
    snapshot("01MainScreen")
  }
}

Now, run fastlane while specifying the lane:

$ fastlane appstore

Snapshot will then launch the simulator and generate the iPhone6-01MainScreen.png file inside the fastlane/screenshots/en-US directory.

Spotlight on fastlane: snapshot

Also, a screenshots.html file is generated that provides an overview of all screenshots that were created.

You can pass a number of arguments to configure snapshot. To see a complete list, run:

$ snapshot --help

Snapshot is a fantastic way to save hours of menial work by automating the process. For detailed documentation, head over to the project’s GitHub repository.