Flick Documentation
Flick is a YAML-driven automated testing tool for iOS, Android, and web apps. Write test steps in plain YAML — Flick handles device detection, driver setup, error capture, and reporting.
Installation
# install globally
npm install -g @flick-run/cli
# verify
flick --version
Flick requires Node.js 20 or higher. Run node --version to check.
Quick start
1. Create a config
# for iOS
flick init --platform ios
# for Android
flick init --platform android
# for web
flick init --platform web
2. Edit flick.yml
Open the generated flick.yml and update the app field with your app's scheme
name (iOS), package name (Android), or URL (web).
3. Run
flick run
Flick opens the dashboard at http://localhost:4040, starts your app, and runs all sessions.
Configuration reference
config:
platform: ios # ios | android | web
app: FlickStore # scheme name, .apk path, or URL
retries: 2 # crash retry attempts per step
auth:
email: test@example.com
password: ${TEST_PASSWORD} # from .env or environment
sessions:
- name: "Login flow"
steps:
- action: tap
selector: "~login-btn"
- action: assert
selector: "~dashboard-screen"
visible: true
| Field | Type | Description |
|---|---|---|
| platform | ios | android | web |
Target platform |
| app | string | iOS: scheme name or .app path. Android: .apk path. Web: base URL |
| retries | number | How many times to retry a step after a crash. Default: 2 |
| auth.email | string | Available as ${auth.email} in step values |
| auth.password | string | Available as ${auth.password} in step values |
Actions
Every step in a session has an action field. The available actions are:
| Action | Required fields | Description |
|---|---|---|
| tap | selector | Tap an element. Waits up to 20s for it to exist. |
| fill | selector, value | Clear and type into an input field. |
| assert | selector, visible | Assert an element is visible (true) or hidden (false). |
| scroll | — | Scroll the view down by one screen height. |
| wait | duration | Wait for N milliseconds. Useful after animations. |
Examples
# tap a button
- action: tap
selector: "~login-btn"
# fill an input
- action: fill
selector: "~email-input"
value: ${auth.email}
# assert element is visible
- action: assert
selector: "~dashboard-screen"
visible: true
# wait 1.5 seconds
- action: wait
duration: 1500
Selectors
Mobile (iOS & Android) — iOS Android
Mobile selectors use the ~ prefix to reference testID props in React Native:
# React Native component
<TouchableOpacity testID="login-btn">
# flick.yml selector
selector: "~login-btn"
Add testID props to every interactive element you want to test. This is the only setup
required in your app code.
Web — Web
Web selectors use standard CSS selectors:
selector: "#login-btn" # by id
selector: ".submit-btn" # by class
selector: "button" # by tag
selector: "[data-testid='x']" # by attribute
Environment variables
Flick loads .env from the current directory automatically. No dotenv setup
needed.
# .env
TEST_PASSWORD=mysecretpassword
OPENAI_API_KEY=sk-...
OLLAMA_HOST=http://localhost:11434
Reference them in flick.yml with ${VAR_NAME}:
password: ${TEST_PASSWORD}
iOS iOS
For iOS, set app to your Xcode scheme name. Flick searches DerivedData automatically.
config:
platform: ios
app: MyApp # your Xcode scheme name — no path needed
Prerequisites:
- Xcode installed
- App built for simulator:
npx react-native run-ios - iOS Simulator open (Flick boots one automatically if not)
WebDriverAgentRunner will appear in the simulator during testing — this is normal. It is Appium's helper that controls your app remotely. You can ignore it.
Android Android
config:
platform: android
app: ./android/app/build/outputs/apk/debug/app-debug.apk
Prerequisites:
- Android Studio installed with an AVD emulator, OR a connected Android device
- ADB in your PATH:
adb devicesshould list your device - App built:
cd android && ./gradlew assembleDebug
Web Web
config:
platform: web
url: http://localhost:3000
Web runs use headless Chrome via WebdriverIO. No browser window opens — everything is visible in the Flick dashboard live preview panel.
Use CSS selectors: #id, .class, tag, [attribute].
Dashboard
The dashboard runs at http://localhost:4040 during every flick run and stays
alive after the run finishes so you can browse the report.
- Session timeline — every session and step with pass/fail status and timing
- Error details — click any failed step to see the error message and screenshot
- Live preview — web runs show a real-time screenshot stream in the right panel
- AI analysis — summary, suggestions, and patterns from local LLM
- Run history — sidebar lists all past runs, newest first
- Resizable panels — drag the dividers to resize sidebar and preview panel
To browse past runs without running a new test:
flick serve
AI analysis
After each run Flick analyses failures using a local LLM. No API key, no cloud, no cost.
Setup Ollama (recommended)
# install
brew install ollama
# start server
ollama serve
# pull a model
ollama pull llama3.2
# check flick sees it
flick ai
Setup LM Studio (alternative)
Open LM Studio, load any model, click Start Server. Flick auto-detects it at
localhost:1234.
AI analysis is always optional. If no provider is running, Flick skips it silently and the run completes normally.
Crash handling
When a step causes the app to crash, Flick:
- Takes a screenshot of the last known screen state
- Records the action that caused the crash
- Waits up to 5 seconds for the app to recover
- Retries the step (up to
config.retriestimes) - If still crashing, marks the step as
crashedand moves on
All crash details — screenshot, last event, retry count — are stored in the run report and visible in the dashboard.
CLI reference
| Command | Description |
|---|---|
flick run |
Run tests from flick.yml. Opens dashboard, runs sessions, saves report. |
flick init --platform <p> |
Create a starter flick.yml for the given platform. |
flick serve |
Open the dashboard to browse past runs. |
flick ai |
Check AI provider status and list installed models. |
flick run options
| Flag | Default | Description |
|---|---|---|
-c, --config <path> |
flick.yml | Path to config file |
-p, --port <number> |
4040 | Dashboard port |
--no-open |
— | Don't auto-open browser or simulator |