saffron-ai 0.8.0 → 0.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,92 @@ All notable changes to Saffron, in one place: the `saffron-ai` runner (npm),
4
4
  the VS Code extension (`ChathurangaJayasinghe.saffron-vscode`) and the
5
5
  JetBrains plugin (`ai.saffron.jetbrains`). Dates are publish dates.
6
6
 
7
+ ## 0.8.2
8
+
9
+ Released 2026-09-22.
10
+
11
+ Runner
12
+
13
+ - **Split a suite across CI machines: `--shard 2/4` and
14
+ `saffron report --merge`.** `--workers` stops at one machine's cores;
15
+ sharding gives the suite to several. Each shard runs a fixed part, split
16
+ by scenario rather than by file, so one large feature file spreads over
17
+ every machine, and every scenario runs exactly once. `--shard-by file`
18
+ (or `"shardBy": "file"`) keeps each feature file on one machine instead,
19
+ for files whose scenarios share expensive or order-dependent state. A shard writes
20
+ `.saffron/reports/shard-2-of-4.json` instead of `latest.json` and leaves
21
+ `history.jsonl` alone, because part of a run would read as a run in the
22
+ trends. `saffron report --merge` finds the shard reports under `.saffron/`
23
+ (or the folders you name) and writes `latest.json`, `latest.html` and one
24
+ history line, with the same totals, scenario order and trends as an
25
+ unsharded run. It refuses a missing shard, the same shard twice, shards
26
+ that ran a different suite, and shards from different CI runs; merging
27
+ twice does not count the run twice. Setup and teardown run on each shard
28
+ and receive `SAFFRON_SHARD`. The docs have a GitHub Actions example.
29
+
30
+ ## 0.8.1
31
+
32
+ Released 2026-09-22.
33
+
34
+ Runner
35
+
36
+ - **Google Chrome and Microsoft Edge: `--browser chrome` and
37
+ `--browser msedge`.** Run on the branded browser your users actually
38
+ have, not only the open-source Chromium build. Both speak CDP, so
39
+ everything works there: replay, recording and healing. Recordings are the
40
+ same files, so a scenario recorded on `chromium` replays on `chrome` and
41
+ `msedge` and the other way round. Saffron uses the copy installed on the
42
+ machine; when it is missing the run stops before the first scenario, exit
43
+ code 2, and names the browser (`npx playwright install chrome` adds it on
44
+ a CI image). Also accepted as `browser` in the config.
45
+ - **Setup and teardown: `"setup"` and `"teardown"` in the config.** Shell
46
+ commands, one or a list, that Saffron runs once around a run, in the
47
+ project root: seed the data your scenarios read before any browser
48
+ opens, and clean up after the last scenario. A failed setup stops the
49
+ run with exit code 2 and no scenario runs. Teardown always runs: after
50
+ failures, after a failed setup, after Ctrl-C (which first stops a running
51
+ setup and waits for it, so nothing writes behind the cleanup). A failed teardown leaves
52
+ the verdicts alone and turns an otherwise green exit into 2, because what
53
+ it left behind is the next run's false red. The commands receive
54
+ `SAFFRON_BASE_URL` and `SAFFRON_ENV`. `--no-hooks` skips them,
55
+ `hookTimeoutMs` (default five minutes) bounds each one, and the report
56
+ lists every command with how it ended. With `{unique:name}` from 0.8.0
57
+ this makes a suite re-runnable and parallel-safe.
58
+
59
+ Fixes
60
+
61
+ - **Step reuse could bring back a stale data value.** When a `{data:...}`
62
+ value changed, the scenario's recording correctly went stale, but a new
63
+ recording could be seeded from that same recording's steps, putting the
64
+ old literal back under a fresh data snapshot, verified, at zero AI calls.
65
+ A step whose source recording still spells out a value that has since
66
+ changed is no longer reused.
67
+ - **`every {data:list}` counted hidden content as shown.** A value sitting
68
+ in a `hidden` or `display: none` element satisfied the check. The target
69
+ must now be visible, and only text the page actually shows counts. A
70
+ native `<select>` keeps its exception, since its options are never
71
+ visible while it is closed, but only when the select itself is visible.
72
+ Text is still compared as written, so CSS `text-transform` does not
73
+ change the result.
74
+ - **`{unique:name}` inside an Examples cell, a table cell or a doc string
75
+ reached the browser as the literal token.** Unique values were resolved
76
+ before parameters were substituted. They are now resolved in parameter
77
+ values too, with the same per-run seed, for values and locators alike.
78
+ - **`saffron prune` could list the screenshots of a live scenario as
79
+ orphaned** when its feature file is outside the configured directory and
80
+ the scenario has only ever failed, so no cache or proposal named the
81
+ file. Each screenshot folder now records which feature and scenario it
82
+ belongs to, prune reads it before judging, and the listing names what
83
+ the pictures were of.
84
+
85
+ Editors (VS Code extension 0.2.8)
86
+
87
+ - **VS Code ignored environment-specific CSV files.** With environment
88
+ `staging` and `roles.staging.csv`, `Examples: {data:roles}` was reported
89
+ as not resolving, or described from the base `roles.csv`. Diagnostics,
90
+ hover and go-to-definition now follow the runner: the environment's CSV
91
+ replaces the base one, and the hover names the file it read.
92
+
7
93
  ## 0.8.0
