@swmansion/argent 0.27.1-next.9 → 0.28.0

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.
Binary file
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@swmansion/argent",
3
- "version": "0.27.1-next.9",
3
+ "version": "0.28.0",
4
4
  "mcpName": "io.github.software-mansion/argent",
5
5
  "description": "MCP server for iOS Simulator and Android Emulator control",
6
6
  "license": "Apache-2.0",
@@ -118,7 +118,7 @@ Directives stop the flow on failure and skip later steps. The available directiv
118
118
  - Unfolded, the UI is landscape. `swipe` and `scroll-to` directions and the reading order stay as the user sees the UI. Coordinates stay in the space of the `describe` frames.
119
119
  - A fold between two angles that are not `closed` or `open` can keep the current panel. The step passes, and the report names the panel. To change panels, fold to `closed` or `open`.
120
120
 
121
- Use the launch map for cross-platform flows. A bare launch applies everywhere and becomes an app path on Chromium. The map takes `native:`, `ios:`, `android:`, `vega:`, and `chromium:`. `native:` is one id shared by iOS, Android, and Vega, and a per-platform key overrides it for that platform. `chromium:` accepts a relative or absolute app path. A launch that declares no id for the run's platform is an error, not a cue to switch platforms. A run on a remote simulator uses the `ios:` id, or the `native:` id when the map has no `ios:` key, so no flow needs a key for a remote run. On iOS, a successful launch also pins later tree reads to that app until the next raw `tool:` step, so read [The runner tree is not the discovery tree](#the-runner-tree-is-not-the-discovery-tree) when a read describes the wrong screen.
121
+ Use the launch map for cross-platform flows. A bare launch applies everywhere and becomes an app path on Chromium. The map takes `native:`, `ios:`, `android:`, `vega:`, and `chromium:`. `native:` is one id shared by iOS, Android, and Vega, and a per-platform key overrides it for that platform. `chromium:` accepts a relative or absolute app path. `ios:` also accepts `{ app, args }`; a simulator passes `args` to the app at launch. A launch that declares no id for the run's platform is an error, not a cue to switch platforms. A run on a remote simulator uses the `ios:` id, or the `native:` id when the map has no `ios:` key, so no flow needs a key for a remote run. On iOS, a successful launch also pins later tree reads to that app until the next raw `tool:` step, so read [The runner tree is not the discovery tree](#the-runner-tree-is-not-the-discovery-tree) when a read describes the wrong screen.
122
122
 
