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.
Files changed (66) hide show
  1. package/CHANGELOG.md +72 -0
  2. package/FEATURES.md +1 -1
  3. package/README.md +175 -238
  4. package/clients/kotlin/README.md +1 -1
  5. package/clients/kotlin/build.gradle.kts +1 -1
  6. package/clients/python/pyproject.toml +1 -1
  7. package/clients/rust/Cargo.lock +1 -1
  8. package/clients/rust/Cargo.toml +1 -1
  9. package/clients/typescript/package.json +1 -1
  10. package/docs/agent-discovery.md +10 -0
  11. package/docs/ai-agents.md +18 -0
  12. package/docs/benchmarking.md +39 -0
  13. package/docs/benchmarks/2026-06-09-android-workflow.md +73 -0
  14. package/docs/benchmarks/2026-06-09-android-workflow.results.jsonl +20 -0
  15. package/docs/benchmarks/2026-06-09-framework-baseline-status.md +32 -0
  16. package/docs/benchmarks/2026-06-09-ios-appium-comparison.md +115 -0
  17. package/docs/benchmarks/2026-06-09-ios-appium-comparison.results.jsonl +40 -0
  18. package/docs/benchmarks/2026-06-09-ios-demo.md +90 -0
  19. package/docs/benchmarks/2026-06-09-ios-demo.results.jsonl +20 -0
  20. package/docs/benchmarks/2026-06-09-ios-maestro-comparison.md +128 -0
  21. package/docs/benchmarks/2026-06-09-ios-maestro-comparison.results.jsonl +40 -0
  22. package/docs/benchmarks/2026-06-09-ios-workflow-comparison.md +143 -0
  23. package/docs/benchmarks/2026-06-09-ios-workflow-comparison.results.jsonl +40 -0
  24. package/docs/benchmarks/2026-06-09-ios-xctest-floor.md +106 -0
  25. package/docs/benchmarks/2026-06-09-ios-xctest-floor.results.jsonl +40 -0
  26. package/docs/benchmarks/README.md +36 -0
  27. package/docs/benchmarks/benchmark-lab-v1.json +155 -0
  28. package/docs/benchmarks/benchmark-lab-v1.md +95 -0
  29. package/docs/clients.md +16 -0
  30. package/docs/demo.md +36 -1
  31. package/docs/frameworks.md +10 -0
  32. package/docs/npm.md +44 -2
  33. package/docs/protocol-fixtures/core-session.responses.jsonl +1 -1
  34. package/docs/protocol.md +10 -10
  35. package/docs/scenario-authoring.md +15 -0
  36. package/docs/trace-privacy.md +9 -0
  37. package/docs/troubleshooting.md +6 -0
  38. package/examples/android-workflow.json +79 -0
  39. package/examples/ios-dev-client-open-link.json +24 -13
  40. package/examples/ios-dev-client-route-snapshot.json +33 -8
  41. package/examples/ios-shim-workflow.json +79 -0
  42. package/examples/react-native-expo-workflow.json +75 -0
  43. package/npm/scenarios.mjs +15 -8
  44. package/npm/wizard.mjs +1 -1
  45. package/package.json +6 -1
  46. package/prebuilds/darwin-arm64/zmr +0 -0
  47. package/prebuilds/darwin-x64/zmr +0 -0
  48. package/prebuilds/linux-arm64/zmr +0 -0
  49. package/prebuilds/linux-x64/zmr +0 -0
  50. package/scripts/benchmark-lab.py +253 -0
  51. package/scripts/create-android-demo-app.sh +324 -29
  52. package/scripts/create-ios-demo-app.sh +174 -7
  53. package/scripts/create-react-native-expo-demo-app.sh +727 -0
  54. package/scripts/demo.sh +3 -0
  55. package/scripts/install-ios-shim.sh +2 -2
  56. package/shims/ios/ZMRShim.swift +10 -0
  57. package/shims/ios/ZMRShimUITestCase.swift +49 -1
  58. package/shims/ios/protocol.md +1 -0
  59. package/src/cli_import.zig +31 -15
  60. package/src/cli_trace.zig +38 -16
  61. package/src/cli_validate.zig +12 -6
  62. package/src/ios.zig +44 -11
  63. package/src/ios_shim.zig +36 -2
  64. package/src/main.zig +6 -0
  65. package/src/version.zig +1 -1
  66. package/viewer/app.js +23 -3
