Prowl CLI · Open source

End-to-end tests for your Mac and web apps, from one YAML file.

Prowl is a CLI-first E2E testing tool. Describe a user flow as a short YAML hunt, then run it against a native macOS app — menu bar extras included — through the Accessibility API, or against a browser through Playwright. Deterministic runs, artifacts in your repo, no cloud, no metered pricing.

$ npm install -g prowl-tools

One hunt format

Change the target, not the test

A hunt describes what a user does, not how a platform is driven. Point target at a native Mac app or a URL and the same steps run against either.

.prowl/hunts/save-note.ymlruns on both
name: save-note
steps:
  - fill:
      "Title": "Standup notes"
  - click: "Save"
  - assert:
      visible: "Saved"
native macOS app
# .prowl/config.yml
target:
  type: macos
  app: com.example.Notes
web app
# .prowl/config.yml
target:
  type: web
  url: http://localhost:3000

macOS

Native apps through the Accessibility API — windows, sheets, and menu bar extras. Select by accessibility id, role, or label.

Web

Browsers through Playwright — Chromium, Firefox, and WebKit — with its full selector engine.

Android & iOS Simulator

Experimental

The same portable steps on an emulator, a USB device, or the iOS Simulator.

Portable steps — click, fill, type, press, assert, screenshot, if, repeat — run on every target. Web-only steps such as navigate and mockRoute are rejected up front on a native target with a clear error, not ten minutes into a CI run.

Why Prowl

Your tests, your data, your keys

Prowl exists so you can own your own testing — no vendor ecosystem, no metered pricing, no data leaving your repo.

Made for agents, controlled by humans

Hunts are deterministic, bounded by guardrails, and reviewable in a pull request — safe to point at agent-generated work, with structured output an agent can branch on.

Your tests and data stay in your repo

Hunts, run history, screenshots, and visual baselines live under .prowl/ in your repository. There is no dashboard to sign into and nothing to host.

Bring your own key

The AI-assisted steps — like prowl generate — run on your own provider key, paid directly to the provider. No usage caps and no metered pricing from us.

Open source, Apache-2.0

Built in the open by Genkei Labs. Read the code, run it anywhere, and never get locked into a vendor's ecosystem.

How it works

Four steps from install to a hunt running in CI.

Step 01

Install and initialize

Install the CLI globally and bootstrap your first hunt in one command.

$ npm install -g prowl-tools
$ prowl init

Step 02

Describe real user flows in YAML

Login, onboarding, checkout, a menu bar action — human-readable steps that run against a Mac app or a browser.

name: checkout-flow
steps:
  - navigate: "/cart"
  - click: "Checkout"

Step 03

Run locally and in CI

Run hunts from the terminal, then wire the same command into your pull request pipeline.

$ prowl run checkout-flow --json --trace

Step 04

Debug with artifacts

Screenshots, logs, and traces land in your repo on every failure, so you fix the bug instead of reproducing it.

PASS checkout-flow (1.2s) 2/2 steps
Artifacts: .prowl/runs/2026-08-29_10-30-45
login-flow.yml
name: login-flowsteps:  - navigate: "/login"  - fill:      "Email": "{{TEST_EMAIL}}"  - fill:      "Password": "{{TEST_PASSWORD}}"  - click: "Sign In"  - assert:      visible: "Dashboard"
Terminal
  ● Running hunt: login-flow    ✓ navigate "/login" (120ms)    ✓ fill "Email" (85ms)    ✓ fill "Password" (62ms)    ✓ click "Sign In" (340ms)    ✓ assert visible "Dashboard" (15ms)  PASS login-flow (622ms) 5/5 steps

Built for AI-assisted development

AI agents can analyze a page or an app, generate hunts, and execute tests through the CLI or a native MCP server — deterministic results, structured output, no UI reasoning required. Generation runs on your own provider key.

Three-command pipeline

analyze → generate → run

login.yml

name: login
steps:
  - navigate: "/login"
  - fill: "Email" "{{TEST_EMAIL}}"
  - fill: "Password" "{{TEST_PASSWORD}}"
  - click: "Sign in"
  - assert: visible "Dashboard"

