📘A library for isolated developing UI components and automatically taking snapshots of them.

Overview

Playbook

A library for isolated developing UI components and automatically taking snapshots of them.

playbook

Playbook

Playbook

Swift5 CI Status Lincense
Release Swift Package Manager CocoaPods Carthage

Playbook is a library that provides a sandbox for building UI components without having to worry about application-specific dependencies, strongly inspired by Storybook for JavaScript in web-frontend development.

Components built by using Playbook can generate a standalone app as living styleguide.
This allows you to not only review UI quickly but also deliver more robost designs by separating business logics out of components.

Besides, snapshots of each component can be automatically generated by unit tests, and visual regression testing can be performed using arbitrary third-party tools.

For complex modern app development, it’s important to catch UI changes more sensitively and keep improving them faster.
With the Playbook, you don't have to struggle through preparing the data and spend human resources for manual testings.



Usage


Playbook

Playbook is a framework that provides the basic functionality for managing components. It supports both SwiftUI and UIKit.
Components are uniquely stored as scenarios. A Scenario has the way to layout component. Please check the API Doc for the variety of layouts.

Playbook.default.addScenarios(of: "Home") {
    Scenario("CategoryHome", layout: .fill) {
        CategoryHome().environmentObject(UserData.stub)
    }

    Scenario("LandmarkList", layout: .fill) {
        NavigationView {
            LandmarkList().environmentObject(UserData.stub)
        }
    }

    Scenario("UIView red", layout: .fixed(length: 100)) {
        let view = UIView()
        view.backgroundColor = .red
        return view
    }
}

ScenarioProvider allows you to isolate additional scenarios and keep your playbook building clean.

struct HomeScenarios: ScenarioProvider {
    static func addScenarios(into playbook: Playbook) {
        playbook.addScenarios(of: "Home") {
            Scenario("CategoryHome", layout: .fill) {
                CategoryHome().environmentObject(UserData.stub)
            }
        }
    }
}

struct AllScenarios: ScenarioProvider {
    static func addScenarios(into playbook: Playbook) {
        playbook.add(HomeScenarios.self)
    }
}

You can use the ScenarioContext passed to the closure that creates the component to get the screen size in snapshot, or wait before generating a snapshot.

Scenario("MapView", layout: .fill) { context in
    MapView(coordinate: landmarkData[10].locationCoordinate) {
        // This closure will called after the map has completed to render.
        context.snapshotWaiter.fulfill()
     }
     .onAppear(perform: context.snapshotWaiter.wait)
}

PlaybookUI

PlaybookUI is a framework that provides user interfaces made by SwiftUI for browsing a list of scenarios.

PlaybookGallery

The component visuals are listed and displayed.
Those that are displayed on the top screen are not actually doing layout, but rather display the snapshots that are efficiently generated at runtime.

Browser Detail
Gellery LightGellery Dark Gellery Content LightGellery Content Dark

PlaybookCatalog

The UI that search and select a scenario in a drawer. It's more similar to Storybook.
If you have too many scenarios, this may be more efficient than PlaybookCatalog.

Browser Detail
Catalog Drawer LightCatalog Drawer Dark Catalog LightCatalog Dark

How to Save Snapshot Images

To save snapshot images to the photo library from the share button on each UI, NSPhootLibraryAddUsageDescription must be supported. See the official document for more information.


PlaybookSnapshot

Scenarios can be tested by the instance of types conform to TestTool protocol.
Snapshot is one of them, which can generate the snapshots of all scenarios with simulate the screen size and safe area of the given devices.
Since Snapshot depends on XCTest, it should be used in the module for unit test.

final class SnapshotTests: XCTestCase {
    func testTakeSnapshot() throws {
        let directory = ProcessInfo.processInfo.environment["SNAPSHOT_DIR"]!

        try Playbook.default.run(
            Snapshot(
                directory: URL(fileURLWithPath: directory),
                clean: true,
                format: .png,
                keyWindow: UIApplication.shared.windows.first { $0.isKeyWindow },
                devices: [.iPhone11Pro(.portrait)]
            )
        )
    }
}

