Prefire transforms your #Preview
blocks into:
- β Snapshot tests
- β Playbook views
- β Visual flows with states and user stories
- β Living documentation β fully automated
- π§ Smart Preview Parsing β including
#Preview
,@Previewable
- πΈ Snapshot Testing β automatic test generation from previews
- π Playbook View β auto-generated interactive component catalog
- π Flow-aware β build user stories from multiple preview steps
- π§© UIKit Support β support for
UIView
andUIViewController
- βοΈ SPM + Xcode Plugins β works in CLI, Xcode build phases, or CI
- π§ Fast Caching β fingerprint-based AST and body caching avoids redundant work
- βοΈ Stencil Templates β customize output with your own templates
- π₯ Save Time - Generate tests and documentation automatically
- π₯ Stay Consistent - Keep previews and tests always in sync
- π₯ Improve Quality - Catch visual regressions before users do
- π₯ Boost Collaboration - Share living documentation with your team
π¦ Example project available at: Prefire Example
// Package.swift
dependencies: [
.package(url: "https://github.com/BarredEwe/Prefire.git", from: "4.0.0")
],
.testTarget(
plugins: [
// For Snapshot Tests
.plugin(name: "PrefireTestsPlugin", package: "Prefire")
]
)
#Preview {
Button("Submit")
}
Just run the test target π β Prefire will auto-generate snapshots based on your previews.
π‘ If your test target is empty, Prefire will still generate files and snapshot code during build.
Supports:
- β
SPM Plugin (
Package.swift
) - β Xcode Build Tool Plugin
- β
CLI (
brew install prefire
) - β GitHub Actions / CI
See detailed setup in the Installation guide
- Finds all
#Preview
andPreviewProvider
blocks - Supports modifiers:
.prefireEnabled()
,.prefireIgnored()
- Based on file modification date + SHA-256 of inputs
- Avoids re-parsing if nothing changed
- Uses
Stencil
templates - Respects
.prefire.yml
configuration
- Groups by
UserStory
,State
- Outputs
PreviewModels.generated.swift
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
- If you want to see a list of all the Views, use
isComponent: true
- If you want to sort by UserStory, use
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
andPincodeView
-
If a preview contains more than one
View
, you can markState
for these views..previewState(.loading)
static var previews: some View { TestView("Default") TestView("Loading") .previewState(.loading) }
Feature | Modifier |
---|---|
Include in snapshot | .prefireEnabled() |
Exclude from snapshot | .prefireIgnored() |
Group in a flow | .previewUserStory(.auth) |
Mark a UI state | .previewState(.error) |
Customize snapshot | .snapshot(delay: 0.3, precision: 0.95) |
# Generate snapshot tests
prefire tests
# Generate playbook models
prefire playbook
Run prefire tests --help
or prefire playbook --help
for more options.
See detailed configuration in the Configuration guide
test_configuration:
target: MyApp
playbook_configuration:
preview_default_enabled: true
When 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;
PrefireCore
β AST + preview parsing, caching, logicPrefireGenerator
β handles stencil templating + snapshot generationPrefireCacheManager
β unifies caching forTypes
andPreviews
PrefireTestsPlugin
/PrefirePlaybookPlugin
β SPM/Xcode integrationsprefire
β CLI entry point, calls shared generator code
- Swift 5.6 or higher
- Xcode 14.0 or higher
- iOS 14 or higher
NavigationView
in Preview not supported for Playbook
- Consider using other views or layouts for your Playbook needs.
Running Prefire via CI
- To run Prefire via Continuous Integration (CI), you need to configure permissions:
defaults write com.apple.dt.Xcode IDESkipPackagePluginFingerprintValidatation -bool YES
Xcode is unable to generate tests in a custom path.
- To resolve this, youβll need to disable the sandbox for file generation by running the following command in your terminal:
defaults write com.apple.dt.Xcode IDEPackageSupportDisablePluginExecutionSandbox -bool YES
We welcome contributions! Please follow these steps:
- Fork the repository
- Create a feature branch
- Submit a Pull Request
Prefire is released under the Apache License 2.0. See LICENSE for details.