Skip to content
| Marketplace
Sign in
Visual Studio Code>Programming Languages>SaffronNew to Visual Studio Code? Get it now.
Saffron

Saffron

Chathuranga Jayasinghe

|
6 installs
| (0) | Free
Saffron end-to-end tests in VS Code: .saffron highlighting, step completion from your replay cache, right-click Run, and a panel for proposals and reports.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

Saffron for VS Code

Saffron is an end-to-end test runner for the web where you write tests in plain language and nothing else. There are no step definitions and no glue code. The first time a scenario runs, an AI agent drives a real browser and records what it did into a small JSON cache. Every run after that is replayed by Saffron in a real browser: zero AI calls, zero tokens, at the speed of the browser and your app. When the UI changes and a step fails, the agent heals it mid-run and files a proposal you review and accept, like a snapshot update. Then steps are never healed: an assertion passes because the app is right, or it fails.

Feature: Checkout

  Scenario: Guest can place an order
    Given I am on the products page
    When I add "Blue Widget" to the cart
    And I place the order and wait for the order API to return 201
    Then I should see "Order placed"

.saffron is Saffron's own test language, and it goes further than Gherkin: StepSet: for reusable step groups such as a login flow, {env:VAR} tokens that keep secrets out of recordings and reports, and {data:...} references to your data files. Standard .feature files run too.

Get the runner with npm i -D saffron-ai, then npx saffron init. Docs and the full story: saffron-ai.io. Package: saffron-ai on npm.

This extension brings Saffron into the editor: it knows your project's step vocabulary, runs your feature files, and shows what needs review.