generate images


PlaybookAccessibilitySnapshot

An extension to Playbook that uses AccessibilitySnapshot to produce snapshots with accessibility information such as activation points and labels.

accessibility-snapshot


Integration with Third-party Tools

The generated snapshot images can be used for more advanced visual regression testing by using a variety of third party tools.

percy

percy

reg-viz/reg-suit

reg-suit


Requirements

  • Swift 5.1+
  • Xcode 11.0+
  • iOS
    • Playbook: 11.0+
    • PlaybookSnapshot: 11.0+
    • PlaybookUI: 13.0+

Installation

Playbook features are separated into the following frameworks.

  • Playbook: Core system of component management.
  • PlaybookSnapshot: Generates snapshots of all components.
  • PlaybookUI: Products a browsing UI for components managed by Playbook.

CocoaPods

Add the following to your Podfile:

target 'YourPlaybook' do
  pod 'Playbook'
  pod 'PlaybookUI'

  target 'YourPlaybookTests' do
    inherit! :search_paths

    pod 'PlaybookSnapshot'
  end
end

Carthage

Add the following to your Cartfile:

github "playbook-ui/playbook-ios"

Swift Package Manager

Select Xcode menu File > Swift Packages > Add Package Dependency... and enter repository URL with GUI.

Repository: https://github.com/playbook-ui/playbook-ios

Note: Currently, SwiftPM doesn't support specifying the OS version for each library, so only iOS13 is supported.


License

Playbook is released under the Apache 2.0 License.


Playbook