@@ -0,0 +1,128 @@
1
+ # 2026-06-09 iOS Simulator ZMR vs Maestro Comparison
2
+
3
+ This evidence pack compares ZMR with Maestro on the generated public iOS demo
4
+ app. It is a command-level benchmark: each row starts the runner command,
5
+ executes one smoke flow on the same booted simulator, and records the 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 | 2236 ms | 2282 ms |
16
+ | Maestro | 20 | 95.00% | 1 | 7578 ms | 7918 ms |
17
+
18
+ For this run, ZMR was 3.39x faster on mean duration and 3.47x faster on p95
19
+ duration. Maestro run 8 failed while launching the app with a driver connection
20
+ error: `Failed to connect to /127.0.0.1:7001`.
21
+
22
+ ## Environment
23
+
24
+ | Field | Value |
25
+ | --- | --- |
26
+ | ZMR runner | `0.1.8` |
27
+ | ZMR protocol | `2026-04-28` |
28
+ | Maestro | `1.40.3` |
29
+ | Java | OpenJDK 21.0.6 |
30
+ | Host OS | macOS 26.6, arm64 |
31
+ | Xcode | 26.5, build 17F42 |
32
+ | Simulator | Booted iOS 26.5 simulator, `zmr-iPhone` |
33
+ | App id | `com.example.mobiletest` |
34
+ | App build label | `generated-ios-demo-20260609` |
35
+ | Demo app source | Generated by `scripts/create-ios-demo-app.sh` |
36
+
37
+ ## ZMR Command
38
+
39
+ ```bash
40
+ ZMR_BIN="$PWD/zig-out/bin/zmr" scripts/benchmark.sh \
41
+ --zmr examples/ios-smoke.json \
42
+ --platform ios \
43
+ --ios-device-type simulator \
44
+ --device booted \
45
+ --app-id com.example.mobiletest \
46
+ --xcrun xcrun \
47
+ --app-build generated-ios-demo-20260609 \
48
+ --runs 20 \
49
+ --trace-root traces/public-benchmarks/20260609-ios-maestro-comparison/zmr \
50
+ --results traces/public-benchmarks/20260609-ios-maestro-comparison/results.jsonl \
51
+ --replace \
52
+ --min-pass-rate 100 \
53
+ --max-failures 0
54
+ ```
55
+
56
+ The ZMR scenario launches the app, opens `exampleapp:///e2e-auth?probe=1`, and
57
+ captures a snapshot:
58
+
59
+ ```json
60
+ {
61
+ "name": "ZMR iOS simulator smoke demo",
62
+ "appId": "com.example.mobiletest",
63
+ "steps": [
64
+ { "action": "launch" },
65
+ { "action": "openLink", "url": "exampleapp:///e2e-auth?probe=1" },
66
+ { "action": "snapshot" }
67
+ ]
68
+ }
69
+ ```
70
+
71
+ ## Maestro Command
72
+
73
+ ```bash
74
+ scripts/benchmark-command.sh \
75
+ --tool maestro \
76
+ --platform ios \
77
+ --device booted \
78
+ --app-id com.example.mobiletest \
79
+ --scenario examples/ios-smoke.json \
80
+ --app-build generated-ios-demo-20260609 \
81
+ --runs 20 \
82
+ --trace-root traces/public-benchmarks/20260609-ios-maestro-comparison/maestro \
83
+ --results traces/public-benchmarks/20260609-ios-maestro-comparison/results.jsonl \
84
+ --min-pass-rate 100 \
85
+ --max-failures 0 \
86
+ -- maestro --platform ios --device F839B002-5388-4814-B64F-DBE5A113EBED test --no-ansi /tmp/zmr-maestro-benchmark-20260609/ios-smoke.yaml
87
+ ```
88
+
89
+ The Maestro flow launches the same app, opens the same deep link, and asserts
90
+ the resulting status text:
91
+
92
+ ```yaml
93
+ appId: com.example.mobiletest
94
+ ---
95
+ - launchApp
96
+ - openLink: exampleapp:///e2e-auth?probe=1
97
+ - assertVisible: Deep link opened
98
+ ```
99
+
100
+ ## Comparison Report
101
+
102
+ ```text
103
+ # Benchmark Comparison
104
+
105
+ | Tool | Runs | Pass rate | Failures | Mean ms | P95 ms |
106
+ | --- | ---: | ---: | ---: | ---: | ---: |
107
+ | zmr | 20 | 100.00% | 0 | 2236 | 2282 |
108
+ | maestro | 20 | 95.00% | 1 | 7578 | 7918 |
109
+
110
+ - Mean speedup: 3.39x (-70.5% candidate vs baseline)
111
+ - P95 speedup: 3.47x (-71.2% candidate vs baseline)
112
+ - Same benchmark context: yes
113
+ ```
114
+
115
+ The sanitized result rows are committed in
116
+ [2026-06-09-ios-maestro-comparison.results.jsonl](2026-06-09-ios-maestro-comparison.results.jsonl).
117
+
118
+ Raw local trace and runner logs are not committed because they can include local
119
+ absolute paths. The failure detail above was taken from the failed Maestro
120
+ run's local stdout log.
121
+
122
+ ## Scope
123
+
124
+ This benchmark compares the local command surfaces under repeated execution. It
125
+ does not compare cloud execution, long multi-screen flows, Detox, XCTest-only
126
+ flows, or app-specific selectors. Detox requires a project-specific native test
127
+ harness, so it should get its own evidence pack rather than being forced into
128
+ this demo comparison.
@@ -0,0 +1,40 @@
1
+ {"tool":"zmr","run":1,"status":"ok","durationMs":2347,"traceDir":"traces/public-benchmarks/20260609-ios-maestro-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":2233,"traceDir":"traces/public-benchmarks/20260609-ios-maestro-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":2282,"traceDir":"traces/public-benchmarks/20260609-ios-maestro-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":2204,"traceDir":"traces/public-benchmarks/20260609-ios-maestro-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":2231,"traceDir":"traces/public-benchmarks/20260609-ios-maestro-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":2185,"traceDir":"traces/public-benchmarks/20260609-ios-maestro-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":2208,"traceDir":"traces/public-benchmarks/20260609-ios-maestro-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":2196,"traceDir":"traces/public-benchmarks/20260609-ios-maestro-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":2189,"traceDir":"traces/public-benchmarks/20260609-ios-maestro-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":2211,"traceDir":"traces/public-benchmarks/20260609-ios-maestro-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":2268,"traceDir":"traces/public-benchmarks/20260609-ios-maestro-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":2245,"traceDir":"traces/public-benchmarks/20260609-ios-maestro-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":2244,"traceDir":"traces/public-benchmarks/20260609-ios-maestro-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":2249,"traceDir":"traces/public-benchmarks/20260609-ios-maestro-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":2224,"traceDir":"traces/public-benchmarks/20260609-ios-maestro-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":2236,"traceDir":"traces/public-benchmarks/20260609-ios-maestro-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":2236,"traceDir":"traces/public-benchmarks/20260609-ios-maestro-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":2226,"traceDir":"traces/public-benchmarks/20260609-ios-maestro-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":2262,"traceDir":"traces/public-benchmarks/20260609-ios-maestro-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":2248,"traceDir":"traces/public-benchmarks/20260609-ios-maestro-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":"maestro","run":1,"status":"ok","durationMs":7762,"traceDir":"traces/public-benchmarks/20260609-ios-maestro-comparison/maestro/maestro-1","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
22
+ {"tool":"maestro","run":2,"status":"ok","durationMs":7793,"traceDir":"traces/public-benchmarks/20260609-ios-maestro-comparison/maestro/maestro-2","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
23
+ {"tool":"maestro","run":3,"status":"ok","durationMs":7771,"traceDir":"traces/public-benchmarks/20260609-ios-maestro-comparison/maestro/maestro-3","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
24
+ {"tool":"maestro","run":4,"status":"ok","durationMs":7762,"traceDir":"traces/public-benchmarks/20260609-ios-maestro-comparison/maestro/maestro-4","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
25
+ {"tool":"maestro","run":5,"status":"ok","durationMs":7838,"traceDir":"traces/public-benchmarks/20260609-ios-maestro-comparison/maestro/maestro-5","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
26
+ {"tool":"maestro","run":6,"status":"ok","durationMs":7918,"traceDir":"traces/public-benchmarks/20260609-ios-maestro-comparison/maestro/maestro-6","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
27
+ {"tool":"maestro","run":7,"status":"ok","durationMs":7975,"traceDir":"traces/public-benchmarks/20260609-ios-maestro-comparison/maestro/maestro-7","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
28
+ {"tool":"maestro","run":8,"status":"failed","durationMs":5091,"traceDir":"traces/public-benchmarks/20260609-ios-maestro-comparison/maestro/maestro-8","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
29
+ {"tool":"maestro","run":9,"status":"ok","durationMs":6764,"traceDir":"traces/public-benchmarks/20260609-ios-maestro-comparison/maestro/maestro-9","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
30
+ {"tool":"maestro","run":10,"status":"ok","durationMs":7716,"traceDir":"traces/public-benchmarks/20260609-ios-maestro-comparison/maestro/maestro-10","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
31
+ {"tool":"maestro","run":11,"status":"ok","durationMs":7738,"traceDir":"traces/public-benchmarks/20260609-ios-maestro-comparison/maestro/maestro-11","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
32
+ {"tool":"maestro","run":12,"status":"ok","durationMs":7738,"traceDir":"traces/public-benchmarks/20260609-ios-maestro-comparison/maestro/maestro-12","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
33
+ {"tool":"maestro","run":13,"status":"ok","durationMs":7808,"traceDir":"traces/public-benchmarks/20260609-ios-maestro-comparison/maestro/maestro-13","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
34
+ {"tool":"maestro","run":14,"status":"ok","durationMs":7772,"traceDir":"traces/public-benchmarks/20260609-ios-maestro-comparison/maestro/maestro-14","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
35
+ {"tool":"maestro","run":15,"status":"ok","durationMs":7681,"traceDir":"traces/public-benchmarks/20260609-ios-maestro-comparison/maestro/maestro-15","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
36
+ {"tool":"maestro","run":16,"status":"ok","durationMs":7629,"traceDir":"traces/public-benchmarks/20260609-ios-maestro-comparison/maestro/maestro-16","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
37
+ {"tool":"maestro","run":17,"status":"ok","durationMs":7702,"traceDir":"traces/public-benchmarks/20260609-ios-maestro-comparison/maestro/maestro-17","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
38
+ {"tool":"maestro","run":18,"status":"ok","durationMs":7661,"traceDir":"traces/public-benchmarks/20260609-ios-maestro-comparison/maestro/maestro-18","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
39
+ {"tool":"maestro","run":19,"status":"ok","durationMs":7787,"traceDir":"traces/public-benchmarks/20260609-ios-maestro-comparison/maestro/maestro-19","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
40
+ {"tool":"maestro","run":20,"status":"ok","durationMs":7658,"traceDir":"traces/public-benchmarks/20260609-ios-maestro-comparison/maestro/maestro-20","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
@@ -0,0 +1,143 @@
1
+ # 2026-06-09 iOS Simulator Workflow Comparison
2
+
3
+ This evidence pack compares ZMR with Maestro on the generated public iOS demo
4
+ app using a longer workflow than the smoke benchmark. The flow launches the
5
+ app, fills a profile form, opens a catalog item, saves it, reviews the order,
6
+ and asserts the final state.
7
+
8
+ This is not a universal claim about either project. Treat it as reproducible
9
+ evidence for this app, host, simulator, app build, and workflow shape.
10
+
11
+ ## Result
12
+
13
+ | Tool | Runs | Pass rate | Failures | Mean duration | p95 duration |
14
+ | --- | ---: | ---: | ---: | ---: | ---: |
15
+ | ZMR | 20 | 100.00% | 0 | 19539 ms | 22970 ms |
16
+ | Maestro | 20 | 100.00% | 0 | 36240 ms | 47502 ms |
17
+
18
+ For this run, ZMR was 1.85x faster on mean duration and 2.07x 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
+ | Maestro | `1.40.3` |
28
+ | Java | OpenJDK 21.0.6 |
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-workflow-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-shim-workflow.json \
41
+ --platform ios \
42
+ --ios-device-type simulator \
43
+ --device booted \
44
+ --app-id com.example.mobiletest \
45
+ --xcrun xcrun \
46
+ --ios-shim /tmp/zmr-ios-workflow-demo-20260609/.zmr/ios-shim \
47
+ --app-build generated-ios-workflow-demo-20260609 \
48
+ --runs 20 \
49
+ --trace-root traces/public-benchmarks/20260609-ios-workflow-comparison/zmr \
50
+ --results traces/public-benchmarks/20260609-ios-workflow-comparison/results.jsonl \
51
+ --replace \
52
+ --min-pass-rate 100 \
53
+ --max-failures 0
54
+ ```
55
+
56
+ The ZMR scenario is committed as
57
+ [`examples/ios-shim-workflow.json`](../../examples/ios-shim-workflow.json).
58
+
59
+ ## Maestro Command
60
+
61
+ ```bash
62
+ MAESTRO_BIN="$HOME/.maestro/bin/maestro"
63
+ scripts/benchmark-command.sh \
64
+ --tool maestro \
65
+ --platform ios \
66
+ --device booted \
67
+ --app-id com.example.mobiletest \
68
+ --scenario examples/ios-shim-workflow.json \
69
+ --app-build generated-ios-workflow-demo-20260609 \
70
+ --runs 20 \
71
+ --trace-root traces/public-benchmarks/20260609-ios-workflow-comparison/maestro \
72
+ --results traces/public-benchmarks/20260609-ios-workflow-comparison/results.jsonl \
73
+ --min-pass-rate 90 \
74
+ --max-failures 2 \
75
+ -- "$MAESTRO_BIN" \
76
+ --platform ios \
77
+ --device F839B002-5388-4814-B64F-DBE5A113EBED \
78
+ test \
79
+ --no-ansi \
80
+ /tmp/zmr-maestro-workflow-20260609/ios-workflow.yaml
81
+ ```
82
+
83
+ The measured Maestro flow used the same visible labels and app state:
84
+
85
+ ```yaml
86
+ appId: com.example.mobiletest
87
+ ---
88
+ - launchApp
89
+ - assertVisible: ZMR iOS Demo
90
+ - tapOn: Continue
91
+ - assertVisible: Profile
92
+ - tapOn: Name
93
+ - inputText: Riley
94
+ - tapOn: Email
95
+ - inputText: riley@example.test
96
+ - hideKeyboard
97
+ - tapOn: Save profile
98
+ - assertVisible: Catalog
99
+ - tapOn: North Ridge Pack
100
+ - assertVisible: North Ridge Pack
101
+ - tapOn: Save item
102
+ - assertVisible: Saved North Ridge Pack
103
+ - tapOn: Review order
104
+ - assertVisible: Workflow complete
105
+ ```
106
+
107
+ ## Comparison Report
108
+
109
+ ```text
110
+ # Benchmark Comparison
111
+
112
+ | Tool | Runs | Pass rate | Failures | Mean ms | P95 ms |
113
+ | --- | ---: | ---: | ---: | ---: | ---: |
114
+ | zmr | 20 | 100.00% | 0 | 19539 | 22970 |
115
+ | maestro | 20 | 100.00% | 0 | 36240 | 47502 |
116
+
117
+ - Mean speedup: 1.85x (-46.1% candidate vs baseline)
118
+ - P95 speedup: 2.07x (-51.6% candidate vs baseline)
119
+ - Same benchmark context: yes
120
+ ```
121
+
122
+ The sanitized result rows are committed in
123
+ [2026-06-09-ios-workflow-comparison.results.jsonl](2026-06-09-ios-workflow-comparison.results.jsonl).
124
+
125
+ Raw local trace and runner logs are not committed because they can include local
126
+ absolute paths.
127
+
128
+ ## Other Baselines
129
+
130
+ Appium 3.5.0 with XCUITest driver 11.10.0 was attempted against the same app
131
+ and simulator. The smoke run failed twice while starting WebDriverAgent with
132
+ `connect ECONNREFUSED 127.0.0.1:8100`, so no Appium timing rows are included in
133
+ this evidence pack.
134
+
135
+ Detox needs a project-specific native test harness and app build wiring, so it
136
+ should get its own fixture rather than being forced into this generated SwiftUI
137
+ demo.
138
+
139
+ ## Scope
140
+
141
+ This benchmark compares local command surfaces under repeated execution. It
142
+ does not compare cloud execution, Android, Flutter widget-tree automation, or
143
+ framework-specific project harnesses.
@@ -0,0 +1,40 @@
1
+ {"tool":"zmr","run":1,"status":"ok","durationMs":21874,"traceDir":"traces/public-benchmarks/20260609-ios-workflow-comparison/zmr-final/zmr-1","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-shim-workflow.json","appBuild":"generated-ios-workflow-demo-20260609","traceStatus":"passed"}
2
+ {"tool":"zmr","run":2,"status":"ok","durationMs":17173,"traceDir":"traces/public-benchmarks/20260609-ios-workflow-comparison/zmr-final/zmr-2","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-shim-workflow.json","appBuild":"generated-ios-workflow-demo-20260609","traceStatus":"passed"}
3
+ {"tool":"zmr","run":3,"status":"ok","durationMs":16724,"traceDir":"traces/public-benchmarks/20260609-ios-workflow-comparison/zmr-final/zmr-3","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-shim-workflow.json","appBuild":"generated-ios-workflow-demo-20260609","traceStatus":"passed"}
4
+ {"tool":"zmr","run":4,"status":"ok","durationMs":16453,"traceDir":"traces/public-benchmarks/20260609-ios-workflow-comparison/zmr-final/zmr-4","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-shim-workflow.json","appBuild":"generated-ios-workflow-demo-20260609","traceStatus":"passed"}
5
+ {"tool":"zmr","run":5,"status":"ok","durationMs":17385,"traceDir":"traces/public-benchmarks/20260609-ios-workflow-comparison/zmr-final/zmr-5","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-shim-workflow.json","appBuild":"generated-ios-workflow-demo-20260609","traceStatus":"passed"}
6
+ {"tool":"zmr","run":6,"status":"ok","durationMs":23807,"traceDir":"traces/public-benchmarks/20260609-ios-workflow-comparison/zmr-final/zmr-6","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-shim-workflow.json","appBuild":"generated-ios-workflow-demo-20260609","traceStatus":"passed"}
7
+ {"tool":"zmr","run":7,"status":"ok","durationMs":18335,"traceDir":"traces/public-benchmarks/20260609-ios-workflow-comparison/zmr-final/zmr-7","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-shim-workflow.json","appBuild":"generated-ios-workflow-demo-20260609","traceStatus":"passed"}
8
+ {"tool":"zmr","run":8,"status":"ok","durationMs":18195,"traceDir":"traces/public-benchmarks/20260609-ios-workflow-comparison/zmr-final/zmr-8","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-shim-workflow.json","appBuild":"generated-ios-workflow-demo-20260609","traceStatus":"passed"}
9
+ {"tool":"zmr","run":9,"status":"ok","durationMs":17859,"traceDir":"traces/public-benchmarks/20260609-ios-workflow-comparison/zmr-final/zmr-9","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-shim-workflow.json","appBuild":"generated-ios-workflow-demo-20260609","traceStatus":"passed"}
10
+ {"tool":"zmr","run":10,"status":"ok","durationMs":21344,"traceDir":"traces/public-benchmarks/20260609-ios-workflow-comparison/zmr-final/zmr-10","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-shim-workflow.json","appBuild":"generated-ios-workflow-demo-20260609","traceStatus":"passed"}
11
+ {"tool":"zmr","run":11,"status":"ok","durationMs":21375,"traceDir":"traces/public-benchmarks/20260609-ios-workflow-comparison/zmr-final/zmr-11","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-shim-workflow.json","appBuild":"generated-ios-workflow-demo-20260609","traceStatus":"passed"}
12
+ {"tool":"zmr","run":12,"status":"ok","durationMs":20713,"traceDir":"traces/public-benchmarks/20260609-ios-workflow-comparison/zmr-final/zmr-12","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-shim-workflow.json","appBuild":"generated-ios-workflow-demo-20260609","traceStatus":"passed"}
13
+ {"tool":"zmr","run":13,"status":"ok","durationMs":18959,"traceDir":"traces/public-benchmarks/20260609-ios-workflow-comparison/zmr-final/zmr-13","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-shim-workflow.json","appBuild":"generated-ios-workflow-demo-20260609","traceStatus":"passed"}
14
+ {"tool":"zmr","run":14,"status":"ok","durationMs":20610,"traceDir":"traces/public-benchmarks/20260609-ios-workflow-comparison/zmr-final/zmr-14","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-shim-workflow.json","appBuild":"generated-ios-workflow-demo-20260609","traceStatus":"passed"}
15
+ {"tool":"zmr","run":15,"status":"ok","durationMs":22176,"traceDir":"traces/public-benchmarks/20260609-ios-workflow-comparison/zmr-final/zmr-15","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-shim-workflow.json","appBuild":"generated-ios-workflow-demo-20260609","traceStatus":"passed"}
16
+ {"tool":"zmr","run":16,"status":"ok","durationMs":18852,"traceDir":"traces/public-benchmarks/20260609-ios-workflow-comparison/zmr-final/zmr-16","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-shim-workflow.json","appBuild":"generated-ios-workflow-demo-20260609","traceStatus":"passed"}
17
+ {"tool":"zmr","run":17,"status":"ok","durationMs":22970,"traceDir":"traces/public-benchmarks/20260609-ios-workflow-comparison/zmr-final/zmr-17","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-shim-workflow.json","appBuild":"generated-ios-workflow-demo-20260609","traceStatus":"passed"}
18
+ {"tool":"zmr","run":18,"status":"ok","durationMs":18682,"traceDir":"traces/public-benchmarks/20260609-ios-workflow-comparison/zmr-final/zmr-18","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-shim-workflow.json","appBuild":"generated-ios-workflow-demo-20260609","traceStatus":"passed"}
19
+ {"tool":"zmr","run":19,"status":"ok","durationMs":18347,"traceDir":"traces/public-benchmarks/20260609-ios-workflow-comparison/zmr-final/zmr-19","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-shim-workflow.json","appBuild":"generated-ios-workflow-demo-20260609","traceStatus":"passed"}
20
+ {"tool":"zmr","run":20,"status":"ok","durationMs":18951,"traceDir":"traces/public-benchmarks/20260609-ios-workflow-comparison/zmr-final/zmr-20","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-shim-workflow.json","appBuild":"generated-ios-workflow-demo-20260609","traceStatus":"passed"}
21
+ {"tool":"maestro","run":1,"status":"ok","durationMs":47502,"traceDir":"traces/public-benchmarks/20260609-ios-workflow-comparison/maestro/maestro-1","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-shim-workflow.json","appBuild":"generated-ios-workflow-demo-20260609"}
22
+ {"tool":"maestro","run":2,"status":"ok","durationMs":29793,"traceDir":"traces/public-benchmarks/20260609-ios-workflow-comparison/maestro/maestro-2","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-shim-workflow.json","appBuild":"generated-ios-workflow-demo-20260609"}
23
+ {"tool":"maestro","run":3,"status":"ok","durationMs":31898,"traceDir":"traces/public-benchmarks/20260609-ios-workflow-comparison/maestro/maestro-3","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-shim-workflow.json","appBuild":"generated-ios-workflow-demo-20260609"}
24
+ {"tool":"maestro","run":4,"status":"ok","durationMs":27151,"traceDir":"traces/public-benchmarks/20260609-ios-workflow-comparison/maestro/maestro-4","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-shim-workflow.json","appBuild":"generated-ios-workflow-demo-20260609"}
25
+ {"tool":"maestro","run":5,"status":"ok","durationMs":31825,"traceDir":"traces/public-benchmarks/20260609-ios-workflow-comparison/maestro/maestro-5","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-shim-workflow.json","appBuild":"generated-ios-workflow-demo-20260609"}
26
+ {"tool":"maestro","run":6,"status":"ok","durationMs":32080,"traceDir":"traces/public-benchmarks/20260609-ios-workflow-comparison/maestro/maestro-6","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-shim-workflow.json","appBuild":"generated-ios-workflow-demo-20260609"}
27
+ {"tool":"maestro","run":7,"status":"ok","durationMs":27544,"traceDir":"traces/public-benchmarks/20260609-ios-workflow-comparison/maestro/maestro-7","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-shim-workflow.json","appBuild":"generated-ios-workflow-demo-20260609"}
28
+ {"tool":"maestro","run":8,"status":"ok","durationMs":30177,"traceDir":"traces/public-benchmarks/20260609-ios-workflow-comparison/maestro/maestro-8","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-shim-workflow.json","appBuild":"generated-ios-workflow-demo-20260609"}
29
+ {"tool":"maestro","run":9,"status":"ok","durationMs":31528,"traceDir":"traces/public-benchmarks/20260609-ios-workflow-comparison/maestro/maestro-9","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-shim-workflow.json","appBuild":"generated-ios-workflow-demo-20260609"}
30
+ {"tool":"maestro","run":10,"status":"ok","durationMs":30227,"traceDir":"traces/public-benchmarks/20260609-ios-workflow-comparison/maestro/maestro-10","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-shim-workflow.json","appBuild":"generated-ios-workflow-demo-20260609"}
31
+ {"tool":"maestro","run":11,"status":"ok","durationMs":29175,"traceDir":"traces/public-benchmarks/20260609-ios-workflow-comparison/maestro/maestro-11","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-shim-workflow.json","appBuild":"generated-ios-workflow-demo-20260609"}
32
+ {"tool":"maestro","run":12,"status":"ok","durationMs":30119,"traceDir":"traces/public-benchmarks/20260609-ios-workflow-comparison/maestro/maestro-12","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-shim-workflow.json","appBuild":"generated-ios-workflow-demo-20260609"}
33
+ {"tool":"maestro","run":13,"status":"ok","durationMs":38762,"traceDir":"traces/public-benchmarks/20260609-ios-workflow-comparison/maestro/maestro-13","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-shim-workflow.json","appBuild":"generated-ios-workflow-demo-20260609"}
34
+ {"tool":"maestro","run":14,"status":"ok","durationMs":36592,"traceDir":"traces/public-benchmarks/20260609-ios-workflow-comparison/maestro/maestro-14","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-shim-workflow.json","appBuild":"generated-ios-workflow-demo-20260609"}
35
+ {"tool":"maestro","run":15,"status":"ok","durationMs":29813,"traceDir":"traces/public-benchmarks/20260609-ios-workflow-comparison/maestro/maestro-15","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-shim-workflow.json","appBuild":"generated-ios-workflow-demo-20260609"}
36
+ {"tool":"maestro","run":16,"status":"ok","durationMs":34198,"traceDir":"traces/public-benchmarks/20260609-ios-workflow-comparison/maestro/maestro-16","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-shim-workflow.json","appBuild":"generated-ios-workflow-demo-20260609"}
37
+ {"tool":"maestro","run":17,"status":"ok","durationMs":42114,"traceDir":"traces/public-benchmarks/20260609-ios-workflow-comparison/maestro/maestro-17","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-shim-workflow.json","appBuild":"generated-ios-workflow-demo-20260609"}
38
+ {"tool":"maestro","run":18,"status":"ok","durationMs":46397,"traceDir":"traces/public-benchmarks/20260609-ios-workflow-comparison/maestro/maestro-18","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-shim-workflow.json","appBuild":"generated-ios-workflow-demo-20260609"}
39
+ {"tool":"maestro","run":19,"status":"ok","durationMs":44429,"traceDir":"traces/public-benchmarks/20260609-ios-workflow-comparison/maestro/maestro-19","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-shim-workflow.json","appBuild":"generated-ios-workflow-demo-20260609"}
40
+ {"tool":"maestro","run":20,"status":"ok","durationMs":73476,"traceDir":"traces/public-benchmarks/20260609-ios-workflow-comparison/maestro/maestro-20","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-shim-workflow.json","appBuild":"generated-ios-workflow-demo-20260609"}
@@ -0,0 +1,106 @@
1
+ # 2026-06-09 iOS Simulator XCTest Shim Floor
2
+
3
+ This evidence pack compares the optimized ZMR iOS shim-backed smoke flow with a
4
+ direct XCTest-shim floor on the generated public iOS demo app.
5
+
6
+ The floor is not a competing product. It bypasses ZMR scenario parsing, trace
7
+ events, screenshots, result normalization, and reporting. It is useful because
8
+ it shows how much room remains between ZMR and the warmed native shim path.
9
+
10
+ ## Result
11
+
12
+ | Tool | Runs | Pass rate | Failures | Mean duration | p95 duration |
13
+ | --- | ---: | ---: | ---: | ---: | ---: |
14
+ | ZMR with XCTest shim | 20 | 100.00% | 0 | 2007 ms | 2969 ms |
15
+ | Direct XCTest shim floor | 20 | 100.00% | 0 | 1004 ms | 962 ms |
16
+
17
+ Before this run, ZMR was changed to skip the slow best-effort iOS "Open"
18
+ confirmation probe for custom URL schemes. Universal `http://` and `https://`
19
+ links still keep that safety check.
20
+
21
+ The result: ZMR is now roughly 2.0x the direct warmed shim mean for this flow,
22
+ while still producing scenario semantics and trace artifacts.
23
+
24
+ ## Environment
25
+
26
+ | Field | Value |
27
+ | --- | --- |
28
+ | ZMR runner | `0.1.8` |
29
+ | ZMR protocol | `2026-04-28` |
30
+ | Host OS | macOS 26.6, arm64 |
31
+ | Xcode | 26.5, build 17F42 |
32
+ | Simulator | Booted iOS 26.5 simulator, `zmr-iPhone` |
33
+ | App id | `com.example.mobiletest` |
34
+ | App build label | `generated-ios-demo-20260609` |
35
+ | Demo app source | Generated by `scripts/create-ios-demo-app.sh` |
36
+
37
+ ## ZMR Command
38
+
39
+ ```bash
40
+ ZMR_BIN="$PWD/zig-out/bin/zmr" scripts/benchmark.sh \
41
+ --zmr examples/ios-smoke.json \
42
+ --platform ios \
43
+ --ios-device-type simulator \
44
+ --device booted \
45
+ --app-id com.example.mobiletest \
46
+ --xcrun xcrun \
47
+ --ios-shim /tmp/zmr-public-benchmark-ios-demo-20260609-plain/.zmr/ios-shim \
48
+ --app-build generated-ios-demo-20260609 \
49
+ --runs 20 \
50
+ --trace-root traces/public-benchmarks/20260609-ios-xctest-floor-optimized/zmr \
51
+ --results traces/public-benchmarks/20260609-ios-xctest-floor-optimized/results.jsonl \
52
+ --replace \
53
+ --min-pass-rate 100 \
54
+ --max-failures 0
55
+ ```
56
+
57
+ ## Direct XCTest Shim Floor Command
58
+
59
+ The direct floor launches the already-installed app, opens the same custom
60
+ scheme URL, sends one `snapshot` command to the warmed XCTest shim server, and
61
+ asserts that the snapshot contains `Deep link opened`.
62
+
63
+ It intentionally does not terminate the app before each run. Terminating the app
64
+ under a persistent XCTest runner can invalidate XCTest's connection to the app
65
+ and create failures unrelated to ZMR.
66
+
67
+ ```bash
68
+ scripts/benchmark-command.sh \
69
+ --tool xctest-shim \
70
+ --platform ios \
71
+ --device booted \
72
+ --app-id com.example.mobiletest \
73
+ --scenario examples/ios-smoke.json \
74
+ --app-build generated-ios-demo-20260609 \
75
+ --runs 20 \
76
+ --trace-root traces/public-benchmarks/20260609-ios-xctest-floor-optimized/xctest-shim \
77
+ --results traces/public-benchmarks/20260609-ios-xctest-floor-optimized/results.jsonl \
78
+ --min-pass-rate 100 \
79
+ --max-failures 0 \
80
+ -- bash -lc '<simctl launch, simctl openurl, direct shim snapshot, grep status text>'
81
+ ```
82
+
83
+ ## Comparison Report
84
+
85
+ ```text
86
+ # Benchmark Comparison
87
+
88
+ | Tool | Runs | Pass rate | Failures | Mean ms | P95 ms |
89
+ | --- | ---: | ---: | ---: | ---: | ---: |
90
+ | zmr | 20 | 100.00% | 0 | 2007 | 2969 |
91
+ | xctest-shim | 20 | 100.00% | 0 | 1004 | 962 |
92
+
93
+ - Mean speedup: 0.50x (+99.9% candidate vs baseline)
94
+ - P95 speedup: 0.32x (+208.6% candidate vs baseline)
95
+ - Same benchmark context: yes
96
+ ```
97
+
98
+ The sanitized result rows are committed in
99
+ [2026-06-09-ios-xctest-floor.results.jsonl](2026-06-09-ios-xctest-floor.results.jsonl).
100
+
101
+ ## Scope
102
+
103
+ This floor is a native-path reference point, not a replacement for product
104
+ benchmarks. It does not include trace writing, scenario validation, artifact
105
+ capture, report generation, JSONL result normalization, or multi-step selector
106
+ logic.
@@ -0,0 +1,40 @@
1
+ {"tool":"zmr","run":1,"status":"ok","durationMs":4500,"traceDir":"traces/public-benchmarks/20260609-ios-xctest-floor-optimized/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":1810,"traceDir":"traces/public-benchmarks/20260609-ios-xctest-floor-optimized/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":2969,"traceDir":"traces/public-benchmarks/20260609-ios-xctest-floor-optimized/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":1816,"traceDir":"traces/public-benchmarks/20260609-ios-xctest-floor-optimized/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":1778,"traceDir":"traces/public-benchmarks/20260609-ios-xctest-floor-optimized/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":1782,"traceDir":"traces/public-benchmarks/20260609-ios-xctest-floor-optimized/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":1936,"traceDir":"traces/public-benchmarks/20260609-ios-xctest-floor-optimized/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":1820,"traceDir":"traces/public-benchmarks/20260609-ios-xctest-floor-optimized/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":1797,"traceDir":"traces/public-benchmarks/20260609-ios-xctest-floor-optimized/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":1794,"traceDir":"traces/public-benchmarks/20260609-ios-xctest-floor-optimized/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":1791,"traceDir":"traces/public-benchmarks/20260609-ios-xctest-floor-optimized/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":1801,"traceDir":"traces/public-benchmarks/20260609-ios-xctest-floor-optimized/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":1901,"traceDir":"traces/public-benchmarks/20260609-ios-xctest-floor-optimized/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":1709,"traceDir":"traces/public-benchmarks/20260609-ios-xctest-floor-optimized/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":1847,"traceDir":"traces/public-benchmarks/20260609-ios-xctest-floor-optimized/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":1805,"traceDir":"traces/public-benchmarks/20260609-ios-xctest-floor-optimized/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":1810,"traceDir":"traces/public-benchmarks/20260609-ios-xctest-floor-optimized/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":1800,"traceDir":"traces/public-benchmarks/20260609-ios-xctest-floor-optimized/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":1843,"traceDir":"traces/public-benchmarks/20260609-ios-xctest-floor-optimized/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":1833,"traceDir":"traces/public-benchmarks/20260609-ios-xctest-floor-optimized/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":"xctest-shim","run":1,"status":"ok","durationMs":3403,"traceDir":"traces/public-benchmarks/20260609-ios-xctest-floor-optimized/xctest-shim/xctest-shim-1","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
22
+ {"tool":"xctest-shim","run":2,"status":"ok","durationMs":879,"traceDir":"traces/public-benchmarks/20260609-ios-xctest-floor-optimized/xctest-shim/xctest-shim-2","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
23
+ {"tool":"xctest-shim","run":3,"status":"ok","durationMs":808,"traceDir":"traces/public-benchmarks/20260609-ios-xctest-floor-optimized/xctest-shim/xctest-shim-3","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
24
+ {"tool":"xctest-shim","run":4,"status":"ok","durationMs":912,"traceDir":"traces/public-benchmarks/20260609-ios-xctest-floor-optimized/xctest-shim/xctest-shim-4","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
25
+ {"tool":"xctest-shim","run":5,"status":"ok","durationMs":904,"traceDir":"traces/public-benchmarks/20260609-ios-xctest-floor-optimized/xctest-shim/xctest-shim-5","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
26
+ {"tool":"xctest-shim","run":6,"status":"ok","durationMs":874,"traceDir":"traces/public-benchmarks/20260609-ios-xctest-floor-optimized/xctest-shim/xctest-shim-6","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
27
+ {"tool":"xctest-shim","run":7,"status":"ok","durationMs":959,"traceDir":"traces/public-benchmarks/20260609-ios-xctest-floor-optimized/xctest-shim/xctest-shim-7","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
28
+ {"tool":"xctest-shim","run":8,"status":"ok","durationMs":871,"traceDir":"traces/public-benchmarks/20260609-ios-xctest-floor-optimized/xctest-shim/xctest-shim-8","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
29
+ {"tool":"xctest-shim","run":9,"status":"ok","durationMs":870,"traceDir":"traces/public-benchmarks/20260609-ios-xctest-floor-optimized/xctest-shim/xctest-shim-9","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
30
+ {"tool":"xctest-shim","run":10,"status":"ok","durationMs":870,"traceDir":"traces/public-benchmarks/20260609-ios-xctest-floor-optimized/xctest-shim/xctest-shim-10","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
31
+ {"tool":"xctest-shim","run":11,"status":"ok","durationMs":865,"traceDir":"traces/public-benchmarks/20260609-ios-xctest-floor-optimized/xctest-shim/xctest-shim-11","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
32
+ {"tool":"xctest-shim","run":12,"status":"ok","durationMs":876,"traceDir":"traces/public-benchmarks/20260609-ios-xctest-floor-optimized/xctest-shim/xctest-shim-12","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
33
+ {"tool":"xctest-shim","run":13,"status":"ok","durationMs":962,"traceDir":"traces/public-benchmarks/20260609-ios-xctest-floor-optimized/xctest-shim/xctest-shim-13","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
34
+ {"tool":"xctest-shim","run":14,"status":"ok","durationMs":864,"traceDir":"traces/public-benchmarks/20260609-ios-xctest-floor-optimized/xctest-shim/xctest-shim-14","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
35
+ {"tool":"xctest-shim","run":15,"status":"ok","durationMs":823,"traceDir":"traces/public-benchmarks/20260609-ios-xctest-floor-optimized/xctest-shim/xctest-shim-15","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
36
+ {"tool":"xctest-shim","run":16,"status":"ok","durationMs":861,"traceDir":"traces/public-benchmarks/20260609-ios-xctest-floor-optimized/xctest-shim/xctest-shim-16","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
37
+ {"tool":"xctest-shim","run":17,"status":"ok","durationMs":862,"traceDir":"traces/public-benchmarks/20260609-ios-xctest-floor-optimized/xctest-shim/xctest-shim-17","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
38
+ {"tool":"xctest-shim","run":18,"status":"ok","durationMs":878,"traceDir":"traces/public-benchmarks/20260609-ios-xctest-floor-optimized/xctest-shim/xctest-shim-18","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
39
+ {"tool":"xctest-shim","run":19,"status":"ok","durationMs":865,"traceDir":"traces/public-benchmarks/20260609-ios-xctest-floor-optimized/xctest-shim/xctest-shim-19","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
40
+ {"tool":"xctest-shim","run":20,"status":"ok","durationMs":865,"traceDir":"traces/public-benchmarks/20260609-ios-xctest-floor-optimized/xctest-shim/xctest-shim-20","platform":"ios","device":"booted","appId":"com.example.mobiletest","scenario":"examples/ios-smoke.json","appBuild":"generated-ios-demo-20260609"}
@@ -0,0 +1,36 @@
1
+ # Benchmark Evidence
2
+
3
+ This directory contains public-safe benchmark evidence collected from
4
+ reproducible ZMR demo apps.
5
+
6
+ Evidence here is intentionally narrow:
7
+
8
+ - It records the command, platform, runner version, run count, pass rate, and
9
+ duration summary.
10
+ - It does not claim ZMR is faster than another tool unless an equivalent
11
+ baseline was collected on the same app build, device state, and scenario.
12
+ - Raw local traces are not committed because generated reports and JUnit files
13
+ can include absolute local paths. Public rows are sanitized before commit.
14
+
15
+ ## Evidence Packs
16
+
17
+ - [Benchmark Lab v1](benchmark-lab-v1.md): public fixture, timing-mode,
18
+ runner-adapter, and claim-rule plan for framework-level evidence.
19
+ - [2026-06-09 iOS simulator demo](2026-06-09-ios-demo.md): 20 repeated runs of
20
+ the public iOS smoke scenario on a booted simulator.
21
+ - [2026-06-09 iOS simulator ZMR vs Maestro comparison](2026-06-09-ios-maestro-comparison.md):
22
+ command-level comparison against Maestro on the same generated iOS demo app.
23
+ - [2026-06-09 iOS simulator ZMR vs Appium comparison](2026-06-09-ios-appium-comparison.md):
24
+ command-level comparison against Appium on the same generated iOS demo app.
25
+ - [2026-06-09 iOS simulator workflow comparison](2026-06-09-ios-workflow-comparison.md):
26
+ longer profile, catalog, save, and review workflow on the generated iOS demo
27
+ app.
28
+ - [2026-06-09 Android emulator workflow](2026-06-09-android-workflow.md):
29
+ 20 repeated ZMR runs of the generated Android workflow demo app.
30
+ - React Native/Expo fixture: generated app and ZMR workflow scenarios are
31
+ available through `zmr-create-react-native-expo-demo-app`; public timing rows
32
+ are still pending.
33
+ - [2026-06-09 iOS simulator XCTest shim floor](2026-06-09-ios-xctest-floor.md):
34
+ native-path floor for the optimized iOS shim-backed smoke flow.
35
+ - [2026-06-09 framework baseline status](2026-06-09-framework-baseline-status.md):
36
+ status for Detox, Flutter, Espresso, and other framework-specific baselines.