Skip to content

Swift Examples

These examples assume your UI test target imports VizzlyXCTest.

import XCTest
import Vizzly
import VizzlyXCTest

SwiftUI previews

Keep using regular SwiftUI previews:

#Preview("Home screen") {
HomeView()
}

Capture that preview with:

Terminal window
npx vizzly previews --include "Home screen"

See SwiftUI Preview Capture for setup and options.

Full screen

app.vizzlyScreenshot(name: "home-screen")

Element capture

app.buttons["Submit"].vizzlyScreenshot(name: "submit-button")

Variants with stable properties

Use properties when one screenshot name has intentional variants. Keep the keys stable. Vizzly uses them to understand what it is looking at.

Avoid helper-owned keys like platform, deviceName, deviceModel, osName, osVersion, viewport, and elementType unless you intentionally want to override the automatic XCTest metadata.

app.vizzlyScreenshot(
name: "login-form",
properties: ["state": "empty"]
)
app.vizzlyScreenshot(
name: "login-form",
properties: ["state": "filled"]
)

Per-screenshot comparison settings

Most projects should keep comparison defaults in vizzly.config.js. Override them per screenshot only when a specific screen needs different behavior.

app.vizzlyScreenshot(
name: "dashboard-chart",
properties: ["theme": "dark"],
threshold: 2.5,
minClusterSize: 4,
fullPage: true,
requestTimeout: 60_000
)

Orientation variants

XCUIDevice.shared.orientation = .portrait
app.vizzlyScreenshot(name: "home", properties: ["orientation": "portrait"])
XCUIDevice.shared.orientation = .landscapeLeft
app.vizzlyScreenshot(name: "home", properties: ["orientation": "landscape"])

Check readiness first

The SDK degrades gracefully when Vizzly is not running. If you want to make that explicit in a helper, check readiness before capturing.

if VizzlyClient.shared.isReady {
app.vizzlyScreenshot(name: "settings")
}

Use the core client directly

Use VizzlyClient when you already have PNG data or when your target should avoid the XCTest helper module.

import Vizzly
import XCTest
let screenshot = app.screenshot()
VizzlyClient.shared.screenshot(
name: "settings",
image: screenshot.pngRepresentation,
properties: [
"surface": "settings",
"mode": "signed-in"
]
)

Wrap native UI tests in CI

Run the same native test command locally and in CI. The wrapper starts the local server, passes VIZZLY_SERVER_URL to the test process, and uploads screenshots as the SDK sends them.

Terminal window
vizzly tdd run "xcodebuild test -scheme MyApp -destination 'platform=iOS Simulator,name=iPhone 15'"
Terminal window
VIZZLY_TOKEN=vzt_project_token \
vizzly run "xcodebuild test -scheme MyApp -destination 'platform=iOS Simulator,name=iPhone 15'" --wait

Tip

Keep names stable and wait for the UI you care about before capturing. That matters. Add screenshot helpers only where they make the test easier to read.

Next steps