What you get

  • Syntax highlighting for .saffron: every keyword, first-class StepSet: definitions and StepSet <name> invocations, {env:...}, {data:...} and {unique:...} tokens, <param> placeholders, tables, doc strings.
  • Step completion with status badges. Type a step keyword (Given , When , …) and every step the project knows is suggested, ranked by usage, badged from the replay cache:
    • ● recorded: replays at zero tokens
    • ● divergent: same text, different recordings
    • ○ written, not recorded yet
  • StepSet completion after typing StepSet , with the set's steps in the documentation popup.
  • Go to definition on a StepSet <name> invocation jumps to the StepSet: block, wherever it lives.
  • Hover on steps (status, usage, files) and on invocations (the expanded steps with badges).
  • Run from the editor or the Explorer. Right-click a .saffron file or a folder of them and choose Saffron: Run, Run (replay only, no AI), Run (headed browser) or Re-record. The play button in the editor title runs the open file. Commands run as a VS Code task in the project that owns the file, the folder of the nearest saffron.config.json above it, using that project's own saffron-ai install (npx otherwise). A folder above several projects runs each of them, from its own root. The Command Palette also has Saffron: Run all feature files, Open latest report and Accept all pending proposals.
  • Run one scenario. Above each Scenario: line, ▶ Run scenario, Replay only and Headed run that scenario alone, by name, saffron run <file>:<name> (an outline runs every row), saving the file first. They show in .saffron files and in the .feature files of a project with a saffron.config.json, in the file's own Gherkin language (# language:). Needs saffron-ai 0.9.8 or later.
  • The Saffron side panel. Click the Saffron icon in the activity bar: Feature files lists every .saffron file with its scenarios as children (click a scenario to jump to it), inline Run and Replay-only buttons per file, checkboxes plus Run selected in the title, and Run all. Run options and status holds the replay-only and headed toggles (applied to every run started from the extension), the last run's totals with the report one click away, and the number of proposals pending review with Accept all. It refreshes as files, reports and proposals change.
  • Tags, Proposals, Health and Orphaned recordings sections in the same panel, read from saffron status --json (saffron-ai 0.5.4 or later). Tick tags and Run tagged. Tick proposals, hover for the narrative, proof-replay verdict and cost, then Accept selected, Reject selected or Accept all. Clicking one opens the diff of what it changes, action by action, so you approve the recording rather than the description of it. Accept and Reject selected are bound to the revision you saw: a proposal a later run replaced comes back unticked, and the runner refuses one that changed before the command ran. That needs saffron-ai 0.9.0 or later; an older runner gets the plain file, as before. Accept all runs saffron accept --all, which takes whatever is pending when it runs, not what the panel shows, skips UNVERIFIED proposals and refuses STALE ones. Health shows the vocabulary counts, divergent steps, duplicate wordings proven by identical recordings, the effective config (click to open the file) and the pass rate of recent runs. Orphaned recordings lists caches and proposals whose scenario no longer exists, says why (the scenario is gone from the file, or the file itself is gone), and removes them with one action after a confirmation. It needs the saffron-ai release that added saffron prune.
  • Test data, {data:...}: completion of data files and keys with their values, the current value on hover (a list's values, or an Examples file's columns), go-to-definition into the JSON, and an error underline for a reference that does not resolve. {data:...} and {unique:...} are highlighted like {env:VAR}.
  • Last run: the scenarios that failed or healed, with the step that failed. Its title bar has Open Replay (every scenario the run traced, also when everything passed) and Open Report (the HTML report in your browser). Click one to open the screenshot of the page at the moment it went wrong, in VS Code's image preview; the inline action jumps to the scenario. Open Replay (on a scenario with an execution trace) runs saffron trace for it and opens the replay in your browser: the steps as written, the page at every action, the network alongside. A row acts on the project it came from, and a screenshot a later run replaced is refused rather than shown as this run's. The preview is a copy of the checked picture, named after the scenario and kept in the extension's own storage until the window closes; the row's tooltip gives the file in the project, for attaching it to a bug. Open Replay and the screenshot check need saffron-ai 0.9.0 or later, and Open Replay needs "trace": "retain-on-failure" (or "on") in the config.
  • CI runs: the CI runs of your current branch, GitHub Actions or Azure Pipelines, from saffron runs. The list reloads when you switch branches or press its refresh button, not as files change: each load asks the CI over the network (a branch switch while the view is collapsed reloads it when you open it). The runner reaches the CI through its own tool, which keeps the credentials: the GitHub CLI (gh auth login) or the Azure CLI with its azure-devops extension (az login); the extension never sees a token. Expand a run to see what it found without changing your checkout: saffron report --run downloads its results under .saffron/ci/ (git ignores them) and checks them as an import would, filing nothing. Under the run: the totals, each failed and healed scenario with its failing step and the first line of its error (the tooltip has what the agent changed), and "N proposals: M importable", each one saying why it would not import. Open Report shows the run's report in your browser; Open Trace replays a traced scenario, view only. A run with no results says why (still running, expired, or none uploaded). Results over saffron.ciMaxDownloadMB (default 100) ask before downloading. Viewing needs saffron-ai 0.9.7 or later. Show Results (the graph icon on a run) opens the run as one page in an editor tab: the totals, each failed and pending-review scenario as a card with its screenshot, failing step, error and what the agent said, what passed, and the proposals, with buttons for Open trace, Open scenario, Open report, Open run page and Import. On GitHub the row also says what the run left before you open it (results and their size, a summary only, results expired, no results). Both need saffron-ai 1.0.0 or later. A heal made in CI is reviewed here instead of being made again: Import (on a run) runs saffron import --run, which downloads the run's Saffron bundle (the saffron-bundle* artifact its pipeline uploads after saffron export) and imports it. The run then lists what happened to each proposal: imported (click to open its diff), already here, or not imported with the reason (a scenario or recording that changed since, for one), and warns when your checkout is not at the commit the run tested. Imported proposals appear under Proposals marked with the run they came from, linked in the tooltip when the link is on github.com or Azure DevOps; the run's report, screenshots and traces appear under Last run. Accept as usual, then commit and push the new recordings with the Source Control view. CI runs need saffron-ai 0.9.3 or later. The full guide, with the pipeline setup: CI runs in your IDE.
  • Multi-root workspaces: a selection that spans projects becomes one run per project, each from its own root with its own config and install. The status-backed sections show which project they describe, and Saffron: Select project switches it.
  • Dashboard in an editor tab: Saffron: Open dashboard (or click Last run) shows the suite's quality in the run report's design: tests, passing share, failing (and for how many runs in a row), flaky scenarios, scenarios healed again and again, never run and left out of the last run, slowest, pass rate and execution time over the last 20 runs, and results per tag. Click a scenario's name to open it. Refreshed after each run; needs saffron-ai 0.9.4 or later.
  • Diagnostics: unknown StepSet names, duplicate set definitions (with the "remove the colon to invoke" hint), and near-duplicate wording warnings: writing "I visit the home page" when "I navigate to the home page" is already recorded gets flagged before it costs a recording.

The vocabulary is derived live from your workspace: .feature/.saffron files contribute the wording, .saffron/cache/**.json contributes the status. No configuration.

Getting started

  1. Install this extension, then in your project: npm i -D saffron-ai and npx saffron init (add --examples for a ready-made suite against saucedemo.com).
  2. Open a .saffron file. Completion, navigation and diagnostics work straight away; they read your feature files and .saffron/cache.
  3. Right-click a feature file and choose Saffron: Run, or use the Saffron icon in the activity bar. The first run records with AI and needs Claude credentials (a Claude Code login or ANTHROPIC_API_KEY); later runs replay for free.
  4. Review what was recorded in the Proposals section, accept it, and commit .saffron/cache/ like snapshots.

The panel's Tags, Proposals and Health sections need saffron-ai 0.5.4 or later in the project.

Zero-extension fallback

Without this extension, saffron steps --snippets writes .vscode/saffron.code-snippets for native completion, and one settings line gives .saffron files Gherkin highlighting:

{ "files.associations": { "*.saffron": "feature" } }
  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
  • Your Privacy Choices
  • Consumer Health Privacy
© 2026 Microsoft