Comments
  • Scenario names containing the path separator (`/`) causes test failure

    Scenario names containing the path separator (`/`) causes test failure

    Checklist

    • [x] This is not a Apple's bug.
    • [x] Reviewed the README and documents.
    • [x] Searched existing issues for ensure not duplicated.

    Description (Include Screenshots)

    Hi, I found that scenario names containing the path separator (/) can be problematic.

    When it's used in the name of a group of scenarios, it's recognized literally as a path separator and makes additional directory structure. I couldn't figure out whether this is an intended behavior or not.

    Screen Shot 2020-11-05 at 14 31 56

    When it's in a scenario name, it causes the test to fail with an error "No such file or directory." I guess it's a bit confusing, and would be best to be avoided.

    image

    A few possible ways to improve it I have in my mind:

    • Encode the entire name in a URL safe way such as addingPercentEncoding
    • Replace only / with another (say, _)
    • Throw an error with an improved message like "You cannot use / in a scenario name"

    Encoding the whole is indeed the most safe way, but will make the report generated by reg-suit ugly. What do you think?

    Last but not least, thank you for sharing and maintaining this great project!

    Steps to Reproduce

    Contain / in names; see screenshots above.

    Reproducible Demo Project

    Reproducible with the example project.

    Environments

    • Library version: Checked with the example in master (c8c14d7b066c)
    • Swift version: Apple Swift version 5.3 (swiftlang-1200.0.29.2 clang-1200.0.30.1)
    • iOS version: 14
    • Xcode version: Version 12.1 (12A7403)
    • Devices/Simulators: iPhone 12
    • Package manager version: N/A
    opened by akkyie 6
  • Support for AccessibilitySnapshot

    Support for AccessibilitySnapshot

    Checklist

    • [x] All tests are passed.
    • [x] Added tests or Playbook scenario.
    • [x] Documented the code using Xcode markup.
    • [x] Searched existing pull requests for ensure not duplicated.

    Description

    In order to create an extension to Playbook for accessibility testing, the UIView of the scenario snapshot is needed. The function makeResource is split into two parts: creating the UIView using SnapshotWindow and generating the image data of the UIView.

    Motivation and Context

    This is to create PlaybookAccessibility (WIP) and it uses AccessibilitySnapshot. To do this:

    1. AccessibilitySnapshot takes the UIView of a scenario using SnapshotSupport.view(...)
    2. An AccessibilitySnapshotView is generated
    3. AccessibilitySnapshotView is passed to snapshotSupport.data(for: view, ...) to generate image data for saving
    opened by jiayi-zhou 2
  • Mention the purpose of the document

    Mention the purpose of the document

    Checklist

    • [x] This is not a Apple's bug.
    • [x] Reviewed the README and documents.
    • [x] Searched existing issues for ensure not duplicated.

    Description (Include Screenshots)

    Mention the purpose of the document located at https://playbook-ui.github.io/playbook-ios/. The document lists APIS. However, it nowhere mentions that it is an API document. Please provide an appropriate title/heading.

    Steps to Reproduce

    1. Go to https://playbook-ui.github.io/playbook-ios/.
    2. In the menu on the left, read headings.
    3. Review if you can read API document anywhere.

    Reproducible Demo Project

    Environments

    • Library version:

    • Swift version:

    • iOS version:

    • Xcode version:

    • Devices/Simulators:

    • Package manager version:

    opened by vitish 2
  • Incorrect article

    Incorrect article

    Checklist

    • [x] This is not a Apple's bug.
    • [x] Reviewed the README and documents.
    • [x] Searched existing issues for ensure not duplicated.

    Description (Include Screenshots)

    At the https://playbook-ui.github.io/playbook-ios/Playbook.html, in ScenarioStore, in the Parameters section, in the first bullet point, instead of an write a.

    Steps to Reproduce

    1. Go to https://playbook-ui.github.io/playbook-ios/.
    2. Click the ScenarioStore
    3. In the Parameters section, in the first bullet point, instead of an write a.

    Reproducible Demo Project

    Environments

    • Library version:

    • Swift version:

    • iOS version:

    • Xcode version:

    • Devices/Simulators:

    • Package manager version:

    opened by vitish 2
  • Fix typo and broken link in README

    Fix typo and broken link in README

    Checklist

    • ~[ ] All tests are passed.~
    • ~[ ] Added tests or Playbook scenario.~
    • ~[ ] Documented the code using Xcode markup.~
    • ~[ ] Searched existing pull requests for ensure not duplicated.~

    Description

    This PR is just fixing typo and broken link in README. Please review!

    opened by jollyjoester 1
  • Remove VALID_ARCHS

    Remove VALID_ARCHS

    Checklist

    • [x] All tests are passed.
    • [ ] Added tests or Playbook scenario.
    • [ ] Documented the code using Xcode markup.
    • [x] Searched existing pull requests for ensure not duplicated.

    Description

    Remove VALID_ARCHS since it's not used in Xcode 12 by default. This will support Apple Silicon builds.

    opened by taoshotaro 1
  • fix import so sample app builds

    fix import so sample app builds

    Checklist

    • [ x ] All tests are passed.
    • [ n/a ] Added tests or Playbook scenario.
    • [ n/a ] Documented the code using Xcode markup.
    • [ x ] Searched existing pull requests for ensure not duplicated.

    Description

    SampleApp doesn't build. This import fixes it.

    Related Issue

    Motivation and Context

    Screenshots

    opened by spnkr 1
  • Version 0.1.1

    Version 0.1.1

    Checklist

    • [x] All tests are passed.
    • [ ] Added tests or Playbook scenario.
    • [x] Documented the code using Xcode markup.
    • [x] Searched existing pull requests for ensure not duplicated.

    Description

    • Update version to 0.1.1
    • Use swift-doc only instead of gitbook
    • Update tools and formats
    • Some fix for iOS 13.4 regression
    • Fix typography

    Related Issue

    close #16 close #17 close #18 close #19 close #22

    opened by ra1028 1
  • Fix Documentation

    Fix Documentation

    Checklist

    • [x] All tests are passed.
    • [x] Added tests or Playbook scenario.
    • [x] Documented the code using Xcode markup.
    • [x] Searched existing pull requests for ensure not duplicated.

    Description

    I noticed some grammatical mistakes in the documentation while reading so I fixed them.

    opened by yuzushioh 1
  • Remove .edgesIgnoringSafeArea line from sample app code

    Remove .edgesIgnoringSafeArea line from sample app code

    Checklist

    • [x] All tests are passed.
    • [ ] Added tests or Playbook scenario.
    • [ ] Documented the code using Xcode markup.
    • [x] Searched existing pull requests for ensure not duplicated.

    Description

    Remove .edgesIgnoringSafeArea line from sample app code

    Related Issue

    Closes #20

    Motivation and Context

    Screenshot

    Fixed screen shot: Screen Shot 2020-04-06 at 21 26 20

    opened by kagemiku 1
  • Typing mistake

    Typing mistake

    Checklist

    • [x] This is not a Apple's bug.
    • [x] Reviewed the README and documents.
    • [x] Searched existing issues for ensure not duplicated.

    Description (Include Screenshots)

    In the playbook README and API Document, in the second paragraph where the sentence starts with 'Components built using...'; instead of writing 'can generates' write 'generate'.

    Steps to Reproduce

    1. Go to https://github.com/playbook-ui/playbook-ios or https://playbook-ui.github.io/playbook-ios/.

    2. Go to the README section at https://github.com/playbook-ui/playbook-ios and Read the Introduction section at https://playbook-ui.github.io/playbook-ios/.

    3. Read the README and/or Introduction section.

    4. Read the first line of the second paragraph.

    Reproducible Demo Project

    Environments

    • Library version:

    • Swift version:

    • iOS version:

    • Xcode version:

    • Devices/Simulators:

    • Package manager version:

    opened by vitish 1
  • Set up documentation

    Set up documentation

    Checklist

    • [x ] Reviewed the README and documents.
    • [x ] Searched existing issues for ensure not duplicated.

    Description

    It is very hard to figure out how to set Playbook up for a UIKit app

    Motivation and Context

    I'd like to set Playbook for my my UIKit app, but there is no documentation on how to set things up. The sample app is SwiftUi only, so it makes it hard to figure it out

    Proposed Solution

    Add a page in the documentation explaining how to setup the playbook target to for a UIKit app

    opened by otusweb 0
  • Add `TestTool` for compare snapshot diffs without dependency

    Add `TestTool` for compare snapshot diffs without dependency

    Checklist

    • [x] Reviewed the README and documents.
    • [x] Searched existing issues for ensure not duplicated.

    Description

    Add a new TestTool compare snapshot diffs without dependency like pointfreeco/swift-snapshot-testing and uber/ios-snapshot-test-case.

    Motivation and Context

    Visual regression tests using third-party tools such as reg-suit are powerful, but a framework that can be used more simply on unit tests is needed.

    Proposed Solution

    Playbook.default.run(
        SnapshotCompare(devices: [.iPhone11Pro(.portrait)])
    )
    
    opened by ra1028 1
