Write tests in plain language.Pay for AI once.Replay forever.
An AI agent executes each scenario in a real browser on the first run and records a deterministic cache. Every later run is replayed by Saffron in a real browser, at zero LLM tokens and at Playwright's speed. When the UI changes, the agent heals mid-run and files a reviewable proposal, like snapshot testing for user journeys.
$ saffron run (excerpt) GREENSign the guestbook and leave a note (cache, 1412ms)YELLOWNote after the standard guests (agent-record, 38204ms) 5 AI calls · 21,877 tokens ⚡ 4/5 steps seeded from existing recordings ✓ proposal verified by zero-AI proof replayGREENGuest count via step set (cache, 903ms)GREENSuccessful login (cache, 812ms)GREENLogin with a credentials table (cache, 1087ms)GREENFailed login shows an error (example 1) (cache, 655ms)GREENFailed login shows an error (example 2) (cache, 641ms) 6 passed, 1 pending review, 0 failed · $0.61cached scenarios: 0 AI calls, 0 tokensreport: .saffron/reports/latest.htmloutput from the runner's example suite · 6/7 replayed from cache · one novel scenario recorded and verified
Three minutes, from install to a free replay
The whole loop in one video: write a test in plain language, let an AI agent record it once in a real browser, review what it recorded, and replay it with zero AI calls.
Then watch a test heal itself three times, each change harder than the last: the healing series.
Six rules that keep it honest
Saffron's culture is honesty over convenience. The runner refuses to hide costs, refuses to heal assertions, and refuses to change your suite without a commit.
Assertions are sacred
No Then is healed by default: enforced mechanically in the runner, not by prompt discipline. Projects may opt in to adaptable mid-scenario checkpoints; the final assertion block of every scenario stays strict under every policy.
Three result states
Green: replayed from cache. Gold: recorded or adapted by the agent this run; the proposal awaits review, stamped verified or honestly unverified. Red: failed. No fourth category.
Diagnose before adapting
The agent decides whether the failure is UI drift or a real application defect. Defects surface as red, not as a silent heal.
Caches are git artifacts
.saffron/cache lives in your repo and gets reviewed like snapshots. Diffs are readable. Nothing changes on CI without a commit.
Proposals carry their proof
Each new recording is proof-replayed with zero AI before it is filed. One that fails its proof is filed as unverified, with the reason: saffron accept --all skips it, a CI export keeps that status, and only an explicit accept takes it in.
Honest cost reporting
Prompt-cache reads and writes are shown alongside token counts. The number at the bottom of the report is what you paid on an API key; on a subscription it is an estimate at API rates.
Record once, replay forever, heal when the UI moves
Every scenario travels one of three paths. The runner picks the path automatically based on cache state and the outcome of the replay.
An AI agent drives a real browser through Playwright MCP, and Saffron records what it does as semantic actions in a JSON cache: ARIA role and accessible name first, CSS only as a fallback. Each recording is proof-replayed with zero AI before it is filed for your review.
Saffron replays the recorded actions in a real browser, on Playwright's browser engine. No agent is loaded, no MCP, no tokens: it runs at Playwright's speed.
When a cached step fails, the agent takes over in the same browser via CDP, adapts around the drift, finishes the scenario, and files a proposal with a cache diff and a suggested feature-file edit. Nothing is applied without your review.
Cost scales with novel steps, not with runs
Real numbers from an internal checkout suite, at API rates. A new scenario gets cheaper as the suite grows because the agent seeds from every step it has already recorded. A cached replay spends no LLM tokens; it still costs what any Playwright run costs in CI minutes, and a heal is a new, smaller AI session when the UI changes.
| Scenario | Cost |
|---|---|
| Full unseeded recording | $2.07 |
| Tuned inner loop | $1.16 |
| Seeded recording, 6-step scenario, one novel step | $0.15 |
| Every cached replay after that | 0 tokens |
New scenarios get cheaper as the suite grows, because cost scales with novel steps only.
Works where you already work
One install per tool. JetBrains and VS Code get highlighting, completion with recorded/divergent/unrecorded badges, StepSet navigation, diagnostics, run buttons and Run lenses above each scenario, and a Saffron panel with proposals, CI runs, tags, health and the report. Claude Code gets the same language server, the MCP tools and the agent skill; Codex gets the MCP tools and the skill.
Saffron plugin for IntelliJ, WebStorm, PyCharm, Rider
File type, highlighting and the language server, plus run configurations, right-click Run and a Saffron tool window with proposals, CI runs, tags, health and an embedded dashboard. Community editions included.
Settings → Plugins → Marketplace → search "Saffron"
Saffron extension for VS Code
Highlighting, completion with status badges, StepSet navigation, diagnostics, right-click Run, a Saffron side panel with proposals, CI runs, tags and health, and an in-editor dashboard.
code --install-extension ChathurangaJayasinghe.saffron-vscode
Saffron plugin for Claude Code
The language server, so Claude sees diagnostics and navigates StepSets while it edits .saffron files, the MCP server with search_steps, list_step_sets, project_status, run_plan, api_contract and verify, and the Saffron agent skill, as one plugin.
/plugin marketplace add s-chathuranga-j/saffron-claude-plugin /plugin install saffron@saffron
Saffron plugin for Codex
The MCP server with search_steps, list_step_sets, project_status, run_plan, api_contract and verify, so Codex reuses your recorded wordings, and the Saffron agent skill, from the same marketplace as the Claude Code plugin. Codex plugins have no language server.
codex plugin marketplace add s-chathuranga-j/saffron-claude-plugin codex plugin add saffron@saffron
JetBrains, Visual Studio Code, Claude, OpenAI and Codex are trademarks of their respective owners, shown to indicate compatibility. Saffron is not affiliated with or endorsed by them.
A few commands to your first zero-token run
npm i -D saffron-ainpx playwright install chromiumnpx saffron init --examples # config, agent skill, Saucedemo example suite npx saffron run # agent records, files proposalsnpx saffron accept --all # promote proposals to cachesnpx saffron run # 0 LLM tokens, the whole suite in secondsNo step definitions, no glue code. Write .feature or .saffron files, point saffron.config.json at your app, and run. The agent, needed only to record and heal, runs on an AI account you already have: Claude by default (a Claude Code login or an ANTHROPIC_API_KEY), or a Codex subscription, with Google AI (through Antigravity, experimental) and Cursor (not yet verified live) as well; npx saffron login checks the setup. Replay-only CI needs no AI access at all, runs cross-browser (--browser chrome|msedge|firefox|webkit, or several at once), and parallelizes with --workers N.
No app to point it at yet? saffron init --examples installs a handful of short .saffron scenarios against the public demo shop at saucedemo.com (login, a Scenario Outline, cart, checkout, StepSets at the start and mid-scenario), with the config and a .env.example ready. Recording the two @smoke scenarios cost about $3 of AI usage; every replay after that is free. The docs walk through it step by step.
Saffron is live on npm: free to use, including commercially. Bug reports, feature requests and questions live in the public community repository, linked from the Community page.
Questions people ask first
What is Saffron?
Saffron (saffron-ai) runs end-to-end tests written in plain language, as .feature or .saffron files. An AI agent records each scenario once in a real browser into a JSON recording you commit to git. Every later run replays that recording with zero AI calls, and when a replay fails because the UI changed, it heals and files a proposal you review. Why Saffron
How is Saffron different from Cucumber?
Saffron reads the same Gherkin feature files but needs no step definitions and no glue code. The step text is the test: the agent records what each step does, and replay runs that recording. .saffron files add step sets, {env:...} secrets and {data:...} references on top. Cucumber without step definitions
Does Saffron use AI tokens on every run?
No. AI is used only to record a new or changed scenario and to heal a broken replay. Replays make zero AI calls, so replay-only CI needs no AI access at all. Recording the two smoke scenarios of the example suite cost about $3; new scenarios get cheaper as recorded steps are reused. The execution model
Can a self-healing test hide a real bug?
Not by healing an assertion. By default Then steps are never healed, enforced in code rather than by a prompt, and the final checks of a scenario stay strict under every policy. Every heal is a proposal, checked by a replay with no AI, that you accept or reject. Self-healing tests that never heal assertions
Which AI does Saffron use, and who pays for it?
The agent runs on an AI account you already have: Claude by default, or Codex, Antigravity (experimental) or Cursor. Saffron never bills you for tokens. AI providers and sign-in
Is Saffron free?
Yes. Saffron is free to use, including commercially, under the Saffron Free Use License. The runner's source is closed. Install it from npm with npm i -D saffron-ai on Node 22.12 or later. The license
Which browsers, editors and CI systems does it support?
Replays run in Chromium, Chrome, Edge, Firefox and WebKit, in parallel and across browsers. Saffron runs in CI, and its VS Code and JetBrains plugins run tests, show reports and review proposals in the editor. Saffron in CI
Is saffron-ai related to other products called Saffron?
No. saffron-ai is the end-to-end testing tool at saffron-ai.io, published on npm as saffron-ai and on the VS Code and JetBrains marketplaces as Saffron.
What is shipped, what is ahead
Shipped is what is in the package you install today, grouped by what it lets you do. Ahead is ordered by how close it is, not by a date.
Shipped
91 capabilities · in saffron-ai 1.3.4Runner core
20- Record once, replay at zero tokens
- Mid-run healing into verified proposals
- Proposals bound to what you reviewed: stale ones cannot be accepted
- Recordings validated on read, problems named by path
- Heal notes that name the kind of change, checked against the recording
- Sacred assertions, with an assertion policy
- Step reuse: new recordings seeded from old ones
- Cross-browser replay, parallel workers, heal model
- Google Chrome and Microsoft Edge, recording included
- Setup and teardown commands around a run
- Sharding across CI machines, with one merged report
- Re-record a wrong recording, and prune the ones nothing owns
- A baseURL with a path or query, for variants behind a flag
- Record and heal on your Claude or Codex subscription; Google AI (Antigravity) is experimental and Cursor not yet verified live
- CI heals exported as a checked bundle and imported into your checkout
- saffron runs and import --run, over GitHub Actions and Azure Pipelines
- Draft heal pull requests on GitHub and Azure DevOps
- Run one scenario, by a line in it or by its name
- Multi-session scenarios: several users in one scenario, each in its own browser context
- Your own tests folder: one config key points runs, the editors and the agent tools at it
Writing tests
8- Step sets and the .saffron dialect
- Tables, doc strings and Scenario Outlines
- Secrets as {env:VAR}, masked in the text Saffron writes
- Secrets the AI agent never sees: it types the token, the value goes only to the browser
- Export to Playwright Test (beta): saffron eject, never looser than replay
- Test data in a data folder: values, lists, Examples from a file
- Values that are new on every run, and data per environment
- Guided first run with an example suite
Real-world pages
5- Dialogs, uploads, drag-and-drop, iframes
- Network-aware steps, in plain prose
- JSON response field checks by pointer, with types kept
- Multi-tab scenarios, in plain prose
- Dynamic values and date templates
Editors and agents
11- VS Code extension and JetBrains plugin
- Run from the IDE, panels and a dashboard
- Last run in the IDE, with the failure screenshot one click away
- Proposals, orphans, tags and health panels in both IDEs
- CI runs in VS Code and JetBrains: a run's results viewed without importing, its heals imported in one click
- Run, Replay only and Headed above each scenario, in both IDEs
- {data:...} completion, hover and diagnostics
- Claude Code plugin with the language server
- Codex plugin with the MCP server and skill
- Agent skill, MCP server and saffron init
- Codex and Antigravity on an API key, for CI machines with no login
Reports and history
10- Failure screenshots, embedded in the report
- Execution replay: the page inspectable at every step, navigated by your Gherkin
- Heal review inside the replay: what the cache tried beside what the agent chose, accept or reject from the page
- saffron diff: what a proposal changes, field by field
- Retries visible per step
- Cost by how the run was paid for
- Run history, trends, chronic scenarios
- Quality dashboard: failing and for how long, flaky, repeated heals, never run, slowest, trends, per tag
- saffron status for panels and dashboards
- Tag expressions: and, or, not; tags inherited as in Cucumber, in the report JSON
API test automation (beta), 1.2.0
7- @api features test an HTTP API with no browser, recorded once and replayed at zero tokens
- Status, field, header, timing and pinned OpenAPI contract checks; polling for a state
- Several APIs by name, and a contract pinned with saffron api pin
- Fixtures and named operations: a login once per feature, its values in every scenario
- Credentials the API hands out masked everywhere, and sent only to the APIs under test
- Request transcripts in the report and the trace viewer
- saffron eject exports API steps and schema checks (beta)
Recordings checked by machine, 1.3.0
6- An Outline's recording proved on every row it serves before it is filed
- A moved-clock check: dates that would break tomorrow or next month are named
- Writes the page cut off, and checks that changed the page, held for review
- Every view agrees: a recording that fails a row is never shown as verified
- Values captured while recording typed by later steps, a pattern keeping only the value
- Data tables for API requests: headers, parameters and fields edited at zero tokens
Checks for what vanishes, 1.3.1
6- A video of each scenario's run, kept for failures or for every run
- Checks for messages that vanish: a toast gone before the check still counts
- Negative and exact URL checks, and computed-style checks
- A Then is read-only while recording, and a not shown check must see something disappear
- One StepSet accepted from a proposal on its own
- Live progress and a time budget per agent session
Exact checks and secrets kept masked, 1.3.2
6- A pass rate never reads 100% while a scenario failed: 473 of 475 is 99.58%
- Amounts and URLs checked whole: no pass on a negative amount, a decimal part or an encoded letter
- Big and decimal numbers in JSON checks compared exactly, never rounded
- A rotated token stays masked everywhere, in fixtures and the agent's view too
- A misread Examples: {data: roles} is an error in the run and in both editors
- A guide page on how a recording is checked, every check in order
Concurrent API requests and recordings that follow their data, 1.3.3
6- Several API requests sent at once from a table, each checked against its own row
- accept --propagate fixes a healed API request in every recording that sends it
- A count check: how many shown elements, from a number, a column or a data value
- Each browser check run while recording, the way replay runs it, before it is kept
- A check recorded looser than the one it replaces, or data kept as typed text, is held for review
- Download checks read captured values, and StepSets work in every Gherkin language
Distribution
6- Public npm package, free for any use
- Generated docs site and one changelog
- Configuration reference, and a community repo for issues
- A browser matrix in one run, and device and viewport profiles
- Recording and healing in parallel, under a cap
- Per-worker timing and the slowest scenarios in every report
Ahead
6 items · nearest firstPlanned for 1.4
Say when an element moved
When replay finds an element by its fallback rather than by the name the step uses, the run says so: a renamed button never stays green unnoticed.
Row proofs in parallel
An Outline's other rows proved on the worker pool, not one after another, so a long Examples table records faster.
Scoped, not scheduled
Live run view
A page that updates while a run is going: scenarios queued, running and done, the step each one is on, and a heal as it happens.
LLM-less MCP replay
Replay through the MCP surface with no model in the loop.
Shared step library
Level 2 of step reuse, gated on evidence from real suites rather than scheduled.
Direction, not a date
Open-core SaaS layer
Hosted history and review for teams. The CLI never requires it.