8
94
 
9
95
  Released 2026-09-21.
@@ -56,7 +142,19 @@ Runner
56
142
  lists those folders with the caches and proposals and removes them with
57
143
  `--yes`; a live scenario's folder is kept, per Examples row. `saffron
58
144
  status --json` reports them as orphans of kind `artifact`, and both IDE
59
- panels (VS Code 0.2.6, JetBrains 0.2.3) show them.
145
+ panels (VS Code 0.2.7, JetBrains 0.2.4) show them.
146
+
147
+ Editors (VS Code extension 0.2.7, JetBrains plugin 0.2.4)
148
+
149
+ - **`{data:...}` in the editor.** VS Code completes data files and keys with
150
+ their values, shows the current value (or a list's values, or an Examples
151
+ file's columns) on hover, jumps to the key, and underlines a reference
152
+ that does not resolve, reading the same files and environment overlay the
153
+ runner does. JetBrains gets the same through `saffron lsp`. Both highlight
154
+ `{data:...}` and `{unique:...}` like `{env:VAR}`, including on an
155
+ `Examples:` line.
156
+ - Both Orphans lists show the screenshot folders of scenarios that no longer
157
+ exist, so "Remove All" never deletes something it did not show.
60
158
 
61
159
  ## 0.7.2
62
160
 
@@ -88,13 +186,6 @@ Runner
88
186
 
89
187
  Editors (VS Code extension 0.2.6, JetBrains plugin 0.2.3)
90
188
 
91
- - **`{data:...}` in the editor.** VS Code completes data files and keys with
92
- their values, shows the current value (or a list's values, or an Examples
93
- file's columns) on hover, jumps to the key, and underlines a reference
94
- that does not resolve, reading the same files and environment overlay the
95
- runner does. JetBrains gets the same through `saffron lsp`. Both highlight
96
- `{data:...}` and `{unique:...}` like `{env:VAR}`, including on an
97
- `Examples:` line.
98
189
  - **Last run, with the screenshot one click away.** Both IDEs list what the
99
190
  last run left to look at: failed scenarios, then healed ones, with the
100
191
  step that failed. VS Code opens the screenshot in its image preview on
package/README.md CHANGED
@@ -72,7 +72,7 @@ node dist/cli/index.js -p examples accept --all
72
72
 
73
73
  | Command | What it does |
74
74
  |---|---|
75
- | `saffron run [paths] [--headed] [--filter @tags] [--rerecord] [--no-agent] [--strict] [--browser b] [--workers n] [--heal-model m] [--no-verify] [--no-reuse] [--model m] [--storage-state f]` | Run features. Cached replays are deterministic; misses/failures escalate to the agent (unless `--no-agent`). Replay cross-browser with `--browser firefox\|webkit`, parallelize with `--workers N`, heal on a cheaper model with `--heal-model`. Exit 1 on red (and on yellow with `--strict`). |
75
+ | `saffron run [paths] [--headed] [--filter @tags] [--rerecord] [--no-agent] [--strict] [--browser b] [--no-hooks] [--workers n] [--heal-model m] [--no-verify] [--no-reuse] [--model m] [--storage-state f]` | Run features. Cached replays are deterministic; misses/failures escalate to the agent (unless `--no-agent`). Replay cross-browser with `--browser firefox\|webkit`, parallelize with `--workers N`, heal on a cheaper model with `--heal-model`. Exit 1 on red (and on yellow with `--strict`). |
76
76
  | `saffron accept [files... \| --all] [--include-unverified] [--with-feature-edit] [--propagate]` | Promote cache proposals to committed caches (`--all` skips UNVERIFIED ones unless `--include-unverified`); `--with-feature-edit` also rewrites the adapted steps in the `.feature` file (and keeps the cache in sync); `--propagate` applies the heal's locator fixes to every other cache using the same locator. One heal repairs N scenarios before they ever fail. No args: list pending proposals. |
77
77
  | `saffron reject [files... \| --all]` | Discard proposals; the agent will try again next run. |
78
78
  | `saffron status [--json]` | Project overview for people, IDE panels and dashboards: feature files and scenarios with cache state, tags, pending proposals, last run, history, vocabulary health (divergent steps, duplicate wordings proven by identical recordings), effective config. |