terminal output

$ prowl analyze https://app.com/login --json
  | prowl generate --intent "test login" --stdout

$ prowl run login --json
PASS login (622ms) 5/5 steps
exitCode: 0
  • +Deterministic execution — same YAML hunt, same result every time
  • +Structured JSON output and exit codes for agent branching
  • +No UI reasoning — Prowl drives the browser or the Accessibility tree
  • +Simple CLI interface — works standalone or as part of a larger agent toolchain

Native MCP server

prowl mcp

Run prowl mcp to expose Prowl to any MCP-capable agent — Claude Desktop, Cursor, OpenClaw — as a small set of named tools. The agent triggers runs and reads structured results; it never needs shell access to your repo.

mcp client config

{
  "mcpServers": {
    "prowl": {
      "command": "prowl",
      "args": ["mcp"]
    }
  }
}

exposed tools

  • list_huntsHunt names in run order
  • run_huntRun one hunt, get the full result
  • run_suiteRun all hunts, auto-log failures as bugs
  • list_projectsRegistered projects in the registry
  • +No shell access — agents call a fixed set of tools, never arbitrary commands
  • +Guardrails apply — allowedDomains, forbiddenSelectors, and maxSteps gate every run
  • +Auto bug-logging — run_suite logs failures as deduplicated tickets in your backlog
  • +Multi-project — one server drives many repos via a project registry

Page analysis

prowl analyze <url> --json (or --app <bundle id>) extracts interactive elements with ranked selectors. Agents get a structured map of a page or an app without driving it.

AI hunt generation

prowl generate turns an analysis and a natural-language intent into a valid, runnable YAML hunt — using the model and key you choose.

Structured execution

Every run returns machine-readable JSON with pass/fail, step timings, and artifact paths. Exit codes let agents branch without parsing.

Library API

Import prowl-tools as a Node module. Run hunts programmatically and get typed results — no shell exec needed.

Built for desktop and web apps

YAML-first

Write tests in readable YAML — no JavaScript, no Swift. Step types cover navigation, forms, assertions, conditionals, mocking, and more.

Native and browser selectors

Accessibility ids, roles, and labels on macOS; the full Playwright selector engine on the web. prowl analyze dumps ranked candidates for either.

Safety guardrails

Forbidden selectors, allowed domains and apps, and max step limits prevent tests from going off the rails.

Rich artifacts

Every run saves screenshots, logs, and — on the web — network data and Playwright traces, under .prowl/runs in your repo.

Visual regression

Compare screenshots against baselines to catch unintended visual changes. Pixel-level diff images show exactly what shifted.

Network mocking

On the web target, intercept API requests and return custom responses. Test error, loading, and empty states without touching your backend.

Conditional logic

Handle cookie banners, optional modals, and dynamic UI with if/repeat steps. Real-world flows need real-world control flow.

CI & agent ready

JSON output, JUnit XML reports, structured exit codes, and a native MCP server. Plugs into any CI pipeline or AI agent workflow.

How it compares

Desktop and web from the same file

Mobile-first and web-only tools each cover part of a Mac developer's app; Prowl covers the native app and the web app with one test format.

Capability comparison of Prowl with Maestro, Playwright, and XCUITest
CapabilityProwlMaestroPlaywrightXCUITest
Native macOS appsYes — Accessibility API, menu bar extras includedNoElectron apps only (experimental)Yes — apps built with Xcode
Web appsYes — Playwright (Chromium, Firefox, WebKit)YesYes — Chromium, Firefox, WebKitNo
Native mobile appsAndroid & iOS Simulator — experimentalYes — iOS and AndroidNoiOS
Tests are written inYAMLYAMLJavaScript / TypeScript, Python, Java, .NETSwift / Objective-C
Runs fromOne CLI — any terminal or CICLI (requires Java)Test runner / CLIXcode / xcodebuild

Based on each project's public documentation as of August 2026. Maestro, Playwright, and XCUITest are trademarks of their respective owners; Prowl is not affiliated with or endorsed by them.

Get started in seconds

Four commands to a green web hunt. Testing a Mac app takes one more step today — see below.

