rnxsim 0.0.0 → 0.1.313
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/LICENSE +21 -0
- package/README.md +512 -0
- package/detox/colors.ts +54 -0
- package/detox/config-loader.ts +135 -0
- package/detox/element-types.ts +39 -0
- package/detox/expectations.ts +537 -0
- package/detox/gestures.ts +480 -0
- package/detox/index.ts +2118 -0
- package/detox/jest-preset.cjs +51 -0
- package/detox/jest-setup-after-env.cjs +18 -0
- package/detox/matchers.ts +30 -0
- package/detox/motion-change.cjs +109 -0
- package/detox/motion-change.d.cts +35 -0
- package/detox/navigation.ts +43 -0
- package/detox/screenshots/animated-color-test-rest-norngh.png +0 -0
- package/detox/screenshots/color-test-after-drag-norngh.png +0 -0
- package/detox/screenshots/color-test-rest-norngh.png +0 -0
- package/detox/screenshots/theme-blue-toggle.png +0 -0
- package/detox/screenshots/theme-blue.png +0 -0
- package/detox/screenshots/theme-red-toggle.png +0 -0
- package/detox/screenshots/theme-red.png +0 -0
- package/dist-cli/bin.js +15 -0
- package/dist-cli/chunks/agent-XZ2KTPCU.js +48 -0
- package/dist-cli/chunks/agent-wrapper-JJYYW2WH.js +17 -0
- package/dist-cli/chunks/app-fonts-IXRNQG6B.js +4 -0
- package/dist-cli/chunks/assert-54T5SK5F.js +49 -0
- package/dist-cli/chunks/auth-FI5UDI45.js +12 -0
- package/dist-cli/chunks/beta-JV6UKADW.js +4 -0
- package/dist-cli/chunks/camera-VL73YIKP.js +22 -0
- package/dist-cli/chunks/chunk-2D2UPBBR.js +4 -0
- package/dist-cli/chunks/chunk-2YR5BGA5.js +5 -0
- package/dist-cli/chunks/chunk-3NV2NCNX.js +4 -0
- package/dist-cli/chunks/chunk-46EUUFJ5.js +4 -0
- package/dist-cli/chunks/chunk-4NPPOV2N.js +5 -0
- package/dist-cli/chunks/chunk-5DHC6KHQ.js +7 -0
- package/dist-cli/chunks/chunk-5TEF3ET3.js +74 -0
- package/dist-cli/chunks/chunk-5TPRP5QT.js +4 -0
- package/dist-cli/chunks/chunk-5YJCOWCH.js +4 -0
- package/dist-cli/chunks/chunk-7GN3LVWB.js +4 -0
- package/dist-cli/chunks/chunk-BBULZ7CG.js +568 -0
- package/dist-cli/chunks/chunk-BTWORNNG.js +71 -0
- package/dist-cli/chunks/chunk-D4FFVGI5.js +5 -0
- package/dist-cli/chunks/chunk-DCEMHR2Y.js +4 -0
- package/dist-cli/chunks/chunk-DZS6WPUI.js +4 -0
- package/dist-cli/chunks/chunk-F5ZRSS3C.js +3 -0
- package/dist-cli/chunks/chunk-FSUYIVJ6.js +9 -0
- package/dist-cli/chunks/chunk-G2WW6L2C.js +23 -0
- package/dist-cli/chunks/chunk-GASE6UBA.js +4 -0
- package/dist-cli/chunks/chunk-GGRX24GF.js +142 -0
- package/dist-cli/chunks/chunk-HI5TFJWN.js +5 -0
- package/dist-cli/chunks/chunk-IJ5CAZZC.js +5 -0
- package/dist-cli/chunks/chunk-IJO63TDP.js +4 -0
- package/dist-cli/chunks/chunk-KTHV3RUS.js +26 -0
- package/dist-cli/chunks/chunk-LF2ZVT7O.js +6 -0
- package/dist-cli/chunks/chunk-MJRLLB4R.js +38 -0
- package/dist-cli/chunks/chunk-NFK7T35W.js +4 -0
- package/dist-cli/chunks/chunk-NMF2ZMZQ.js +15 -0
- package/dist-cli/chunks/chunk-OHAZNXLK.js +4 -0
- package/dist-cli/chunks/chunk-OVFJFXUD.js +101 -0
- package/dist-cli/chunks/chunk-OZSSI4WN.js +28 -0
- package/dist-cli/chunks/chunk-QKDWYITG.js +25 -0
- package/dist-cli/chunks/chunk-RSZWCKNT.js +30 -0
- package/dist-cli/chunks/chunk-RTN5C5RL.js +4 -0
- package/dist-cli/chunks/chunk-TIVZIMMW.js +4 -0
- package/dist-cli/chunks/chunk-TZFFR3SD.js +7 -0
- package/dist-cli/chunks/chunk-UC6U3MML.js +5 -0
- package/dist-cli/chunks/chunk-VFCMSYZK.js +6 -0
- package/dist-cli/chunks/chunk-VNQEB4L7.js +5 -0
- package/dist-cli/chunks/chunk-VZXWHRUZ.js +983 -0
- package/dist-cli/chunks/chunk-W6K4EFPH.js +107 -0
- package/dist-cli/chunks/chunk-WEXDAC74.js +4 -0
- package/dist-cli/chunks/chunk-WF3T4SVI.js +14 -0
- package/dist-cli/chunks/chunk-WINYQ44O.js +4 -0
- package/dist-cli/chunks/chunk-WMIIKMGK.js +10 -0
- package/dist-cli/chunks/chunk-WUSWBCWA.js +507 -0
- package/dist-cli/chunks/chunk-WWZIXIRD.js +4 -0
- package/dist-cli/chunks/chunk-XEVZYVIW.js +766 -0
- package/dist-cli/chunks/chunk-YDGQTMQL.js +4 -0
- package/dist-cli/chunks/chunk-YIFT42WN.js +4 -0
- package/dist-cli/chunks/chunk-ZMJD5GEC.js +125 -0
- package/dist-cli/chunks/cleanup-P27PA6JI.js +25 -0
- package/dist-cli/chunks/cli-version-WWLPBDQ7.js +4 -0
- package/dist-cli/chunks/compat-ZD65FED3.js +20 -0
- package/dist-cli/chunks/config-XMJRNM2A.js +13 -0
- package/dist-cli/chunks/control-KMIQT3QP.js +4 -0
- package/dist-cli/chunks/daemon-G2ME7NLB.js +4 -0
- package/dist-cli/chunks/debug-PT4HOP7N.js +200 -0
- package/dist-cli/chunks/desktop-S3FG72AK.js +31 -0
- package/dist-cli/chunks/detox-B3D4IFCN.js +52 -0
- package/dist-cli/chunks/device-XBNDSB2R.js +18 -0
- package/dist-cli/chunks/diagnose-HMQXJE5N.js +43 -0
- package/dist-cli/chunks/disk-cleanup-BLCZ5BSZ.js +4 -0
- package/dist-cli/chunks/drivers-LDECZGP2.js +4 -0
- package/dist-cli/chunks/film-BJGTBYZB.js +74 -0
- package/dist-cli/chunks/flow-UEQNVTU7.js +4 -0
- package/dist-cli/chunks/help-T5FYSVGB.js +4 -0
- package/dist-cli/chunks/hidden-runtime-alias-ANOYADHM.js +4 -0
- package/dist-cli/chunks/home-paths-GT3LFNOR.js +4 -0
- package/dist-cli/chunks/inspect-ZA6XF5LD.js +4 -0
- package/dist-cli/chunks/install-desktop-TIMUDHPL.js +4 -0
- package/dist-cli/chunks/login-FJ737MWG.js +28 -0
- package/dist-cli/chunks/logout-ZCNMMHMY.js +4 -0
- package/dist-cli/chunks/maestro-SZTNKLDF.js +104 -0
- package/dist-cli/chunks/maestro-generate-DCFAIZ4H.js +36 -0
- package/dist-cli/chunks/mode-GRMQCRXR.js +26 -0
- package/dist-cli/chunks/optional-demo-registry-W36EWFFB.js +4 -0
- package/dist-cli/chunks/perf-QYBAAUZG.js +48 -0
- package/dist-cli/chunks/permissions-3QCQ6VF4.js +13 -0
- package/dist-cli/chunks/record-QPPC2S4E.js +72 -0
- package/dist-cli/chunks/report-issue-7NMFP4HK.js +29 -0
- package/dist-cli/chunks/runtime-XOAXMSTU.js +4 -0
- package/dist-cli/chunks/screenshot-command-67AECJFB.js +159 -0
- package/dist-cli/chunks/screenshot-layers-ASWBYPJL.js +20 -0
- package/dist-cli/chunks/screenshots-capture-PXA3HFQK.js +42 -0
- package/dist-cli/chunks/serve-BI2NBAXG.js +44 -0
- package/dist-cli/chunks/setup-7DWPMRSB.js +32 -0
- package/dist-cli/chunks/skills-S3Y22TUA.js +50 -0
- package/dist-cli/chunks/storage-XUIMJWAJ.js +37 -0
- package/dist-cli/chunks/store-JTHEJLAZ.js +4 -0
- package/dist-cli/chunks/telemetry-ZYJGD2DB.js +4 -0
- package/dist-cli/chunks/timeline-TMPLQPSP.js +24 -0
- package/dist-cli/chunks/upgrade-7HDSIM7K.js +7 -0
- package/dist-cli/chunks/upload-GMSZPWM6.js +4 -0
- package/dist-cli/chunks/version-HOCHZ37L.js +6 -0
- package/dist-cli/chunks/web-DG3WBYD3.js +4 -0
- package/dist-cli/chunks/what-happened-XFVUTZR7.js +25 -0
- package/dist-lib/agent-daemon-client.cjs +468 -0
- package/dist-lib/agent-events.cjs +48 -0
- package/dist-lib/agent-identity.cjs +53 -0
- package/dist-lib/agent-sessions.cjs +725 -0
- package/dist-lib/attached-projects.cjs +526 -0
- package/dist-lib/auth/shared-session.cjs +195 -0
- package/dist-lib/backend-origin.cjs +70 -0
- package/dist-lib/beta.cjs +41 -0
- package/dist-lib/beta.mjs +13 -0
- package/dist-lib/bridge-constants.cjs +161 -0
- package/dist-lib/cli-constants.cjs +32 -0
- package/dist-lib/config.cjs +96 -0
- package/dist-lib/detox/index.cjs +2863 -0
- package/dist-lib/detox/jest-preset.cjs +51 -0
- package/dist-lib/dev-bundle-resolution.cjs +223 -0
- package/dist-lib/home-paths.cjs +421 -0
- package/dist-lib/host/bridge-host.cjs +5600 -0
- package/dist-lib/host/fetch-proxy-handler.cjs +373 -0
- package/dist-lib/host/fetch-proxy-overrides.cjs +63 -0
- package/dist-lib/host/fetch-proxy-overrides.mjs +37 -0
- package/dist-lib/host/websocket-proxy.cjs +214 -0
- package/dist-lib/index.cjs +513 -0
- package/dist-lib/jump-to-source-babel.cjs +93 -0
- package/dist-lib/menu.cjs +620 -0
- package/dist-lib/menu.mjs +581 -0
- package/dist-lib/metro.cjs +297 -0
- package/dist-lib/profiles.cjs +246 -0
- package/dist-lib/public-brand.cjs +39 -0
- package/dist-lib/render-mode.cjs +54 -0
- package/dist-lib/scripts/dev-server-scanner.cjs +1034 -0
- package/dist-lib/sdk.cjs +2333 -0
- package/dist-lib/sdk.mjs +2240 -0
- package/dist-lib/skills.cjs +23922 -0
- package/dist-lib/vite.cjs +358 -0
- package/package.json +189 -18
- package/scripts/dev-server-scanner.ts +941 -0
- package/scripts/optional-demo-registry.ts +113 -0
- package/scripts/postinstall.cjs +3 -0
- package/scripts/preuninstall.cjs +118 -0
- package/skills/contrast/SKILL.md +171 -0
- package/skills/rnx-debug/SKILL.md +425 -0
- package/skills/rnx-perf/SKILL.md +295 -0
- package/skills/rnx-setup/SKILL.md +160 -0
- package/skills/rnx-test/SKILL.md +292 -0
- package/skills/rnx-visual/SKILL.md +122 -0
- package/src/agent-daemon-client.ts +410 -0
- package/src/agent-events.ts +71 -0
- package/src/agent-identity.ts +23 -0
- package/src/agent-prompt.ts +71 -0
- package/src/agent-sessions.ts +573 -0
- package/src/attached-projects.ts +539 -0
- package/src/auth/shared-session.ts +204 -0
- package/src/backend-origin.ts +49 -0
- package/src/beta.ts +19 -0
- package/src/bridge-constants.ts +171 -0
- package/src/browser-cache.ts +16 -0
- package/src/cli-constants.ts +1 -0
- package/src/cli-version.ts +32 -0
- package/src/codex-client.ts +215 -0
- package/src/config.ts +134 -0
- package/src/dev-bundle-resolution.ts +236 -0
- package/src/disk-cleanup.ts +466 -0
- package/src/home-paths.ts +552 -0
- package/src/host/agent-host.ts +666 -0
- package/src/host/bridge-host.ts +2626 -0
- package/src/host/fetch-proxy-handler.ts +397 -0
- package/src/host/fetch-proxy-overrides.ts +51 -0
- package/src/host/open-url.ts +89 -0
- package/src/host/websocket-proxy.ts +210 -0
- package/src/index.ts +12 -705
- package/src/jump-to-source-babel.ts +135 -0
- package/src/menu.ts +734 -0
- package/src/metro-plugin.ts +139 -0
- package/src/native-dev-bundle-url.ts +96 -0
- package/src/native-seam-manifest.ts +341 -0
- package/src/plist.ts +27 -0
- package/src/poll-until.ts +92 -0
- package/src/profiles.ts +179 -0
- package/src/public-brand.ts +9 -0
- package/src/render-mode.ts +27 -0
- package/src/runtime-assets.ts +228 -0
- package/src/runtime-delivery.ts +54 -0
- package/src/screenshots/compose.ts +422 -0
- package/src/screenshots/frame-compose.ts +454 -0
- package/src/screenshots/orchestrate.ts +256 -0
- package/src/screenshots/org-deck.ts +91 -0
- package/src/screenshots/registry.ts +58 -0
- package/src/screenshots/schema.ts +364 -0
- package/src/sdk.ts +7 -0
- package/src/settings-bundle.ts +418 -0
- package/src/skills/builtin/a11y-review.ts +132 -0
- package/src/skills/builtin/compat-check.ts +71 -0
- package/src/skills/builtin/maestro-test.ts +121 -0
- package/src/skills/builtin/perf-profile.ts +90 -0
- package/src/skills/builtin/screenshot-all.ts +52 -0
- package/src/skills/builtin/visual-diff.ts +100 -0
- package/src/skills/registry.ts +107 -0
- package/src/skills/types.ts +41 -0
- package/src/team-machine-prompt.ts +73 -0
- package/src/vite-plugin-one.ts +190 -0
- package/src/vite-plugin.ts +1750 -0
- package/src/worklets-babel.ts +134 -0
|
@@ -0,0 +1,425 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rnx-debug
|
|
3
|
+
description: Debug rendering, animation, gesture, performance, and accessibility issues in a React Native app running under rnx. Reach for this whenever an animation looks wrong (janky, stutters, snaps, only updates once, or doesn't move at all), a swipe/transition/gesture misbehaves or feels broken, scrolling drops frames or feels slow, the UI renders the wrong tree/props, or a screen reader can't reach something — and drive the rnxsim CLI debug tooling first, not screenshots or ad-hoc logging.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# rnx debug
|
|
7
|
+
|
|
8
|
+
the foundational skill for "something is wrong with my app in rnx".
|
|
9
|
+
covers debugging, performance, and accessibility — three branches that
|
|
10
|
+
share the same CLI primitives, the same auto-settling contract, and the
|
|
11
|
+
same diff/snapshot workflow. start here for any rendering, interaction,
|
|
12
|
+
event-order, or correctness question. for pixel-level rendering fidelity
|
|
13
|
+
load `/rnx-visual` instead.
|
|
14
|
+
|
|
15
|
+
> needs a connected, pinned sim. if `rnxsim describe` errors, load
|
|
16
|
+
> `/rnx-setup` first.
|
|
17
|
+
|
|
18
|
+
## principle — drive the CLI, don't probe by hand
|
|
19
|
+
|
|
20
|
+
for any rendering, animation, gesture, or interaction bug, reach for the
|
|
21
|
+
rnxsim CLI debug tooling **first** — `describe` and `find` to read the
|
|
22
|
+
tree, `debug snapshot` + `debug diff` to capture before/after, `debug
|
|
23
|
+
recent` on a channel and `perf shell` for frame-by-frame stats, and the
|
|
24
|
+
timeline for "what just happened". **do not** debug these by eye with
|
|
25
|
+
screenshots, sprinkle `console.log` through the render path, or spin up a
|
|
26
|
+
one-off browser-automation script. the canvas has no DOM to inspect, and a
|
|
27
|
+
CLI capture is reproducible, diffable, and shareable in a way a screenshot
|
|
28
|
+
never is.
|
|
29
|
+
|
|
30
|
+
if the existing CLI tools don't capture the issue cleanly — the animation
|
|
31
|
+
is too fast to read, the signal you need isn't on any channel, the
|
|
32
|
+
interaction spans a boundary the timeline doesn't section — the right move
|
|
33
|
+
is to **improve the debug tooling**, not to paper over it with throwaway
|
|
34
|
+
probes. add a durable, channel-gated, start/stop instrument that's off by
|
|
35
|
+
default (so baseline performance is untouched) and emits exactly the signal
|
|
36
|
+
you're chasing. a good capture command is one-shot reproducible, every
|
|
37
|
+
agent after you benefits from it, and the same capture can become a
|
|
38
|
+
regression test. a pile of ad-hoc logs helps no one and gets deleted.
|
|
39
|
+
|
|
40
|
+
## route in
|
|
41
|
+
|
|
42
|
+
- "my app renders wrong / wrong props / wrong tree" → [debugging](#branch--debugging)
|
|
43
|
+
- "feels slow / drops frames / janks on scroll" → [performance](#branch--performance)
|
|
44
|
+
- "screen reader can't find this / wrong label / tap target too small" → [accessibility](#branch--accessibility)
|
|
45
|
+
- "I want to see what just happened" (ephemeral toast, async navigation,
|
|
46
|
+
fetch + alert sequence) → [the timeline](#the-timeline-what-happened)
|
|
47
|
+
- "I want pixel-level fidelity to iOS" → load `/rnx-visual`
|
|
48
|
+
- "I want to author a test" → load `/rnx-test`
|
|
49
|
+
|
|
50
|
+
## anti-patterns (apply to every branch)
|
|
51
|
+
|
|
52
|
+
- **`a1`/`a2`/`b0` style ids mean rnxsim sims, never browser tabs.** when a user
|
|
53
|
+
says "look at a3", that's the `rnxsim list` sim id. do not open chrome
|
|
54
|
+
MCP unless the user explicitly says "use chrome" — the canvas has no
|
|
55
|
+
DOM to inspect anyway.
|
|
56
|
+
- **the CLI auto-settles. don't add `sleep`.** every read waits up to
|
|
57
|
+
1800 ms for in-flight transitions to start; every write polls layout
|
|
58
|
+
hash until stable. if a read keeps racing its write, the fix is **never**
|
|
59
|
+
a blind `sleep` — it's `wait selector`, `wait ready`, `wait idle`, or
|
|
60
|
+
fixing the underlying animation-completion signal.
|
|
61
|
+
- **prefer `--testid` over text matching.** text drifts under i18n, copy
|
|
62
|
+
changes, and duplicate strings. add `testID` during implementation and
|
|
63
|
+
query against it.
|
|
64
|
+
- **pin a sim once.** if more than one is live, an unpinned command
|
|
65
|
+
refuses to choose. run `rnxsim use <id>` at the start of the workflow.
|
|
66
|
+
- **keep one sim and reuse its browser tab.** before `rnxsim open`, run
|
|
67
|
+
`rnxsim list --all`. pin the target and use `rnxsim do reload`; a plain
|
|
68
|
+
`rnxsim open <target>` also navigates the saved sim. reserve `--new` for a
|
|
69
|
+
genuinely concurrent sim. repeated browser trees consume memory and CPU on a
|
|
70
|
+
shared machine.
|
|
71
|
+
- **`debug eval` is an escape hatch.** if a top-level command feels
|
|
72
|
+
broken or missing, file an issue — every agent after you benefits from
|
|
73
|
+
a better CLI, not a pile of ad-hoc scripts.
|
|
74
|
+
- **sweep `get errors` and `get requests` after every repro.** the
|
|
75
|
+
one-line summary tells you the count grew; you still have to *look at
|
|
76
|
+
them*. a "fixed" behavior with a new console error is not fixed.
|
|
77
|
+
- **"found a testID" is not done.** done is: reliable repro + identified
|
|
78
|
+
root cause (specific node + prop, or event + handler) + verified fix.
|
|
79
|
+
|
|
80
|
+
## the timeline ("what happened")
|
|
81
|
+
|
|
82
|
+
between two CLI calls, things happen invisibly — toasts flash, keyboards
|
|
83
|
+
open and close, screens push and pop, alerts fire and dismiss, async
|
|
84
|
+
fetches resolve. the timeline records them so you can ask "what
|
|
85
|
+
happened" instead of racing the UI with `find`.
|
|
86
|
+
|
|
87
|
+
```sh
|
|
88
|
+
rnxsim timeline start # arm recording (cheap kinds default-on)
|
|
89
|
+
# reproduce the flow
|
|
90
|
+
rnxsim what-happened # events since the last CLI call
|
|
91
|
+
rnxsim what-happened --since 10s # absolute window
|
|
92
|
+
rnxsim what-happened --kinds toast,fetch # filter to a few kinds
|
|
93
|
+
rnxsim what-happened --summary # one-line counts
|
|
94
|
+
rnxsim what-happened --flow # section events by screen/route
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
semantic kinds the timeline understands: `keyboard`, `screen`, `route`,
|
|
98
|
+
`alert`, `actionsheet`, `picker`, `notification`, `toast`, `scroll`,
|
|
99
|
+
`gesture`, `text-input`, `reanimated`, `animation`, `fetch`, `console`,
|
|
100
|
+
`app-launch`, `shell`. cheap kinds record by default; heavier kinds
|
|
101
|
+
(scroll, gesture, text-input, reanimated, animation) opt in via
|
|
102
|
+
`rnxsim timeline start scroll,gesture,…`.
|
|
103
|
+
|
|
104
|
+
every other CLI command also prints a one-line footer for events since
|
|
105
|
+
the last call — that's the headline indicator. when the footer is empty,
|
|
106
|
+
there's nothing new to look at; when it says `since last: 1 error · 1
|
|
107
|
+
toast · 1 screen push`, run `rnxsim what-happened` to see the detail.
|
|
108
|
+
|
|
109
|
+
> reach for the timeline first when the question involves *something
|
|
110
|
+
> that appeared briefly and disappeared*. it's faster than a screenshot
|
|
111
|
+
> and tells you the duration too.
|
|
112
|
+
|
|
113
|
+
## automatic settling — when you actually need a manual wait
|
|
114
|
+
|
|
115
|
+
every CLI command already participates in a two-phase settle. you only
|
|
116
|
+
need a manual wait when:
|
|
117
|
+
|
|
118
|
+
1. the CLI explicitly printed `⚠ auto-wait timed out after Nms — next
|
|
119
|
+
command may see mid-animation state` *and* your next read depends on
|
|
120
|
+
the animation finishing.
|
|
121
|
+
2. the transition is longer than ~400 ms (full stack navigation,
|
|
122
|
+
crossfades, video first-frame, network-backed render).
|
|
123
|
+
3. you want `--strict` settle, which also requires animation flags to
|
|
124
|
+
clear — only safe for apps with no perpetual background animation
|
|
125
|
+
(no pulsing dots, no shimmer, no looping Lottie).
|
|
126
|
+
|
|
127
|
+
```sh
|
|
128
|
+
rnxsim do settle 5 # wait up to 5s for layout stability
|
|
129
|
+
rnxsim wait idle --max-ms 5000 # same thing under the `wait` verb
|
|
130
|
+
rnxsim wait idle --strict # also require animation flags clear
|
|
131
|
+
rnxsim do tap-id play --no-wait # skip auto-settle on one command
|
|
132
|
+
SOOTSIM_NO_AUTO_WAIT=1 rnxsim ... # disable auto-settle for a lane
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## branch — debugging
|
|
136
|
+
|
|
137
|
+
the playbook for "wrong tree / wrong props / wrong handler":
|
|
138
|
+
|
|
139
|
+
```sh
|
|
140
|
+
rnxsim describe # what's on screen now
|
|
141
|
+
rnxsim get errors 5 # any console smoke?
|
|
142
|
+
rnxsim find --testid <node> # locate the suspect
|
|
143
|
+
rnxsim debug snapshot before
|
|
144
|
+
# reproduce
|
|
145
|
+
rnxsim debug snapshot after
|
|
146
|
+
rnxsim debug diff before after # structural diff: what changed?
|
|
147
|
+
rnxsim what-happened # timeline events during the repro
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
for nested scroll ownership or momentum transfer, compare the shell's resolved
|
|
151
|
+
gesture chain with the published scroll registry:
|
|
152
|
+
|
|
153
|
+
```sh
|
|
154
|
+
rnxsim debug state scroll-input
|
|
155
|
+
rnxsim debug state scroll-mirror
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
reading `describe` output:
|
|
159
|
+
|
|
160
|
+
```
|
|
161
|
+
[button] "Sign in" #loginButton @(0,347) 402x44 [bg:#006AFF fg:#fff] (tap)
|
|
162
|
+
<text> "Forgot?" @(341,287) 55x28 [fg:#666 fontSize:14]
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
format: `[type] "text" #testID @(x,y) WxH [styles] (flags)`. coordinates
|
|
166
|
+
are points (CSS pixels), origin top-left, parent-relative.
|
|
167
|
+
|
|
168
|
+
for transitions, alerts, native UI, or anything spanning the shell ↔
|
|
169
|
+
tenant boundary, lean on the timeline before reaching for traces:
|
|
170
|
+
|
|
171
|
+
```sh
|
|
172
|
+
rnxsim timeline start
|
|
173
|
+
# reproduce the launch / dismiss / alert
|
|
174
|
+
rnxsim what-happened --kinds shell,alert,screen,animation
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
you're done when:
|
|
178
|
+
|
|
179
|
+
1. repro is reliable (same input → same output)
|
|
180
|
+
2. root cause is identified (specific node + prop, or event + handler,
|
|
181
|
+
not "something in the navigation stack")
|
|
182
|
+
3. fix re-verified through the same `snapshot → reproduce → diff` loop
|
|
183
|
+
|
|
184
|
+
## branch — performance
|
|
185
|
+
|
|
186
|
+
```sh
|
|
187
|
+
rnxsim perf shell start # arm capture (also clears prior frames)
|
|
188
|
+
# reproduce the slow interaction
|
|
189
|
+
rnxsim perf shell stop # full report, including worst frames
|
|
190
|
+
rnxsim perf shell stop --json # machine-readable summary
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
`perf shell` output:
|
|
194
|
+
|
|
195
|
+
```
|
|
196
|
+
frames: 847
|
|
197
|
+
total: 14123ms
|
|
198
|
+
avg: 16.7ms
|
|
199
|
+
max: 42ms (⚠ dropped frames)
|
|
200
|
+
p95: 22.3ms
|
|
201
|
+
layout frames: 123
|
|
202
|
+
layout avg: 2.1ms
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
frame budget: target **8 ms / frame (120 fps)** — render <4 ms, layout
|
|
206
|
+
<2 ms, JS/react <2 ms. heavier paints can fall back to the 16 ms / 60 fps
|
|
207
|
+
budget. **p95 >20 ms is visible jank for a scrolling surface.**
|
|
208
|
+
|
|
209
|
+
profiling a whole flow:
|
|
210
|
+
|
|
211
|
+
```sh
|
|
212
|
+
rnxsim maestro test .maestro/scroll-feed.yaml --profile # per-step + frame stats
|
|
213
|
+
rnxsim perf cpu --duration 5 --output /tmp/trace.cpuprofile # sampled CPU
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
common patterns → first probe:
|
|
217
|
+
|
|
218
|
+
| symptom | likely | next |
|
|
219
|
+
| --- | --- | --- |
|
|
220
|
+
| scroll jank | layout firing during scroll | `debug enable layout` + `debug recent layout 40` |
|
|
221
|
+
| anim stutter | `Animated.Value` on `width`/`height` | switch to `transform: [{ scale }]` or `translate` |
|
|
222
|
+
| first-tap lag | font / image still loading | `get requests` + `debug state image` |
|
|
223
|
+
| memory growth | live animation drivers not cleaned up | `debug state animations` |
|
|
224
|
+
| slow initial render | many text measurements | `debug recent text` on first paint |
|
|
225
|
+
|
|
226
|
+
debug channels that help, but cost 1–3 ms/frame on their own — enable
|
|
227
|
+
only what you're investigating:
|
|
228
|
+
|
|
229
|
+
```sh
|
|
230
|
+
rnxsim debug enable layout,onlayout,render,animated
|
|
231
|
+
# reproduce
|
|
232
|
+
rnxsim debug recent layout 20 # last 20 layout events
|
|
233
|
+
rnxsim debug recent render 20 # last 20 draw passes
|
|
234
|
+
rnxsim debug disable layout,onlayout,render,animated
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
you're done when: a p95 number for the interaction + named hot path +
|
|
238
|
+
remeasured (a fresh `perf start` between runs clears the buffer) and the
|
|
239
|
+
number moved.
|
|
240
|
+
|
|
241
|
+
watch out for:
|
|
242
|
+
|
|
243
|
+
- **dynamic format strings bust the text-measurement cache.** `${count}
|
|
244
|
+
messages` re-measures every change — render the number and the word as
|
|
245
|
+
separate `<Text>` nodes.
|
|
246
|
+
- **`--strict` settle hangs forever on perpetual animation.** anything
|
|
247
|
+
with a pulsing dot or looping Lottie will never go quiet under
|
|
248
|
+
`--strict`. use plain `wait idle` there.
|
|
249
|
+
- **p95 over a single run is noise.** take three runs minimum.
|
|
250
|
+
|
|
251
|
+
## branch — accessibility
|
|
252
|
+
|
|
253
|
+
```sh
|
|
254
|
+
rnxsim get a11y # roles, labels, hints, and target geometry
|
|
255
|
+
rnxsim get layout --styling # boxes, styles, and native pixel contrast
|
|
256
|
+
rnxsim describe --a11y # inline a11y info on every node
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
native styled layout reads rendered pixels rather than inferring contrast from
|
|
260
|
+
tokens. it compares the normal frame with one CanvasKit capture where text is
|
|
261
|
+
suppressed and adds each text score to the existing layout row and issue list.
|
|
262
|
+
|
|
263
|
+
contrast summary format:
|
|
264
|
+
|
|
265
|
+
```
|
|
266
|
+
#loginButton @(24,347) 120x24 font:16 color:#777 contrast:1.4/4.5 FAIL on:#888888 "Sign in"
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
finding offenders fast:
|
|
270
|
+
|
|
271
|
+
```sh
|
|
272
|
+
rnxsim find --no-label # interactive nodes missing label
|
|
273
|
+
rnxsim find --no-role # interactive nodes missing role
|
|
274
|
+
rnxsim find --pressable --max-dim 44 # undersized tap targets
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
what gets checked:
|
|
278
|
+
|
|
279
|
+
- **missing labels** — interactive nodes without `accessibilityLabel`
|
|
280
|
+
- **missing roles** — `Pressable`/`Touchable` without `accessibilityRole`
|
|
281
|
+
- **missing hints** — complex interactions without `accessibilityHint`
|
|
282
|
+
- **touch target size** — tappable nodes with hitSlop-expanded rect <44×44
|
|
283
|
+
- **contrast** — run `rnxsim get layout --styling`; it samples final text and
|
|
284
|
+
text-suppressed background pixels, including gradients and composited opacity
|
|
285
|
+
- **label / visible-text mismatch** — label that reads differently from
|
|
286
|
+
the text VoiceOver would fall back to (often a translation bug)
|
|
287
|
+
- **duplicate labels** — two reachable nodes with identical labels on
|
|
288
|
+
one screen ("Open" + "Open" leaves no way to disambiguate)
|
|
289
|
+
|
|
290
|
+
triage order:
|
|
291
|
+
|
|
292
|
+
- **P0** — interactive node with no label or no role (blocks screen
|
|
293
|
+
reader entirely)
|
|
294
|
+
- **P1** — tap target <44×44, duplicate labels
|
|
295
|
+
- **P2** — contrast, label/visible-text mismatch
|
|
296
|
+
|
|
297
|
+
fix → verify loop (the same shape as debugging):
|
|
298
|
+
|
|
299
|
+
```sh
|
|
300
|
+
rnxsim get a11y > before-a11y.txt
|
|
301
|
+
rnxsim get layout --styling --json > before-layout.json
|
|
302
|
+
# apply the fix
|
|
303
|
+
rnxsim get a11y > after-a11y.txt
|
|
304
|
+
rnxsim get layout --styling --json > after-layout.json
|
|
305
|
+
diff before-a11y.txt after-a11y.txt
|
|
306
|
+
diff before-layout.json after-layout.json
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
fixing common cases:
|
|
310
|
+
|
|
311
|
+
```tsx
|
|
312
|
+
// bad: icon button with no accessible name
|
|
313
|
+
<Pressable onPress={onBack}>
|
|
314
|
+
<ChevronLeftIcon />
|
|
315
|
+
</Pressable>
|
|
316
|
+
|
|
317
|
+
// good: labeled + roled + hinted + hitSlop'd
|
|
318
|
+
<Pressable
|
|
319
|
+
onPress={onBack}
|
|
320
|
+
accessibilityRole="button"
|
|
321
|
+
accessibilityLabel="Back"
|
|
322
|
+
accessibilityHint="Returns to the previous screen"
|
|
323
|
+
hitSlop={12} // bumps tap target to 44×44 minimum
|
|
324
|
+
>
|
|
325
|
+
<ChevronLeftIcon />
|
|
326
|
+
</Pressable>
|
|
327
|
+
|
|
328
|
+
// bad: text input with no programmatic label
|
|
329
|
+
<TextInput placeholder="Email" onChangeText={setEmail} />
|
|
330
|
+
|
|
331
|
+
// good: label survives even when placeholder is hidden
|
|
332
|
+
<TextInput
|
|
333
|
+
placeholder="Email"
|
|
334
|
+
accessibilityLabel="Email address"
|
|
335
|
+
onChangeText={setEmail}
|
|
336
|
+
/>
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
watch out for:
|
|
340
|
+
|
|
341
|
+
- **placeholders are not labels.** they disappear after the user types.
|
|
342
|
+
- **hitSlop expands the a11y rect too.** rarely need to make the
|
|
343
|
+
rendered button bigger — `hitSlop={12}` is usually enough.
|
|
344
|
+
- **`accessibilityRole="image"` is not an `alt` tag.** pair it with
|
|
345
|
+
`accessibilityLabel` or VoiceOver reads "image" and nothing else.
|
|
346
|
+
- **`importantForAccessibility="no-hide-descendants"` hides an entire
|
|
347
|
+
subtree.** useful for decorative chrome, dangerous if you forget it.
|
|
348
|
+
|
|
349
|
+
run the screen reader on a real device at least once before shipping —
|
|
350
|
+
labels that read fine on paper often sound robotic ("delete_message_btn_v2"
|
|
351
|
+
type names sneak in).
|
|
352
|
+
|
|
353
|
+
## recovery — common failure modes
|
|
354
|
+
|
|
355
|
+
- **`describe` returns nothing** — no sim pinned, or the app isn't
|
|
356
|
+
loaded. load `/rnx-setup` and re-confirm.
|
|
357
|
+
- **`find` returns multiple matches** — narrow with `--testid`,
|
|
358
|
+
`--visible`, or both.
|
|
359
|
+
- **`perf shell` reports zero frames** — you didn't run `perf shell start`
|
|
360
|
+
first, or the capture window closed before any frame committed.
|
|
361
|
+
- **`get a11y` returns 100+ items** — narrow with `find --role`,
|
|
362
|
+
`find --pressable`, or `find --no-label`; the a11y tree is descriptive and
|
|
363
|
+
intentionally does not invent an `--issues` grading mode.
|
|
364
|
+
- **styled layout cannot capture pixels** — open a tenant app, dismiss system
|
|
365
|
+
overlays, and let the launch transition finish before retrying.
|
|
366
|
+
- **timeline footer keeps showing 1 error but `get errors` is empty** —
|
|
367
|
+
the footer reads "since last cursor advance"; `get errors` is absolute.
|
|
368
|
+
the error already scrolled out of the absolute ring buffer.
|
|
369
|
+
|
|
370
|
+
## reference
|
|
371
|
+
|
|
372
|
+
### finding and interacting
|
|
373
|
+
|
|
374
|
+
```sh
|
|
375
|
+
rnxsim describe # all visible elements with styles
|
|
376
|
+
rnxsim describe button # filter by text/role/label/testID
|
|
377
|
+
rnxsim describe --testid foo # only the subtree under a testID
|
|
378
|
+
rnxsim describe --verbose # include every style property
|
|
379
|
+
|
|
380
|
+
rnxsim find "Sign in" # by text content
|
|
381
|
+
rnxsim find --testid loginButton
|
|
382
|
+
rnxsim find --role button
|
|
383
|
+
rnxsim find --pressable
|
|
384
|
+
rnxsim find --visible # only on-screen nodes
|
|
385
|
+
|
|
386
|
+
rnxsim do tap-id loginButton # tap by testID (preferred)
|
|
387
|
+
rnxsim do tap-text "Submit" # tap by text
|
|
388
|
+
rnxsim do tap 196 400 # tap at coordinates
|
|
389
|
+
rnxsim do type "hello world" # type into focused input
|
|
390
|
+
rnxsim do type-into emailInput "a@b" # focus then type
|
|
391
|
+
rnxsim do key return # special key (return, backspace, …)
|
|
392
|
+
rnxsim do scroll feed-list 0 500 # scroll a testID by dx/dy
|
|
393
|
+
rnxsim do swipe feed-list left # directional swipe
|
|
394
|
+
rnxsim do long-press messageRow 800 # ms hold
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
### errors and requests
|
|
398
|
+
|
|
399
|
+
```sh
|
|
400
|
+
rnxsim get errors 5 # last 5 console errors
|
|
401
|
+
rnxsim get warnings 5
|
|
402
|
+
rnxsim get requests 5 # recent failed requests
|
|
403
|
+
rnxsim logs --since 30s # recent console output
|
|
404
|
+
rnxsim network --since 30s # recent network traffic
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
### snapshots and diff
|
|
408
|
+
|
|
409
|
+
```sh
|
|
410
|
+
rnxsim debug snapshot before
|
|
411
|
+
# interact
|
|
412
|
+
rnxsim debug snapshot after
|
|
413
|
+
rnxsim debug diff before after # added / removed / changed nodes
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
### debug channels
|
|
417
|
+
|
|
418
|
+
useful: `animated`, `layout`, `onlayout`, `render`, `sheets`, `portals`,
|
|
419
|
+
`gesture`, `scroll`, `text`, `image`.
|
|
420
|
+
|
|
421
|
+
```sh
|
|
422
|
+
rnxsim debug enable animated,layout,sheets,portals
|
|
423
|
+
rnxsim debug recent layout 20 # last 20 events on the channel
|
|
424
|
+
rnxsim debug disable animated,layout,sheets,portals
|
|
425
|
+
```
|