Releases(0.3.2)
An open source Instapaper clone that features apps and extensions that use native UI Components for Mac and iOS.

TODO: Screenshot outdated Hipstapaper - iOS and Mac Reading List App A macOS, iOS, and iPadOS app written 100% in SwiftUI. Hipstapaper is an app that

Jeffrey Bergier 51 Nov 15, 2022
Swift AWS Lambda to automatically assign engineers to pull requests with a Slack integration

PR Assigner A Swift AWS Lambda to automatically assign engineers to pull requests with a Slack integration. Features ??

Just Eat 28 Oct 18, 2022
Automatically set your keyboard's backlight based on your Mac's ambient light sensor.

QMK Ambient Backlight Automatically set your keyboard's backlight based on your Mac's ambient light sensor. Compatibility macOS Big Sur or later, a Ma

Karl Shea 29 Aug 6, 2022
Cross-Platform, Protocol-Oriented Programming base library to complement the Swift Standard Library. (Pure Swift, Supports Linux)

SwiftFoundation Cross-Platform, Protocol-Oriented Programming base library to complement the Swift Standard Library. Goals Provide a cross-platform in

null 620 Oct 11, 2022
ZIP Foundation is a library to create, read and modify ZIP archive files.

ZIP Foundation is a library to create, read and modify ZIP archive files. It is written in Swift and based on Apple's libcompression for high performa