1

Install the CLI

npm install -g prowl-tools

Or with Homebrew:

brew tap prowl-tools/tap && brew install prowl

2

Install a browser for the web target

npx playwright install chromium

3

Initialize your project

prowl init

4

Run the starter hunt

prowl run hello

Testing a native Mac app?

The macOS target ships in the CLI, but its Accessibility helper, prowl-macdriver, is not bundled in the npm package yet — you build it once from the source checkout with the Swift toolchain, then set target.type: macos and grant Accessibility permission to your terminal. A prebuilt, signed helper is the next release milestone.

macOS target guide

FAQ

What people ask before pointing Prowl at their app.

Who is Prowl for?

Indie and small-team Mac developers who need end-to-end tests for a desktop app, and web developers who want the same YAML-driven coverage for a browser app — without writing test code in Swift or JavaScript.

Can Prowl test a native macOS app?

Yes. Set target.type to macos and target.app to a bundle id or .app path, and Prowl drives the app through Apple's Accessibility API — windows, sheets, and menu bar extras included, with statusItem and menu= selectors for status menus. The target is labelled experimental: its helper binary is built from source today, and a prebuilt, signed helper is the next milestone.

Do I need to know Playwright or XCUITest?

No. You write hunts in YAML. On the web target Prowl runs Playwright under the hood; on macOS it talks to the Accessibility API. Portable steps run on both, and web-only steps are rejected up front on native targets with a clear error.

What about iOS and Android?

Experimental. Prowl 0.1.5 added Android (emulator and USB device) and iOS Simulator targets that run the same portable steps. They are usable today but the selector dialect and step coverage may still change, and real iOS devices are out of scope for now.

Can we run this in CI?

Yes. prowl ci runs a suite with deterministic exit codes, JSON and JUnit XML output, and artifacts for the pipeline. Web hunts run on any hosted runner; macOS-app hunts need a runner that has been granted Accessibility permission, which in practice means a self-hosted or MDM-managed Mac.

Can AI agents use Prowl?

Yes, two ways. Agents can drive the structured CLI directly — prowl analyze extracts page structure as JSON, prowl generate turns that into a runnable hunt from a natural language intent, and prowl run --json returns structured results with exit codes. Or run prowl mcp to expose Prowl as a native MCP server, so any MCP-capable agent calls it as named tools. You can also import Prowl as a Node library.

Does Prowl have an MCP server?

Yes. Run prowl mcp to start an MCP server (stdio) that exposes Prowl to any MCP-capable agent — Claude Desktop, Cursor, OpenClaw — as a fixed set of named tools: list_hunts, run_hunt, run_suite, and list_projects. The agent triggers runs and reads structured results without shell access, and your guardrails (allowedDomains, forbiddenSelectors, maxSteps) apply to every run. run_suite also auto-logs failures as deduplicated bug tickets in your backlog, and a project registry lets one server drive multiple repos.

Why not rely on manual testing only?

Manual checks miss regressions in large apps. Prowl gives repeatable coverage of critical user journeys on every release.

What is visual regression testing?

Visual regression compares screenshots against saved baselines to detect unintended visual changes. Prowl's assertScreenshot step does pixel-level comparison with a configurable threshold. On first run it saves the baseline automatically. Run prowl update-baselines to accept new screenshots as baselines.

Can Prowl generate tests automatically?

Yes. Run prowl analyze <url> --json (or --app <bundle id> for a Mac app) to extract elements and ranked selectors, then pipe the output to prowl generate --intent 'describe the test' to produce a valid hunt file. Generation uses the model and provider key you configure — your key, paid to your provider — and the YAML is validated against Prowl's schema before output.

Does Prowl support network mocking?

Yes, on the web target. The mockRoute step intercepts requests matching a URL pattern and returns a custom response — inline JSON or from a file. Use unmockRoute to remove the mock. This lets you test error, loading, and empty states without backend changes.

Start catching regressions today

One YAML file. Your Mac and web apps, tested.

Deterministic hunts, artifacts in your repo, your own keys — end-to-end coverage without a vendor in the loop.

Prowl mascot