@swmansion/argent 0.32.1-next.8 → 0.33.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/README.md +1 -1
- package/assets/manifest.json +2 -2
- package/bin/argent-android-devtools-0.4.0.apk +0 -0
- package/bin/darwin/argent-macos-helper +0 -0
- package/bin/darwin/ax-service +0 -0
- package/bin/darwin/tvos-ax-service +0 -0
- package/bin/darwin/tvos-hid-daemon +0 -0
- package/bin/network-inspector/network-inspector.jar +0 -0
- package/bin/tcp/ax-service +0 -0
- package/dist/cli-cmds.mjs +530 -438
- package/dist/client.d.ts +5 -0
- package/dist/client.js +60 -9
- package/dist/installer.mjs +372 -202
- package/dist/mcp-server.mjs +156 -20
- package/dist/tool-args.generated.d.ts +87 -51
- package/dist/tool-server.cjs +39520 -34927
- package/dylibs/libArgentInjectionBootstrap.dylib +0 -0
- package/dylibs/libKeyboardPatch.dylib +0 -0
- package/dylibs/libNativeDevtoolsIos.dylib +0 -0
- package/dylibs/macos/libArgentInjectionBootstrap.dylib +0 -0
- package/dylibs/macos/libNativeDevtoolsMacos.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 +2 -2
- package/rules/argent.md +1 -1
- package/skills/argent-create-e2e/references/e2e-yaml.md +4 -4
- package/skills/argent-create-e2e/references/reliability-and-recovery.md +3 -3
- package/skills/argent-device-interact/SKILL.md +3 -2
- package/skills/argent-device-interact/references/chromium.md +1 -1
- package/skills/argent-device-interact/references/harmonyos.md +1 -1
- package/skills/argent-ios-simulator-setup/SKILL.md +1 -1
- package/skills/argent-macos-app-interact/SKILL.md +44 -0
- package/skills/argent-macos-app-interact/references/e2e.md +6 -0
- package/skills/argent-qa-e2e/SKILL.md +1 -1
- package/skills/argent-react-native-app-workflow/SKILL.md +2 -0
- package/skills/argent-react-native-optimization/SKILL.md +2 -3
- package/skills/argent-react-native-profiler/SKILL.md +8 -8
- package/skills/argent-screenshot-diff/SKILL.md +1 -1
- package/skills/argent-test-ui-flow/SKILL.md +1 -1
- package/skills/argent-tv-interact/SKILL.md +4 -4
- package/bin/argent-android-devtools-0.3.0.apk +0 -0
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@swmansion/argent",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.33.0",
|
|
4
4
|
"mcpName": "io.github.software-mansion/argent",
|
|
5
|
-
"description": "MCP server for iOS Simulator
|
|
5
|
+
"description": "MCP server for iOS Simulator, Android Emulator, Chromium app and Mac app control",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
package/rules/argent.md
CHANGED
|
@@ -12,7 +12,7 @@ Argent - general rules:
|
|
|
12
12
|
- Interaction tools return screenshot and element tree automatically.
|
|
13
13
|
- prefer `launch-app` or `open-url` than tapping icons on home screen.
|
|
14
14
|
- If a task can require a saved e2e test, load `argent-create-e2e` (`argent-qa-e2e` for acceptance tests) before the first launch or in-app action; recording is not retroactive.
|
|
15
|
-
- Load the matching `argent-*` skill before React Native build/debug, profiling, a physical phone or a TV.
|
|
15
|
+
- Load the matching `argent-*` skill before React Native build/debug, profiling, a physical phone, a Mac app or a TV.
|
|
16
16
|
- Do not stop simulator servers when a task finishes: the next task reuses them. Call `stop-all-simulator-servers` when the user asks to clean up or ends the session, or when a skill tells you to recycle a device's services, with devices this session used. One tool-server is shared by every other agent, so unscoped call tears down their devices too. Never stop a Metro the user started unless they ask.
|
|
17
17
|
- Use the `await-ui-element` tool to block until the UI settles instead of polling using screenshot.
|
|
18
18
|
- The `argent` CLI manages the toolkit: `argent --help` lists commands, `argent --version` shows the installed version.
|
|
@@ -122,7 +122,7 @@ Directives stop the test on failure and skip later steps. The available directiv
|
|
|
122
122
|
- iOS: 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.
|
|
123
123
|
- iOS: 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`.
|
|
124
124
|
|
|
125
|
-
Use the launch map for cross-platform tests. 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
|
|
125
|
+
Use the launch map for cross-platform tests. A bare launch applies everywhere and becomes an app path on Chromium. The map takes `native:`, `ios:`, `android:`, `vega:`, `macos:`, and `chromium:`. `native:` is one id shared by iOS, Android, Vega, and macOS, and a per-platform key overrides it for that platform. `macos:` takes a Mac app's bundle id. `chromium:` accepts a relative or absolute app path. `ios:` and `macos:` also accept `{ app, args }`; Argent 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 test needs a key for a remote run. On an iOS simulator, 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.
|
|
126
126
|
|
|
127
127
|
```yaml
|
|
128
128
|
- launch: { native: com.acme.app, chromium: ../../app }
|
|
@@ -230,7 +230,7 @@ Use `when:` only for optional setup or an interstitial that reconverges:
|
|
|
230
230
|
- tap: { text: Got it }
|
|
231
231
|
```
|
|
232
232
|
|
|
233
|
-
The guard accepts one `exists`, `visible`, `hidden`, or `text` condition, or `{ platform: ios|android|chromium|vega }`. A run on a remote simulator matches `ios`. UI guards use the short assert grace and reject `timeout`. There is no `else` or per-step `optional`. Put separate behavioral paths in separate tests. Never place a required acceptance check inside `when:`.
|
|
233
|
+
The guard accepts one `exists`, `visible`, `hidden`, or `text` condition, or `{ platform: ios|android|chromium|vega|macos }`. A run on a remote simulator matches `ios`. UI guards use the short assert grace and reject `timeout`. There is no `else` or per-step `optional`. Put separate behavioral paths in separate tests. Never place a required acceptance check inside `when:`.
|
|
234
234
|
|
|
235
235
|
## Composition and platform limits
|
|
236
236
|
|
|
@@ -258,7 +258,7 @@ Over a link (`argent link` or `ARGENT_TOOLS_URL`, also to 127.0.0.1), `e2e-add-s
|
|
|
258
258
|
|
|
259
259
|
## Snapshots and CLI runs
|
|
260
260
|
|
|
261
|
-
`argent e2e run <name> [--device <id>] [--platform ios|android|chromium|vega|ios-remote] [--update-baselines] [--output <dir>] [--json]` runs without an LLM and exits non-zero on failure.
|
|
261
|
+
`argent e2e run <name> [--device <id>] [--platform ios|android|chromium|vega|macos|ios-remote] [--update-baselines] [--output <dir>] [--json]` runs without an LLM and exits non-zero on failure.
|
|
262
262
|
|
|
263
263
|
A screenshot is human evidence. A `snapshot:` is executable visual verification. A missing baseline or excessive mismatch fails. A `cropOn` size change also fails. Use snapshots for color, layout, size, spacing, typography, clipping, overflow, images, icons, or stable component appearance. Use full screen for global changes and `cropOn` for one component.
|
|
264
264
|
|
|
@@ -266,7 +266,7 @@ Do not use a snapshot as the only proof of navigation, persistence, data, access
|
|
|
266
266
|
|
|
267
267
|
Baselines live beside the test, under `.argent/e2e/__baselines__/<name>/` 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 test that a `tool: e2e-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.
|
|
268
268
|
|
|
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 snapshots' images and failed steps' screenshots under `<dir>/<name>/` for CI artifact upload.
|
|
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. For a Mac app, pass `--platform macos` and omit `--device`; the key holds the window size in points, so a new window size needs new baselines. The runner pins mobile status bars during visual runs. `--output <dir>` writes failed snapshots' images and failed steps' screenshots under `<dir>/<name>/` for CI artifact upload.
|
|
270
270
|
|
|
271
271
|
## YAML safety
|
|
272
272
|
|
|
@@ -26,7 +26,7 @@ Convert element-seeking swipes to `scroll-to`. Keep a coordinate swipe only when
|
|
|
26
26
|
|
|
27
27
|
Work this gate as soon as capture warns that it kept a raw point or recorded a role-only selector. Keep the source screen available and do these checks:
|
|
28
28
|
|
|
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`
|
|
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` is an accessibility projection. It cannot prove that no YAML selector exists.
|
|
30
30
|
2. **Other platforms:** use `describe`; for React Native on Android, also `debugger-component-tree`, for testIDs `describe` omits. Verify Android and Chromium candidates in step 3. Their discovery trees can omit runner elements.
|
|
31
31
|
3. Test each candidate in a scratch fragment with `assert: { visible: <candidate> }` on the valid screen. Inspect every failure before trying a better id, label, app, or container.
|
|
32
32
|
4. If source is available, inspect its `testID`, `accessibilityIdentifier`, or `resource-id`. If none exists, report the missing stable id as the real fix.
|
|
@@ -43,8 +43,8 @@ On an iOS simulator, the full runner tree exists only for an app launched by Arg
|
|
|
43
43
|
|
|
44
44
|
1. If Metro, Expo, Xcode, an icon, or a prior process launched the app, call `restart-app`. Restore the source screen and retry capture. `launch-app` can only foreground the existing process.
|
|
45
45
|
2. Tap capture does **not** wait for that connection. It makes one tree read and turns any failure straight into the kept-coordinates warning. A recording-time `restart-app` returns before the devtools connection opens, so the first tap after a restart can warn transiently. Re-record that tap once before escalating; only a warning that survives the retry is evidence of a real fault.
|
|
46
|
-
3. If the warning survives, call `native-
|
|
47
|
-
4. If an injectable app remains disconnected, call `stop-all-simulator-servers` once, **scoped to `devices: [<this simulator's UDID>]`**. This does not change app or account data. Then restart and
|
|
46
|
+
3. If the warning survives, call `native-full-hierarchy` with the same UDID and bundle id and `maxDepth: 1`. A `status` other than `ok` carries a `message`: follow it. It names the one action that helps and says when to stop. If the call fails with `ViewInspector RPC timed out`, the app is connected and its main thread is stalled, so skip step 4: wait a few seconds, then repeat this call.
|
|
47
|
+
4. If an injectable app remains disconnected, call `stop-all-simulator-servers` once, **scoped to `devices: [<this simulator's UDID>]`**. This does not change app or account data. Then restart and repeat the step 3 call.
|
|
48
48
|
5. If it still fails, report an instrumentation blocker. Do not replace selectors with coordinates in a QA e2e test.
|
|
49
49
|
|
|
50
50
|
Use the same explicit UDID throughout. Multiple booted simulators are not an injection fault. Pass `--device <udid>` when CLI device selection is ambiguous.
|
|
@@ -9,6 +9,7 @@ Each tool's own description carries its parameters, defaults, return shape and e
|
|
|
9
9
|
|
|
10
10
|
- Get a target id from `list-devices`; if none is ready, `boot-device` one. Full setup flow: `argent-ios-simulator-setup` / `argent-ios-device-setup` / `argent-android-emulator-setup`. The same tool names drive iOS, Android and Chromium; each takes the `udid` from `list-devices`.
|
|
11
11
|
- Physical iPhone (`kind: "device"`): read `argent-ios-device-interact` first. Only the tools it lists exist there, and `describe` sees only the app `launch-app` registered.
|
|
12
|
+
- Mac app (`platform: "macos"`): read `argent-macos-app-interact` first.
|
|
12
13
|
- Read the matching reference before driving these targets: `references/chromium.md` for a `chromium` target, `references/harmonyos.md` for a `harmony` target, `references/foldables.md` for a device `list-devices` marks `foldable: true` (or before calling `fold`).
|
|
13
14
|
- Load a deferred tool's schema with ToolSearch before its first call (e.g. `gesture-pinch`, `gesture-rotate`, `gesture-custom`); without it, numbers go out as strings and fail validation.
|
|
14
15
|
- If you delegate device tasks to sub-agents, make sure they have MCP permissions.
|
|
@@ -30,7 +31,7 @@ Each tool's own description carries its parameters, defaults, return shape and e
|
|
|
30
31
|
| Two-finger rotation | `gesture-rotate` | |
|
|
31
32
|
| Hardware key | `button` | Home, back, power, volume, appSwitch, actionButton |
|
|
32
33
|
| Type text or press a named key | `keyboard` | Every platform; text or one key per call (§6) |
|
|
33
|
-
| Paste text | `paste` | Only where a user would paste (§6). Sim/emu
|
|
34
|
+
| Paste text | `paste` | Only where a user would paste (§6). Sim/emu, Mac app |
|
|
34
35
|
| Rotate device | `rotate` | Orientation changes |
|
|
35
36
|
| Fold device | `fold` | Foldables only: `references/foldables.md` |
|
|
36
37
|
| Shake device | `shake` | Shake handlers (sim/emu only), Undo-typing prompt, RN dev menu |
|
|
@@ -44,7 +45,7 @@ After an action moves you to a different screen, or whenever you don't know an e
|
|
|
44
45
|
| Need | Tool |
|
|
45
46
|
| ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
|
|
46
47
|
| Any screen: app, system dialog, Home screen | `describe` |
|
|
47
|
-
|
|
|
48
|
+
| UIKit properties of a view (iOS simulator) | `native-find-views` (needs `bundleId` and a class, id, label, tag or `nativeID` to match) |
|
|
48
49
|
| What sits at a known raw point (iOS simulator) | `native-user-interactable-view-at-point` (the view that receives touch) or `native-view-at-point` (the visually deepest view) |
|
|
49
50
|
| Final visual fallback | `screenshot`, only when the tools above cannot expose the control. Do not derive routine in-app navigation targets from pixels |
|
|
50
51
|
|
|
@@ -6,4 +6,4 @@ A Chromium (CDP) target is an Electron app or a Chromium-family browser (Chrome/
|
|
|
6
6
|
|
|
7
7
|
- Scroll with `gesture-scroll` and drag with `gesture-drag`; `gesture-swipe` is touch-only.
|
|
8
8
|
- Tabs and windows: `chromium-tabs`. Every other tool acts on the **active** tab, so `select` before driving a different one. A cross-process navigation (some redirects) can swap a tab's CDP target; `list` again to pick it up under a fresh id.
|
|
9
|
-
- Cookies, HttpOnly included: `chromium-cookies`. Web Storage: `
|
|
9
|
+
- Cookies, HttpOnly included: `chromium-cookies`. Web Storage: `debugger-evaluate`, with `localStorage.getItem("token")` for one key or `Object.fromEntries(Object.entries(localStorage))` for all. A bare `localStorage` comes back as `{}` even when it has data. Use them to seed auth before an e2e test or assert app state after one.
|
|
@@ -17,7 +17,7 @@ Refused as unsupported on harmony:
|
|
|
17
17
|
|
|
18
18
|
- `gesture-rotate` and `gesture-custom`: the device moves each contact along one straight line per call, so there is no arc and no long-press. There is no long-press tool on HarmonyOS.
|
|
19
19
|
- `gesture-drag` and `gesture-scroll` (Chromium-only), and `rotate`: the device has no orientation command.
|
|
20
|
-
- `native-
|
|
20
|
+
- `native-view-at-point`, `native-user-interactable-view-at-point`, `debugger-component-tree`, the rest of the debugger (`debugger-evaluate`, `debugger-log-registry`), `view-network-logs` and the profilers.
|
|
21
21
|
- `paste`, so a `{{secret:...}}` placeholder goes through `keyboard` only.
|
|
22
22
|
- Screen recording: HarmonyOS exposes no readable frame stream. Use `screenshot` for a still frame.
|
|
23
23
|
|
|
@@ -5,7 +5,7 @@ description: Set up and connect to an iOS simulator using argent MCP tools. Use
|
|
|
5
5
|
|
|
6
6
|
## 1. Setup Steps
|
|
7
7
|
|
|
8
|
-
1. **Find a booted simulator.** Use `list-devices`. Filter for entries with `platform: "ios"` and skip `kind: "device"` (a physical iPhone): booted simulators are listed first. If no fitting simulator is booted, call `boot-device` with `udid: <chosen UDID>`.
|
|
8
|
+
1. **Find a booted simulator.** Use `list-devices`. Filter for entries with `platform: "ios"` and skip `kind: "device"` (a physical iPhone): booted simulators are listed first. Through MCP, simulators that are shut down follow the JSON object, one line each, with the udid second. If no fitting simulator is booted, call `boot-device` with `udid: <chosen UDID>`.
|
|
9
9
|
2. **No connect step.** Interaction tools (`gesture-tap`, `describe`, `screenshot`, …) auto-start the simulator server on first use.
|
|
10
10
|
|
|
11
11
|
## 2. Notes
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: argent-macos-app-interact
|
|
3
|
+
description: Drive a native Mac app (AppKit, SwiftUI, react-native-macos) through argent. Use when a list-devices entry has platform "macos", or the user names a Mac app, a macOS app or a native desktop app. Never for an iOS simulator, an iPhone, or an Electron or Chromium app (platform "chromium").
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
`argent-device-interact` still applies for everything not listed here (`run-sequence`, `await-ui-element`, secrets).
|
|
7
|
+
|
|
8
|
+
## Contract
|
|
9
|
+
|
|
10
|
+
- Needs the `macos-apps` flag, which is on by default. When a tool says it is off, tell the user to run the command it names. Do not change the flag yourself.
|
|
11
|
+
- One app is one device. `list-devices` shows only apps argent started that still run, also those of other sessions: never pick one unless the user named that app or this session started it.
|
|
12
|
+
- Start an app with `boot-device {macosAppPath: "<abs path>.app"}`, never with `open` or Xcode. Use `launch-app` only for an app argent already started: with no recorded path it takes whichever copy Spotlight finds.
|
|
13
|
+
- Build the `.app` without starting it: `xcodebuild ... build`, then take the bundle from `BUILT_PRODUCTS_DIR` (`xcodebuild -showBuildSettings`). Xcode Run and `react-native run-macos` start a copy without the argent library: `boot-device` then fails with `already running ... without the argent library`. Retry with `force: true`, but ask the user first when they may have work open in that copy.
|
|
14
|
+
- Never pass `force` when the error names another build path; report it.
|
|
15
|
+
- After a code change: rebuild, then `restart-app`.
|
|
16
|
+
- A start result with a `note` that the app showed no window: taps and screenshots need one. Tell the user, and read the log file it names.
|
|
17
|
+
- On a hardened-runtime refusal, report it to the user. Do not sign files or change code signing.
|
|
18
|
+
- Never activate the app or drive it with `osascript`, `open` or other system tools.
|
|
19
|
+
- At the end: `stop-all-simulator-servers {devices: ["macos-app-<bundle id>"]}` closes argent's connection; the app keeps running.
|
|
20
|
+
|
|
21
|
+
## Per-tool notes
|
|
22
|
+
|
|
23
|
+
- Swipe or drag: `gesture-drag`. Long press: `gesture-drag` with the same start and end point. Scroll: `gesture-scroll`.
|
|
24
|
+
- Zoom or rotate: `gesture-pinch` and `gesture-rotate` fail; use the app's own controls or shortcuts.
|
|
25
|
+
- After a right-click (`gesture-tap` with `button: "right"`), the returned tree lists the menu items; a plain `gesture-tap` on one chooses it (the menu can stay in the tree for a moment while it closes). `keyboard` `escape` closes the menu; `enter` chooses nothing after a right-click, so tap the item.
|
|
26
|
+
- No hover: a tooltip is out of reach.
|
|
27
|
+
- `open-url`: the URL goes to the running app. A custom scheme must be one the app declares; `http` and `https` go to the app, not the browser; a `file:` URL opens that document in the app.
|
|
28
|
+
- A SwiftUI `DisclosureGroup` opens only at its chevron, near the left end of its frame: a tap at the centre passes and does nothing. Tap along the left end in steps of about 0.008 until its `value` changes.
|
|
29
|
+
- `menu-bar` for any menu command. An item listed `[disabled]` cannot be chosen right now: an edit command (Copy, Select All) needs the text field clicked first; while an alert is open only its own commands work, so answer the alert first. When a menu of the app is open, `choose` fails: send `keyboard {key: "escape"}`, then choose again.
|
|
30
|
+
- Open and save panels: never click in the file list, which `describe` cannot read. Use `file-panel`, also for the Delete or Don't Save prompt of an edited new document.
|
|
31
|
+
|
|
32
|
+
## Tree
|
|
33
|
+
|
|
34
|
+
- Identifiers: AppKit accessibility identifier, SwiftUI `.accessibilityIdentifier()`, web `data-testid` (else `id`), React Native `testID` (also on a plain `View` or `Text`).
|
|
35
|
+
- Hint `The Mac is locked` or `fallback walk`: clicks and typing still work, elements can be missing (an open context menu among them), and a `hidden` check cannot pass. Ask the user to unlock when a target is missing.
|
|
36
|
+
- An action that fails or has no effect: a minimized window takes no input. Restore it by choosing it in the Window menu with `menu-bar`; without such an item, ask the user.
|
|
37
|
+
|
|
38
|
+
## E2E tests
|
|
39
|
+
|
|
40
|
+
Read `references/e2e.md` before recording or writing a test for a Mac app.
|
|
41
|
+
|
|
42
|
+
## react-native-macos
|
|
43
|
+
|
|
44
|
+
A Debug build loads JavaScript from Metro: start Metro before `boot-device` (see `argent-react-native-app-workflow`). `debugger-*` and the React profiler do not take a Mac app id: read the screen with `describe`.
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# E2E tests on a Mac app
|
|
2
|
+
|
|
3
|
+
- Record the launch as a `restart-app` step, then write it as `launch: { macos: <bundle id> }` (keep `{ app, args }` if the recorder wrote args) so the runner picks the Mac app and starts it. Otherwise run with `--platform macos` or the device id: without them the runner never picks a Mac app.
|
|
4
|
+
- A `swipe` is a mouse drag, a `long-press` a press and hold. `pinch` and `rotate` fail.
|
|
5
|
+
- A right-click is `tap: { on: <selector>, button: right }`.
|
|
6
|
+
- A file panel is a `tool: file-panel` step, a menu command a `tool: menu-bar` step (`args: { action: choose, path: [Edit, Select All] }`). Gate a branch with `when: { platform: macos }`.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: argent-qa-e2e
|
|
3
|
-
description: Write repeatable QA regression e2e tests from test cases, tickets, or acceptance criteria. Use when the user asks to write, automate, or generate an e2e test or preserve an automated regression scenario, with deterministic setup, stable targets, executable structural or visual evidence, and two consecutive full passes. For one-off UI checks or replayable paths without acceptance criteria, use argent-test-ui-flow or argent-create-e2e. Supports iOS, Android, Chromium, and Vega (Fire TV), where recorded tv-remote steps replace touch directives. Apple TV and Android TV are unsupported; use argent-tv-interact there and report the limitation.
|
|
3
|
+
description: Write repeatable QA regression e2e tests from test cases, tickets, or acceptance criteria. Use when the user asks to write, automate, or generate an e2e test or preserve an automated regression scenario, with deterministic setup, stable targets, executable structural or visual evidence, and two consecutive full passes. For one-off UI checks or replayable paths without acceptance criteria, use argent-test-ui-flow or argent-create-e2e. Supports iOS, Android, Chromium, Mac apps, and Vega (Fire TV), where recorded tv-remote steps replace touch directives. Apple TV and Android TV are unsupported; use argent-tv-interact there and report the limitation.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Create a QA regression e2e test
|
|
@@ -5,6 +5,8 @@ description: Step-by-step workflows for developing or debugging React Native app
|
|
|
5
5
|
|
|
6
6
|
Physical iPhone (`kind: "device"`): Metro debugging and profiling tools reject it. Use a simulator.
|
|
7
7
|
|
|
8
|
+
react-native-macos app: start Metro (§1.2), then follow `argent-macos-app-interact` instead of `run-macos`.
|
|
9
|
+
|
|
8
10
|
## 1. Starting the React Native App
|
|
9
11
|
|
|
10
12
|
### 1.1 Read the project's configuration first
|
|
@@ -39,9 +39,8 @@ See [references/semantic-checklist.md](references/semantic-checklist.md) for ful
|
|
|
39
39
|
|
|
40
40
|
### Phase 3: Profiling
|
|
41
41
|
|
|
42
|
-
1.
|
|
43
|
-
2.
|
|
44
|
-
3. Cross-reference the profiling results with the Phase 1–2 findings, and fix the highest-impact issues top-down. Re-profile after architectural changes; batch mechanical fixes.
|
|
42
|
+
1. Load the `argent-react-native-profiler` skill and follow its workflow (React and native profiling together) on the key user flows: the screens the user named, or all major flows. It covers analysis, drill-down, and re-profiling after each fix.
|
|
43
|
+
2. Cross-reference the profiling results with the Phase 1–2 findings, and fix the highest-impact issues top-down. Re-profile after architectural changes; batch mechanical fixes.
|
|
45
44
|
|
|
46
45
|
### Phase 4: Verify no regressions
|
|
47
46
|
|
|
@@ -12,16 +12,14 @@ Physical iPhone: not supported; `react-profiler-*` reject `kind: "device"`. Prof
|
|
|
12
12
|
### React Profiler (Hermes / React commits)
|
|
13
13
|
|
|
14
14
|
- `react-profiler-start` / `react-profiler-stop`: record CPU samples and React commits around an interaction.
|
|
15
|
-
- `react-profiler-analyze`: turn the recording into a ranked report: hot commits with the JS functions that ran during each.
|
|
16
|
-
- `react-profiler-status`: **only after an interruption** (debugger drop, Metro reload, pause, subagent handoff, any doubt), never otherwise.
|
|
17
|
-
- `react-profiler-component-source`: source, location and memoization status of a component the report flagged.
|
|
18
|
-
- `react-profiler-renders`: how many instances of each component are mounted in the top 30 levels of the tree, with their last render time; no session needed. It does not count re-renders: record a profile for that.
|
|
15
|
+
- `react-profiler-analyze`: turn the recording into a ranked report: hot commits with the JS functions that ran during each, and the file and line of each ranked component it finds in the project.
|
|
16
|
+
- `react-profiler-status`: **only after an interruption** (debugger drop, Metro reload, pause, subagent handoff, any doubt), never otherwise. After a debugger drop, react-profiler-stop can no longer collect the run; check status before stopping or restarting.
|
|
19
17
|
- `react-profiler-fiber-tree`: live component hierarchy, no session needed, for tracing a component's ancestry.
|
|
20
18
|
|
|
21
19
|
### Drill-down queries (after analyze)
|
|
22
20
|
|
|
23
21
|
- `profiler-cpu-query`: JS CPU: top functions, a time window, a function's call tree, CPU during a component's commits.
|
|
24
|
-
- `profiler-commit-query`: React commits by component, time range, commit index, or cascade tree.
|
|
22
|
+
- `profiler-commit-query`: React commits by component, time range, commit index, or cascade tree, and render counts over all commits.
|
|
25
23
|
- `profiler-stack-query`: native data: hang stacks, function callers, thread breakdown, leak details.
|
|
26
24
|
- `profiler-combined-report`: correlates native hangs with React commits when both profilers ran.
|
|
27
25
|
- `profiler-load`: reload an earlier session from disk for the query tools.
|
|
@@ -61,7 +59,7 @@ Call `react-profiler-stop` **and** `native-profiler-stop` in parallel (skip the
|
|
|
61
59
|
|
|
62
60
|
Call `react-profiler-analyze` with your annotations. Check the report's React Compiler and build-mode lines before proposing fixes.
|
|
63
61
|
|
|
64
|
-
If both profilers ran, also call `native-profiler-analyze`, then **you must** call `profiler-combined-report`: it surfaces correlations the individual reports miss.
|
|
62
|
+
If both profilers ran, also call `native-profiler-analyze`, then **you must** call `profiler-combined-report`: it surfaces correlations the individual reports miss. If it says no React commits are stored, use the native report on its own.
|
|
65
63
|
|
|
66
64
|
### Step 4: Assess results
|
|
67
65
|
|
|
@@ -78,6 +76,7 @@ Chain the query tools from what the report flags:
|
|
|
78
76
|
- **Slow commit** → `profiler-commit-query` `by_index` (every component, props changes, parent cascade) or `cascade_tree` (who triggered whom).
|
|
79
77
|
- **Slow component** → `profiler-cpu-query` `component_cpu` → `call_tree` for the hot function → read the source → propose a fix.
|
|
80
78
|
- **A time range** → `profiler-commit-query` `by_time_range`, or `profiler-cpu-query` `time_window`.
|
|
79
|
+
- **Re-render counts over the whole session** → `profiler-commit-query` `render_counts`: every component, including commits under 16 ms that the other modes do not store.
|
|
81
80
|
- **Native hang or leak** → `profiler-stack-query` `hang_stacks` / `leak_stacks`; correlate the hang's timing with React commits.
|
|
82
81
|
|
|
83
82
|
Pass component names exactly as the report prints them; the wrapped name (`Memo(...)`, `Forget(...)`, `ForwardRef(...)`) resolves too. Repeat until you find the root-cause function and file, judging the evidence as in Step 4. After each round, ask the user whether to keep digging or move to fixing.
|
|
@@ -88,7 +87,7 @@ To revisit earlier data, e.g. to compare before and after a fix: `profiler-load`
|
|
|
88
87
|
|
|
89
88
|
### Step 8: Apply fix and re-profile
|
|
90
89
|
|
|
91
|
-
Read the bottleneck's source (`
|
|
90
|
+
Read the bottleneck's source (the report gives its path from `project_root` and the line), apply the fix, then re-profile the same scenario (Step 1 → interaction → Steps 2-4). Report honestly whether the target metric improved, stayed flat, or regressed, and whether any _other_ metric got worse (e.g. fewer renders but more CPU time, or a different component now re-renders more). If the fix brought no net benefit or unacceptable tradeoffs, revert and reconsider.
|
|
92
91
|
|
|
93
92
|
If the interaction was recorded as an e2e test, replay it with `e2e-execute` instead of repeating the steps by hand. If the replay fails (e.g. a UI fix changed the layout), follow `argent-create-e2e`'s [Diagnose a replay failure](../argent-create-e2e/references/reliability-and-recovery.md#diagnose-a-replay-failure) before retrying the profiling cycle.
|
|
94
93
|
|
|
@@ -98,7 +97,8 @@ If the user does not want changes, present the report and suggest the fix withou
|
|
|
98
97
|
|
|
99
98
|
## 4. Caveats
|
|
100
99
|
|
|
101
|
-
- **Dev builds** render ~3x slower than production (the report notes it)
|
|
100
|
+
- **Dev builds** render ~3x slower than production (the report notes it), and Strict Mode can double durations, but not counts. Use counts together with cost: a high count matters only when its time adds up. Do not memoize a component just because it renders often.
|
|
101
|
+
- **No hot commit** does not mean the app is fine. The report then gives render time, the busiest second and the app components that re-rendered in at least 10 commits and used at least 1 ms of self time per second. `render_counts` lists the rest. These are dev-build numbers, idle time in the recording lowers the share, and a listed component is not a finding.
|
|
102
102
|
- **Live API data** may differ between runs (payload sizes, item counts) and shift render counts and durations independently of your fix. Note when data-dependent components vary.
|
|
103
103
|
- **Run-to-run noise:** variations under ~10-15% in commit duration may be noise; only treat consistent, directional changes as signal.
|
|
104
104
|
- **Profiler overhead:** if the native profile shows `JSLexer`, `JSONEmitter` or Hermes internals dominating the JS thread, that is instrumentation cost, not app work. Discount those entries.
|
|
@@ -7,7 +7,7 @@ description: Compare saved or live app screenshots with the argent screenshot-di
|
|
|
7
7
|
|
|
8
8
|
Use `screenshot-diff` as supporting visual evidence for UI QA and visual regression checks. It highlights pixel-visible change or stability; it does not replace visual inspection, accessibility/component-tree state, frame/attribute checks, logs, network evidence, or app behavior. Its description covers the input combinations, physical-iPhone captures and the result.
|
|
9
9
|
|
|
10
|
-
Do not use screenshot diffing for tap-coordinate discovery. Use `describe`
|
|
10
|
+
Do not use screenshot diffing for tap-coordinate discovery. Use `describe` to find targets first.
|
|
11
11
|
|
|
12
12
|
## 2. When To Use
|
|
13
13
|
|
|
@@ -20,7 +20,7 @@ For implementation tasks that modify visible UI, this workflow also serves as a
|
|
|
20
20
|
3. **Interact**: perform the action (`gesture-tap`, `gesture-swipe`, `keyboard`, `button`, ...); you receive a screenshot automatically.
|
|
21
21
|
4. **Verify**: check the returned screenshot. If it shows a loading/transitional state, block with `await-ui-element` (expected element `visible`, or a spinner `hidden`) rather than a guessed delay (its result carries the new screenshot and element tree), but only with a selector you can trust (`text`/`identifier`/`role`) that the screen is known to have or that you saw in a prior `describe`; a guessed one just times out. Otherwise use a short fixed wait. Pick evidence by what's being asserted:
|
|
22
22
|
- **Visual** (layout, spacing, color, typography, image/icon rendering, clipping, overflow, text rendering): prefer `screenshot-diff` against the step 1 baseline: it surfaces pixel-visible changes the auto-screenshot might miss. Fall back to inspecting the auto-screenshot only when a stable baseline isn't available.
|
|
23
|
-
- **Structural** (navigation state, element existence, accessibility labels/values, selection, hierarchy, route): verify with `describe
|
|
23
|
+
- **Structural** (navigation state, element existence, accessibility labels/values, selection, hierarchy, route): verify with `describe` or `debugger-component-tree`.
|
|
24
24
|
- **Runtime / log / network** (console errors, API calls, persistence, timing): verify with `view-network-logs`, `debugger-log-registry`, `debugger-evaluate`, or targeted tests. A `not_connected` result from the debugger tools is not evidence about the app: follow its `guidance`, then re-verify.
|
|
25
25
|
- **Mixed**: collect evidence for each relevant class.
|
|
26
26
|
- Report the combined verdict: expected behavior, observed behavior, evidence used, and any blocker for requested visual diffing.
|
|
@@ -15,9 +15,9 @@ description: Control and inspect TV apps via argent, Apple TV (tvOS), Android TV
|
|
|
15
15
|
|
|
16
16
|
## The navigation loop
|
|
17
17
|
|
|
18
|
-
1. `describe`: find the cursor and your target
|
|
19
|
-
2. `tv-remote`: move focus toward the target. Prefer **one** call with a path ending in `select`, e.g. `{button:["down","right","select"]}`; count rows/columns from the
|
|
20
|
-
3. `describe` again to confirm
|
|
18
|
+
1. `describe`: find the cursor and your target.
|
|
19
|
+
2. `tv-remote`: move focus toward the target. Prefer **one** call with a path ending in `select`, e.g. `{button:["down","right","select"]}`; count rows/columns from the list order.
|
|
20
|
+
3. `describe` again to confirm, or on Apple TV `await-ui-element {condition:"exists", selector:{text:"X", role:"focused"}}`. On a miss, repeat.
|
|
21
21
|
|
|
22
22
|
## Tools
|
|
23
23
|
|
|
@@ -29,7 +29,7 @@ description: Control and inspect TV apps via argent, Apple TV (tvOS), Android TV
|
|
|
29
29
|
|
|
30
30
|
### Apple TV (tvOS simulator)
|
|
31
31
|
|
|
32
|
-
- Boot like any iOS sim (`boot-device`); the
|
|
32
|
+
- Boot like any iOS sim (`boot-device`); the first `describe` / `tv-remote` starts the AX + HID daemons (a few seconds).
|
|
33
33
|
- Dev build: `open-url {udid, url:"<scheme>://expo-development-client/?url=http%3A%2F%2F<HOST_IP>%3A8081"}` (`<HOST_IP>` = your Mac's LAN IP, shown on the launcher).
|
|
34
34
|
|
|
35
35
|
### Android TV (leanback emulator)
|
|
Binary file
|