Thomas Zoechling 1.9k Dec 27, 2022
Butterfly is a lightweight library for integrating bug-report and feedback features with shake-motion event.

Butterfly is a lightweight library for integrating bug-report and feedback features with shake-motion event. Goals of this project One of th

Zigii Wong 410 Sep 9, 2022
Focus is an Optics library for Swift (where Optics includes Lens, Prisms, and Isos)

Focus Focus is an Optics library for Swift (where Optics includes Lens, Prisms, and Isos) that is inspired by Haskell's Lens library. Introduction Foc

TypeLift 201 Dec 31, 2022
A Swift micro library for generating Sunrise and Sunset times.

Solar A Swift helper for generating Sunrise and Sunset times. Solar performs its calculations locally using an algorithm from the United States Naval

Chris Howell 493 Dec 25, 2022
Plugin and runtime library for using protobuf with Swift

Swift Protobuf Welcome to Swift Protobuf! Apple's Swift programming language is a perfect complement to Google's Protocol Buffer ("protobuf") serializ

Apple 4.1k Dec 28, 2022
A Swift package for rapid development using a collection of micro utility extensions for Standard Library, Foundation, and other native frameworks.

ZamzamKit ZamzamKit is a Swift package for rapid development using a collection of micro utility extensions for Standard Library, Foundation, and othe

Zamzam Inc. 261 Dec 15, 2022
Hammer is a touch, stylus and keyboard synthesis library for emulating user interaction events

Hammer is a touch, stylus and keyboard synthesis library for emulating user interaction events. It enables better ways of triggering UI actions in unit tests, replicating a real world environment as much as possible.

Lyft 626 Dec 23, 2022
Pigeon is a SwiftUI and UIKit library that relies on Combine to deal with asynchronous data.

Pigeon ?? Introduction Pigeon is a SwiftUI and UIKit library that relies on Combine to deal with asynchronous data. It is heavily inspired by React Qu

Fernando Martín Ortiz 369 Dec 30, 2022
μ-library enabling if/else and switch statements to be used as expressions.

swift-expression Many languages such as Scala, Rust and Kotlin support using if/else and switch statements as expressions – meaning that they can by t

Nikita Mounier 1 Nov 8, 2021
A cross-platform library of Swift utils to ease your iOS | macOS | watchOS | tvOS and Linux development.

Mechanica A library of Swift utils to ease your iOS, macOS, watchOS, tvOS and Linux development. Requirements Documentation Installation License Contr

Alessandro 28 Aug 28, 2022
A μframework of extensions for SequenceType in Swift 2.0, inspired by Python's itertools, Haskell's standard library, and other things.

SwiftSequence Full reference here. (If you're looking for data structures in Swift, those have been moved to here) SwiftSequence is a lightweight fram

Donnacha Oisín Kidney 376 Oct 12, 2022
Swift library and command line tool that interacts with the mach-o file format.

MachO-Reader Playground project to learn more about the Mach-O file format. How to run swift run MachO-Reader <path-to-binary> You should see a simila

Gonzalo 5 Jun 25, 2022
A Swift library for converting to and from opus/ogg format

swift-ogg This library provides a very simple API to convert between opus/ogg and MPEG4AAC/m4a files. It uses opus's libopus libogg to convert between

Element 13 Dec 31, 2022
macOS system library in Swift

SystemKit A macOS system library in Swift based off of libtop, from Apple's top implementation. For an example usage of this library, see dshb, a macO

null 323 Jan 5, 2023
Swift library to develop custom Alexa Skills

AlexaSkillsKit AlexaSkillsKit is a Swift library that allows you to develop custom skills for Amazon Alexa, the voice service that powers Echo. It tak

Claus Höfele 170 Dec 27, 2022