@swmansion/argent 0.28.1-next.9 → 0.29.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.
- package/agents/argent-environment-inspector.md +7 -7
- package/agents/references/quality-control-checklist.md +14 -14
- package/assets/manifest.json +2 -2
- package/bin/argent-android-devtools-0.3.0.apk +0 -0
- package/bin/darwin/ax-service +0 -0
- package/bin/darwin/simulator-server +0 -0
- package/bin/darwin/tvos-ax-service +0 -0
- package/bin/darwin/tvos-hid-daemon +0 -0
- package/bin/linux/simulator-server +0 -0
- package/bin/linux-arm64/simulator-server +0 -0
- package/bin/tcp/ax-service +0 -0
- package/bin/win32/simulator-server.exe +0 -0
- package/dist/cli-cmds.mjs +4 -1
- package/dist/client.d.ts +18 -0
- package/dist/client.js +3 -0
- package/dist/installer.mjs +9 -2
- package/dist/mcp-server.mjs +13 -1
- package/dist/tool-args.generated.d.ts +87 -77
- package/dist/tool-server.cjs +947 -370
- package/dylibs/libArgentInjectionBootstrap.dylib +0 -0
- package/dylibs/libKeyboardPatch.dylib +0 -0
- package/dylibs/libNativeDevtoolsIos.dylib +0 -0
- package/dylibs/tcp/libArgentInjectionBootstrap.dylib +0 -0
- package/dylibs/tcp/libKeyboardPatch.dylib +0 -0
- package/dylibs/tcp/libNativeDevtoolsIos.dylib +0 -0
- package/dylibs/tvos/libArgentInjectionBootstrap.dylib +0 -0
- package/dylibs/tvos/libKeyboardPatch.dylib +0 -0
- package/dylibs/tvos/libNativeDevtoolsIos.dylib +0 -0
- package/package.json +1 -1
- package/rules/argent.md +16 -16
- package/skills/argent-android-emulator-setup/SKILL.md +9 -9
- package/skills/argent-create-flow/references/flow-yaml.md +11 -11
- package/skills/argent-create-flow/references/live-authoring.md +11 -11
- package/skills/argent-create-flow/references/reliability-and-recovery.md +13 -13
- package/skills/argent-device-interact/SKILL.md +47 -47
- package/skills/argent-device-interact/references/chromium.md +1 -1
- package/skills/argent-device-interact/references/gesture-examples.md +7 -7
- package/skills/argent-device-interact/references/secrets.md +6 -6
- package/skills/argent-lens/SKILL.md +21 -21
- package/skills/argent-metro-debugger/SKILL.md +24 -24
- package/skills/argent-metro-debugger/references/failure-scenarios.md +11 -11
- package/skills/argent-metro-debugger/references/source-maps.md +4 -4
- package/skills/argent-native-profiler/SKILL.md +13 -13
- package/skills/argent-qa-flows/SKILL.md +3 -3
- package/skills/argent-react-native-app-workflow/SKILL.md +18 -18
- package/skills/argent-react-native-optimization/SKILL.md +12 -12
- package/skills/argent-react-native-optimization/references/fix-reference.md +10 -10
- package/skills/argent-react-native-optimization/references/lint-rules.md +1 -1
- package/skills/argent-react-native-profiler/SKILL.md +25 -25
- package/skills/argent-react-native-profiler/references/diagnostic-tools.md +19 -19
- package/skills/argent-screen-recording/SKILL.md +14 -14
- package/skills/argent-test-ui-flow/SKILL.md +9 -9
- package/skills/argent-tv-interact/SKILL.md +19 -19
- package/bin/argent-android-devtools-0.2.0.apk +0 -0
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
package/rules/argent.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Argent iOS Simulator and Android Emulator Agent
|
|
2
|
+
description: Argent iOS Simulator and Android Emulator Agent, always-on guidance for methodology and tools for working with, interacting, testing and profiling mobile app work
|
|
3
3
|
alwaysApply: true
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
<description>
|
|
7
|
-
If argent is installed and configured in this environment, its MCP tools are the preferred form of interaction with the application for iOS simulator, physical iPhone, Android emulator, Chromium (CDP) app, and Vega (Amazon Fire TV) device control; otherwise see `<availability_check>` below before attempting any argent workflow. A "Chromium (CDP) app" is any Chromium runtime exposing a Chrome DevTools Protocol endpoint
|
|
7
|
+
If argent is installed and configured in this environment, its MCP tools are the preferred form of interaction with the application for iOS simulator, physical iPhone, Android emulator, Chromium (CDP) app, and Vega (Amazon Fire TV) device control; otherwise see `<availability_check>` below before attempting any argent workflow. A "Chromium (CDP) app" is any Chromium runtime exposing a Chrome DevTools Protocol endpoint: an Electron app, or any Chromium-family browser (Chrome/Brave/Edge) launched with `--remote-debugging-port`; all are driven through the same tool surface and tagged `platform: "chromium"`. A "Vega device" is a virtual device (VVD) or physical unit, driven by tv-remote (D-pad) and tagged `platform: "vega"`. Physical iPhones (iPads are not supported) appear in `list-devices` as iOS entries with kind `"device"`; they are driven over USB cable only, and the on-device runner's signing is auto-detected from the Mac's keychain (`ARGENT_IOS_TEAM_ID` overrides). Automation there is app-scoped: `launch-app` registers the target app before anything else can act. Read `argent-ios-device-setup` to get one connected and `argent-ios-device-interact` before interacting.
|
|
8
8
|
Running MCP server and managing the Argent toolkit utilises `argent` command - if asked use `argent --help` for reference.
|
|
9
9
|
To check current version of MCP server run `argent --version` command.
|
|
10
10
|
|
|
@@ -17,7 +17,7 @@ Use cases:
|
|
|
17
17
|
- Any request to execute manual QA, UI QA, or visual behavior validation for a mobile app
|
|
18
18
|
- Running, debugging, or testing a React Native app (iOS, Android or Vega)
|
|
19
19
|
- Profiling performance or diagnosing re-renders in a React Native app (iOS or Android)
|
|
20
|
-
- Running, debugging, or testing a Chromium (CDP) app
|
|
20
|
+
- Running, debugging, or testing a Chromium (CDP) app: an Electron app (boot with `boot-device` + `electronAppPath`) or a Chromium browser exposing CDP (auto-discovered on port `9222` / `ARGENT_CHROMIUM_PORTS`); on Chromium scroll with `gesture-scroll` and drag with `gesture-drag`; `gesture-swipe` is touch-only
|
|
21
21
|
</description>
|
|
22
22
|
|
|
23
23
|
<availability_check>
|
|
@@ -37,9 +37,9 @@ If argent is ABSENT, treat it as an expected state, not an error to retry. Do no
|
|
|
37
37
|
|
|
38
38
|
<tapping_rule>
|
|
39
39
|
<important>**Never** derive tap coordinates from screenshot pixels</important>
|
|
40
|
-
Interaction tools (`gesture-tap`, `gesture-swipe`, `keyboard`, `button`, `launch-app`, `open-url`, `run-sequence`, …) return the screen **after** the action: a screenshot AND the accessibility element tree (`--- Elements after action (describe) ---`, the same format `describe` prints, with normalized 0–1 frames). Take tap coordinates from that tree
|
|
40
|
+
Interaction tools (`gesture-tap`, `gesture-swipe`, `keyboard`, `button`, `launch-app`, `open-url`, `run-sequence`, …) return the screen **after** the action: a screenshot AND the accessibility element tree (`--- Elements after action (describe) ---`, the same format `describe` prints, with normalized 0–1 frames). Take tap coordinates from that tree: the centre of the element's frame (`x + width/2`, `y + height/2`). You do not need a separate discovery call before a tap when the last result already lists the target.
|
|
41
41
|
|
|
42
|
-
Call a discovery tool yourself only when you have no fresh tree for the current screen
|
|
42
|
+
Call a discovery tool yourself only when you have no fresh tree for the current screen: before the first action on a screen you have not touched yet, after waiting for something to load, or when the last tree did not list your target. Preferred tools are, in order:
|
|
43
43
|
|
|
44
44
|
- `describe` - native app-level components and safely targetable foreground apps (iOS and Android).
|
|
45
45
|
- `native-describe-screen` - accessibility screen description via injected native devtools (iOS only)
|
|
@@ -70,12 +70,12 @@ Decision order:
|
|
|
70
70
|
|
|
71
71
|
<general_rules>
|
|
72
72
|
|
|
73
|
-
- All simulator/emulator interactions go through argent MCP tools
|
|
73
|
+
- All simulator/emulator interactions go through argent MCP tools; never use `xcrun simctl`,
|
|
74
74
|
raw `curl` to simulator ports, or the simulator-server binary directly.
|
|
75
75
|
- Before calling any gesture tool for the first time, use ToolSearch to load its schema.
|
|
76
76
|
- Interaction tools (`gesture-tap`, `gesture-swipe`, `gesture-pinch`, `gesture-rotate`, `gesture-custom`, `launch-app`, etc.) return a screenshot and the element tree automatically.
|
|
77
77
|
Call `screenshot` or `describe` separately only for a baseline before any action or after a delay.
|
|
78
|
-
- Always open apps with `launch-app` or `open-url
|
|
78
|
+
- Always open apps with `launch-app` or `open-url`; never tap home screen icons.
|
|
79
79
|
- If a task can require a saved flow, choose `argent-create-flow` or `argent-qa-flows` before the first launch or in-app action. Start the recorder before walking the path; recording is not retroactive.
|
|
80
80
|
- Always use `run-sequence` when performing multiple sequential device actions where you don't need to observe the screen between steps. More in `argent-device-interact` skill.
|
|
81
81
|
- When the session ends or the user says they are done: call `stop-all-simulator-servers` with `devices: [...]`
|
|
@@ -90,7 +90,7 @@ Decision order:
|
|
|
90
90
|
<react_native_detection>
|
|
91
91
|
Project type is determined by the `argent-environment-inspector` subagent (see `subagents` section).
|
|
92
92
|
When the subagent result is available, use its `is_react_native` field as the authoritative
|
|
93
|
-
source
|
|
93
|
+
source; do not re-inspect files manually.
|
|
94
94
|
|
|
95
95
|
If the subagent has not run yet and project type is unknown, run it first before proceeding. Always use subagents if available to run `gather-workspace-data` data tool, if possible do not run yourself.
|
|
96
96
|
|
|
@@ -98,11 +98,11 @@ When `is_react_native` is true: load `argent-react-native-app-workflow` skill. U
|
|
|
98
98
|
</react_native_detection>
|
|
99
99
|
|
|
100
100
|
<skill_routing>
|
|
101
|
-
Load the matching skill before starting work and executing tools from argent-mcp
|
|
101
|
+
Load the matching skill before starting work and executing tools from argent-mcp: skills contain the full step-by-step
|
|
102
102
|
procedure and edge-case handling for each workflow.
|
|
103
103
|
|
|
104
104
|
PLATFORM DETECTION
|
|
105
|
-
If the user did not specify a platform, call `list-devices` first and pick the booted target
|
|
105
|
+
If the user did not specify a platform, call `list-devices` first and pick the booted target; do not default to iOS. Vega (Amazon Fire TV) devices appear as `platform:"vega"`, when present load `argent-tv-interact`
|
|
106
106
|
|
|
107
107
|
iOS SIMULATOR SETUP
|
|
108
108
|
Skill: `argent-ios-simulator-setup`
|
|
@@ -123,14 +123,14 @@ When: Performing touch interactions, typing, pressing hardware buttons, launchin
|
|
|
123
123
|
|
|
124
124
|
APP PERMISSIONS (GRANT / DENY / RESET WITHOUT THE SETTINGS UI)
|
|
125
125
|
Skill: `argent-settings-permissions`
|
|
126
|
-
When: You must change an app runtime permission (camera, microphone, photos, contacts, notifications, calendar, location, location-always, media-library, motion, reminders) that the app itself can't flip
|
|
126
|
+
When: You must change an app runtime permission (camera, microphone, photos, contacts, notifications, calendar, location, location-always, media-library, motion, reminders) that the app itself can't flip: pre-authorize or deny it before the app asks, re-enable one the user already denied (iOS never re-prompts), or reset it so the first-run dialog reappears. Works on the iOS simulator and Android emulator/device. Do NOT use it when the app has an in-app toggle or is showing its own permission dialog; tap that instead (see `argent-device-interact`); nor for permissions/settings outside that list.
|
|
127
127
|
Prompt keywords: permission, grant, deny, revoke, reset permission, privacy, camera access, location access, TCC
|
|
128
128
|
|
|
129
129
|
TV INTERACTION (APPLE TV / ANDROID TV / FIRE TV)
|
|
130
130
|
Skill: `argent-tv-interact`
|
|
131
|
-
When: Any TV target
|
|
131
|
+
When: Any TV target: a `list-devices` entry with `runtimeKind: "tv"` (Apple TV simulator or Android TV emulator) or `platform:"vega"` / `kind:"vvd"` (Amazon Fire TV / VVD), or the user mentions Apple TV / tvOS / Android TV / leanback / Vega / Fire TV. A TV UI is focus-driven, not touch-driven: drive it with `describe` (read focus) + `tv-remote` (D-pad presses) + `keyboard` (type); `gesture-*` tools do NOT apply. Covers booting the target, app lifecycle, focus navigation, typing, screenshots, and (Vega) VVD lifecycle + Fast Refresh + JS-runtime debugging (evaluate, console logs, network inspector).
|
|
132
132
|
Prompt keywords: apple tv, tvos, android tv, leanback, vega, fire tv, vvd, d-pad
|
|
133
|
-
Saved artifacts: on Vega, a replayable path is `argent-create-flow` and an acceptance-criteria regression test is `argent-qa-flows
|
|
133
|
+
Saved artifacts: on Vega, a replayable path is `argent-create-flow` and an acceptance-criteria regression test is `argent-qa-flows`; both record D-pad navigation as `tool: tv-remote` steps. Apple TV and Android TV have no saved-flow support; report that limitation.
|
|
134
134
|
|
|
135
135
|
SCREENSHOT DIFF & VISUAL REGRESSION
|
|
136
136
|
Skill: `argent-screenshot-diff`
|
|
@@ -159,7 +159,7 @@ When: Profiling native performance (CPU hotspots, UI hangs, memory leaks). iOS o
|
|
|
159
159
|
|
|
160
160
|
PERFORMANCE OPTIMIZATION
|
|
161
161
|
Use skill: `argent-react-native-optimization`
|
|
162
|
-
When: App feels slow, user asks to optimize, reducing bundle size, improving startup time, fixing re-renders, optimizing lists/images/navigation, or any performance-related task. This is the entry-point skill for all performance work
|
|
162
|
+
When: App feels slow, user asks to optimize, reducing bundle size, improving startup time, fixing re-renders, optimizing lists/images/navigation, or any performance-related task. This is the entry-point skill for all performance work; it delegates to `argent-react-native-profiler` for measurement.
|
|
163
163
|
|
|
164
164
|
INTERACTIVE UI TESTING (ONE-OFF, NOT SAVED)
|
|
165
165
|
Skill: `argent-test-ui-flow`
|
|
@@ -178,7 +178,7 @@ Routing: one-off check → `argent-test-ui-flow`; saved path → `argent-create-
|
|
|
178
178
|
|
|
179
179
|
PROPOSING DESIGN VARIANTS FOR HUMAN SELECTION
|
|
180
180
|
Use skill: `argent-lens`
|
|
181
|
-
When: The user asks for design alternatives / options / A-B choices for a screen or component, or you have produced more than one candidate look for an element and want a human to pick before committing. Covers the build → navigate → screenshot → propose_variant loop and the single blocking await_user_selection call. (Gated behind the `argent-lens` flag, off by default
|
|
181
|
+
When: The user asks for design alternatives / options / A-B choices for a screen or component, or you have produced more than one candidate look for an element and want a human to pick before committing. Covers the build → navigate → screenshot → propose_variant loop and the single blocking await_user_selection call. (Gated behind the `argent-lens` flag, off by default; run `argent enable argent-lens` first.)
|
|
182
182
|
Prompt keywords: variant, design option, alternative, A/B, "let me pick", "show me options"
|
|
183
183
|
</skill_routing>
|
|
184
184
|
|
|
@@ -189,7 +189,7 @@ When:
|
|
|
189
189
|
- Environment context of the project is not yet known
|
|
190
190
|
- No "Project Environment" section exists in project memory / `MEMORY.md` or you lack information about basic setup workflows
|
|
191
191
|
- Need to determine build commands, startup scripts, metro port, platform support, or QA tooling
|
|
192
|
-
If the subagent already ran this session (result in memory), use that context directly
|
|
192
|
+
If the subagent already ran this session (result in memory), use that context directly; do NOT re-run.
|
|
193
193
|
Rules:
|
|
194
194
|
- Run the `argent-environment-inspector` subagent if possible. Never call `gather-workspace-data` yourself - do only if subagent is not available.
|
|
195
195
|
- The main agent is responsible for persisting the subagent's JSON result to project memory
|
|
@@ -5,26 +5,26 @@ description: Set up and connect to an Android emulator using argent MCP tools. U
|
|
|
5
5
|
|
|
6
6
|
## 1. Prerequisites
|
|
7
7
|
|
|
8
|
-
- **Android SDK Platform Tools** on PATH
|
|
9
|
-
- **Android Emulator** on PATH
|
|
8
|
+
- **Android SDK Platform Tools** on PATH: provides `adb`.
|
|
9
|
+
- **Android Emulator** on PATH: needed to boot AVDs. If you will only use an already-running emulator or a physical device, adb alone is sufficient.
|
|
10
10
|
- An AVD created via Android Studio or `avdmanager create avd`.
|
|
11
11
|
|
|
12
12
|
Verify with `adb version` and `emulator -list-avds`.
|
|
13
13
|
|
|
14
14
|
## 2. Setup
|
|
15
15
|
|
|
16
|
-
1. **Find a ready device
|
|
17
|
-
2. **Boot if needed
|
|
18
|
-
3. **Metro (for React Native)
|
|
16
|
+
1. **Find a ready device**: call `list-devices`. Filter for entries with `platform: "android"`. Ready devices (`state: "device"`) come first. Pick the first `serial` (e.g. `emulator-5554`) unless the user specified one.
|
|
17
|
+
2. **Boot if needed**: if nothing Android is ready, call `boot-device` with `avdName: <name>` from the same call's `avds` list. The tool transparently picks hot vs cold boot: it probes the AVD's `default_boot` snapshot, restores it under a tight deadline when usable, and falls back to a full cold boot otherwise. Hot path is typically ~30s; cold path takes 2–10 min. On any stage failure the tool kills the emulator process it started so your next call starts from a clean state.
|
|
18
|
+
3. **Metro (for React Native)**: once a device is up, run `adb -s <serial> reverse tcp:8081 tcp:8081` so the device can reach Metro on your host. Repeat if the device restarts.
|
|
19
19
|
|
|
20
20
|
## 3. Using the device
|
|
21
21
|
|
|
22
|
-
Pass the Android serial as `udid` to the unified interaction tools
|
|
22
|
+
Pass the Android serial as `udid` to the unified interaction tools: `gesture-tap`, `gesture-swipe`, `describe`, `screenshot`, `launch-app`, `keyboard`, etc. Dispatch is automatic based on the id shape. See `argent-device-interact` for platform-neutral interaction tooling and the Android-specific gotchas section at the bottom of that skill.
|
|
23
23
|
|
|
24
24
|
## 4. Notes
|
|
25
25
|
|
|
26
|
-
- **Android TV / leanback AVDs** boot through this exact flow (same `boot-device` + `avdName`), but they are **focus-driven, not touch-driven
|
|
27
|
-
- Serials are the adb device id. iOS UDIDs and Android serials are not interchangeable, but you do NOT need to tell the tools which platform
|
|
26
|
+
- **Android TV / leanback AVDs** boot through this exact flow (same `boot-device` + `avdName`), but they are **focus-driven, not touch-driven**; do not use `gesture-tap`/`gesture-swipe` on them. `list-devices` tags a leanback device with `runtimeKind: "tv"` (detected via the system feature list, not the serial: a TV AVD's serial looks just like a phone's). When you see `runtimeKind: "tv"`, drive it with the focus-driven tools (`describe` / `tv-remote` / `keyboard`) and the `argent-tv-interact` skill (it covers Android TV as well as Apple TV, including the full TV setup flow).
|
|
27
|
+
- Serials are the adb device id. iOS UDIDs and Android serials are not interchangeable, but you do NOT need to tell the tools which platform: dispatch is automatic.
|
|
28
28
|
- `describe` on Android returns a shallower tree than iOS (no accessibility-service equivalent), but covers most tap-target discovery.
|
|
29
29
|
- `reinstall-app` on Android always installs with `-g` so first-launch runtime permissions are pre-granted.
|
|
30
|
-
- To stop the emulator, run `adb -s <serial> emu kill` from a shell (clean shutdown). Never `pkill -9`/`kill -9` qemu
|
|
30
|
+
- To stop the emulator, run `adb -s <serial> emu kill` from a shell (clean shutdown). Never `pkill -9`/`kill -9` qemu: a hard kill leaves the userdata image dirty, after which cold boots can hang for many minutes doing recovery (runaway writes, `boot_completed` never flips). If an image gets into that state, boot once with `-wipe-data` to reset it.
|
|
@@ -40,7 +40,7 @@ steps: []
|
|
|
40
40
|
|
|
41
41
|
Flows never store a device id. The runner binds the device. `launch:` restarts the process but does not clear app, account, or backend data.
|
|
42
42
|
|
|
43
|
-
The one exception is a device _scope_ rather than a target: `stop-all-simulator-servers`' `devices` list **is** kept in the YAML, because without it the step means the machine-wide sweep and would tear down devices other agents are mid-session on. Replay rebinds a recorded scope only when you pass `device` explicitly
|
|
43
|
+
The one exception is a device _scope_ rather than a target: `stop-all-simulator-servers`' `devices` list **is** kept in the YAML, because without it the step means the machine-wide sweep and would tear down devices other agents are mid-session on. Replay rebinds a recorded scope only when you pass `device` explicitly: an auto-detected device would retarget the teardown at a device the flow never named. So the recorded ids are what run when you replay without `device`; on another host they reap nothing and come back in `unmatched`, so re-record the cleanup flow there or pass `device`. A step that recorded no scope is narrowed onto the run's device **only when the run resolved one**. A cleanup flow whose only step is that teardown needs no device, so with none or several booted it resolves none, replays as the machine-wide sweep, and still reports a pass. Record the scope, or pass `device` at replay, whenever the sweep must stay confined.
|
|
44
44
|
|
|
45
45
|
## Selectors
|
|
46
46
|
|
|
@@ -131,7 +131,7 @@ In a `scroll-to` map, put the selector under `target:`. The map supports `up`, `
|
|
|
131
131
|
|
|
132
132
|
### `swipe`
|
|
133
133
|
|
|
134
|
-
`swipe` is one semantic finger flick where the gesture itself is the action
|
|
134
|
+
`swipe` is one semantic finger flick where the gesture itself is the action: dismiss a card, page a carousel, open a drawer, pull-to-refresh: `- swipe: left`, `- swipe: { from: Card, direction: left }`, `- swipe: { by: { y: -0.4 } }`.
|
|
135
135
|
|
|
136
136
|
**Never use `swipe` to scroll.** Whenever the goal is "bring X on screen so the next step can act on it", write `scroll-to: <X>` instead: it is goal-seeking (stops exactly when the target appears), momentum-free, and a no-op if the target is already visible.
|
|
137
137
|
|
|
@@ -158,7 +158,7 @@ On Chromium a swipe is a mouse drag (`gesture-drag`), so a `from` on an `<img>`,
|
|
|
158
158
|
|
|
159
159
|
`type` presses Enter in a second `keyboard` call unless `submit: false`. A polished focus tap plus one text-only `keyboard` call usually needs `submit: false`. Store external values as `{{secret:NAME}}`. The runner uses the first source that defines the name: environment `ARGENT_SECRET_NAME`; project `.argent/secrets.env`; project `.env.local`, then `.env`; then `~/.argent/secrets.env`. The two `secrets.env` files accept the bare `NAME`, but the shared dotenv files expose only `ARGENT_SECRET_`-prefixed keys, so a bare `NAME=…` in `.env` or `.env.local` stays unresolved. The runner redacts every resolved value, so do not use a placeholder for content a report must show.
|
|
160
160
|
|
|
161
|
-
A **selector-less gesture**
|
|
161
|
+
A **selector-less gesture** (a coordinate `tap`/`long-press`/`swipe`, or a `pinch`/`rotate` with no `on:`) resolves no frame, so a tree source it cannot read does not fail it. It settles best effort, dispatches anyway, and the step **passes carrying a warning** that quotes the source's own error. That green says the gesture was sent, not that it landed: one aimed at a moving element can miss it entirely. Restore the tree source, usually by relaunching the app so the instrumentation loads. Accept the warning only where the app serves no tree at all, and put an explicit `wait:` before a gesture that follows a transition. The first such gesture proves the outage and later ones spend that verdict without paying the settle window again. A tree read that comes back, or a relaunch, retires that verdict, which only makes the next gesture pay a fresh window, and it warns again if the source is still down.
|
|
162
162
|
|
|
163
163
|
## Verification conditions
|
|
164
164
|
|
|
@@ -205,14 +205,14 @@ The identity selector must exist only on the destination. A dropped tap can leav
|
|
|
205
205
|
|
|
206
206
|
It **never fails a run.** Every outcome short of a clean settle passes with a warning, because readiness is not an acceptance criterion. Read that warning rather than stepping over it:
|
|
207
207
|
|
|
208
|
-
- **the screen never held still
|
|
209
|
-
- **a small part of it was still changing
|
|
210
|
-
- **the screen was still for the last Nms
|
|
211
|
-
- **the tree stayed empty
|
|
212
|
-
- **settled on the UI tree alone
|
|
213
|
-
- **too few reads
|
|
208
|
+
- **the screen never held still**: it spent the timeout and was still moving on the last interval. A video, shimmer, carousel, or live text stays healthy while moving, and a load that never finished looks identical.
|
|
209
|
+
- **a small part of it was still changing**: a spinner, caret, or progress dot moved through the hold. Too small to count as the screen moving, so the settle completed anyway.
|
|
210
|
+
- **the screen was still for the last Nms**: the wait ran out mid-hold, so no settle was confirmed. It names the term that was short: a second agreeing interval, or the rest of `stableFor`. Raise this step's `timeout:`, because the wait was too short rather than the screen too busy.
|
|
211
|
+
- **the tree stayed empty**: the screen rendered no accessible content: a canvas or video surface, or a screen that never arrived.
|
|
212
|
+
- **settled on the UI tree alone**: no screenshot pair could be read, so presentation-layer animation was never waited out.
|
|
213
|
+
- **too few reads**: a settle needs three reads across two intervals and this step got fewer, so it ended with no evidence either way.
|
|
214
214
|
|
|
215
|
-
Only a tree source this step could not read stops the run, as an errored step
|
|
215
|
+
Only a tree source this step could not read stops the run, as an errored step: one still failing when the wait ends, one that wedges after answering, one that answers with an empty tree it flags as degraded (an unattached Vega toolkit, an AX service asking to be relaunched), or one that never answers (raise `timeout` before suspecting the app). The run is then not ok and every later step is skipped. A single failed read is not that: the hold restarts from the next good read. The same outage stops no [selector-less gesture](#directives), which needs no frame and passes with its own warning instead.
|
|
216
216
|
|
|
217
217
|
`idle` proves readiness only and never identifies the screen, so it cannot serve as acceptance evidence or replace the identity gate. Gate the next action on a stable element. Add `idle` during polish after each screen change, not after every step.
|
|
218
218
|
|
|
@@ -235,7 +235,7 @@ A `run:` target is a YAML path resolved against the directory of the flow file c
|
|
|
235
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
236
|
|
|
237
237
|
- iOS and Android can run fragments or e2e flows inline. A nested e2e launch restarts its app.
|
|
238
|
-
- Chromium boots one instance per launch **step**, not one per run. The leading launch
|
|
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.
|
|
239
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`.
|
|
240
240
|
|
|
241
241
|
## Local scripts
|
|
@@ -43,7 +43,7 @@ Obey these lifecycle rules:
|
|
|
43
43
|
3. Give concurrent recordings separate devices. Their files are isolated, but their live device actions are not.
|
|
44
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.
|
|
45
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.
|
|
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`
|
|
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.
|
|
47
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.
|
|
48
48
|
|
|
49
49
|
## Start in the correct order
|
|
@@ -62,7 +62,7 @@ On iOS, only `restart-app` guarantees an instrumented launch. `launch-app` can f
|
|
|
62
62
|
|
|
63
63
|
### Chromium e2e flows
|
|
64
64
|
|
|
65
|
-
**The app sets the window size; no boot argument overrides it.** Electron ignores `--window-size
|
|
65
|
+
**The app sets the window size; no boot argument overrides it.** Electron ignores `--window-size`: the size comes from the app's own `BrowserWindow` options, and Argent never resizes the window. Boot a fresh target with `boot-device` and `electronAppPath`, then take one `screenshot` and record its pixel dimensions: that capture size is the snapshot device class ([Flow YAML: Snapshots](flow-yaml.md#snapshots-and-standalone-runs)) and must match when CI replays. If the app sizes its window from host or session state, say so in the report.
|
|
66
66
|
|
|
67
67
|
After boot, start the recorder before the first in-app action. Record the first-screen wait. `restart-app` has no Chromium support, so the call errors and records nothing, and a recorded Chromium flow is always a fragment: its launch is written in during polish rather than captured, and any `executionPrerequisite` the recording declared must go with it. A launch-first flow must not carry one. During polish, add the matching launch:
|
|
68
68
|
|
|
@@ -114,9 +114,9 @@ Without step 1, `hidden` also passes for a typo or an element that never existed
|
|
|
114
114
|
|
|
115
115
|
### Taps
|
|
116
116
|
|
|
117
|
-
`flow-add-step` cannot receive a flow selector directly. Discover the element first, then record `gesture-tap` at its frame center; the live coordinates are transport for the gesture, not a final locator. The recorder reads the pre-tap tree and derives the selector in a fixed order
|
|
117
|
+
`flow-add-step` cannot receive a flow selector directly. Discover the element first, then record `gesture-tap` at its frame center; the live coordinates are transport for the gesture, not a final locator. The recorder reads the pre-tap tree and derives the selector in a fixed order (`id`, then `text`, then `role`), giving three outcomes. Read the `recorded` line after every tap, because only two of them warn. It names the derived form (a selector map, or the kept point):
|
|
118
118
|
|
|
119
|
-
1. **`tap: { id: ... }` or `tap: { text: ... }
|
|
119
|
+
1. **`tap: { id: ... }` or `tap: { text: ... }`**: the good case.
|
|
120
120
|
2. **`tap: { role: ... }`, appended with no warning.** An icon-only button with neither id nor visible label lands here. `role` matches as a case-insensitive substring, so a replay screen holding a second control of that role can win the [ranking](flow-yaml.md#the-runner-tree-is-not-the-discovery-tree) and the tap reports a pass on the wrong control.
|
|
121
121
|
3. **A kept raw point**, with a warning naming the reason and the retarget.
|
|
122
122
|
|
|
@@ -130,9 +130,9 @@ Record the focus tap, then record `keyboard` with `text`. A `keyboard` call carr
|
|
|
130
130
|
|
|
131
131
|
**Never `describe` or `screenshot` a non-secure field you just filled from `{{secret:…}}`.** Only a password field is redacted; a plain text input hands the resolved value back into your context, and an API key or token typed into one is the ordinary case. Submit or navigate away first, then verify the resulting screen.
|
|
132
132
|
|
|
133
|
-
**`describe` reports focus on Chromium only.** iOS and Android leave it unset
|
|
133
|
+
**`describe` reports focus on Chromium only.** iOS and Android leave it unset (it is a Vega/D-pad signal there), so those platforms have no live pre-typing focus check, and the value check afterwards is what proves the keys landed. On Chromium, read `focused` before recording `keyboard`.
|
|
134
134
|
|
|
135
|
-
If characters are lost, restore the field with direct calls. Do not record a duplicate typing step. Polish the valid pair into `type:`. Its replay focus wait reads the runner's own tree, which does report focus on iOS, Android, and Chromium, but an unconfirmed poll falls through to typing rather than failing
|
|
135
|
+
If characters are lost, restore the field with direct calls. Do not record a duplicate typing step. Polish the valid pair into `type:`. Its replay focus wait reads the runner's own tree, which does report focus on iOS, Android, and Chromium, but an unconfirmed poll falls through to typing rather than failing, so retain the committed-value check. Store credentials as `{{secret:NAME}}`. Never record a literal credential.
|
|
136
136
|
|
|
137
137
|
### Scrolling and swiping
|
|
138
138
|
|
|
@@ -154,19 +154,19 @@ Record `await-ui-element` through `flow-add-step`. The recorder writes the step
|
|
|
154
154
|
|
|
155
155
|
Only `unmet` disproves the condition. Never delete a step during the recording.
|
|
156
156
|
|
|
157
|
-
A stale `hidden` whose selector matches nothing replays as a silent pass
|
|
157
|
+
A stale `hidden` whose selector matches nothing replays as a silent pass: the unfalsifiable gate that [Record absence in three steps](#record-absence-in-three-steps) exists to prevent. Never proceed as though the gate passed. See the `await-ui-element` section of `argent-device-interact` for the full live condition and selector reference.
|
|
158
158
|
|
|
159
159
|
A wait inside `run-sequence` gets no recorder warning. Inspect the nested result. Any `success: false` fails the sequence during replay.
|
|
160
160
|
|
|
161
161
|
The live tool and flow runner use [different trees](flow-yaml.md#the-runner-tree-is-not-the-discovery-tree). After a successful wait, the recorder checks the same condition on the runner tree:
|
|
162
162
|
|
|
163
163
|
- No warning: The condition holds on both trees.
|
|
164
|
-
- Mismatch: For `text`, first rule out a selector that matches more than one element. Then rule out a changed screen. If the trees really differ,
|
|
164
|
+
- Mismatch: For `text`, first rule out a selector that matches more than one element. Then rule out a changed screen. If the trees really differ, keep the raw `await-ui-element` step: it replays on the tree it passed on.
|
|
165
165
|
- Unreadable, slow, or cancelled check: The conversion is unknown. Restore the source or re-record before conversion.
|
|
166
166
|
|
|
167
167
|
A warning does not reject the step. `flow-finish-recording` repeats each warning below its step and reports dropped warnings.
|
|
168
168
|
|
|
169
|
-
Do not edit YAML before finishing because edits can drop recorded verdicts. If the finish reports drops, record the waits again. Replay every conversion. Keep a raw tool only for `pollIntervalMs` or
|
|
169
|
+
Do not edit YAML before finishing because edits can drop recorded verdicts. If the finish reports drops, record the waits again. Replay every conversion. Keep a raw tool only for `pollIntervalMs`, `bundleId`, or a cross-tree mismatch.
|
|
170
170
|
|
|
171
171
|
### Wrong turns
|
|
172
172
|
|
|
@@ -248,7 +248,7 @@ rg -n '(visible|hidden|exists) *: *["'"'"'A-Za-z0-9]' .argent/flows/<name>.yaml
|
|
|
248
248
|
rg -n '^\s*- wait:|open-url' .argent/flows/<name>.yaml
|
|
249
249
|
```
|
|
250
250
|
|
|
251
|
-
The condition grep matches a condition key with a scalar after it
|
|
251
|
+
The condition grep matches a condition key with a scalar after it (`visible: Save`) and not `visible:` opening a map. Recorder output is always block style, so both forms are one line below their `await:`/`assert:`. It covers `when:` guards too, which take the same loose fallback.
|
|
252
252
|
|
|
253
253
|
Resolve every hit and confirm:
|
|
254
254
|
|
|
@@ -288,7 +288,7 @@ These steps do not work over a link, in the flow or in a fragment or flow that i
|
|
|
288
288
|
|
|
289
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.
|
|
290
290
|
|
|
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
|
|
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.
|
|
292
292
|
|
|
293
293
|
**A passing step that carries a `warning` is a finding, not noise.** `await: { idle: true }` raises [six different warnings](flow-yaml.md#idle-readiness) and they do not share one meaning. Two say the screen was moving; one says the wait ran out mid-hold and is repaired by raising the step's `timeout:`; one says the tree stayed empty; one says the tree did hold still and only the screenshot pairs were missing, so the capture path is what to check; one says the step ended with no evidence either way. No report separates intended motion from a load that never finished. Read which one it is, look at that screen, disclose what you found, and confirm the following step targets a stable element rather than stillness.
|
|
294
294
|
|
|
@@ -24,7 +24,7 @@ Convert element-seeking swipes to `scroll-to`. Keep a coordinate swipe only when
|
|
|
24
24
|
|
|
25
25
|
### Run the gate when capture warns
|
|
26
26
|
|
|
27
|
-
Work this gate as soon as capture warns that it kept a raw point
|
|
27
|
+
Work this gate as soon as capture warns that it kept a raw point, and equally when it silently recorded a role-only selector, which warns about nothing. Keep the source screen available and do these checks:
|
|
28
28
|
|
|
29
29
|
1. **iOS:** query plausible ids or labels with `native-find-views`. If no term is useful, call `native-full-hierarchy` with narrow fields and `maxDepth: 100`. `describe` and `native-describe-screen` are accessibility projections. They cannot prove that no flow selector exists.
|
|
30
30
|
2. **Other platforms:** use `debugger-component-tree` for React Native; otherwise, use `describe`. Verify Android and Chromium candidates in step 3. Their discovery trees can omit runner elements.
|
|
@@ -53,9 +53,9 @@ Use the same explicit UDID throughout. Multiple booted simulators are not an inj
|
|
|
53
53
|
|
|
54
54
|
This fallback applies only to `com.apple.*` system apps. A connection failure in another app never authorizes it.
|
|
55
55
|
|
|
56
|
-
Argent refuses `com.apple.*` bundle ids at every native-devtools read that names one, because a system app is never the app under test. The instrumentation has been seen both loading and not loading into one, depending on the simulator runtime
|
|
56
|
+
Argent refuses `com.apple.*` bundle ids at every native-devtools read that names one, because a system app is never the app under test. The instrumentation has been seen both loading and not loading into one, depending on the simulator runtime; either way it is no basis for a selector. `restart-app`, `launch-app`, and `describe` still work on one; it just never gets a flow tree.
|
|
57
57
|
|
|
58
|
-
Give the flow a `launch:` step as usual. On iOS the launch waits the full devtools budget out, then passes for one of these bundle ids: starting the app is all that step is for, and a coordinate-driven flow needs nothing more. The flow stays e2e; it just pays roughly sixteen seconds at the launch. Where the refusal bites is selector resolution, and the first selector step reports it there
|
|
58
|
+
Give the flow a `launch:` step as usual. On iOS the launch waits the full devtools budget out, then passes for one of these bundle ids: starting the app is all that step is for, and a coordinate-driven flow needs nothing more. The flow stays e2e; it just pays roughly sixteen seconds at the launch. Where the refusal bites is selector resolution, and the first selector step reports it there (terminally, naming the coordinate remedy) rather than as a launch failure. The rest of the tree-free form:
|
|
59
59
|
|
|
60
60
|
- Raw `tool: await-ui-element` accessibility checks.
|
|
61
61
|
- Point taps or long-presses derived from `describe`, each named by an echo.
|
|
@@ -68,7 +68,7 @@ A recorded wait carries a different warning: it adds about one second and report
|
|
|
68
68
|
|
|
69
69
|
Report that the flow has no flow tree and its coordinates are not portable. It cannot satisfy the QA contract. Report the artifact and platform blocker instead.
|
|
70
70
|
|
|
71
|
-
A normally injectable app that is broken in the environment gets the same coordinate-only treatment, but not the same launch: there the `launch:` step fails, since the gate withholds its verdict only for a bundle id argent refuses outright. Start such a flow with a raw `tool: restart-app`, which terminates and relaunches without the readiness gate, and accept that the result is a **fragment
|
|
71
|
+
A normally injectable app that is broken in the environment gets the same coordinate-only treatment, but not the same launch: there the `launch:` step fails, since the gate withholds its verdict only for a bundle id argent refuses outright. Start such a flow with a raw `tool: restart-app`, which terminates and relaunches without the readiness gate, and accept that the result is a **fragment**: its first step that is neither `echo:` nor `script:` is not `launch:`, so the runner never classifies it as e2e, and it cannot complete `argent-qa-flows`, which requires a leading `launch:`. Report the blocker rather than labeling that fallback a completed QA test.
|
|
72
72
|
|
|
73
73
|
## Tree source recovery on Android, Chromium, and Vega
|
|
74
74
|
|
|
@@ -107,15 +107,15 @@ Keep a dismissal swipe only when the UI supports it. Pass it through the coordin
|
|
|
107
107
|
|
|
108
108
|
Classify before editing:
|
|
109
109
|
|
|
110
|
-
| Outcome | Meaning | Response
|
|
111
|
-
| ------------------ | ---------------------------------------------- |
|
|
112
|
-
| Hard failure | A step fails and later steps skip | Inspect that step and actual state
|
|
113
|
-
| Environment error | The reason says the check could not run | Repair the environment and rerun; it is no verdict about the app. A failed `launch:` is `errored` too but **is** a verdict
|
|
114
|
-
| Silent misfire | The run passes but final state is wrong | Restore the first wrong screen and record a stronger gate
|
|
115
|
-
| Partial divergence | An intermediate result disagrees with its echo | Find the first divergent transition
|
|
116
|
-
| Acceptance failure | Actions pass but a requested check fails | Preserve the check and investigate behavior
|
|
117
|
-
| Idle warning | A readiness step passes without settling | Read [which of the six warnings](flow-yaml.md#idle-readiness) it is, then gate the next action on a stable element
|
|
118
|
-
| Unsettled gesture | A selector-less gesture passes unsettled | Restore the tree source, usually by relaunching the app; the green says [only that the gesture was sent](flow-yaml.md#directives)
|
|
110
|
+
| Outcome | Meaning | Response |
|
|
111
|
+
| ------------------ | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
112
|
+
| Hard failure | A step fails and later steps skip | Inspect that step and actual state |
|
|
113
|
+
| Environment error | The reason says the check could not run | Repair the environment and rerun; it is no verdict about the app. A failed `launch:` is `errored` too but **is** a verdict; treat it as a hard failure |
|
|
114
|
+
| Silent misfire | The run passes but final state is wrong | Restore the first wrong screen and record a stronger gate |
|
|
115
|
+
| Partial divergence | An intermediate result disagrees with its echo | Find the first divergent transition |
|
|
116
|
+
| Acceptance failure | Actions pass but a requested check fails | Preserve the check and investigate behavior |
|
|
117
|
+
| Idle warning | A readiness step passes without settling | Read [which of the six warnings](flow-yaml.md#idle-readiness) it is, then gate the next action on a stable element |
|
|
118
|
+
| Unsettled gesture | A selector-less gesture passes unsettled | Restore the tree source, usually by relaunching the app; the green says [only that the gesture was sent](flow-yaml.md#directives) |
|
|
119
119
|
|
|
120
120
|
Then:
|
|
121
121
|
|