123
123
  ```yaml
124
124
  - launch: { native: com.acme.app, chromium: ../../app }
@@ -232,6 +232,8 @@ The guard accepts one `exists`, `visible`, `hidden`, or `text` condition, or `{
232
232
 
233
233
  A `run:` target is a YAML path resolved against the directory of the flow file containing the step, so `../shared/login.yaml` reaches a sibling directory rather than the project root. The `.yaml` suffix is optional: `run: login` and `run: login.yaml` both name `login.yaml` beside the flow.
234
234
 
235
+ `run:` steps and `tool: flow-execute` steps make one chain of flows. A step that closes a cycle in that chain, such as a flow that runs itself through `tool: flow-execute`, fails with a reason that contains `cyclic flow reference:`. A step that makes the chain longer than 20 flows fails with a reason that contains `max run depth exceeded`.
236
+
235
237
  - iOS and Android can run fragments or e2e flows inline. A nested e2e launch restarts its app.
236
238
  - Chromium boots one instance per launch **step**, not one per run. The leading launch — the flow's own, or the one its leading `run:` chain reaches — boots before step 1, unless you pinned the run with an explicit `device`, where it only attaches. Every later launch boots a fresh instance, moves the run onto it, and tears down the instance the run already owned for that app path. Nesting a Chromium e2e flow with its own launch is therefore the supported way to give a sub-scenario its own restart. Chromium rejects `pinch` and `rotate`. Use the app's own zoom or rotate controls.
237
239
  - Vega uses `tool: tv-remote` and raw `tool: keyboard`. The touch directives (`tap`, `long-press`, `swipe`, `type`, `scroll-to`, `pinch`, `rotate`) are unsupported. Gate focus and navigation results with `await`.
@@ -250,7 +252,7 @@ Use the map form shown above. A bare `script: scripts/seed.mjs` is invalid.
250
252
  - **`path`** is relative to the flow file that contains the step. Include `.mjs` and match the file name's letter case.
251
253
  - **`timeout`** is optional and uses milliseconds. The default is 30000. The minimum is 100.
252
254
 
253
- If `flow-add-script` cannot access the file, finish the recording. Add the step to YAML, then replay it locally.
255
+ Over a link (`argent link` or `ARGENT_TOOLS_URL`, also to 127.0.0.1), `flow-add-script` refuses the call, and a replay rejects a flow with a `script:` step. Record and replay a flow with a script without a link.
254
256
 
255
257
  If a script fails, check its changes before you retry.
256
258
 
@@ -262,7 +264,7 @@ A screenshot is human evidence. A `snapshot:` is executable visual verification.
262
264
 
263
265
  Do not use a snapshot as the only proof of navigation, persistence, data, accessibility state, logs, or network behavior. Avoid unstable timestamps, live data, ads, animation, and device drift. First establish deterministic state, identity, and readiness.
264
266
 
265
- Baselines live under `.argent/flows/__baselines__/<flow>/` and are keyed by platform and full-capture geometry; `cropOn` also contributes its selector. A run on a remote simulator uses `ios` in the key, so it uses the same baseline as a local iOS run with the same capture geometry. Seed from a known-good state with `--update-baselines`. A run on a remote simulator with `--update-baselines` rewrites the same baseline file that a local run uses, and its step reason says that a remote simulator wrote it. Inspect every baseline and require user review. Do not commit it yourself. Baseline creation or update is not a test pass. Never update a baseline only to make a diff pass. The default `maxMismatch` is 0.5 percent.
267
+ Baselines live under `.argent/flows/__baselines__/<flow>/` and are keyed by platform and full-capture geometry; `cropOn` also contributes its selector. A run on a remote simulator uses `ios` in the key, so it uses the same baseline as a local iOS run with the same capture geometry. Seed from a known-good state with `--update-baselines`. A flow that a `tool: flow-execute` step runs keeps its own baselines, and `--update-baselines` updates them too unless the step sets `updateBaselines` itself. A run on a remote simulator with `--update-baselines` rewrites the same baseline file that a local run uses, and its step reason says that a remote simulator wrote it. Inspect every baseline and require user review. Do not commit it yourself. Baseline creation or update is not a test pass. Never update a baseline only to make a diff pass. The default `maxMismatch` is 0.5 percent.
266
268
 
267
269
  Pin `--platform` and `--device` for iOS, Android, or Vega. For Chromium the device class is the window's own pixel size, which the app sets and no launch argument changes: pass `--platform chromium` and omit `--device` so the runner boots the declared app path instead of attaching to a running window of another size. A window sized from host or session state produces a key CI cannot reproduce, and the step fails for a missing baseline. The runner pins mobile status bars during visual runs. `--output <dir>` writes failed baseline, current, and diff images under `<dir>/<flow>/` for CI artifact upload.
268
270
 
@@ -34,6 +34,8 @@ A recorded `flow-execute` has two names. The top-level `name` identifies the rec
34
34
 
35
35
  When the user requests a script, call `flow-add-script` at the point where it must run. Read [Flow YAML: Local scripts](flow-yaml.md#local-scripts) first. If the call fails, check its changes before you retry.
36
36
 
37
+ Over a link, `flow-add-step` refuses a call whose step a replay over the same link rejects, and runs nothing. It also refuses a `flow-execute` call whose flow does not pass. That flow can have changed the device before it stopped. In both cases the recorder records no step. See [Replay](#replay) for the steps that a replay over a link rejects.
38
+
37
39
  Obey these lifecycle rules:
38
40
 
39
41
  1. Pass the same `name` and absolute `project_root` to every recording tool.
@@ -42,7 +44,7 @@ Obey these lifecycle rules:
42
44
  4. Treat `flow-start-recording` as destructive. It always truncates the named YAML, including a finished or committed flow. `restarted` reports only a displaced live take.
43
45
  5. If a call says the recording is inactive, do not restart under that name. The completed take can still be on disk. Copy it aside or record under a fresh name.
44
46
  6. Inspect `toolResult`, `message`, and `recorded` after each call. A call that errors records nothing, but a call that returns normally while reporting an unmet condition **does** append the step, and `message` says the step was added either way. A failed `flow-add-script` call appends nothing. `await-ui-element` is the case that turns up in practice (see [Live waits and checks](#live-waits-and-checks)). Only `flow-start-recording` and `flow-finish-recording` return the whole YAML as `flowFile`. A step call returns `recorded` — one summary line for the step it appended — plus a running `stepCount`. Read `recorded`: the recorder does not always store the tool call you made, and that line is where a rewrite shows up. To see the whole file mid-recording, read it at `savedTo`. A `savedTo` that comes back `null` means the write failed on your side. The step is still in the recording, so continue: the next step rewrites the whole file, and `flow-finish-recording` returns `flowFile` regardless.
45
- 7. Edit or reorder the YAML only after `flow-finish-recording`. An active remote recording can overwrite mid-recording edits.
47
+ 7. Edit or reorder the YAML only after `flow-finish-recording`. A recording over a link, also to 127.0.0.1, overwrites edits made during the recording.
46
48
 
47
49
  ## Start in the correct order
48
50
 
@@ -52,7 +54,7 @@ Obey these lifecycle rules:
52
54
  2. Record a plain `restart-app` as the first action that is neither an echo nor a script. Pass only the device id and app id. The recorder converts it to `launch:`.
53
55
  3. Record `await-ui-element` for the real first screen immediately after restart.
54
56
 
55
- Extra restart arguments prevent `launch:` conversion. An Android `activity`, for example, leaves a raw tool step and therefore a fragment.
57
+ Extra restart arguments prevent `launch:` conversion. An Android `activity`, for example, leaves a raw tool step and therefore a fragment. On iOS, `launchArgs` is the exception: it records as `launch: { native: <app id>, ios: { app, args } }`.
56
58
 
57
59
  Do not use splash content as a selector or landmark. Wait for the first real screen.
58
60
 
@@ -266,7 +268,25 @@ Resolve every hit and confirm:
266
268
 
267
269
  Run `flow-execute` on the complete YAML with the absolute project root. For a fragment, verify its prerequisite before setting `prerequisiteAcknowledged: true`.
268
270
 
269
- `flow-execute` takes exactly one flow source: `name`, for a flow saved under `.argent/flows/`, or `flow_path`, an absolute path to any flow `.yaml`. `run:` targets and baselines resolve on the tool server's filesystem, beside the YAML it actually reads. `flow_path` therefore requires the agent and the tool server to share a filesystem and is refused when they do not. `name` still runs remotely, but the server receives only that one YAML in a fresh temp directory. It checks the whole flow first and refuses a `run:`, `script:`, or `snapshot:` step at any depth, naming the missing co-location rather than a missing fragment, script, or baseline. Replay self-contained flows remotely; a composing, scripting, or snapshotting flow needs one shared filesystem.
271
+ `flow-execute` takes exactly one flow source: `name`, for a flow saved under `.argent/flows/`, or `flow_path`, an absolute path to any flow `.yaml`.
272
+
273
+ Over `argent link` or `ARGENT_TOOLS_URL`, the client sends the flow file, its `run:` fragments, the flows that its `tool: flow-execute` steps name, the snapshot baselines of each run and the file arguments of its `tool:` steps with the call. These steps work over a link:
274
+
275
+ - `run:` fragments and the flows that `tool: flow-execute` steps name, when they are under `project_root`, under its `.argent/flows/`, or beside the flow file. Keep them there.
276
+ - `snapshot:` steps in the flow and in its fragments. The baselines stay in the project. With `updateBaselines: true`, the client writes each new baseline when the run ends. A `baseline not written` line in the report means that the client did not save that baseline: fix the reason in the line and run again.
277
+ - A `tool:` step whose file argument is an absolute path to a `.png` or `.yaml` file, such as `baselinePath` of `screenshot-diff`. Keep the real file under the project root or beside the flow file, not behind a symlink to another place. Otherwise the step reports `error` when it runs, after the earlier steps acted.
278
+ - A `tool: flow-execute` step that names its flow with `name` and an absolute `project_root` without a `..` segment. Keep the flow that the step names under the project on the client, and spell `name` in the letter case of its file. That flow uses its own baselines. A replay with `updateBaselines` also updates them, unless the step sets `updateBaselines` itself.
279
+
280
+ These steps do not work over a link, in the flow or in a fragment or flow that it runs:
281
+
282
+ - `script:`
283
+ - a `tool:` step that takes a directory, an app or an output directory, such as `reinstall-app`, `gather-workspace-data`, or `screenshot-diff` with `outputDir`
284
+ - a `tool:` step with a relative file path, or a file other than `.png` or `.yaml`
285
+ - a `tool:` step whose tool builds the file path from several arguments, such as `flow-read-prerequisite` with `name`
286
+ - a `tool: flow-execute` step with `flow_path`, or with `name` and a relative `project_root` or one with a `..` segment
287
+ - a `tool:` step that records a flow
288
+
289
+ The tool-server checks the flow, its fragments and the flows that it runs before the first step. The error lists each step that does not work over a link, and each `run:` or `tool: flow-execute` step whose flow the client could not send, with the reason. A fragment or a flow that does not exist fails its step when the step runs. Run a flow that needs these steps with no link and no `ARGENT_TOOLS_URL`, on the computer that runs the tool-server.
270
290
 
271
291
  Manual rescue invalidates the pass. An `errored` step was never evaluated: an `idle` wait whose tree source could not be read, a step that threw, an unresolvable `run:` target, or a `launch:` that did not start the app. Read the reason — most name the environment, but a failed `launch:` is a verdict about the app. Unconfirmed focus is not in this class at all: the replay focus poll has no failure return, so a `type:` step whose focus was never confirmed is scored a **pass**, and only the value check after typing catches it.
272
292