A library for easily generating automatic Playbook (Demo) view and Tests using SwiftUI Preview
Works with: UI-components, screens and flows
Do you like SwiftUI Preview and use it? Then you must try 🔥Prefire!
You can try 🔥Prefire starting from example project.
Prefire can be installed for an Xcode Project
or only for one Package
.
You can integrate Prefire as an Xcode Build Tool Plug-in if you're working on a project in Xcode.
Prefire
as a package dependency to your project without linking any of the products.Build Phases
inspector.
Open Run Build Tool Plug-ins
and select the +
button.
From the list, select PrefirePlaybookPlugin
or PrefireTestsPlugin
, and add it to the project.You can integrate Prefire as a Swift Package Manager Plug-in if you're working with
a Swift Package with a Package.swift
manifest.
Package.swift
file.dependencies: [
.package(url: "https://github.com/BarredEwe/Prefire", from: "1.0.0")
]
plugins
parameter..target(
plugins: [
// For Playbook (Demo) view
.plugin(name: "PrefirePlaybookPlugin", package: "Prefire")
]
),
.testTarget(
plugins: [
// For Snapshot Tests
.plugin(name: "PrefireTestsPlugin", package: "Prefire")
]
)
To generate tests and playbook, simply mark your preview using the PrefireProvider
protocol:
struct Text_Previews: PreviewProvider, PrefireProvider {
static var previews: some View { ... }
}
If you use the #Preview
macro, 🔥Prefire will automatically find it!
If you don't need it, mark view - .prefireIgnored()
:
#Preview {
Text("")
.prefireIgnored()
}
If you want to disable the automatic get of all previews, use the setting preview_default_enabled
: false. Then to include preview in the test, you need to call the .prefireEnabled()
:
#Preview {
Text("")
.prefireEnabled()
}
To use Playbook, simply use PlaybookView
isComponent: true
isComponent: false
import Prefire
struct ContentView: View {
var body: some View {
PlaybookView(isComponent: true, previewModels: PreviewModels.models)
}
}
Just run generated tests 🚀 All tests will be generated in the DerivedData folder.
Plugin PrefireTestsPlugin
will handle everything for you 🛠️
For detailed instruction, check out swift-snapshot-testing or examine an example project.
Prefire provide new commands for previews:
You can set the delay, precision and perceptualPrecision parameters for the snapshot:
.snapshot(delay: 0.3, precision: 0.95, perceptualPrecision: 0.98)
static var previews: some View {
TestView()
.snapshot(delay: 0.3, precision: 0.95, perceptualPrecision: 0.98)
}
Function for connecting preview together in one Flow:
.previewUserStory(.auth)
static var previews: some View {
PrefireView()
.previewUserStory(.auth)
}
static var previews: some View {
AuthView()
.previewUserStory(.auth)
}
For example Authorization flow: LoginView
, OTPView
and PincodeView
If a preview contains more than one View
, you can mark State
for these views.
.previewState(.loading)
static var previews: some View {
TestView("Default")
TestView("Loading")
.previewState(.loading)
}
To further customize Prefire, you can create a .prefire.yml
file in the root directory of your project. Here's an example of its content:
test_configuration:
- target: PrefireExample
- test_file_path: PrefireExampleTests/PreviewTests.generated.swift
- template_file_path: CustomPreviewTests.stencil
- simulator_device: "iPhone15,2"
- required_os: 16
- preview_default_enabled: true
- sources:
- ${PROJECT_DIR}/Sources/
- snapshot_devices:
- iPhone 14
- iPad
- imports:
- UIKit
- SwiftUI
- testable_imports:
- Prefire
playbook_configuration:
- preview_default_enabled: true
- template_file_path: CustomModels.stencil
- imports:
- UIKit
- Foundation
- testable_imports:
- SwiftUI
target
- Your project Target for Snapshot tests. Default: FirstTargettest_file_path
- Filepath to generated file. Default: DerivedDatatemplate_file_path
- Stencil file for generated file. Optional parameter.\
For test plugin Default: Templates/PreviewTests.stencil from the package.\
For playbook plugin Default: Templates/PreviewModels.stencil from the packagesimulator_device
- Device for Snapshot testing. Optional parameter.required_os
- iOS version for Snapshot testing. Optional parameter.snapshot_devices
- the list of devices snapshots should be generated for. The simulator_device
specified above will still be required and used, but snapshotting will take on the traits of the snapshot_devices
. The displayScale
will default to 2.0
and device specific safe areas will be .zero
. Optional parameter.preview_default_enabled
- Do I need to automatically add all previews based on the new syntax to the tests. Default: trueimports
- Additional imports for the generated Playbook/Tests. Optional parameter.testable_imports
- Additional @testable
imports for the generated Playbook/Tests. Optional parameter.sources
- Paths to swift file or directory sources. Default: File paths of a specific target or projectWhen preparing for distribution, you may want to exclude your PreviewProvider
and mock data from release builds. This can be achieved by wrapping them in #if DEBUG
compiler directives. Alternatively, you can pass a compiler flag to exclude PreviewModels
from release builds.
To exclude PreviewModels
using Swift Package Manager, pass the PLAYBOOK_DISABLED
swift setting in the package that links PrefirePlaybookPlugin
:
swiftSettings: [
.define("PLAYBOOK_DISABLED", .when(configuration: .release)),
]
If you are using Xcode, you can pass the compiler flag in the Xcode build settings:
SWIFT_ACTIVE_COMPILATION_CONDITIONS = PLAYBOOK_DISABLED;
NavigationView
in Preview not supported for Playbook
Running Prefire via CI
defaults write com.apple.dt.Xcode IDESkipPackagePluginFingerprintValidatation -bool YES
Xcode is unable to generate tests in a custom path.
defaults write com.apple.dt.Xcode IDEPackageSupportDisablePluginExecutionSandbox -bool YES