zeno-mobile-runner 0.1.8 → 0.2.1
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 +72 -0
- package/FEATURES.md +1 -1
- package/README.md +175 -238
- package/clients/kotlin/README.md +1 -1
- package/clients/kotlin/build.gradle.kts +1 -1
- package/clients/python/pyproject.toml +1 -1
- package/clients/rust/Cargo.lock +1 -1
- package/clients/rust/Cargo.toml +1 -1
- package/clients/typescript/package.json +1 -1
- package/docs/agent-discovery.md +10 -0
- package/docs/ai-agents.md +18 -0
- package/docs/benchmarking.md +39 -0
- package/docs/benchmarks/2026-06-09-android-workflow.md +73 -0
- package/docs/benchmarks/2026-06-09-android-workflow.results.jsonl +20 -0
- package/docs/benchmarks/2026-06-09-framework-baseline-status.md +32 -0
- package/docs/benchmarks/2026-06-09-ios-appium-comparison.md +115 -0
- package/docs/benchmarks/2026-06-09-ios-appium-comparison.results.jsonl +40 -0
- package/docs/benchmarks/2026-06-09-ios-demo.md +90 -0
- package/docs/benchmarks/2026-06-09-ios-demo.results.jsonl +20 -0
- package/docs/benchmarks/2026-06-09-ios-maestro-comparison.md +128 -0
- package/docs/benchmarks/2026-06-09-ios-maestro-comparison.results.jsonl +40 -0
- package/docs/benchmarks/2026-06-09-ios-workflow-comparison.md +143 -0
- package/docs/benchmarks/2026-06-09-ios-workflow-comparison.results.jsonl +40 -0
- package/docs/benchmarks/2026-06-09-ios-xctest-floor.md +106 -0
- package/docs/benchmarks/2026-06-09-ios-xctest-floor.results.jsonl +40 -0
- package/docs/benchmarks/README.md +36 -0
- package/docs/benchmarks/benchmark-lab-v1.json +155 -0
- package/docs/benchmarks/benchmark-lab-v1.md +95 -0
- package/docs/clients.md +16 -0
- package/docs/demo.md +36 -1
- package/docs/frameworks.md +10 -0
- package/docs/npm.md +44 -2
- package/docs/protocol-fixtures/core-session.responses.jsonl +1 -1
- package/docs/protocol.md +10 -10
- package/docs/scenario-authoring.md +15 -0
- package/docs/trace-privacy.md +9 -0
- package/docs/troubleshooting.md +6 -0
- package/examples/android-workflow.json +79 -0
- package/examples/ios-dev-client-open-link.json +24 -13
- package/examples/ios-dev-client-route-snapshot.json +33 -8
- package/examples/ios-shim-workflow.json +79 -0
- package/examples/react-native-expo-workflow.json +75 -0
- package/npm/scenarios.mjs +15 -8
- package/npm/wizard.mjs +1 -1
- package/package.json +6 -1
- 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/scripts/benchmark-lab.py +253 -0
- package/scripts/create-android-demo-app.sh +324 -29
- package/scripts/create-ios-demo-app.sh +174 -7
- package/scripts/create-react-native-expo-demo-app.sh +727 -0
- package/scripts/demo.sh +3 -0
- package/scripts/install-ios-shim.sh +2 -2
- package/shims/ios/ZMRShim.swift +10 -0
- package/shims/ios/ZMRShimUITestCase.swift +49 -1
- package/shims/ios/protocol.md +1 -0
- package/src/cli_import.zig +31 -15
- package/src/cli_trace.zig +38 -16
- package/src/cli_validate.zig +12 -6
- package/src/ios.zig +44 -11
- package/src/ios_shim.zig +36 -2
- package/src/main.zig +6 -0
- package/src/version.zig +1 -1
- package/viewer/app.js +23 -3
package/docs/ai-agents.md
CHANGED
|
@@ -4,6 +4,24 @@ ZMR is built for external agents. The runner provides device state, typed
|
|
|
4
4
|
actions, waits, assertions, trace explanation, and trace export; the agent
|
|
5
5
|
decides the next step.
|
|
6
6
|
|
|
7
|
+
```mermaid
|
|
8
|
+
sequenceDiagram
|
|
9
|
+
participant Agent as AI agent
|
|
10
|
+
participant ZMR
|
|
11
|
+
participant Device as Emulator / simulator
|
|
12
|
+
Agent->>ZMR: semantic_snapshot
|
|
13
|
+
ZMR->>Device: capture UI + screenshot
|
|
14
|
+
ZMR-->>Agent: roles, stable selectors, bounds
|
|
15
|
+
Agent->>ZMR: tap / type / swipe / open_link
|
|
16
|
+
ZMR->>Device: execute + settle
|
|
17
|
+
Agent->>ZMR: wait_visible / assert_visible
|
|
18
|
+
ZMR-->>Agent: typed result + trace events
|
|
19
|
+
Agent->>ZMR: trace_discover
|
|
20
|
+
ZMR-->>Agent: reviewable replay scenario
|
|
21
|
+
Agent->>ZMR: trace_export --redact
|
|
22
|
+
ZMR-->>Agent: .zmrtrace evidence bundle
|
|
23
|
+
```
|
|
24
|
+
|
|
7
25
|
## Agent Setup Loop
|
|
8
26
|
|
|
9
27
|
Start inside the app checkout:
|
package/docs/benchmarking.md
CHANGED
|
@@ -4,6 +4,39 @@ ZMR benchmark output is intentionally simple: each run appends one JSON object
|
|
|
4
4
|
to `results.jsonl`, and `zmr report` turns that directory into local HTML and
|
|
5
5
|
optional JUnit XML artifacts.
|
|
6
6
|
|
|
7
|
+
## Public Evidence
|
|
8
|
+
|
|
9
|
+
Public-safe benchmark evidence lives in [docs/benchmarks](benchmarks/README.md).
|
|
10
|
+
The first committed pack is
|
|
11
|
+
[2026-06-09 iOS simulator demo](benchmarks/2026-06-09-ios-demo.md): 20 repeated
|
|
12
|
+
runs of the generated iOS smoke scenario with a 100% pass rate. It is a
|
|
13
|
+
single-tool reliability benchmark, not a competitive speed claim.
|
|
14
|
+
|
|
15
|
+
The first baseline comparison is documented in
|
|
16
|
+
[docs/benchmarks](benchmarks/README.md): 20 ZMR runs and 20 baseline runner
|
|
17
|
+
runs against the same generated iOS demo app.
|
|
18
|
+
|
|
19
|
+
Additional public-safe packs in that directory include a second baseline
|
|
20
|
+
comparison and a native shim floor. The floor is not a product comparison; it
|
|
21
|
+
shows the warmed platform path ZMR can approach after runner and trace overhead
|
|
22
|
+
are reduced.
|
|
23
|
+
|
|
24
|
+
A richer iOS workflow pack is also committed there: 20 ZMR rows and 20 baseline
|
|
25
|
+
runner rows against the same generated app build, covering profile entry,
|
|
26
|
+
catalog item selection, save, review, and final-state assertion.
|
|
27
|
+
|
|
28
|
+
Benchmark Lab v1 is the next public evidence layer. It defines framework
|
|
29
|
+
fixtures, timing modes, runner-adapter labels, and claim rules in a manifest
|
|
30
|
+
that can be validated or rendered with `zmr-benchmark-lab`.
|
|
31
|
+
|
|
32
|
+
The generated Android workflow now has its first 20-run evidence pack in
|
|
33
|
+
[docs/benchmarks](benchmarks/README.md), using the platform UIAutomator path
|
|
34
|
+
without the optional Android instrumentation shim.
|
|
35
|
+
|
|
36
|
+
A generated React Native/Expo fixture is now available for the next evidence
|
|
37
|
+
slice. It includes stable `testID` values, accessibility labels, deep-link
|
|
38
|
+
setup, and Android/iOS ZMR workflow scenarios, but no public timing rows yet.
|
|
39
|
+
|
|
7
40
|
## Single Tool Benchmark
|
|
8
41
|
|
|
9
42
|
```bash
|
|
@@ -70,6 +103,10 @@ For `--runs 1`, the script exports normal and redacted `.zmrtrace` bundles.
|
|
|
70
103
|
For `--runs > 1`, the pilot wrappers and generated app reliability scripts
|
|
71
104
|
write benchmark directories with HTML and JUnit reports.
|
|
72
105
|
|
|
106
|
+
Apps scaffolded by `zmr-wizard` get matching package scripts, so app-local
|
|
107
|
+
reliability gates run as `bun run zmr:android:reliability` and
|
|
108
|
+
`bun run zmr:ios:reliability` (or the npm equivalents).
|
|
109
|
+
|
|
73
110
|
The iOS pilot wrapper supports the same repeated-run gates:
|
|
74
111
|
|
|
75
112
|
```bash
|
|
@@ -138,6 +175,8 @@ Benchmark reports include:
|
|
|
138
175
|
|
|
139
176
|
Before making public performance claims, run the same scenario repeatedly on a clean emulator image and include the raw `results.jsonl` plus the redacted trace bundle for any failure.
|
|
140
177
|
|
|
178
|
+

