Skip to main content

Getting Started

Prowl Documentation

Deterministic QA Hunts From Your CLI

Prowl drives native macOS apps (experimental) and web apps from the same declarative YAML — repeatable hunts you can run locally, in CI, or hand to an AI agent. This page gets you from zero to a passing smoke test quickly.

Prowl mascot with magnifying glass
Before you start: Node.js 20+, npm, and a runnable web app. Native macOS app testing uses the same hunt format, but needs the macOS target setup first.

Outcome

By the end of this guide, you will run one hunt that validates your homepage and produces artifacts under .prowl/runs/.

Install

npm install -g prowl-tools

Or with Homebrew:

brew tap prowl-tools/tap
brew install prowl

Prowl uses Playwright under the hood. Install the browser:

npx playwright install chromium

Initialize

cd your-project
prowl init

This creates a .prowl/ directory with a config file, four starter hunts, and a .gitignore:

.prowl/
├── config.yml # Target URL, browser settings, guardrails
├── .gitignore # Keeps runs/, auth-state.json, and .env out of git
└── hunts/
├── hello.yml # Minimal smoke test — verifies the app loads
├── login-flow.yml # Auth example — fill credentials, verify redirect
├── form.yml # Forms example — fill, select, submit, assert
└── macos-hello.yml # Desktop starter — drive TextEdit (macOS, experimental)

The three web starters (hello, login-flow, form) run against the default web target as soon as you point config.yml at your app. macos-hello is a desktop-first first-run hunt that drives TextEdit through the Accessibility API; the macOS target is experimental and needs a one-time setup — see macOS Target.

prowl init finishes by pointing you at the bundled hunts:

  Initialized .prowl directory.
Run prowl run hello to get started.
See .prowl/hunts/login-flow.yml (auth) and .prowl/hunts/form.yml (web forms) for fuller examples.
Desktop-first? .prowl/hunts/macos-hello.yml is a macOS starter (experimental — see its comments to enable).

See Starter Templates for a walkthrough of each bundled hunt.

Configure

Edit .prowl/config.yml to point at your app:

target:
url: "http://localhost:3000"

With your app running at that URL, confirm your setup by running the bundled starter hunt:

prowl run hello

prowl run <name> resolves .prowl/hunts/<name>.yml by file name, so prowl run hello runs .prowl/hunts/hello.yml. As of 0.1.7, a literal hunt path resolves to the same hunt, so prowl run hello, prowl run hunts/hello.yml, and prowl run .prowl/hunts/hello.yml are equivalent (nested paths like .prowl/hunts/admin/users.ymladmin/users included) — handy for shell tab-completion. The same normalization applies to prowl watch and prowl history.

If your app uses authentication, capture storage state early with prowl login so hunts run as an authenticated user.

Write Your First Hunt

Create a new file at .prowl/hunts/smoke-test.yml:

name: smoke-test
description: "Validates homepage loads correctly"
tags:
- smoke
steps:
- navigate: "/"
- wait: "Welcome"
- assert:
visible: "Sign In"
assertions:
- noConsoleErrors: true
retry:
maxRetries: 0
delay: 1000
note
  • The file name is the hunt's identity: prowl run smoke-test loads .prowl/hunts/smoke-test.yml. The name: field is metadata — the file name, not name:, must match the command you run.
  • description — a human-readable summary stored in hunt metadata and shown by prowl list
  • tags — categorize hunts for filtering with --include-tags and --exclude-tags
  • retry — configure automatic retries on failure (maxRetries: 0 means no retries)

Run

prowl run smoke-test
  ● Running hunt: smoke-test
✓ navigate "/" (120ms)
✓ wait "Welcome" (85ms)
✓ assert visible "Sign In" (15ms)

PASS smoke-test (220ms) 3/3 steps
Artifacts: .prowl/runs/2026-02-09_10-30-45

You now have a stable smoke test and a run artifact folder you can inspect in CI.

What's Next

Was this page helpful?