zeno-mobile-runner 0.2.16 → 0.2.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +33 -0
- package/CONTRIBUTING.md +20 -7
- package/FEATURES.md +29 -20
- package/README.md +73 -57
- package/SECURITY.md +11 -6
- package/clients/README.md +8 -7
- package/clients/go/README.md +2 -2
- package/clients/kotlin/README.md +2 -2
- package/clients/kotlin/build.gradle.kts +1 -1
- package/clients/python/README.md +2 -1
- package/clients/python/pyproject.toml +1 -1
- package/clients/rust/Cargo.lock +1 -1
- package/clients/rust/Cargo.toml +1 -1
- package/clients/rust/README.md +2 -2
- package/clients/swift/README.md +2 -2
- package/clients/typescript/README.md +2 -1
- package/clients/typescript/package.json +1 -1
- package/docs/adr/0001-agent-native-runner-boundary.md +1 -1
- package/docs/adr/README.md +7 -5
- package/docs/agent-discovery.md +15 -15
- package/docs/ai-agents.md +30 -20
- package/docs/app-integration.md +59 -27
- package/docs/benchmarking.md +16 -8
- package/docs/benchmarks/README.md +3 -1
- package/docs/benchmarks/benchmark-lab-v1.md +1 -1
- package/docs/client-installation.md +18 -9
- package/docs/clients.md +7 -6
- package/docs/config.md +29 -15
- package/docs/demo.md +14 -9
- package/docs/expo-smoke.md +12 -18
- package/docs/frameworks.md +30 -21
- package/docs/install.md +63 -13
- package/docs/npm.md +45 -27
- package/docs/production-readiness.md +32 -17
- package/docs/protocol-fixtures/core-session.responses.jsonl +1 -1
- package/docs/protocol-versioning.md +5 -3
- package/docs/protocol.md +33 -18
- package/docs/scenario-authoring.md +15 -8
- package/docs/support-matrix.md +38 -0
- package/docs/trace-privacy.md +5 -3
- package/docs/troubleshooting.md +17 -14
- package/npm/app-config.mjs +2 -0
- package/npm/commands.mjs +4 -4
- package/npm/scaffold.mjs +2 -2
- package/package.json +2 -2
- package/prebuilds/darwin-arm64/zmr +0 -0
- package/prebuilds/darwin-x64/zmr +0 -0
- package/prebuilds/linux-arm64/zmr +0 -0
- package/prebuilds/linux-x64/zmr +0 -0
- package/schemas/README.md +6 -3
- package/schemas/import-output.schema.json +1 -1
- package/schemas/scenario.schema.json +2 -0
- package/schemas/zmr-config.schema.json +2 -1
- package/scripts/public-metadata-guard.sh +101 -0
- package/shims/android/README.md +4 -3
- package/shims/android/protocol.md +3 -2
- package/shims/ios/README.md +5 -5
- package/shims/ios/protocol.md +2 -1
- package/skills/zmr-mobile-testing/SKILL.md +9 -8
- package/src/android_emulator.zig +54 -5
- package/src/cli_import.zig +15 -2
- package/src/cli_output.zig +2 -0
- package/src/cli_run.zig +8 -0
- package/src/config.zig +3 -0
- package/src/errors.zig +3 -0
- package/src/ios_devices.zig +100 -0
- package/src/main.zig +1 -1
- package/src/mcp_protocol.zig +12 -9
- package/src/run_options.zig +4 -0
- package/src/scaffold.zig +10 -8
- package/src/scenario.zig +43 -0
- package/src/selector.zig +53 -9
- package/src/trace_json.zig +4 -0
- package/src/validation.zig +5 -0
- package/src/version.zig +1 -1
package/docs/config.md
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
# App-Local Config
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
Use `.zmr/config.json` to keep app-specific defaults in the app repository:
|
|
4
|
+
app ids, device targets, scenario paths, trace directories, artifact settings,
|
|
5
|
+
redaction rules, and shim command paths.
|
|
5
6
|
|
|
6
|
-
The schema is published at `schemas/zmr-config.schema.json`.
|
|
7
|
-
|
|
7
|
+
The schema is published at `schemas/zmr-config.schema.json`. Runtime parsing
|
|
8
|
+
follows the schema for primitive field types. For example,
|
|
8
9
|
boolean fields such as `artifacts.screenRecording`, `artifacts.screenshots`,
|
|
9
|
-
`android.resetBeforeRun`,
|
|
10
|
-
strings. Path, id, redaction-list, and script command string
|
|
11
|
-
non-empty. `zmr doctor --json --config .zmr/config.json`
|
|
12
|
-
structured `config` warnings. Unknown
|
|
13
|
-
app-local config do not silently fall back
|
|
10
|
+
`android.resetBeforeRun`, `android.waitReady`, and `ios.ensureDevice` must be
|
|
11
|
+
JSON booleans, not strings. Path, id, redaction-list, and script command string
|
|
12
|
+
fields must be non-empty. `zmr doctor --json --config .zmr/config.json`
|
|
13
|
+
reports those type/value mistakes as structured `config` warnings. Unknown
|
|
14
|
+
fields are rejected too, so typos in app-local config do not silently fall back
|
|
15
|
+
to defaults.
|
|
14
16
|
|
|
15
17
|
Example:
|
|
16
18
|
|
|
@@ -29,13 +31,15 @@ Example:
|
|
|
29
31
|
"avdSystemImage": "system-images;android-35;google_apis;arm64-v8a",
|
|
30
32
|
"avdDeviceProfile": "pixel_6",
|
|
31
33
|
"resetBeforeRun": false,
|
|
32
|
-
"waitReady": true
|
|
34
|
+
"waitReady": true,
|
|
35
|
+
"ensureDevice": true
|
|
33
36
|
},
|
|
34
37
|
"ios": {
|
|
35
38
|
"enabled": true,
|
|
36
39
|
"defaultDevice": "booted",
|
|
37
40
|
"smokeScenario": ".zmr/ios-smoke.json",
|
|
38
|
-
"traceDir": "traces/zmr-ios"
|
|
41
|
+
"traceDir": "traces/zmr-ios",
|
|
42
|
+
"ensureDevice": true
|
|
39
43
|
},
|
|
40
44
|
"artifacts": {
|
|
41
45
|
"screenshots": true,
|
|
@@ -68,12 +72,13 @@ invoked from another checkout. Relative optional tool commands such as
|
|
|
68
72
|
`tools.adbPath` are resolved the same way when they look like paths; bare
|
|
69
73
|
commands such as `adb`, `xcrun`, or `zig` stay as PATH lookups.
|
|
70
74
|
|
|
71
|
-
Explicit CLI flags always win
|
|
75
|
+
Explicit CLI flags always win. Use config for stable app defaults and CLI flags
|
|
76
|
+
for one-off local or CI overrides:
|
|
72
77
|
|
|
73
78
|
- `--app-id` overrides `appId`
|
|
74
79
|
- `--device` overrides platform `defaultDevice`
|
|
75
80
|
- `--trace-dir` overrides platform `traceDir`
|
|
76
|
-
- `--android-avd`, `--create-avd-if-missing`, `--avd-system-image`, `--avd-device`, `--restore-snapshot`, `--reset-emulator`, and `--
|
|
81
|
+
- `--android-avd`, `--create-avd-if-missing`, `--avd-system-image`, `--avd-device`, `--restore-snapshot`, `--reset-emulator`, `--wait-emulator`, `--ensure-device`, and `--no-ensure-device` override device lifecycle defaults
|
|
77
82
|
- `--screen-record` and `--no-screen-record` override `artifacts.screenRecording`
|
|
78
83
|
- a positional scenario path overrides platform `smokeScenario`
|
|
79
84
|
- `--adb`, `--emulator`, `--avdmanager`, `--android-shim`, `--xcrun`, `--ios-shim`, and `--zig` override optional tool paths
|
|
@@ -83,6 +88,9 @@ Explicit CLI flags always win:
|
|
|
83
88
|
The Android platform config can boot and wait for an emulator before a traced
|
|
84
89
|
`zmr run` starts:
|
|
85
90
|
|
|
91
|
+
- `ensureDevice`: when the requested Android device is not ready, boot the
|
|
92
|
+
configured `avdName`; if no `avdName` is configured, boot the first local AVD
|
|
93
|
+
from `emulator -list-avds`, then wait for `sys.boot_completed=1`.
|
|
86
94
|
- `avdName`: AVD name passed to the Android emulator.
|
|
87
95
|
- `createAvdIfMissing`: check `emulator -list-avds` and create the AVD when absent.
|
|
88
96
|
- `avdSystemImage`: installed Android system image package for `avdmanager create avd`.
|
|
@@ -91,12 +99,18 @@ The Android platform config can boot and wait for an emulator before a traced
|
|
|
91
99
|
- `resetBeforeRun`: best-effort `adb emu kill` before booting the configured AVD.
|
|
92
100
|
- `waitReady`: wait for `adb wait-for-device` and `sys.boot_completed=1`.
|
|
93
101
|
|
|
94
|
-
The equivalent CLI flags are `--
|
|
102
|
+
The equivalent CLI flags are `--ensure-device`, `--no-ensure-device`,
|
|
103
|
+
`--android-avd <name>`,
|
|
95
104
|
`--create-avd-if-missing`, `--avd-system-image <package>`,
|
|
96
105
|
`--avd-device <profile>`, `--restore-snapshot <name>`, `--reset-emulator`,
|
|
97
106
|
and `--wait-emulator`. AVD creation, snapshot restore, and reset require an AVD
|
|
98
107
|
name. AVD creation also requires an installed system image package.
|
|
99
108
|
|
|
109
|
+
For iOS simulator runs, `ensureDevice` or `--ensure-device` reuses an already
|
|
110
|
+
booted simulator when one exists. If the target is `booted` and none are
|
|
111
|
+
running, ZMR boots the first available shutdown simulator and waits for
|
|
112
|
+
`simctl bootstatus -b`. Physical iOS devices are never auto-booted.
|
|
113
|
+
|
|
100
114
|
## Android Shim
|
|
101
115
|
|
|
102
116
|
Set `tools.androidShimPath` when an app repo has built or installed an Android
|
|
@@ -127,7 +141,7 @@ CLI `--ios-shim <path>` takes precedence over the config value for `zmr run`,
|
|
|
127
141
|
## Artifact Capture
|
|
128
142
|
|
|
129
143
|
The `artifacts` object controls what raw trace artifacts are persisted during
|
|
130
|
-
`zmr run`.
|
|
144
|
+
`zmr run`. Turn off raw artifacts when traces might leave a trusted machine.
|
|
131
145
|
|
|
132
146
|
- `screenshots`: write PNG screenshot artifacts.
|
|
133
147
|
- `hierarchy`: write raw Android UI hierarchy XML artifacts.
|
package/docs/demo.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# Demo
|
|
2
2
|
|
|
3
|
-
Run the local demo
|
|
3
|
+
Run the local demo when you want a fast proof of the CLI, schemas, fake-device
|
|
4
|
+
flows, reference clients, trace output, and diagnostics without an emulator,
|
|
5
|
+
simulator, app build, or credentials:
|
|
4
6
|
|
|
5
7
|
```bash
|
|
6
8
|
./scripts/demo.sh
|
|
@@ -94,14 +96,15 @@ snapshot handling.
|
|
|
94
96
|
Load any generated `.zmrtrace` in `viewer/index.html` to inspect the replay
|
|
95
97
|
timeline, payloads, screenshot, UI tree, selected node details, and raw
|
|
96
98
|
artifacts side-by-side. When the viewer and the bundle are served over HTTP,
|
|
97
|
-
link straight to a loaded trace with `viewer/index.html?bundle=<url
|
|
98
|
-
for CI artifact links and shared triage.
|
|
99
|
+
link straight to a loaded trace with `viewer/index.html?bundle=<url>`, which is
|
|
100
|
+
useful for CI artifact links and shared triage.
|
|
99
101
|
|
|
100
102
|

|
|
101
103
|
|
|
102
104
|
## Real Android Pilot Demo
|
|
103
105
|
|
|
104
|
-
Run the Android pilot against a sample app test build
|
|
106
|
+
Run the Android pilot against a sample app test build when you want real
|
|
107
|
+
emulator/device evidence:
|
|
105
108
|
|
|
106
109
|
```bash
|
|
107
110
|
./scripts/run-android-pilot.sh \
|
|
@@ -109,11 +112,13 @@ Run the Android pilot against a sample app test build:
|
|
|
109
112
|
--device emulator-5554
|
|
110
113
|
```
|
|
111
114
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
`--
|
|
115
|
-
|
|
116
|
-
|
|
115
|
+
Direct `zmr run --ensure-device` can boot an Android emulator or iOS simulator
|
|
116
|
+
before the scenario starts. To force a known Android emulator state, direct
|
|
117
|
+
`zmr run` also supports `--android-avd`, `--create-avd-if-missing`,
|
|
118
|
+
`--avd-system-image`, `--avd-device`, `--restore-snapshot`,
|
|
119
|
+
`--reset-emulator`, and `--wait-emulator`. The pilot wrapper accepts the same
|
|
120
|
+
state controls while also building/installing the app. Add `--screen-record` to
|
|
121
|
+
keep a pilot-level MP4 under the trace root:
|
|
117
122
|
|
|
118
123
|
```bash
|
|
119
124
|
./scripts/run-android-pilot.sh \
|
package/docs/expo-smoke.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# Expo Smoke Test
|
|
2
2
|
|
|
3
|
-
This is the quickest public smoke path for an Expo app. It proves
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
This is the quickest public smoke path for an Expo app. It proves the
|
|
4
|
+
framework-neutral ZMR binary install, app-local scaffold, iOS app launch,
|
|
5
|
+
screenshot capture, trace collection, HTML reporting, JUnit XML, and redacted
|
|
6
|
+
export.
|
|
7
7
|
|
|
8
8
|
Run the flow below on a local iOS simulator before treating a specific app build
|
|
9
9
|
as validated.
|
|
@@ -11,12 +11,11 @@ as validated.
|
|
|
11
11
|
```bash
|
|
12
12
|
npx create-expo-app@latest /tmp/zmr-expo-smoke --template blank --yes
|
|
13
13
|
cd /tmp/zmr-expo-smoke
|
|
14
|
-
|
|
14
|
+
curl -fsSL https://raw.githubusercontent.com/johnmikel/zeno-mobile-runner/main/install.sh | sh
|
|
15
|
+
export PATH="$HOME/.local/bin:$PATH"
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
--app-id com.example.zenoexposmoke
|
|
18
|
-
--ios \
|
|
19
|
-
--package-json
|
|
17
|
+
zmr init --app --dir . \
|
|
18
|
+
--app-id com.example.zenoexposmoke
|
|
20
19
|
```
|
|
21
20
|
|
|
22
21
|
Boot a simulator, then build and launch the app:
|
|
@@ -29,14 +28,14 @@ npx expo run:ios --device <simulator-name>
|
|
|
29
28
|
Run the generated ZMR scenario:
|
|
30
29
|
|
|
31
30
|
```bash
|
|
32
|
-
|
|
31
|
+
zmr run .zmr/ios-smoke.json \
|
|
33
32
|
--platform ios \
|
|
34
33
|
--device booted \
|
|
35
34
|
--trace-dir traces/zmr-ios \
|
|
36
35
|
--json
|
|
37
36
|
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
zmr report traces/zmr-ios --out traces/zmr-ios/report.html --junit traces/zmr-ios/junit.xml
|
|
38
|
+
zmr export traces/zmr-ios --out traces/zmr-ios-redacted.zmrtrace --redact
|
|
40
39
|
```
|
|
41
40
|
|
|
42
41
|
Expected result shape:
|
|
@@ -62,12 +61,7 @@ the XCTest shim described in [app integration](app-integration.md).
|
|
|
62
61
|
Android follows the same pattern with a connected emulator or device:
|
|
63
62
|
|
|
64
63
|
```bash
|
|
65
|
-
|
|
66
|
-
--app-id com.example.zenoexposmoke \
|
|
67
|
-
--android \
|
|
68
|
-
--package-json
|
|
69
|
-
|
|
70
|
-
npx zmr run .zmr/android-smoke.json \
|
|
64
|
+
zmr run .zmr/android-smoke.json \
|
|
71
65
|
--platform android \
|
|
72
66
|
--device emulator-5554 \
|
|
73
67
|
--trace-dir traces/zmr-android \
|
package/docs/frameworks.md
CHANGED
|
@@ -2,25 +2,31 @@
|
|
|
2
2
|
|
|
3
3
|
ZMR drives the installed mobile app through Android and iOS automation surfaces.
|
|
4
4
|
It does not require a React Native, Expo, Flutter, Swift, Kotlin, or Java test
|
|
5
|
-
SDK inside the app. The app only needs stable selectors
|
|
6
|
-
|
|
5
|
+
SDK inside the app. The app only needs stable selectors, predictable navigation,
|
|
6
|
+
and build artifacts that ZMR can install or launch.
|
|
7
7
|
|
|
8
8
|
## React Native
|
|
9
9
|
|
|
10
|
-
Use app-owned selectors for controls that agents need to find:
|
|
10
|
+
Use app-owned selectors for controls that agents need to find repeatedly:
|
|
11
11
|
|
|
12
12
|
- `testID` for Android resource ids and iOS accessibility identifiers.
|
|
13
|
-
- `accessibilityLabel` for user-facing controls that should be visible to
|
|
14
|
-
|
|
13
|
+
- `accessibilityLabel` for user-facing controls that should be visible to
|
|
14
|
+
assistive technology.
|
|
15
|
+
- Stable visible text for headings, tabs, and actions that are not localized or
|
|
16
|
+
data-driven.
|
|
15
17
|
- Deep links for jumping directly to logged-in, onboarding, or error states.
|
|
16
18
|
|
|
17
|
-
Keep generated ZMR files under `.zmr/` and
|
|
19
|
+
Keep generated ZMR files under `.zmr/` and initialize ZMR from the app repo:
|
|
18
20
|
|
|
19
21
|
```bash
|
|
20
|
-
|
|
22
|
+
zmr init --app --app-id com.example.mobiletest
|
|
21
23
|
```
|
|
22
24
|
|
|
23
|
-
|
|
25
|
+
JavaScript teams that want generated package scripts can use
|
|
26
|
+
`npx zmr-wizard --app-id com.example.mobiletest --package-json` instead.
|
|
27
|
+
|
|
28
|
+
To inspect a generated public fixture with a longer workflow, use the npm
|
|
29
|
+
helper from a JavaScript toolchain:
|
|
24
30
|
|
|
25
31
|
```bash
|
|
26
32
|
npx zmr-create-react-native-expo-demo-app --out /tmp/zmr-rn-expo-demo
|
|
@@ -32,9 +38,11 @@ values, accessibility labels, and Android/iOS ZMR workflow scenarios under
|
|
|
32
38
|
|
|
33
39
|
## Expo
|
|
34
40
|
|
|
35
|
-
Expo development builds work like React Native apps once they are installed on
|
|
36
|
-
|
|
37
|
-
|
|
41
|
+
Expo development builds work like React Native apps once they are installed on
|
|
42
|
+
an emulator, simulator, or device. `zmr init --app` creates baseline Android
|
|
43
|
+
and iOS smoke scenarios. For dev-client flows that need generated open-link
|
|
44
|
+
scenarios, use the JavaScript wizard and give ZMR the scheme that opens the
|
|
45
|
+
development build:
|
|
38
46
|
|
|
39
47
|
```bash
|
|
40
48
|
npx zmr-wizard \
|
|
@@ -43,15 +51,15 @@ npx zmr-wizard \
|
|
|
43
51
|
--package-json
|
|
44
52
|
```
|
|
45
53
|
|
|
46
|
-
The wizard adds Android and iOS dev-client scenarios that open Metro
|
|
47
|
-
selector assertions run.
|
|
54
|
+
The wizard adds Android and iOS dev-client scenarios that open Metro
|
|
55
|
+
before selector assertions run. For CI, prefer a known Metro command, stable
|
|
56
|
+
deep link, and a prebuilt development client.
|
|
48
57
|
|
|
49
58
|
## Flutter
|
|
50
59
|
|
|
51
|
-
ZMR supports Flutter apps at the
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
artifacts.
|
|
60
|
+
ZMR supports Flutter apps at the Android/iOS app level. It can launch the app,
|
|
61
|
+
open deep links, wait for accessibility semantics, tap visible controls, type
|
|
62
|
+
text, take screenshots, collect traces, and export redacted artifacts.
|
|
55
63
|
|
|
56
64
|
ZMR does not inspect Flutter widget trees, read Dart state, or replace Flutter's
|
|
57
65
|
own widget/integration test APIs. For reliable ZMR scenarios, expose stable
|
|
@@ -66,8 +74,9 @@ Semantics(
|
|
|
66
74
|
```
|
|
67
75
|
|
|
68
76
|
Prefer app-owned semantics labels for form fields, primary buttons, tabs, and
|
|
69
|
-
important states. Deep links are the cleanest way to skip setup screens and
|
|
70
|
-
the state an agent needs to inspect.
|
|
77
|
+
important states. Deep links are the cleanest way to skip setup screens and
|
|
78
|
+
reach the state an agent needs to inspect. Do not describe ZMR as a Flutter
|
|
79
|
+
widget-tree driver.
|
|
71
80
|
|
|
72
81
|
## Native Android And iOS
|
|
73
82
|
|
|
@@ -76,7 +85,7 @@ Native apps should expose:
|
|
|
76
85
|
- Android `resourceId` values or content descriptions for important controls.
|
|
77
86
|
- iOS accessibility identifiers or labels for important controls.
|
|
78
87
|
- Deep links for direct navigation into test states.
|
|
79
|
-
- Optional Android and iOS shims when native selector actions and
|
|
80
|
-
hierarchy snapshots are needed.
|
|
88
|
+
- Optional Android and iOS/iPadOS shims when native selector actions and
|
|
89
|
+
bounded hierarchy snapshots are needed.
|
|
81
90
|
|
|
82
91
|
See [app-integration.md](app-integration.md) for the shim setup commands.
|
package/docs/install.md
CHANGED
|
@@ -1,10 +1,52 @@
|
|
|
1
1
|
# Install
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
the app they belong to.
|
|
3
|
+
Install ZMR where the mobile app lives. That keeps `.zmr/` config, scenarios,
|
|
4
|
+
generated package scripts, and trace output next to the app they verify.
|
|
6
5
|
|
|
7
|
-
|
|
6
|
+
Use the curl installer for the framework-neutral path. It installs the native
|
|
7
|
+
`zmr` binary from the GitHub release archive for your OS and CPU, verifies the
|
|
8
|
+
archive against `SHA256SUMS`, and leaves app setup to `zmr init --app`. npm
|
|
9
|
+
remains the convenience path for JavaScript teams that want package scripts and
|
|
10
|
+
helper bins in `node_modules/.bin`.
|
|
11
|
+
|
|
12
|
+
## Curl Install
|
|
13
|
+
|
|
14
|
+
Recommended path for native Android, native iOS, Flutter, React Native, Expo,
|
|
15
|
+
and mixed mobile repositories:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
curl -fsSL https://raw.githubusercontent.com/johnmikel/zeno-mobile-runner/main/install.sh | sh
|
|
19
|
+
export PATH="$HOME/.local/bin:$PATH"
|
|
20
|
+
zmr init --app --app-id com.example.mobiletest
|
|
21
|
+
zmr doctor --strict --json --config .zmr/config.json
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
The installer defaults to the latest GitHub release. It downloads
|
|
25
|
+
`zmr-<version>-<target>.tar.gz` plus `SHA256SUMS` from the release, and refuses
|
|
26
|
+
to install when the archive checksum entry is missing or mismatched:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
./install.sh --version 0.2.17 --dry-run
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Dry-run output includes `checksum-verification: required`, the selected
|
|
33
|
+
platform target, the archive URL, and the checksum URL. Use
|
|
34
|
+
`--install-dir <dir>` to install somewhere other than `~/.local/bin`, or
|
|
35
|
+
`--base-url <url>` when testing release candidates from a staging bucket.
|
|
36
|
+
|
|
37
|
+
The native binary works the same way regardless of app framework:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
zmr validate .zmr/android-smoke.json
|
|
41
|
+
zmr run .zmr/android-smoke.json --device emulator-5554 --trace-dir traces/zmr-android --ensure-device
|
|
42
|
+
zmr mcp --config .zmr/config.json --trace-dir traces/zmr-agent
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## JavaScript Teams
|
|
46
|
+
|
|
47
|
+
Use npm when the app repo wants ZMR pinned as a dev dependency, generated npm
|
|
48
|
+
scripts, and the helper commands such as `zmr-wizard`,
|
|
49
|
+
`zmr-install-android-shim`, `zmr-install-ios-shim`, and `zmr-device-matrix`:
|
|
8
50
|
|
|
9
51
|
```bash
|
|
10
52
|
npm install --save-dev zeno-mobile-runner
|
|
@@ -13,8 +55,8 @@ npx zmr doctor --strict --json --config .zmr/config.json
|
|
|
13
55
|
```
|
|
14
56
|
|
|
15
57
|
The wizard creates `.zmr/config.json`, Android and iOS smoke scenarios,
|
|
16
|
-
`.zmr/device-matrix.json`,
|
|
17
|
-
before touching a device:
|
|
58
|
+
`.zmr/device-matrix.json`, `.zmr/AGENTS.md`, and optional package scripts. Run
|
|
59
|
+
the generated validation before touching a device:
|
|
18
60
|
|
|
19
61
|
```bash
|
|
20
62
|
npm run zmr:validate
|
|
@@ -36,14 +78,17 @@ app-local `.zmr/` setup.
|
|
|
36
78
|
|
|
37
79
|
## Homebrew Or Existing Binary
|
|
38
80
|
|
|
39
|
-
|
|
40
|
-
|
|
81
|
+
Homebrew remains a native install option once you have a generated formula from
|
|
82
|
+
the release artifacts:
|
|
41
83
|
|
|
42
84
|
```bash
|
|
43
85
|
brew install --build-from-source ./dist/homebrew/zmr.rb
|
|
44
86
|
zmr version
|
|
45
87
|
```
|
|
46
88
|
|
|
89
|
+
Any existing `zmr` binary can also be used by language clients, MCP configs, or
|
|
90
|
+
scripts as long as it matches the protocol version expected by the app repo.
|
|
91
|
+
|
|
47
92
|
## Build From Source
|
|
48
93
|
|
|
49
94
|
```bash
|
|
@@ -60,6 +105,9 @@ verification path used by CI and release gates.
|
|
|
60
105
|
|
|
61
106
|
## First Run Without A Device
|
|
62
107
|
|
|
108
|
+
These commands prove the binary, schemas, and fake-device demo before device
|
|
109
|
+
or simulator setup enters the loop:
|
|
110
|
+
|
|
63
111
|
```bash
|
|
64
112
|
zmr version --json
|
|
65
113
|
zmr schemas --json
|
|
@@ -71,8 +119,8 @@ zmr validate examples/demo-fake.json
|
|
|
71
119
|
|
|
72
120
|
## App Codebase Integration
|
|
73
121
|
|
|
74
|
-
ZMR runs outside the app process and points at app build artifacts. For real
|
|
75
|
-
|
|
122
|
+
ZMR runs outside the app process and points at app build artifacts. For a real
|
|
123
|
+
app pilot, pass the app root, app id, target device, and optional shim paths:
|
|
76
124
|
|
|
77
125
|
```bash
|
|
78
126
|
npx zmr-pilot-gate \
|
|
@@ -91,6 +139,8 @@ npx zmr-pilot-gate \
|
|
|
91
139
|
--evidence-out traces/zmr-pilots/evidence.jsonl
|
|
92
140
|
```
|
|
93
141
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
142
|
+
Next:
|
|
143
|
+
|
|
144
|
+
- [app-integration.md](app-integration.md): app-side test surface and shims
|
|
145
|
+
- [frameworks.md](frameworks.md): React Native, Expo, Flutter, and native apps
|
|
146
|
+
- [config.md](config.md): `.zmr/config.json` defaults and CLI precedence
|
package/docs/npm.md
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
# npm Package
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Install the npm package inside a mobile app repo when you want the `zmr` binary,
|
|
4
|
+
setup wizard, app-local scripts, schemas, examples, clients, and agent skill to
|
|
5
|
+
version with the app:
|
|
4
6
|
|
|
5
7
|
```bash
|
|
6
8
|
npm install --save-dev zeno-mobile-runner
|
|
7
9
|
```
|
|
8
10
|
|
|
9
|
-
The package exposes:
|
|
11
|
+
The package exposes these command surfaces:
|
|
10
12
|
|
|
11
13
|
- `zmr`: CLI binary wrapper.
|
|
12
14
|
- `zmr-init`: app-local scenario scaffolder.
|
|
@@ -44,8 +46,8 @@ The package exposes:
|
|
|
44
46
|
- packaged docs, schemas, examples, reference clients, and the reusable
|
|
45
47
|
`skills/zmr-mobile-testing` agent skill.
|
|
46
48
|
|
|
47
|
-
|
|
48
|
-
redacted traces. Use
|
|
49
|
+
JavaScript app teams should start with `zmr-wizard`, generated smoke scenarios,
|
|
50
|
+
and redacted traces. Use pilot and readiness helpers when you need repeated
|
|
49
51
|
local evidence for your own app and devices.
|
|
50
52
|
|
|
51
53
|
## App Setup
|
|
@@ -67,25 +69,39 @@ This creates:
|
|
|
67
69
|
AGENTS.md
|
|
68
70
|
```
|
|
69
71
|
|
|
70
|
-
`.zmr/config.json` is the app-local source of truth for default devices, trace
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
`
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
72
|
+
`.zmr/config.json` is the app-local source of truth for default devices, trace
|
|
73
|
+
directories, smoke scenario paths, and suggested script commands.
|
|
74
|
+
`.zmr/device-matrix.json` gives CI a ready Android/iOS matrix starting point.
|
|
75
|
+
ZMR auto-discovers config from the app repo, and explicit CLI flags override it.
|
|
76
|
+
The wizard does not inspect or depend on any other mobile test runner
|
|
77
|
+
configuration.
|
|
78
|
+
|
|
79
|
+
`.zmr/AGENTS.md` gives AI agents an app-local operating note with:
|
|
80
|
+
|
|
81
|
+
- strict doctor and validation commands
|
|
82
|
+
- schema discovery
|
|
83
|
+
- direct `zmr run` smoke commands
|
|
84
|
+
- JSON-RPC and MCP startup commands
|
|
85
|
+
- selector guidance
|
|
86
|
+
- trace-to-test discovery commands
|
|
87
|
+
- failure-triage commands
|
|
88
|
+
- redacted trace export commands
|
|
89
|
+
|
|
90
|
+
`zmr-init` and wizard runs without `--package-json` write direct commands in
|
|
91
|
+
`.zmr/AGENTS.md` so agents can execute the generated guidance immediately.
|
|
92
|
+
`zmr-init` accepts the same platform, shim, and Expo dev-client scaffold flags
|
|
93
|
+
as the wizard, plus `--package-json` for non-interactive app templates that do
|
|
94
|
+
not need dependency checks.
|
|
82
95
|
For setup scripts and AI agents that need a machine-readable handoff, use
|
|
83
96
|
`npx zmr-init --json --dir . --app-id com.example.mobiletest` or
|
|
84
97
|
`npx zmr-wizard --json --dir . --app-id com.example.mobiletest --android --ios`.
|
|
85
|
-
The JSON form is covered by `schemas/init-output.schema.json` and includes
|
|
86
|
-
|
|
98
|
+
The JSON form is covered by `schemas/init-output.schema.json` and includes the
|
|
99
|
+
generated config, scenario, Expo dev-client scenario, device matrix, and
|
|
87
100
|
`AGENTS.md` paths plus `nextCommands`, `scriptCount`, and `scriptNames`.
|
|
88
|
-
Wizard runs with `--package-json` write npm script commands in `.zmr/AGENTS.md`
|
|
101
|
+
Wizard runs with `--package-json` write npm script commands in `.zmr/AGENTS.md`
|
|
102
|
+
because the wizard installs those scripts into `package.json`. Run
|
|
103
|
+
`npm run zmr:validate` after editing generated scenarios and before starting
|
|
104
|
+
longer smoke, matrix, or pilot runs.
|
|
89
105
|
|
|
90
106
|
Add app-local scripts:
|
|
91
107
|
|
|
@@ -95,11 +111,11 @@ Add app-local scripts:
|
|
|
95
111
|
"zmr:doctor": "zmr doctor --strict --json --config .zmr/config.json",
|
|
96
112
|
"zmr:schemas": "zmr schemas --json",
|
|
97
113
|
"zmr:validate": "zmr validate --json .zmr/android-smoke.json && zmr validate --json .zmr/ios-smoke.json",
|
|
98
|
-
"zmr:android": "zmr run .zmr/android-smoke.json --device emulator-5554 --trace-dir traces/zmr-android",
|
|
114
|
+
"zmr:android": "zmr run .zmr/android-smoke.json --device emulator-5554 --trace-dir traces/zmr-android --ensure-device",
|
|
99
115
|
"zmr:android:report": "zmr report traces/zmr-android --out traces/zmr-android/report.html --junit traces/zmr-android/junit.xml",
|
|
100
116
|
"zmr:android:reliability": "export ZMR_BIN=\"${ZMR_BIN:-zmr}\"; zmr-benchmark --zmr .zmr/android-smoke.json --device emulator-5554 --app-id com.example.mobiletest --runs 20 --trace-root traces/zmr-android-reliability --min-pass-rate 100 --max-failures 0 --max-p95-ms 30000 && \"$ZMR_BIN\" report traces/zmr-android-reliability --out traces/zmr-android-reliability/report.html --junit traces/zmr-android-reliability/junit.xml",
|
|
101
117
|
"zmr:matrix": "ZMR_BIN=${ZMR_BIN:-zmr} zmr-device-matrix --matrix .zmr/device-matrix.json --trace-root traces/zmr-matrix --min-pass-rate 100 --max-failures 0",
|
|
102
|
-
"zmr:ios": "zmr run .zmr/ios-smoke.json --platform ios --device booted --trace-dir traces/zmr-ios",
|
|
118
|
+
"zmr:ios": "zmr run .zmr/ios-smoke.json --platform ios --device booted --trace-dir traces/zmr-ios --ensure-device",
|
|
103
119
|
"zmr:ios:report": "zmr report traces/zmr-ios --out traces/zmr-ios/report.html --junit traces/zmr-ios/junit.xml",
|
|
104
120
|
"zmr:ios:reliability": "export ZMR_BIN=\"${ZMR_BIN:-zmr}\"; zmr-benchmark --zmr .zmr/ios-smoke.json --platform ios --device booted --app-id com.example.mobiletest --xcrun xcrun --runs 20 --trace-root traces/zmr-ios-reliability --min-pass-rate 100 --max-failures 0 --max-p95-ms 45000 && \"$ZMR_BIN\" report traces/zmr-ios-reliability --out traces/zmr-ios-reliability/report.html --junit traces/zmr-ios-reliability/junit.xml",
|
|
105
121
|
"zmr:pilot": "zmr-pilot-gate --android --ios --android-app-root . --android-app-id com.example.mobiletest --android-device emulator-5554 --ios-app-root . --ios-app-path ./build/Debug-iphonesimulator/Sample.app --ios-app-id com.example.mobiletest --ios-device booted --runs 20 --min-pass-rate 100 --max-failures 0 --evidence-out traces/zmr-pilots/evidence.jsonl",
|
|
@@ -130,8 +146,9 @@ npx zmr-wizard \
|
|
|
130
146
|
--package-json
|
|
131
147
|
```
|
|
132
148
|
|
|
133
|
-
The wizard checks Node, ZMR, ADB, `xcrun`, and Zig when applicable. It
|
|
134
|
-
|
|
149
|
+
The wizard checks Node, ZMR, ADB, `xcrun`, and Zig when applicable. It
|
|
150
|
+
scaffolds `.zmr` scenarios, can patch `package.json` scripts, and ensures
|
|
151
|
+
`traces/` is ignored in the app repo.
|
|
135
152
|
When `--expo-dev-client-scheme` is set, it also writes
|
|
136
153
|
`.zmr/android-dev-client-smoke.json` and `.zmr/ios-dev-client-open-link.json`.
|
|
137
154
|
Package-script setup also adds `zmr:android:dev-client`,
|
|
@@ -165,8 +182,9 @@ Rerunning `zmr init --app` refreshes generated `.zmr/config.json`,
|
|
|
165
182
|
`.zmr/device-matrix.json`, and `.zmr/AGENTS.md` the same way, while preserving
|
|
166
183
|
existing scenario files. Pass `--force` only when you intentionally want to
|
|
167
184
|
replace the generated smoke scenarios too.
|
|
168
|
-
The reliability scripts use `zmr-benchmark` with `100%` pass-rate and
|
|
169
|
-
defaults
|
|
185
|
+
The reliability scripts use `zmr-benchmark` with `100%` pass-rate and
|
|
186
|
+
zero-failure defaults. Tune p95 thresholds only after capturing stable local
|
|
187
|
+
baseline runs.
|
|
170
188
|
The wizard only adds `zmr:readiness` for Android+iOS setups because the
|
|
171
189
|
production readiness target requires Android, iOS simulator, and physical iOS
|
|
172
190
|
evidence; single-platform setups should use `zmr:pilot` and the platform
|
|
@@ -179,8 +197,8 @@ explicit runner binary instead of relying on `PATH` or `ZMR_BIN`. Add
|
|
|
179
197
|
`--evidence-out traces/zmr-pilots/evidence.jsonl` so production-readiness rows
|
|
180
198
|
can be evaluated with `zmr-release-readiness`.
|
|
181
199
|
|
|
182
|
-
The standalone CLI has the same non-interactive app-local bootstrap for
|
|
183
|
-
|
|
200
|
+
The standalone CLI has the same non-interactive app-local bootstrap for source
|
|
201
|
+
or native-binary installs:
|
|
184
202
|
|
|
185
203
|
```bash
|
|
186
204
|
zmr init --app --json --dir . --app-id com.example.mobiletest
|