|
|
179
|
+
|
|
141
180
|
## Compare Against A Baseline
|
|
142
181
|
|
|
143
182
|
Use `zmr-compare-benchmarks` when a private app repo has benchmark rows from
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# 2026-06-09 Android Emulator Workflow
|
|
2
|
+
|
|
3
|
+
This evidence pack records 20 repeated ZMR runs of the generated public Android
|
|
4
|
+
workflow demo app. The flow launches the app, fills a profile form, scrolls the
|
|
5
|
+
catalog, opens an item detail page, saves the item, reviews the order, and
|
|
6
|
+
asserts the final state.
|
|
7
|
+
|
|
8
|
+
This is a single-tool reliability and timing pack, not a comparison against
|
|
9
|
+
another runner. Treat it as reproducible evidence for this app, host, emulator,
|
|
10
|
+
app build, and workflow shape.
|
|
11
|
+
|
|
12
|
+
## Result
|
|
13
|
+
|
|
14
|
+
| Tool | Runs | Pass rate | Failures | Mean duration | p95 duration |
|
|
15
|
+
| --- | ---: | ---: | ---: | ---: | ---: |
|
|
16
|
+
| ZMR | 20 | 100.00% | 0 | 44134 ms | 46385 ms |
|
|
17
|
+
|
|
18
|
+
The fastest run was 38627 ms and the slowest run was 49875 ms. The later rows
|
|
19
|
+
clustered around 43 seconds, which points to Android UIAutomator snapshot and
|
|
20
|
+
scroll execution as the next optimization target for this fixture.
|
|
21
|
+
|
|
22
|
+
## Environment
|
|
23
|
+
|
|
24
|
+
| Field | Value |
|
|
25
|
+
| --- | --- |
|
|
26
|
+
| ZMR runner | `0.1.8` |
|
|
27
|
+
| ZMR protocol | `2026-04-28` |
|
|
28
|
+
| Host OS | macOS 26.6, arm64 |
|
|
29
|
+
| Android emulator | 36.4.10.0 |
|
|
30
|
+
| ADB | 1.0.41, platform-tools 37.0.0 |
|
|
31
|
+
| Android platform | Android 15, API 35, arm64-v8a |
|
|
32
|
+
| Emulator viewport | 720 x 1280, 320 dpi |
|
|
33
|
+
| App id | `com.example.mobiletest` |
|
|
34
|
+
| App build label | `generated-android-workflow-demo-20260609` |
|
|
35
|
+
| Demo app source | Generated by `scripts/create-android-demo-app.sh` |
|
|
36
|
+
|
|
37
|
+
Before collection, the emulator was booted fresh, the app was reinstalled, the
|
|
38
|
+
screen was unlocked, and Android window, transition, and animator duration
|
|
39
|
+
scales were set to `0`.
|
|
40
|
+
|
|
41
|
+
## Command
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
ZMR_BIN="$PWD/zig-out/bin/zmr" scripts/benchmark.sh \
|
|
45
|
+
--zmr examples/android-workflow.json \
|
|
46
|
+
--platform android \
|
|
47
|
+
--device emulator-5554 \
|
|
48
|
+
--app-id com.example.mobiletest \
|
|
49
|
+
--app-build generated-android-workflow-demo-20260609 \
|
|
50
|
+
--runs 20 \
|
|
51
|
+
--trace-root traces/public-benchmarks/20260609-android-workflow/zmr \
|
|
52
|
+
--results traces/public-benchmarks/20260609-android-workflow/results.jsonl \
|
|
53
|
+
--replace \
|
|
54
|
+
--min-pass-rate 100 \
|
|
55
|
+
--max-failures 0
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
The ZMR scenario is committed as
|
|
59
|
+
[`examples/android-workflow.json`](../../examples/android-workflow.json).
|
|
60
|
+
|
|
61
|
+
## Rows
|
|
62
|
+
|
|
63
|
+
The sanitized result rows are committed in
|
|
64
|
+
[2026-06-09-android-workflow.results.jsonl](2026-06-09-android-workflow.results.jsonl).
|
|
65
|
+
|
|
66
|
+
Raw local trace and runner logs are not committed because they can include local
|
|
67
|
+
absolute paths.
|
|
68
|
+
|
|
69
|
+
## Scope
|
|
70
|
+
|
|
71
|
+
This benchmark uses the platform UIAutomator path without the optional Android
|
|
72
|
+
instrumentation shim. It does not compare cloud execution, React Native, Expo,
|
|
73
|
+
Flutter, Appium, Maestro, Detox, or Android instrumentation-runner baselines.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{"tool":"zmr","run":1,"status":"ok","durationMs":49875,"traceDir":"traces/public-benchmarks/20260609-android-workflow/zmr/zmr-1","platform":"android","device":"emulator-5554","appId":"com.example.mobiletest","scenario":"examples/android-workflow.json","appBuild":"generated-android-workflow-demo-20260609","traceStatus":"passed"}
|
|
2
|
+
{"tool":"zmr","run":2,"status":"ok","durationMs":45169,"traceDir":"traces/public-benchmarks/20260609-android-workflow/zmr/zmr-2","platform":"android","device":"emulator-5554","appId":"com.example.mobiletest","scenario":"examples/android-workflow.json","appBuild":"generated-android-workflow-demo-20260609","traceStatus":"passed"}
|
|
3
|
+
{"tool":"zmr","run":3,"status":"ok","durationMs":46093,"traceDir":"traces/public-benchmarks/20260609-android-workflow/zmr/zmr-3","platform":"android","device":"emulator-5554","appId":"com.example.mobiletest","scenario":"examples/android-workflow.json","appBuild":"generated-android-workflow-demo-20260609","traceStatus":"passed"}
|
|
4
|
+
{"tool":"zmr","run":4,"status":"ok","durationMs":44695,"traceDir":"traces/public-benchmarks/20260609-android-workflow/zmr/zmr-4","platform":"android","device":"emulator-5554","appId":"com.example.mobiletest","scenario":"examples/android-workflow.json","appBuild":"generated-android-workflow-demo-20260609","traceStatus":"passed"}
|
|
5
|
+
{"tool":"zmr","run":5,"status":"ok","durationMs":44028,"traceDir":"traces/public-benchmarks/20260609-android-workflow/zmr/zmr-5","platform":"android","device":"emulator-5554","appId":"com.example.mobiletest","scenario":"examples/android-workflow.json","appBuild":"generated-android-workflow-demo-20260609","traceStatus":"passed"}
|
|
6
|
+
{"tool":"zmr","run":6,"status":"ok","durationMs":44821,"traceDir":"traces/public-benchmarks/20260609-android-workflow/zmr/zmr-6","platform":"android","device":"emulator-5554","appId":"com.example.mobiletest","scenario":"examples/android-workflow.json","appBuild":"generated-android-workflow-demo-20260609","traceStatus":"passed"}
|
|
7
|
+
{"tool":"zmr","run":7,"status":"ok","durationMs":46385,"traceDir":"traces/public-benchmarks/20260609-android-workflow/zmr/zmr-7","platform":"android","device":"emulator-5554","appId":"com.example.mobiletest","scenario":"examples/android-workflow.json","appBuild":"generated-android-workflow-demo-20260609","traceStatus":"passed"}
|
|
8
|
+
{"tool":"zmr","run":8,"status":"ok","durationMs":45751,"traceDir":"traces/public-benchmarks/20260609-android-workflow/zmr/zmr-8","platform":"android","device":"emulator-5554","appId":"com.example.mobiletest","scenario":"examples/android-workflow.json","appBuild":"generated-android-workflow-demo-20260609","traceStatus":"passed"}
|
|
9
|
+
{"tool":"zmr","run":9,"status":"ok","durationMs":38627,"traceDir":"traces/public-benchmarks/20260609-android-workflow/zmr/zmr-9","platform":"android","device":"emulator-5554","appId":"com.example.mobiletest","scenario":"examples/android-workflow.json","appBuild":"generated-android-workflow-demo-20260609","traceStatus":"passed"}
|
|
10
|
+
{"tool":"zmr","run":10,"status":"ok","durationMs":42599,"traceDir":"traces/public-benchmarks/20260609-android-workflow/zmr/zmr-10","platform":"android","device":"emulator-5554","appId":"com.example.mobiletest","scenario":"examples/android-workflow.json","appBuild":"generated-android-workflow-demo-20260609","traceStatus":"passed"}
|
|
11
|
+
{"tool":"zmr","run":11,"status":"ok","durationMs":42968,"traceDir":"traces/public-benchmarks/20260609-android-workflow/zmr/zmr-11","platform":"android","device":"emulator-5554","appId":"com.example.mobiletest","scenario":"examples/android-workflow.json","appBuild":"generated-android-workflow-demo-20260609","traceStatus":"passed"}
|
|
12
|
+
{"tool":"zmr","run":12,"status":"ok","durationMs":43299,"traceDir":"traces/public-benchmarks/20260609-android-workflow/zmr/zmr-12","platform":"android","device":"emulator-5554","appId":"com.example.mobiletest","scenario":"examples/android-workflow.json","appBuild":"generated-android-workflow-demo-20260609","traceStatus":"passed"}
|
|
13
|
+
{"tool":"zmr","run":13,"status":"ok","durationMs":43684,"traceDir":"traces/public-benchmarks/20260609-android-workflow/zmr/zmr-13","platform":"android","device":"emulator-5554","appId":"com.example.mobiletest","scenario":"examples/android-workflow.json","appBuild":"generated-android-workflow-demo-20260609","traceStatus":"passed"}
|
|
14
|
+
{"tool":"zmr","run":14,"status":"ok","durationMs":43056,"traceDir":"traces/public-benchmarks/20260609-android-workflow/zmr/zmr-14","platform":"android","device":"emulator-5554","appId":"com.example.mobiletest","scenario":"examples/android-workflow.json","appBuild":"generated-android-workflow-demo-20260609","traceStatus":"passed"}
|
|
15
|
+
{"tool":"zmr","run":15,"status":"ok","durationMs":43418,"traceDir":"traces/public-benchmarks/20260609-android-workflow/zmr/zmr-15","platform":"android","device":"emulator-5554","appId":"com.example.mobiletest","scenario":"examples/android-workflow.json","appBuild":"generated-android-workflow-demo-20260609","traceStatus":"passed"}
|
|
16
|
+
{"tool":"zmr","run":16,"status":"ok","durationMs":43267,"traceDir":"traces/public-benchmarks/20260609-android-workflow/zmr/zmr-16","platform":"android","device":"emulator-5554","appId":"com.example.mobiletest","scenario":"examples/android-workflow.json","appBuild":"generated-android-workflow-demo-20260609","traceStatus":"passed"}
|
|
17
|
+
{"tool":"zmr","run":17,"status":"ok","durationMs":43780,"traceDir":"traces/public-benchmarks/20260609-android-workflow/zmr/zmr-17","platform":"android","device":"emulator-5554","appId":"com.example.mobiletest","scenario":"examples/android-workflow.json","appBuild":"generated-android-workflow-demo-20260609","traceStatus":"passed"}
|
|
18
|
+
{"tool":"zmr","run":18,"status":"ok","durationMs":43371,"traceDir":"traces/public-benchmarks/20260609-android-workflow/zmr/zmr-18","platform":"android","device":"emulator-5554","appId":"com.example.mobiletest","scenario":"examples/android-workflow.json","appBuild":"generated-android-workflow-demo-20260609","traceStatus":"passed"}
|
|
19
|
+
{"tool":"zmr","run":19,"status":"ok","durationMs":43095,"traceDir":"traces/public-benchmarks/20260609-android-workflow/zmr/zmr-19","platform":"android","device":"emulator-5554","appId":"com.example.mobiletest","scenario":"examples/android-workflow.json","appBuild":"generated-android-workflow-demo-20260609","traceStatus":"passed"}
|
|
20
|
+
{"tool":"zmr","run":20,"status":"ok","durationMs":44693,"traceDir":"traces/public-benchmarks/20260609-android-workflow/zmr/zmr-20","platform":"android","device":"emulator-5554","appId":"com.example.mobiletest","scenario":"examples/android-workflow.json","appBuild":"generated-android-workflow-demo-20260609","traceStatus":"passed"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# 2026-06-09 Framework Baseline Status
|
|
2
|
+
|
|
3
|
+
This note tracks the requested baseline coverage beyond the committed iOS demo
|
|
4
|
+
comparisons.
|
|
5
|
+
|
|
6
|
+
## Completed
|
|
7
|
+
|
|
8
|
+
| Baseline | Status | Evidence |
|
|
9
|
+
| --- | --- | --- |
|
|
10
|
+
| Maestro | Completed | [iOS ZMR vs Maestro comparison](2026-06-09-ios-maestro-comparison.md) |
|
|
11
|
+
| Appium | Completed | [iOS ZMR vs Appium comparison](2026-06-09-ios-appium-comparison.md) |
|
|
12
|
+
| XCTest floor | Completed | [iOS XCTest shim floor](2026-06-09-ios-xctest-floor.md) |
|
|
13
|
+
|
|
14
|
+
## Not Yet Fair To Publish
|
|
15
|
+
|
|
16
|
+
| Baseline | Why it needs a fixture first | Next evidence pack |
|
|
17
|
+
| --- | --- | --- |
|
|
18
|
+
| Detox | The CLI requires a project-local `detox` install and a React Native app with Detox configuration, native iOS/Android build targets, and a test file. Running it against the generated Swift demo would not be representative. | React Native fixture with the same launch, deep link, assertion, and warm-suite/cold-command modes. |
|
|
19
|
+
| Flutter | The local machine does not have the Flutter CLI installed, and ZMR should not claim Flutter widget-tree-driver coverage. | Flutter fixture using platform-level labels/deep links plus either Flutter `integration_test` or an external runner baseline. |
|
|
20
|
+
| Espresso | No Android emulator is currently attached in this workspace. Espresso should compare against an Android fixture with an instrumentation target rather than an iOS-only demo. | Android generated demo with ZMR, direct Espresso instrumentation, and Appium UIAutomator2 rows. |
|
|
21
|
+
|
|
22
|
+
## Speed Work Opened By This Pass
|
|
23
|
+
|
|
24
|
+
The XCTest floor showed that ZMR can be made faster. The first fix from this
|
|
25
|
+
pass skips the expensive iOS system-open alert probe for custom URL schemes and
|
|
26
|
+
keeps it for `http://` and `https://` links. On the generated iOS demo smoke
|
|
27
|
+
flow, the shim-backed ZMR mean dropped to `2007 ms` while the direct warmed
|
|
28
|
+
XCTest shim floor measured `1004 ms`.
|
|
29
|
+
|
|
30
|
+
The next speed target is a warm-suite mode where one ZMR process executes many
|
|
31
|
+
iterations in a single device session, avoiding repeated CLI startup and trace
|
|
32
|
+
setup for benchmark loops.
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# 2026-06-09 iOS Simulator ZMR vs Appium Comparison
|
|
2
|
+
|
|
3
|
+
This evidence pack compares ZMR with Appium on the generated public iOS demo
|
|
4
|
+
app. It is a command-level benchmark: each row starts one local runner command,
|
|
5
|
+
executes the same smoke flow on the same booted simulator, and records command
|
|
6
|
+
duration.
|
|
7
|
+
|
|
8
|
+
This is not a universal claim about either project. Treat it as reproducible
|
|
9
|
+
evidence for this app, host, simulator, and flow shape.
|
|
10
|
+
|
|
11
|
+
## Result
|
|
12
|
+
|
|
13
|
+
| Tool | Runs | Pass rate | Failures | Mean duration | p95 duration |
|
|
14
|
+
| --- | ---: | ---: | ---: | ---: | ---: |
|
|
15
|
+
| ZMR | 20 | 100.00% | 0 | 2315 ms | 2339 ms |
|
|
16
|
+
| Appium | 20 | 100.00% | 0 | 3837 ms | 3883 ms |
|
|
17
|
+
|
|
18
|
+
For this run, ZMR was 1.66x faster on mean duration and 1.66x faster on p95
|
|
19
|
+
duration.
|
|
20
|
+
|
|
21
|
+
## Environment
|
|
22
|
+
|
|
23
|
+
| Field | Value |
|
|
24
|
+
| --- | --- |
|
|
25
|
+
| ZMR runner | `0.1.8` |
|
|
26
|
+
| ZMR protocol | `2026-04-28` |
|
|
27
|
+
| Appium | `3.5.0` |
|
|
28
|
+
| Appium XCUITest driver | `11.10.0` |
|
|
29
|
+
| Host OS | macOS 26.6, arm64 |
|
|
30
|
+
| Xcode | 26.5, build 17F42 |
|
|
31
|
+
| Simulator | Booted iOS 26.5 simulator, `zmr-iPhone` |
|
|
32
|
+
| App id | `com.example.mobiletest` |
|
|
33
|
+
| App build label | `generated-ios-demo-20260609` |
|
|
34
|
+
| Demo app source | Generated by `scripts/create-ios-demo-app.sh` |
|
|
35
|
+
|
|
36
|
+
## ZMR Command
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
ZMR_BIN="$PWD/zig-out/bin/zmr" scripts/benchmark.sh \
|
|
40
|
+
--zmr examples/ios-smoke.json \
|
|
41
|
+
--platform ios \
|
|
42
|
+
--ios-device-type simulator \
|
|
43
|
+
--device booted \
|
|
44
|
+
--app-id com.example.mobiletest \
|
|
45
|
+
--xcrun xcrun \
|
|
46
|
+
--app-build generated-ios-demo-20260609 \
|
|
47
|
+
--runs 20 \
|
|
48
|
+
--trace-root traces/public-benchmarks/20260609-ios-appium-comparison/zmr \
|
|
49
|
+
--results traces/public-benchmarks/20260609-ios-appium-comparison/results.jsonl \
|
|
50
|
+
--replace \
|
|
51
|
+
--min-pass-rate 100 \
|
|
52
|
+
--max-failures 0
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
The ZMR scenario launches the app, opens `exampleapp:///e2e-auth?probe=1`, and
|
|
56
|
+
captures a snapshot.
|
|
57
|
+
|
|
58
|
+
## Appium Command
|
|
59
|
+
|
|
60
|
+
The Appium server was started with a temp Appium home:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
APPIUM_HOME=/tmp/zmr-appium-home-20260609 npx --yes appium@latest --port 4723 --log-level error
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
The XCUITest driver was installed in that temp home:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
APPIUM_HOME=/tmp/zmr-appium-home-20260609 npx --yes appium@latest driver install xcuitest
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Each measured Appium row created a fresh XCUITest WebDriver session against the
|
|
73
|
+
same bundle id, opened the same deep link with `simctl openurl`, read page
|
|
74
|
+
source, asserted `Deep link opened`, and deleted the session.
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
scripts/benchmark-command.sh \
|
|
78
|
+
--tool appium \
|
|
79
|
+
--platform ios \
|
|
80
|
+
--device booted \
|
|
81
|
+
--app-id com.example.mobiletest \
|
|
82
|
+
--scenario examples/ios-smoke.json \
|
|
83
|
+
--app-build generated-ios-demo-20260609 \
|
|
84
|
+
--runs 20 \
|
|
85
|
+
--trace-root traces/public-benchmarks/20260609-ios-appium-comparison/appium \
|
|
86
|
+
--results traces/public-benchmarks/20260609-ios-appium-comparison/results.jsonl \
|
|
87
|
+
-- node -e '<create session, open deep link, assert page source, delete session>'
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Comparison Report
|
|
91
|
+
|
|
92
|
+
```text
|
|
93
|
+
# Benchmark Comparison
|
|
94
|
+
|
|
95
|
+
| Tool | Runs | Pass rate | Failures | Mean ms | P95 ms |
|
|
96
|
+
| --- | ---: | ---: | ---: | ---: | ---: |
|
|
97
|
+
| zmr | 20 | 100.00% | 0 | 2315 | 2339 |
|
|
98
|
+
| appium | 20 | 100.00% | 0 | 3837 | 3883 |
|
|
99
|
+
|
|
100
|
+
- Mean speedup: 1.66x (-39.7% candidate vs baseline)
|
|
101
|
+
- P95 speedup: 1.66x (-39.8% candidate vs baseline)
|
|
102
|
+
- Same benchmark context: yes
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
The sanitized result rows are committed in
|
|
106
|
+
[2026-06-09-ios-appium-comparison.results.jsonl](2026-06-09-ios-appium-comparison.results.jsonl).
|
|
107
|
+
|
|
108
|
+
Raw local trace and runner logs are not committed because they can include local
|
|
109
|
+
absolute paths.
|
|
110
|
+
|
|
111
|
+
## Scope
|
|
112
|
+
|
|
113
|
+
This benchmark compares local command surfaces under repeated execution. It
|
|
114
|
+
does not compare cloud execution, long multi-screen flows, Detox, Flutter,
|
|
115
|
+
Espresso, XCTest-only app tests, or app-specific selectors.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{"tool":"zmr","run":1,"status":"ok","durationMs":2327,"traceDir":"traces/public-benchmarks/20260609-ios-appium-comparison/zmr/zmr-1","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609","traceStatus":"passed"}
|
|
2
|
+
{"tool":"zmr","run":2,"status":"ok","durationMs":2326,"traceDir":"traces/public-benchmarks/20260609-ios-appium-comparison/zmr/zmr-2","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609","traceStatus":"passed"}
|
|
3
|
+
{"tool":"zmr","run":3,"status":"ok","durationMs":2312,"traceDir":"traces/public-benchmarks/20260609-ios-appium-comparison/zmr/zmr-3","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609","traceStatus":"passed"}
|
|
4
|
+
{"tool":"zmr","run":4,"status":"ok","durationMs":2305,"traceDir":"traces/public-benchmarks/20260609-ios-appium-comparison/zmr/zmr-4","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609","traceStatus":"passed"}
|
|
5
|
+
{"tool":"zmr","run":5,"status":"ok","durationMs":2305,"traceDir":"traces/public-benchmarks/20260609-ios-appium-comparison/zmr/zmr-5","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609","traceStatus":"passed"}
|
|
6
|
+
{"tool":"zmr","run":6,"status":"ok","durationMs":2295,"traceDir":"traces/public-benchmarks/20260609-ios-appium-comparison/zmr/zmr-6","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609","traceStatus":"passed"}
|
|
7
|
+
{"tool":"zmr","run":7,"status":"ok","durationMs":2339,"traceDir":"traces/public-benchmarks/20260609-ios-appium-comparison/zmr/zmr-7","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609","traceStatus":"passed"}
|
|
8
|
+
{"tool":"zmr","run":8,"status":"ok","durationMs":2289,"traceDir":"traces/public-benchmarks/20260609-ios-appium-comparison/zmr/zmr-8","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609","traceStatus":"passed"}
|
|
9
|
+
{"tool":"zmr","run":9,"status":"ok","durationMs":2292,"traceDir":"traces/public-benchmarks/20260609-ios-appium-comparison/zmr/zmr-9","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609","traceStatus":"passed"}
|
|
10
|
+
{"tool":"zmr","run":10,"status":"ok","durationMs":2320,"traceDir":"traces/public-benchmarks/20260609-ios-appium-comparison/zmr/zmr-10","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609","traceStatus":"passed"}
|
|
11
|
+
{"tool":"zmr","run":11,"status":"ok","durationMs":2332,"traceDir":"traces/public-benchmarks/20260609-ios-appium-comparison/zmr/zmr-11","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609","traceStatus":"passed"}
|
|
12
|
+
{"tool":"zmr","run":12,"status":"ok","durationMs":2333,"traceDir":"traces/public-benchmarks/20260609-ios-appium-comparison/zmr/zmr-12","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609","traceStatus":"passed"}
|
|
13
|
+
{"tool":"zmr","run":13,"status":"ok","durationMs":2316,"traceDir":"traces/public-benchmarks/20260609-ios-appium-comparison/zmr/zmr-13","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609","traceStatus":"passed"}
|
|
14
|
+
{"tool":"zmr","run":14,"status":"ok","durationMs":2291,"traceDir":"traces/public-benchmarks/20260609-ios-appium-comparison/zmr/zmr-14","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609","traceStatus":"passed"}
|
|
15
|
+
{"tool":"zmr","run":15,"status":"ok","durationMs":2342,"traceDir":"traces/public-benchmarks/20260609-ios-appium-comparison/zmr/zmr-15","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609","traceStatus":"passed"}
|
|
16
|
+
{"tool":"zmr","run":16,"status":"ok","durationMs":2308,"traceDir":"traces/public-benchmarks/20260609-ios-appium-comparison/zmr/zmr-16","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609","traceStatus":"passed"}
|
|
17
|
+
{"tool":"zmr","run":17,"status":"ok","durationMs":2298,"traceDir":"traces/public-benchmarks/20260609-ios-appium-comparison/zmr/zmr-17","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609","traceStatus":"passed"}
|
|
18
|
+
{"tool":"zmr","run":18,"status":"ok","durationMs":2297,"traceDir":"traces/public-benchmarks/20260609-ios-appium-comparison/zmr/zmr-18","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609","traceStatus":"passed"}
|
|
19
|
+
{"tool":"zmr","run":19,"status":"ok","durationMs":2339,"traceDir":"traces/public-benchmarks/20260609-ios-appium-comparison/zmr/zmr-19","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609","traceStatus":"passed"}
|
|
20
|
+
{"tool":"zmr","run":20,"status":"ok","durationMs":2329,"traceDir":"traces/public-benchmarks/20260609-ios-appium-comparison/zmr/zmr-20","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609","traceStatus":"passed"}
|
|
21
|
+
{"tool":"appium","run":1,"status":"ok","durationMs":3825,"traceDir":"traces/public-benchmarks/20260609-ios-appium-comparison/appium/appium-1","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
|
|
22
|
+
{"tool":"appium","run":2,"status":"ok","durationMs":3779,"traceDir":"traces/public-benchmarks/20260609-ios-appium-comparison/appium/appium-2","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
|
|
23
|
+
{"tool":"appium","run":3,"status":"ok","durationMs":3773,"traceDir":"traces/public-benchmarks/20260609-ios-appium-comparison/appium/appium-3","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
|
|
24
|
+
{"tool":"appium","run":4,"status":"ok","durationMs":3776,"traceDir":"traces/public-benchmarks/20260609-ios-appium-comparison/appium/appium-4","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
|
|
25
|
+
{"tool":"appium","run":5,"status":"ok","durationMs":3790,"traceDir":"traces/public-benchmarks/20260609-ios-appium-comparison/appium/appium-5","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
|
|
26
|
+
{"tool":"appium","run":6,"status":"ok","durationMs":3797,"traceDir":"traces/public-benchmarks/20260609-ios-appium-comparison/appium/appium-6","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
|
|
27
|
+
{"tool":"appium","run":7,"status":"ok","durationMs":3747,"traceDir":"traces/public-benchmarks/20260609-ios-appium-comparison/appium/appium-7","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
|
|
28
|
+
{"tool":"appium","run":8,"status":"ok","durationMs":3799,"traceDir":"traces/public-benchmarks/20260609-ios-appium-comparison/appium/appium-8","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
|
|
29
|
+
{"tool":"appium","run":9,"status":"ok","durationMs":4022,"traceDir":"traces/public-benchmarks/20260609-ios-appium-comparison/appium/appium-9","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
|
|
30
|
+
{"tool":"appium","run":10,"status":"ok","durationMs":3871,"traceDir":"traces/public-benchmarks/20260609-ios-appium-comparison/appium/appium-10","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
|
|
31
|
+
{"tool":"appium","run":11,"status":"ok","durationMs":3864,"traceDir":"traces/public-benchmarks/20260609-ios-appium-comparison/appium/appium-11","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
|
|
32
|
+
{"tool":"appium","run":12,"status":"ok","durationMs":3882,"traceDir":"traces/public-benchmarks/20260609-ios-appium-comparison/appium/appium-12","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
|
|
33
|
+
{"tool":"appium","run":13,"status":"ok","durationMs":3858,"traceDir":"traces/public-benchmarks/20260609-ios-appium-comparison/appium/appium-13","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
|
|
34
|
+
{"tool":"appium","run":14,"status":"ok","durationMs":3883,"traceDir":"traces/public-benchmarks/20260609-ios-appium-comparison/appium/appium-14","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
|
|
35
|
+
{"tool":"appium","run":15,"status":"ok","durationMs":3852,"traceDir":"traces/public-benchmarks/20260609-ios-appium-comparison/appium/appium-15","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
|
|
36
|
+
{"tool":"appium","run":16,"status":"ok","durationMs":3879,"traceDir":"traces/public-benchmarks/20260609-ios-appium-comparison/appium/appium-16","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
|
|
37
|
+
{"tool":"appium","run":17,"status":"ok","durationMs":3871,"traceDir":"traces/public-benchmarks/20260609-ios-appium-comparison/appium/appium-17","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
|
|
38
|
+
{"tool":"appium","run":18,"status":"ok","durationMs":3825,"traceDir":"traces/public-benchmarks/20260609-ios-appium-comparison/appium/appium-18","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
|
|
39
|
+
{"tool":"appium","run":19,"status":"ok","durationMs":3825,"traceDir":"traces/public-benchmarks/20260609-ios-appium-comparison/appium/appium-19","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
|
|
40
|
+
{"tool":"appium","run":20,"status":"ok","durationMs":3818,"traceDir":"traces/public-benchmarks/20260609-ios-appium-comparison/appium/appium-20","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# 2026-06-09 iOS Simulator Demo Benchmark
|
|
2
|
+
|
|
3
|
+
This evidence pack records a repeat-run reliability benchmark for the public
|
|
4
|
+
ZMR iOS demo app. It is a single-tool benchmark, not a comparison against
|
|
5
|
+
Maestro, Appium, Detox, XCTest, or another runner.
|
|
6
|
+
|
|
7
|
+
## Result
|
|
8
|
+
|
|
9
|
+
| Metric | Value |
|
|
10
|
+
| --- | --- |
|
|
11
|
+
| Scenario | `examples/ios-smoke.json` |
|
|
12
|
+
| Platform | iOS simulator |
|
|
13
|
+
| Runs | 20 |
|
|
14
|
+
| Passed | 20 |
|
|
15
|
+
| Failed | 0 |
|
|
16
|
+
| Pass rate | 100.00% |
|
|
17
|
+
| Mean duration | 4192 ms |
|
|
18
|
+
| p95 duration | 5409 ms |
|
|
19
|
+
| Min duration | 3065 ms |
|
|
20
|
+
| Max duration | 6395 ms |
|
|
21
|
+
|
|
22
|
+
## Environment
|
|
23
|
+
|
|
24
|
+
| Field | Value |
|
|
25
|
+
| --- | --- |
|
|
26
|
+
| ZMR runner | `0.1.8` |
|
|
27
|
+
| Protocol | `2026-04-28` |
|
|
28
|
+
| Host OS | macOS 26.6, arm64 |
|
|
29
|
+
| Xcode | 26.5, build 17F42 |
|
|
30
|
+
| Simulator | Booted iOS 26.5 simulator, `zmr-iPhone` |
|
|
31
|
+
| App id | `com.example.mobiletest` |
|
|
32
|
+
| Demo app source | Generated by `scripts/create-ios-demo-app.sh` |
|
|
33
|
+
|
|
34
|
+
## Command
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
rm -rf traces/public-benchmarks/20260609-ios-demo /tmp/zmr-public-benchmark-ios-demo-20260609-plain
|
|
38
|
+
|
|
39
|
+
scripts/create-ios-demo-app.sh \
|
|
40
|
+
--out /tmp/zmr-public-benchmark-ios-demo-20260609-plain \
|
|
41
|
+
--name ZMRDemo \
|
|
42
|
+
--bundle-id com.example.mobiletest \
|
|
43
|
+
--deployment-target 16.0
|
|
44
|
+
|
|
45
|
+
xcodebuild \
|
|
46
|
+
-project /tmp/zmr-public-benchmark-ios-demo-20260609-plain/ios/ZMRDemo.xcodeproj \
|
|
47
|
+
-scheme ZMRDemo \
|
|
48
|
+
-destination 'generic/platform=iOS Simulator' \
|
|
49
|
+
-configuration Debug \
|
|
50
|
+
-derivedDataPath /tmp/zmr-public-benchmark-ios-demo-20260609-plain/DerivedData \
|
|
51
|
+
build
|
|
52
|
+
|
|
53
|
+
ZMR_BIN="$PWD/zig-out/bin/zmr" scripts/run-ios-pilot.sh \
|
|
54
|
+
--app-root /tmp/zmr-public-benchmark-ios-demo-20260609-plain \
|
|
55
|
+
--app-path /tmp/zmr-public-benchmark-ios-demo-20260609-plain/DerivedData/Build/Products/Debug-iphonesimulator/ZMRDemo.app \
|
|
56
|
+
--device booted \
|
|
57
|
+
--app-id com.example.mobiletest \
|
|
58
|
+
--xcrun xcrun \
|
|
59
|
+
--runs 20 \
|
|
60
|
+
--trace-root traces/public-benchmarks/20260609-ios-demo \
|
|
61
|
+
--min-pass-rate 100 \
|
|
62
|
+
--max-failures 0
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
The local run wrote:
|
|
66
|
+
|
|
67
|
+
- `traces/public-benchmarks/20260609-ios-demo/ios-smoke-benchmark/results.jsonl`
|
|
68
|
+
- `traces/public-benchmarks/20260609-ios-demo/ios-smoke-benchmark/report.html`
|
|
69
|
+
- `traces/public-benchmarks/20260609-ios-demo/ios-smoke-benchmark/junit.xml`
|
|
70
|
+
|
|
71
|
+
Those raw artifacts are intentionally not committed because generated reports
|
|
72
|
+
and JUnit properties include absolute local paths. The sanitized result rows are
|
|
73
|
+
committed in
|
|
74
|
+
[2026-06-09-ios-demo.results.jsonl](2026-06-09-ios-demo.results.jsonl).
|
|
75
|
+
|
|
76
|
+
## Scope
|
|
77
|
+
|
|
78
|
+
This run validates the public iOS simulator smoke path: install, launch, deep
|
|
79
|
+
link, snapshot, trace collection, benchmark gate, HTML report generation, and
|
|
80
|
+
JUnit report generation.
|
|
81
|
+
|
|
82
|
+
This run does not measure the app-local XCTest shim path. During collection, a
|
|
83
|
+
shim compatibility check found a generated wrapper portability issue in
|
|
84
|
+
one-shot mode: the wrapper used a `mktemp` template with `XXXXXX` before a
|
|
85
|
+
`.log` suffix, which is not portable on macOS. That generator bug was fixed
|
|
86
|
+
before this evidence pack was committed.
|
|
87
|
+
|
|
88
|
+
Do not use this evidence as a speed comparison against another mobile testing
|
|
89
|
+
framework. Baseline comparisons require equivalent candidate and baseline rows
|
|
90
|
+
from the same app build, device state, and scenario.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{"tool":"zmr","run":1,"status":"ok","durationMs":5409,"traceDir":"traces/public-benchmarks/20260609-ios-demo/ios-smoke-benchmark/zmr-1","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","traceStatus":"passed"}
|
|
2
|
+
{"tool":"zmr","run":2,"status":"ok","durationMs":3289,"traceDir":"traces/public-benchmarks/20260609-ios-demo/ios-smoke-benchmark/zmr-2","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","traceStatus":"passed"}
|
|
3
|
+
{"tool":"zmr","run":3,"status":"ok","durationMs":3319,"traceDir":"traces/public-benchmarks/20260609-ios-demo/ios-smoke-benchmark/zmr-3","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","traceStatus":"passed"}
|
|
4
|
+
{"tool":"zmr","run":4,"status":"ok","durationMs":3323,"traceDir":"traces/public-benchmarks/20260609-ios-demo/ios-smoke-benchmark/zmr-4","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","traceStatus":"passed"}
|
|
5
|
+
{"tool":"zmr","run":5,"status":"ok","durationMs":3562,"traceDir":"traces/public-benchmarks/20260609-ios-demo/ios-smoke-benchmark/zmr-5","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","traceStatus":"passed"}
|
|
6
|
+
{"tool":"zmr","run":6,"status":"ok","durationMs":4048,"traceDir":"traces/public-benchmarks/20260609-ios-demo/ios-smoke-benchmark/zmr-6","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","traceStatus":"passed"}
|
|
7
|
+
{"tool":"zmr","run":7,"status":"ok","durationMs":3606,"traceDir":"traces/public-benchmarks/20260609-ios-demo/ios-smoke-benchmark/zmr-7","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","traceStatus":"passed"}
|
|
8
|
+
{"tool":"zmr","run":8,"status":"ok","durationMs":3065,"traceDir":"traces/public-benchmarks/20260609-ios-demo/ios-smoke-benchmark/zmr-8","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","traceStatus":"passed"}
|
|
9
|
+
{"tool":"zmr","run":9,"status":"ok","durationMs":3692,"traceDir":"traces/public-benchmarks/20260609-ios-demo/ios-smoke-benchmark/zmr-9","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","traceStatus":"passed"}
|
|
10
|
+
{"tool":"zmr","run":10,"status":"ok","durationMs":3514,"traceDir":"traces/public-benchmarks/20260609-ios-demo/ios-smoke-benchmark/zmr-10","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","traceStatus":"passed"}
|
|
11
|
+
{"tool":"zmr","run":11,"status":"ok","durationMs":3702,"traceDir":"traces/public-benchmarks/20260609-ios-demo/ios-smoke-benchmark/zmr-11","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","traceStatus":"passed"}
|
|
12
|
+
{"tool":"zmr","run":12,"status":"ok","durationMs":5092,"traceDir":"traces/public-benchmarks/20260609-ios-demo/ios-smoke-benchmark/zmr-12","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","traceStatus":"passed"}
|
|
13
|
+
{"tool":"zmr","run":13,"status":"ok","durationMs":4929,"traceDir":"traces/public-benchmarks/20260609-ios-demo/ios-smoke-benchmark/zmr-13","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","traceStatus":"passed"}
|
|
14
|
+
{"tool":"zmr","run":14,"status":"ok","durationMs":4340,"traceDir":"traces/public-benchmarks/20260609-ios-demo/ios-smoke-benchmark/zmr-14","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","traceStatus":"passed"}
|
|
15
|
+
{"tool":"zmr","run":15,"status":"ok","durationMs":6395,"traceDir":"traces/public-benchmarks/20260609-ios-demo/ios-smoke-benchmark/zmr-15","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","traceStatus":"passed"}
|
|
16
|
+
{"tool":"zmr","run":16,"status":"ok","durationMs":5128,"traceDir":"traces/public-benchmarks/20260609-ios-demo/ios-smoke-benchmark/zmr-16","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","traceStatus":"passed"}
|
|
17
|
+
{"tool":"zmr","run":17,"status":"ok","durationMs":3955,"traceDir":"traces/public-benchmarks/20260609-ios-demo/ios-smoke-benchmark/zmr-17","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","traceStatus":"passed"}
|
|
18
|
+
{"tool":"zmr","run":18,"status":"ok","durationMs":4410,"traceDir":"traces/public-benchmarks/20260609-ios-demo/ios-smoke-benchmark/zmr-18","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","traceStatus":"passed"}
|
|
19
|
+
{"tool":"zmr","run":19,"status":"ok","durationMs":4634,"traceDir":"traces/public-benchmarks/20260609-ios-demo/ios-smoke-benchmark/zmr-19","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","traceStatus":"passed"}
|
|
20
|
+
{"tool":"zmr","run":20,"status":"ok","durationMs":4425,"traceDir":"traces/public-benchmarks/20260609-ios-demo/ios-smoke-benchmark/zmr-20","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","traceStatus":"passed"}
|