rnxsim 0.1.317 → 0.1.319
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/cli/bin.ts +1 -8
- package/cli/commands/debug.ts +1 -8
- package/cli/commands/detox.ts +16 -4
- package/cli/commands/flow.ts +1 -2
- package/cli/commands/inspect/wait-event.ts +1 -1
- package/cli/commands/inspect/wait-selector.ts +1 -1
- package/cli/commands/inspect.ts +56 -33
- package/cli/commands/maestro.ts +1 -1
- package/cli/commands/profile.ts +4 -6
- package/cli/commands/runtime.ts +0 -4
- package/cli/commands/storage.ts +1 -1
- package/cli/commands/telemetry.ts +0 -2
- package/cli/commands/timeline.ts +2 -4
- package/cli/parse-args.ts +0 -3
- package/detox/index.ts +155 -15
- package/detox/jest-preset.cjs +0 -1
- package/dist-cli/bin.js +5 -5
- package/dist-cli/chunks/{agent-EKGLRJEN.js → agent-Q4VAKGOL.js} +2 -2
- package/dist-cli/chunks/{agent-wrapper-FONNWB7J.js → agent-wrapper-Q2O4TR7H.js} +2 -2
- package/dist-cli/chunks/{app-fonts-XPM54HRY.js → app-fonts-B7UP3XTI.js} +2 -2
- package/dist-cli/chunks/{assert-PILHTZRZ.js → assert-NAFO4KMH.js} +2 -2
- package/dist-cli/chunks/{auth-Q2VUD5NQ.js → auth-CNUGYLCX.js} +2 -2
- package/dist-cli/chunks/{beta-P4XLZ3KL.js → beta-GN5BSED6.js} +2 -2
- package/dist-cli/chunks/{camera-O4PEVPI4.js → camera-EJRFUEXV.js} +2 -2
- package/dist-cli/chunks/{chunk-R6DDJVBB.js → chunk-2TNUPISH.js} +2 -2
- package/dist-cli/chunks/{chunk-BJ5CYKA7.js → chunk-3DEQXXSF.js} +4 -4
- package/dist-cli/chunks/{chunk-VB2ZZ4JI.js → chunk-3F3R7BM4.js} +2 -2
- package/dist-cli/chunks/{chunk-CUILVYWI.js → chunk-4UY4JSQ4.js} +1 -1
- package/dist-cli/chunks/chunk-522E7BRF.js +937 -0
- package/dist-cli/chunks/{chunk-NF63TOPI.js → chunk-5ABSWU6L.js} +2 -2
- package/dist-cli/chunks/{chunk-NA4AMR2E.js → chunk-5KXQT465.js} +1 -1
- package/dist-cli/chunks/{chunk-6WG4RQKM.js → chunk-6BGXKWGF.js} +2 -2
- package/dist-cli/chunks/{chunk-67ZR7PU7.js → chunk-72VB52IV.js} +1 -1
- package/dist-cli/chunks/{chunk-JQ4Y2XVT.js → chunk-76EVUPAL.js} +1 -1
- package/dist-cli/chunks/{chunk-OWADERTW.js → chunk-7DABL656.js} +2 -2
- package/dist-cli/chunks/{chunk-WWW5DC3G.js → chunk-7IW3PBRN.js} +2 -2
- package/dist-cli/chunks/{chunk-S23KHLTR.js → chunk-AX7PASOS.js} +2 -2
- package/dist-cli/chunks/{chunk-SZIPYT3D.js → chunk-AZ6S36CJ.js} +2 -2
- package/dist-cli/chunks/{chunk-T6W3B2KA.js → chunk-B27W3QWS.js} +1 -1
- package/dist-cli/chunks/{chunk-GQ3D2D4O.js → chunk-BQEWRZON.js} +1 -1
- package/dist-cli/chunks/{chunk-ADAIY3DX.js → chunk-BSCOA6LL.js} +2 -2
- package/dist-cli/chunks/{chunk-NUSBQSRQ.js → chunk-BVVUWEDG.js} +2 -2
- package/dist-cli/chunks/chunk-DD6F2WOA.js +4 -0
- package/dist-cli/chunks/{chunk-J4MCKLWE.js → chunk-DIADYUIH.js} +4 -4
- package/dist-cli/chunks/{chunk-KO7UG262.js → chunk-GHHVBATM.js} +2 -2
- package/dist-cli/chunks/{chunk-QCQQ2VDW.js → chunk-HCM7K4AU.js} +2 -2
- package/dist-cli/chunks/chunk-HPO2HNJX.js +124 -0
- package/dist-cli/chunks/{chunk-67OCUGZD.js → chunk-IHBAZ6ZJ.js} +2 -2
- package/dist-cli/chunks/{chunk-QGPNBTHT.js → chunk-IJYWC6QT.js} +2 -2
- package/dist-cli/chunks/{chunk-JZXCQEKO.js → chunk-JWAF5GXK.js} +2 -2
- package/dist-cli/chunks/{chunk-LSC2HFAB.js → chunk-JZIFPU64.js} +1 -1
- package/dist-cli/chunks/{chunk-RCPPPW7B.js → chunk-KMOLZN54.js} +1 -1
- package/dist-cli/chunks/{chunk-GMWPCQ63.js → chunk-L5JZXGYY.js} +1 -1
- package/dist-cli/chunks/{chunk-YRVJHPCU.js → chunk-LKO7E4VO.js} +2 -2
- package/dist-cli/chunks/{chunk-WJVNVBAI.js → chunk-M52VGRRN.js} +1 -1
- package/dist-cli/chunks/{chunk-7Q7IQ2SS.js → chunk-PFRV3TNY.js} +2 -2
- package/dist-cli/chunks/{chunk-3G7I72XV.js → chunk-PYDVLJOW.js} +2 -2
- package/dist-cli/chunks/{chunk-ATOUAYJP.js → chunk-QNNCKWZF.js} +1 -1
- package/dist-cli/chunks/{chunk-ODHQKXLB.js → chunk-R4JD7RQ5.js} +2 -2
- package/dist-cli/chunks/chunk-RIRZMX6H.js +4 -0
- package/dist-cli/chunks/{chunk-FIPCJ5OS.js → chunk-RVKU4F4H.js} +1 -1
- package/dist-cli/chunks/{chunk-A3GVXVSG.js → chunk-S5XIMHEZ.js} +2 -2
- package/dist-cli/chunks/{chunk-HJKQ6NEU.js → chunk-SPHYBQAZ.js} +2 -2
- package/dist-cli/chunks/chunk-TJSU45JD.js +4 -0
- package/dist-cli/chunks/{chunk-R6MEMDNB.js → chunk-UGYANOZR.js} +2 -2
- package/dist-cli/chunks/{chunk-W4YHMJOO.js → chunk-VB6FBQBW.js} +2 -2
- package/dist-cli/chunks/{chunk-5XVHBFAT.js → chunk-VLT3KCQT.js} +3 -3
- package/dist-cli/chunks/{chunk-OO5D7IJE.js → chunk-VQJMFDUN.js} +1 -1
- package/dist-cli/chunks/{chunk-EL23MRFL.js → chunk-WUZNWEBT.js} +1 -1
- package/dist-cli/chunks/{chunk-5BYFLVSZ.js → chunk-X2AHIPGY.js} +1 -1
- package/dist-cli/chunks/{chunk-OXSCF4UD.js → chunk-XJHAGKJD.js} +2 -2
- package/dist-cli/chunks/{chunk-RG3CME4Y.js → chunk-YPDFFAE7.js} +2 -2
- package/dist-cli/chunks/{chunk-HF4NZ5SD.js → chunk-YS6EWKGV.js} +2 -2
- package/dist-cli/chunks/{chunk-2SAOKV6V.js → chunk-YT6RDBLT.js} +1 -1
- package/dist-cli/chunks/{chunk-KZS5VM6Y.js → chunk-Z4LSUN4M.js} +1 -1
- package/dist-cli/chunks/{chunk-TUFL7CQK.js → chunk-Z72QDFQG.js} +2 -2
- package/dist-cli/chunks/{chunk-ARICQ4CG.js → chunk-ZH5X2H73.js} +2 -2
- package/dist-cli/chunks/{cleanup-O6IWLGDY.js → cleanup-GBLORG7C.js} +2 -2
- package/dist-cli/chunks/cli-version-6C4ZR7I7.js +4 -0
- package/dist-cli/chunks/{compat-562BT6JM.js → compat-OIWTQTTQ.js} +2 -2
- package/dist-cli/chunks/{config-7RO6O45J.js → config-DZCL6YFH.js} +2 -2
- package/dist-cli/chunks/{control-XYKZG442.js → control-MY5IZSCI.js} +2 -2
- package/dist-cli/chunks/daemon-42K3PILG.js +4 -0
- package/dist-cli/chunks/{debug-3VCEOVRM.js → debug-6UQUAZKP.js} +4 -4
- package/dist-cli/chunks/{desktop-K3PPS6VL.js → desktop-DFBFLSQ3.js} +3 -3
- package/dist-cli/chunks/detox-CIHUJOCI.js +52 -0
- package/dist-cli/chunks/{device-NZCR7JIN.js → device-7SOHSSJO.js} +2 -2
- package/dist-cli/chunks/{diagnose-VVJY6RF2.js → diagnose-P2FMX5HU.js} +2 -2
- package/dist-cli/chunks/{disk-cleanup-2VJMHUIY.js → disk-cleanup-6PP5CQVO.js} +2 -2
- package/dist-cli/chunks/drivers-CFJGYQFX.js +4 -0
- package/dist-cli/chunks/{film-CEMBA2DA.js → film-2WWHMPGU.js} +3 -3
- package/dist-cli/chunks/flow-KL7ZTVKL.js +4 -0
- package/dist-cli/chunks/help-T2OCMQPI.js +4 -0
- package/dist-cli/chunks/hidden-runtime-alias-ZZMC3E6R.js +4 -0
- package/dist-cli/chunks/{home-paths-TKPTU62O.js → home-paths-Y6X4LFSU.js} +2 -2
- package/dist-cli/chunks/inspect-PVMJQHMF.js +4 -0
- package/dist-cli/chunks/install-desktop-NHQZI4EH.js +4 -0
- package/dist-cli/chunks/{login-CIQT627K.js → login-BARKKDRL.js} +4 -4
- package/dist-cli/chunks/{logout-V2DJVY3U.js → logout-YVUMTGMP.js} +2 -2
- package/dist-cli/chunks/{maestro-YSZ6ZC5C.js → maestro-UPVELJ7G.js} +7 -7
- package/dist-cli/chunks/{maestro-generate-6JUELIXK.js → maestro-generate-EP76F4GB.js} +3 -3
- package/dist-cli/chunks/{mode-D4HQ6YN3.js → mode-ULOBJKDO.js} +2 -2
- package/dist-cli/chunks/{optional-demo-registry-AC6YJKT4.js → optional-demo-registry-O6RANNU3.js} +2 -2
- package/dist-cli/chunks/{perf-5GRZ4G5X.js → perf-ANPUHMRS.js} +2 -2
- package/dist-cli/chunks/{permissions-4V6UVWGK.js → permissions-NGMRAUGD.js} +2 -2
- package/dist-cli/chunks/{record-IDNLOQLR.js → record-CBO3QGRB.js} +3 -3
- package/dist-cli/chunks/{report-issue-TF6R77TT.js → report-issue-K7XKNJ2D.js} +2 -2
- package/dist-cli/chunks/reset-FXAX2W5A.js +4 -0
- package/dist-cli/chunks/runtime-GNCU66RR.js +4 -0
- package/dist-cli/chunks/{screenshot-command-CHJN7WUT.js → screenshot-command-KZZSYRX5.js} +3 -3
- package/dist-cli/chunks/{screenshot-layers-MSDCGYNE.js → screenshot-layers-Z3KSMJ3R.js} +2 -2
- package/dist-cli/chunks/{screenshots-capture-OGP3OQYR.js → screenshots-capture-QTB5GQNA.js} +2 -2
- package/dist-cli/chunks/{serve-GPBLCMXX.js → serve-JKTMCDG2.js} +2 -2
- package/dist-cli/chunks/{setup-S2KYWZZO.js → setup-GCAPEHZH.js} +2 -2
- package/dist-cli/chunks/{skills-AUS5DTUE.js → skills-Y4YDYEKA.js} +2 -2
- package/dist-cli/chunks/{state-QLYTMIKF.js → state-3HTG2CZU.js} +2 -2
- package/dist-cli/chunks/storage-XQE2XZJM.js +37 -0
- package/dist-cli/chunks/store-22QXHYUS.js +4 -0
- package/dist-cli/chunks/telemetry-VYGOHQWW.js +4 -0
- package/dist-cli/chunks/{timeline-EUHPXPFP.js → timeline-XYACO63Y.js} +3 -3
- package/dist-cli/chunks/{upgrade-JMMBM3ZN.js → upgrade-EVQTCUSG.js} +2 -2
- package/dist-cli/chunks/upload-XH3RQR4U.js +4 -0
- package/dist-cli/chunks/{version-QCF7RCA2.js → version-NLGYSRXS.js} +2 -2
- package/dist-cli/chunks/{web-WPYHMOVH.js → web-25OBFWDS.js} +2 -2
- package/dist-cli/chunks/{what-happened-3RNZP4MB.js → what-happened-MRN6CH5W.js} +2 -2
- package/dist-lib/agent-daemon-client.cjs +1 -1
- package/dist-lib/agent-events.cjs +1 -1
- package/dist-lib/agent-identity.cjs +1 -1
- package/dist-lib/agent-sessions.cjs +1 -1
- package/dist-lib/attached-projects.cjs +1 -1
- package/dist-lib/auth/shared-session.cjs +1 -1
- package/dist-lib/backend-origin.cjs +1 -1
- package/dist-lib/beta.cjs +1 -1
- package/dist-lib/beta.mjs +1 -1
- package/dist-lib/bridge-constants.cjs +1 -1
- package/dist-lib/bridge-contract.cjs +1 -1
- package/dist-lib/cli-constants.cjs +1 -1
- package/dist-lib/config.cjs +1 -1
- package/dist-lib/detox/index.cjs +93 -11
- package/dist-lib/detox/jest-preset.cjs +0 -1
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/home-paths.cjs +1 -1
- package/dist-lib/host/bridge-host.cjs +1 -1
- package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
- package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
- package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
- package/dist-lib/host/websocket-proxy.cjs +1 -1
- package/dist-lib/index.cjs +1 -1
- package/dist-lib/jump-to-source-babel.cjs +1 -1
- package/dist-lib/menu.cjs +1 -1
- package/dist-lib/menu.mjs +1 -1
- package/dist-lib/metro.cjs +1 -1
- package/dist-lib/profiles.cjs +1 -1
- package/dist-lib/public-brand.cjs +1 -1
- package/dist-lib/render-mode.cjs +1 -1
- package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
- package/dist-lib/sdk.cjs +1 -1
- package/dist-lib/sdk.mjs +1 -1
- package/dist-lib/skills.cjs +62 -28
- package/dist-lib/vite.cjs +1 -1
- package/package.json +1 -1
- package/skills/contrast/SKILL.md +0 -1
- package/skills/rnx-perf/SKILL.md +17 -0
- package/src/vite-plugin.ts +74 -43
- package/dist-cli/chunks/chunk-744422UA.js +0 -4
- package/dist-cli/chunks/chunk-CHKTOWRH.js +0 -939
- package/dist-cli/chunks/chunk-O6OIXJ54.js +0 -4
- package/dist-cli/chunks/chunk-VUKB6JW3.js +0 -125
- package/dist-cli/chunks/cli-version-F2R7SUY7.js +0 -4
- package/dist-cli/chunks/daemon-WE37QLQC.js +0 -4
- package/dist-cli/chunks/detox-6ODNKASO.js +0 -52
- package/dist-cli/chunks/drivers-44ZJZ37B.js +0 -4
- package/dist-cli/chunks/flow-ORGIXYVS.js +0 -4
- package/dist-cli/chunks/help-UW52M7FZ.js +0 -4
- package/dist-cli/chunks/hidden-runtime-alias-R2QQLZZA.js +0 -4
- package/dist-cli/chunks/inspect-TNFI6C6G.js +0 -4
- package/dist-cli/chunks/install-desktop-NEJEPL4L.js +0 -4
- package/dist-cli/chunks/reset-D7WAFOZO.js +0 -4
- package/dist-cli/chunks/runtime-O5TNQBYH.js +0 -4
- package/dist-cli/chunks/storage-2MNS4TYO.js +0 -37
- package/dist-cli/chunks/store-UT52X7AA.js +0 -4
- package/dist-cli/chunks/telemetry-CAQVTTHY.js +0 -4
- package/dist-cli/chunks/upload-CEX4UBJL.js +0 -4
package/cli/bin.ts
CHANGED
|
@@ -420,12 +420,6 @@ if (TOP_LEVEL_RUNTIME_COMMANDS.has(command)) {
|
|
|
420
420
|
await exitWithFlush(code)
|
|
421
421
|
}
|
|
422
422
|
|
|
423
|
-
case 'inspect': {
|
|
424
|
-
const { runInspect } = await import('./commands/inspect')
|
|
425
|
-
await runInspect(commandArgsWithSim, { port, verbose })
|
|
426
|
-
break
|
|
427
|
-
}
|
|
428
|
-
|
|
429
423
|
case 'debug': {
|
|
430
424
|
const { runDebug } = await import('./commands/debug')
|
|
431
425
|
await runDebug(commandArgsWithSim, { port, verbose })
|
|
@@ -534,8 +528,7 @@ if (TOP_LEVEL_RUNTIME_COMMANDS.has(command)) {
|
|
|
534
528
|
break
|
|
535
529
|
}
|
|
536
530
|
|
|
537
|
-
case 'upgrade':
|
|
538
|
-
case 'update': {
|
|
531
|
+
case 'upgrade': {
|
|
539
532
|
const { runUpgrade } = await import('./commands/upgrade')
|
|
540
533
|
await runUpgrade(parsed.commandArgs)
|
|
541
534
|
break
|
package/cli/commands/debug.ts
CHANGED
|
@@ -408,14 +408,7 @@ export async function runDebug(args: string[], opts: DebugOptions) {
|
|
|
408
408
|
// implementation lives in inspect.ts. forward to runInspect with the raw
|
|
409
409
|
// `debug` prefix intact — runInspect strips it. done before we open a
|
|
410
410
|
// debug-side bridge so we don't hold two bridges at once.
|
|
411
|
-
const INSPECT_FORWARDED = new Set([
|
|
412
|
-
'state',
|
|
413
|
-
'js',
|
|
414
|
-
'eval',
|
|
415
|
-
'perf',
|
|
416
|
-
'memory',
|
|
417
|
-
'sample-color',
|
|
418
|
-
])
|
|
411
|
+
const INSPECT_FORWARDED = new Set(['state', 'js', 'perf', 'memory', 'sample-color'])
|
|
419
412
|
if (INSPECT_FORWARDED.has(sub)) {
|
|
420
413
|
const { runInspect } = await import('./inspect')
|
|
421
414
|
// pass the raw arg list through so every flag (--sim, --json,
|
package/cli/commands/detox.ts
CHANGED
|
@@ -83,14 +83,26 @@ export async function runDetox(args: string[], opts: RunDetoxOpts = {}): Promise
|
|
|
83
83
|
prev === '--config' ||
|
|
84
84
|
prev === '-t' ||
|
|
85
85
|
prev === '--testNamePattern' ||
|
|
86
|
-
prev === '--grep'
|
|
86
|
+
prev === '--grep' ||
|
|
87
|
+
prev === '--maxWorkers' ||
|
|
88
|
+
prev === '--shard'
|
|
87
89
|
)
|
|
88
90
|
return false
|
|
89
91
|
return true
|
|
90
92
|
})
|
|
91
|
-
const passthroughJestFlags = args.
|
|
92
|
-
|
|
93
|
-
|
|
93
|
+
const passthroughJestFlags = args.flatMap((arg, index) => {
|
|
94
|
+
if (
|
|
95
|
+
arg === '--runInBand' ||
|
|
96
|
+
arg.startsWith('--maxWorkers=') ||
|
|
97
|
+
arg.startsWith('--shard=')
|
|
98
|
+
) {
|
|
99
|
+
return [arg]
|
|
100
|
+
}
|
|
101
|
+
if ((arg === '--maxWorkers' || arg === '--shard') && args[index + 1]) {
|
|
102
|
+
return [arg, args[index + 1]]
|
|
103
|
+
}
|
|
104
|
+
return []
|
|
105
|
+
})
|
|
94
106
|
|
|
95
107
|
// test dir discovery. external test suites set SOOTSIM_TEST_DIR; otherwise
|
|
96
108
|
// we auto-detect the conventional locations.
|
package/cli/commands/flow.ts
CHANGED
|
@@ -966,8 +966,7 @@ async function runFlowSession(args: string[]) {
|
|
|
966
966
|
return
|
|
967
967
|
}
|
|
968
968
|
|
|
969
|
-
case 'keep':
|
|
970
|
-
case 'good': {
|
|
969
|
+
case 'keep': {
|
|
971
970
|
const result = keepFlowCandidate()
|
|
972
971
|
if (!result.active) {
|
|
973
972
|
console.error(' no active flow draft — run `sootsim maestro start` first')
|
|
@@ -116,7 +116,7 @@ export async function runWaitEventSubcommand(opts: WaitEventOptions): Promise<vo
|
|
|
116
116
|
if (!kind) {
|
|
117
117
|
console.error(
|
|
118
118
|
inspectUsage(
|
|
119
|
-
'
|
|
119
|
+
'event',
|
|
120
120
|
'<kind> [--max-ms 5000] [--filter <substring>] [--equals <exact>] [--since now|cursor]',
|
|
121
121
|
),
|
|
122
122
|
)
|
|
@@ -13,7 +13,7 @@ export async function runWaitSelectorSubcommand(opts: {
|
|
|
13
13
|
const { bridge, args, positional, inspectUsage } = opts
|
|
14
14
|
const testId = positional[1]
|
|
15
15
|
if (!testId) {
|
|
16
|
-
console.error(inspectUsage('
|
|
16
|
+
console.error(inspectUsage('selector', '<testid> [--max-ms 5000] [--gone]'))
|
|
17
17
|
process.exit(1)
|
|
18
18
|
}
|
|
19
19
|
const maxMsIdx = args.indexOf('--max-ms')
|
package/cli/commands/inspect.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// sootsim inspect — dump node tree, accessibility info, query nodes
|
|
2
2
|
// connects to the sootsim WS bridge (no Playwright)
|
|
3
3
|
|
|
4
|
+
import { getCliInspectVerbMeta } from '@sootsim/skills/cli'
|
|
4
5
|
import { renderCliCommandHelp, renderCliGroupHelp } from '@sootsim/skills/cli/renderers'
|
|
5
6
|
import { DEFAULT_SOOTSIM_BRIDGE_PORT } from '../../src/bridge-constants'
|
|
6
7
|
import { DEFAULT_SOOTSIM_SHELL_URL } from '../../src/cli-constants'
|
|
@@ -615,6 +616,41 @@ export function printShellPerfReport(result: Record<string, any>) {
|
|
|
615
616
|
printPhase('CanvasKit submission', compositorCadence.canvaskitSubmission)
|
|
616
617
|
}
|
|
617
618
|
const surfaces = Array.isArray(result.auxSurfaces) ? result.auxSurfaces : []
|
|
619
|
+
const graphiteCaches = result.graphiteCaches
|
|
620
|
+
const decodedImageCache = result.decodedImageCache
|
|
621
|
+
if (graphiteCaches || decodedImageCache) {
|
|
622
|
+
const printCache = (
|
|
623
|
+
label: string,
|
|
624
|
+
cache: { bytes?: number; limitBytes?: number; purgeableBytes?: number } | null,
|
|
625
|
+
) => {
|
|
626
|
+
if (typeof cache?.bytes !== 'number' || typeof cache.limitBytes !== 'number') {
|
|
627
|
+
return
|
|
628
|
+
}
|
|
629
|
+
const purgeable =
|
|
630
|
+
typeof cache.purgeableBytes === 'number'
|
|
631
|
+
? ` · ${(cache.purgeableBytes / 1024 / 1024).toFixed(1)}MB purgeable`
|
|
632
|
+
: ''
|
|
633
|
+
console.log(
|
|
634
|
+
` ${label.padEnd(29)} ${(cache.bytes / 1024 / 1024).toFixed(1)}MB/${(cache.limitBytes / 1024 / 1024).toFixed(1)}MB${purgeable}`,
|
|
635
|
+
)
|
|
636
|
+
}
|
|
637
|
+
console.log(``)
|
|
638
|
+
console.log(` device-wide caches:`)
|
|
639
|
+
printCache('Graphite context resources', graphiteCaches?.contextResources ?? null)
|
|
640
|
+
printCache('Graphite recorder resources', graphiteCaches?.recorderResources ?? null)
|
|
641
|
+
printCache('Graphite image provider', graphiteCaches?.imageProvider ?? null)
|
|
642
|
+
printCache('decoded image pixels', decodedImageCache ?? null)
|
|
643
|
+
if (graphiteCaches?.imageProvider) {
|
|
644
|
+
console.log(
|
|
645
|
+
` ${''.padEnd(29)} ${graphiteCaches.imageProvider.entries} entries · ${graphiteCaches.imageProvider.uploads} uploads · ${graphiteCaches.imageProvider.evictions} evictions`,
|
|
646
|
+
)
|
|
647
|
+
}
|
|
648
|
+
if (decodedImageCache) {
|
|
649
|
+
console.log(
|
|
650
|
+
` ${''.padEnd(29)} ${decodedImageCache.entries} entries/${decodedImageCache.maxEntries} max`,
|
|
651
|
+
)
|
|
652
|
+
}
|
|
653
|
+
}
|
|
618
654
|
if (surfaces.length > 0) {
|
|
619
655
|
console.log(``)
|
|
620
656
|
console.log(` surfaces (last 100 frames):`)
|
|
@@ -622,14 +658,6 @@ export function printShellPerfReport(result: Record<string, any>) {
|
|
|
622
658
|
console.log(
|
|
623
659
|
` ${String(s.surfaceId).padEnd(10)} ${String(s.frames).padStart(4)} paints avg ${s.avgMs}ms (layout ${s.avgLayoutMs}, render ${s.avgRenderMs}, flush ${s.avgFlushMs}) max ${s.maxMs}ms`,
|
|
624
660
|
)
|
|
625
|
-
if (
|
|
626
|
-
typeof s.gpuCacheBytes === 'number' &&
|
|
627
|
-
typeof s.gpuCacheLimitBytes === 'number'
|
|
628
|
-
) {
|
|
629
|
-
console.log(
|
|
630
|
-
` ${''.padEnd(10)} gpu cache ${(s.gpuCacheBytes / 1024 / 1024).toFixed(1)}MB/${(s.gpuCacheLimitBytes / 1024 / 1024).toFixed(1)}MB`,
|
|
631
|
-
)
|
|
632
|
-
}
|
|
633
661
|
}
|
|
634
662
|
}
|
|
635
663
|
// two profiles, two workers: the shell paints chrome/overlays, the
|
|
@@ -875,9 +903,9 @@ function keyCodeToVisualKey(code: string) {
|
|
|
875
903
|
}
|
|
876
904
|
|
|
877
905
|
function getInspectCommandName(subcommand: string, directSubcommand: string | null) {
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
906
|
+
if (directSubcommand === subcommand) return `rnxsim ${subcommand}`
|
|
907
|
+
const group = getCliInspectVerbMeta(subcommand)?.group
|
|
908
|
+
return group ? `rnxsim ${group} ${subcommand}` : `rnxsim ${subcommand}`
|
|
881
909
|
}
|
|
882
910
|
|
|
883
911
|
function getInspectUsage(
|
|
@@ -1062,25 +1090,24 @@ export async function runInspect(args: string[], opts: InspectOptions) {
|
|
|
1062
1090
|
const positional = parsed.positional
|
|
1063
1091
|
const subcommand = positional[0]
|
|
1064
1092
|
// used by inspectCommand() below to format usage/error strings with the
|
|
1065
|
-
// same prefix the user actually typed. when
|
|
1066
|
-
//
|
|
1067
|
-
const invocationPrefix: 'get' | 'do' | 'debug' | 'wait' |
|
|
1068
|
-
verbPrefix === 'get' ||
|
|
1069
|
-
verbPrefix === 'do' ||
|
|
1070
|
-
verbPrefix === 'debug' ||
|
|
1071
|
-
verbPrefix === 'wait'
|
|
1072
|
-
? verbPrefix
|
|
1073
|
-
: 'inspect'
|
|
1093
|
+
// same prefix the user actually typed. null when they typed a top-level
|
|
1094
|
+
// command, and inspectCommand asks the registry for the group instead.
|
|
1095
|
+
const invocationPrefix: 'get' | 'do' | 'debug' | 'wait' | null = verbPrefix
|
|
1074
1096
|
const isTopLevel =
|
|
1075
1097
|
typeof effectiveArgs[0] === 'string' &&
|
|
1076
1098
|
TOP_LEVEL_RUNTIME_COMMANDS.has(effectiveArgs[0])
|
|
1077
1099
|
const topLevelCommand = isTopLevel ? effectiveArgs[0] : null
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1100
|
+
// a usage string has to name something the user can actually type. the
|
|
1101
|
+
// registry knows which group each verb belongs to, so an unprefixed
|
|
1102
|
+
// invocation still renders `rnxsim get tree` rather than a bare verb.
|
|
1103
|
+
const inspectCommand = (name: string) => {
|
|
1104
|
+
if (opts.internalPerfCommand && name === 'perf') {
|
|
1105
|
+
return `rnxsim perf ${opts.internalPerfCommand}`
|
|
1106
|
+
}
|
|
1107
|
+
if (isTopLevel && name === effectiveArgs[0]) return `rnxsim ${name}`
|
|
1108
|
+
const group = invocationPrefix ?? getCliInspectVerbMeta(name)?.group
|
|
1109
|
+
return group ? `rnxsim ${group} ${name}` : `rnxsim ${name}`
|
|
1110
|
+
}
|
|
1084
1111
|
const inspectUsage = (name: string, tail: string) =>
|
|
1085
1112
|
` usage: ${inspectCommand(name)}${tail ? ` ${tail}` : ''}`
|
|
1086
1113
|
|
|
@@ -1118,14 +1145,12 @@ export async function runInspect(args: string[], opts: InspectOptions) {
|
|
|
1118
1145
|
}
|
|
1119
1146
|
}
|
|
1120
1147
|
|
|
1121
|
-
// catch-all
|
|
1122
|
-
// each group's listing stitched together.
|
|
1123
|
-
const inspectMeta = renderCliCommandHelp('inspect', docContext)
|
|
1148
|
+
// catch-all help — every group's listing stitched together.
|
|
1124
1149
|
const groupSections = ['do', 'get', 'debug', 'wait']
|
|
1125
1150
|
.map((g) => renderCliGroupHelp(g, docContext))
|
|
1126
1151
|
.filter((s): s is string => s != null)
|
|
1127
1152
|
.join('\n\n')
|
|
1128
|
-
console.log(`${
|
|
1153
|
+
console.log(`${groupSections}\n`)
|
|
1129
1154
|
process.exit(0)
|
|
1130
1155
|
}
|
|
1131
1156
|
|
|
@@ -1190,7 +1215,6 @@ export async function runInspect(args: string[], opts: InspectOptions) {
|
|
|
1190
1215
|
'warnings',
|
|
1191
1216
|
'requests',
|
|
1192
1217
|
'js',
|
|
1193
|
-
'eval',
|
|
1194
1218
|
'reload',
|
|
1195
1219
|
'globals',
|
|
1196
1220
|
'perf',
|
|
@@ -3571,7 +3595,6 @@ export async function runInspect(args: string[], opts: InspectOptions) {
|
|
|
3571
3595
|
break
|
|
3572
3596
|
}
|
|
3573
3597
|
|
|
3574
|
-
case 'eval':
|
|
3575
3598
|
case 'js': {
|
|
3576
3599
|
const code = positional.slice(1).join(' ')
|
|
3577
3600
|
if (!code) {
|
|
@@ -4501,7 +4524,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
|
|
|
4501
4524
|
}
|
|
4502
4525
|
} catch (err: any) {
|
|
4503
4526
|
const message = err instanceof Error ? err.message : String(err)
|
|
4504
|
-
console.error(` ${subcommand ?? '
|
|
4527
|
+
console.error(` ${subcommand ?? 'rnxsim'} failed: ${message}`)
|
|
4505
4528
|
const unknownSim = /^no sim connected with id ([^;]+)(?:; connected sims: .+)?$/.exec(
|
|
4506
4529
|
message,
|
|
4507
4530
|
)
|
package/cli/commands/maestro.ts
CHANGED
|
@@ -94,7 +94,7 @@ workspace mode (directory runs):
|
|
|
94
94
|
|
|
95
95
|
partial:
|
|
96
96
|
clearKeychain — warn-only, rnx has no keychain surface.
|
|
97
|
-
when.platform — rnx reports iOS.
|
|
97
|
+
when.platform — rnx reports iOS for this runner.
|
|
98
98
|
openLink — dispatched into the app via the Linking emulation
|
|
99
99
|
(react-navigation deep links work); no OS-level Safari fallback.
|
|
100
100
|
launchApp.arguments — ignored; rnx has no native process.
|
package/cli/commands/profile.ts
CHANGED
|
@@ -18,7 +18,7 @@ function printHelp() {
|
|
|
18
18
|
rnxsim storage profile — manage isolated storage profiles
|
|
19
19
|
|
|
20
20
|
usage:
|
|
21
|
-
rnxsim storage profile
|
|
21
|
+
rnxsim storage profile list
|
|
22
22
|
rnxsim storage profile create <id>
|
|
23
23
|
rnxsim storage profile clear <id>
|
|
24
24
|
rnxsim storage profile delete <id>
|
|
@@ -28,7 +28,7 @@ service workers in Electron and Playwright launches. Plain browser-tab launches
|
|
|
28
28
|
cannot honor profiles and will fail clearly if a profile is requested.
|
|
29
29
|
|
|
30
30
|
examples:
|
|
31
|
-
rnxsim storage profile
|
|
31
|
+
rnxsim storage profile list
|
|
32
32
|
rnxsim storage profile create qa
|
|
33
33
|
rnxsim open 8081 --profile qa
|
|
34
34
|
rnxsim open 8081 --profile qa --driver playwright
|
|
@@ -43,10 +43,9 @@ export async function runProfile(args: string[], _opts: ProfileOptions): Promise
|
|
|
43
43
|
return 0
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
const subcommand = args[0] ?? '
|
|
46
|
+
const subcommand = args[0] ?? 'list'
|
|
47
47
|
try {
|
|
48
48
|
switch (subcommand) {
|
|
49
|
-
case 'ls':
|
|
50
49
|
case 'list': {
|
|
51
50
|
const profiles = listProfiles()
|
|
52
51
|
for (const profile of profiles) {
|
|
@@ -85,8 +84,7 @@ export async function runProfile(args: string[], _opts: ProfileOptions): Promise
|
|
|
85
84
|
console.log(` cleared profile: ${id}`)
|
|
86
85
|
return 0
|
|
87
86
|
}
|
|
88
|
-
case 'delete':
|
|
89
|
-
case 'rm': {
|
|
87
|
+
case 'delete': {
|
|
90
88
|
const id = args[1]
|
|
91
89
|
if (!id) {
|
|
92
90
|
console.error(' profile delete expects <id>')
|
package/cli/commands/runtime.ts
CHANGED
|
@@ -44,18 +44,14 @@ export async function runRuntime(args: string[], opts: RuntimeOptions = {}) {
|
|
|
44
44
|
case 'install':
|
|
45
45
|
return runtimeInstall(rest, opts)
|
|
46
46
|
case 'list':
|
|
47
|
-
case 'ls':
|
|
48
47
|
return runtimeList(rest)
|
|
49
48
|
case 'use':
|
|
50
49
|
return runtimeUse(rest)
|
|
51
50
|
case 'remove':
|
|
52
|
-
case 'rm':
|
|
53
51
|
return runtimeRemove(rest)
|
|
54
52
|
case 'which':
|
|
55
|
-
case 'active':
|
|
56
53
|
return runtimeWhich()
|
|
57
54
|
case 'notes':
|
|
58
|
-
case 'changelog':
|
|
59
55
|
return runtimeNotes(rest)
|
|
60
56
|
default:
|
|
61
57
|
console.error(` unknown runtime subcommand: ${sub}`)
|
package/cli/commands/storage.ts
CHANGED
|
@@ -33,14 +33,12 @@ export async function runTelemetry(args: string[]): Promise<void> {
|
|
|
33
33
|
return
|
|
34
34
|
|
|
35
35
|
case 'on':
|
|
36
|
-
case 'enable':
|
|
37
36
|
writePrivacyPreferences({ ...readPrivacyPreferences(), productAnalytics: true })
|
|
38
37
|
console.log(' product analytics ON')
|
|
39
38
|
console.log(` config: ${configFilePath()}`)
|
|
40
39
|
return
|
|
41
40
|
|
|
42
41
|
case 'off':
|
|
43
|
-
case 'disable':
|
|
44
42
|
writePrivacyPreferences({ ...readPrivacyPreferences(), productAnalytics: false })
|
|
45
43
|
console.log(' product analytics OFF')
|
|
46
44
|
console.log(` config: ${configFilePath()}`)
|
package/cli/commands/timeline.ts
CHANGED
|
@@ -74,16 +74,14 @@ export async function runTimeline(args: string[], opts: TimelineOptions) {
|
|
|
74
74
|
console.log(JSON.stringify(status, null, json ? 0 : 2))
|
|
75
75
|
break
|
|
76
76
|
}
|
|
77
|
-
case 'start':
|
|
78
|
-
case 'enable': {
|
|
77
|
+
case 'start': {
|
|
79
78
|
if (kinds.length === 0) kinds.push('all')
|
|
80
79
|
await callInBridge(bridge, 'SootSim.bridges.timeline.enable', ...kinds)
|
|
81
80
|
const status = await callInBridge(bridge, 'SootSim.bridges.timeline.status')
|
|
82
81
|
console.log(JSON.stringify(status, null, json ? 0 : 2))
|
|
83
82
|
break
|
|
84
83
|
}
|
|
85
|
-
case 'stop':
|
|
86
|
-
case 'disable': {
|
|
84
|
+
case 'stop': {
|
|
87
85
|
if (kinds.length === 0) kinds.push('all')
|
|
88
86
|
await callInBridge(bridge, 'SootSim.bridges.timeline.disable', ...kinds)
|
|
89
87
|
const status = await callInBridge(bridge, 'SootSim.bridges.timeline.status')
|
package/cli/parse-args.ts
CHANGED
|
@@ -33,7 +33,6 @@ const GLOBAL_FLAGS: Record<
|
|
|
33
33
|
// - `sootsim get <noun>` reads
|
|
34
34
|
// - `sootsim do <action>` writes
|
|
35
35
|
// - `sootsim debug <tool>` instrumentation (handled by runDebug)
|
|
36
|
-
// - `sootsim inspect <sub>` full legacy surface, all subcommands
|
|
37
36
|
// `describe` and `find` stay at root as the most common entrypoints.
|
|
38
37
|
// `list` stays at root because it's a sim-management read.
|
|
39
38
|
export const TOP_LEVEL_RUNTIME_COMMANDS = new Set([
|
|
@@ -70,7 +69,6 @@ const COMMANDS = new Set([
|
|
|
70
69
|
'reset',
|
|
71
70
|
'camera',
|
|
72
71
|
'mode',
|
|
73
|
-
'inspect',
|
|
74
72
|
'debug',
|
|
75
73
|
'timeline',
|
|
76
74
|
'what-happened',
|
|
@@ -93,7 +91,6 @@ const COMMANDS = new Set([
|
|
|
93
91
|
'daemon',
|
|
94
92
|
'runtime',
|
|
95
93
|
'upgrade',
|
|
96
|
-
'update',
|
|
97
94
|
'version',
|
|
98
95
|
'skill',
|
|
99
96
|
'config',
|
package/detox/index.ts
CHANGED
|
@@ -608,6 +608,7 @@ type FastScreenshotData = {
|
|
|
608
608
|
label: string
|
|
609
609
|
offsetMs: number
|
|
610
610
|
actualMs: number
|
|
611
|
+
captureRequestedAtMs?: number
|
|
611
612
|
dataUrl: string
|
|
612
613
|
frameIndex?: number
|
|
613
614
|
virtualTimestampMs?: number
|
|
@@ -1854,17 +1855,44 @@ export const device = {
|
|
|
1854
1855
|
async takeScreenshotStagesFast(
|
|
1855
1856
|
namePrefix: string,
|
|
1856
1857
|
stages: Array<{ label: string; offsetMs: number }>,
|
|
1857
|
-
options
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1858
|
+
options: {
|
|
1859
|
+
anchorAfterTrigger?: boolean
|
|
1860
|
+
skipWarmup?: boolean
|
|
1861
|
+
trigger: () => unknown
|
|
1862
|
+
},
|
|
1863
|
+
): Promise<{
|
|
1864
|
+
captureAnchorMs: number
|
|
1865
|
+
frames: Array<{
|
|
1861
1866
|
label: string
|
|
1862
1867
|
offsetMs: number
|
|
1863
1868
|
actualMs: number
|
|
1864
|
-
|
|
1865
|
-
|
|
1869
|
+
captureRequestedAtMs: number
|
|
1870
|
+
path: string
|
|
1871
|
+
}>
|
|
1872
|
+
triggerCompletedMs: number
|
|
1873
|
+
triggerStartMs: number
|
|
1874
|
+
}> {
|
|
1875
|
+
const page = getPage()
|
|
1876
|
+
const token = `timed-${process.pid}-${Date.now()}-${Math.random()}`
|
|
1877
|
+
const capturePromise: Promise<{
|
|
1878
|
+
captureAnchorMs: number
|
|
1879
|
+
frames: Array<{
|
|
1880
|
+
label: string
|
|
1881
|
+
offsetMs: number
|
|
1882
|
+
actualMs: number
|
|
1883
|
+
captureRequestedAtMs: number
|
|
1884
|
+
dataUrl: string
|
|
1885
|
+
}>
|
|
1886
|
+
}> = page.evaluate(
|
|
1866
1887
|
async (input) => {
|
|
1867
|
-
|
|
1888
|
+
type CaptureState = {
|
|
1889
|
+
anchorPerformanceMs: number | null
|
|
1890
|
+
anchorWallMs: number | null
|
|
1891
|
+
cancelled: boolean
|
|
1892
|
+
ready: boolean
|
|
1893
|
+
}
|
|
1894
|
+
type CaptureWindow = Window & {
|
|
1895
|
+
__sootsimTimedCaptures?: Record<string, CaptureState>
|
|
1868
1896
|
SootSim?: {
|
|
1869
1897
|
bridges?: {
|
|
1870
1898
|
screenshot?: (opts?: unknown) => Promise<string>
|
|
@@ -1877,11 +1905,22 @@ export const device = {
|
|
|
1877
1905
|
}
|
|
1878
1906
|
}
|
|
1879
1907
|
}
|
|
1880
|
-
const
|
|
1881
|
-
const
|
|
1908
|
+
const captureWindow = window as unknown as CaptureWindow
|
|
1909
|
+
const screenshot = captureWindow.SootSim?.bridges?.screenshot
|
|
1910
|
+
const live = captureWindow.SootSim?.bridges?.liveComposite
|
|
1882
1911
|
if (typeof screenshot !== 'function') {
|
|
1883
1912
|
throw new Error('rnx screenshot bridge is not installed')
|
|
1884
1913
|
}
|
|
1914
|
+
const registry =
|
|
1915
|
+
captureWindow.__sootsimTimedCaptures ??
|
|
1916
|
+
(captureWindow.__sootsimTimedCaptures = {})
|
|
1917
|
+
const state: CaptureState = {
|
|
1918
|
+
anchorPerformanceMs: null,
|
|
1919
|
+
anchorWallMs: null,
|
|
1920
|
+
cancelled: false,
|
|
1921
|
+
ready: false,
|
|
1922
|
+
}
|
|
1923
|
+
registry[input.token] = state
|
|
1885
1924
|
// initial warm-up: ensure the worker has produced at least one
|
|
1886
1925
|
// frame after the menu's portal mount before we start sampling.
|
|
1887
1926
|
// (a pump at higher cadence was tried and starved tap propagation —
|
|
@@ -1890,11 +1929,18 @@ export const device = {
|
|
|
1890
1929
|
if (!input.skipWarmup) {
|
|
1891
1930
|
await screenshot({ format: 'png' })
|
|
1892
1931
|
}
|
|
1893
|
-
|
|
1932
|
+
state.ready = true
|
|
1933
|
+
while (state.anchorPerformanceMs === null || state.anchorWallMs === null) {
|
|
1934
|
+
if (state.cancelled) throw new Error('rnx timed capture was cancelled')
|
|
1935
|
+
await new Promise((resolve) => setTimeout(resolve, 0))
|
|
1936
|
+
}
|
|
1937
|
+
const captureAnchorMs = state.anchorWallMs
|
|
1938
|
+
const captureAnchorPerformanceMs = state.anchorPerformanceMs
|
|
1894
1939
|
type Snapshot = {
|
|
1895
1940
|
label: string
|
|
1896
1941
|
offsetMs: number
|
|
1897
1942
|
actualMs: number
|
|
1943
|
+
captureRequestedAtMs: number
|
|
1898
1944
|
dataUrl: string | null
|
|
1899
1945
|
}
|
|
1900
1946
|
// each stage fires at its requested offset and SYNCHRONOUSLY
|
|
@@ -1907,7 +1953,8 @@ export const device = {
|
|
|
1907
1953
|
(stage) =>
|
|
1908
1954
|
new Promise<Snapshot>((resolve) => {
|
|
1909
1955
|
const fire = async () => {
|
|
1910
|
-
const actualMs = performance.now() -
|
|
1956
|
+
const actualMs = performance.now() - captureAnchorPerformanceMs
|
|
1957
|
+
const captureRequestedAtMs = Date.now()
|
|
1911
1958
|
try {
|
|
1912
1959
|
let dataUrl: string | null = null
|
|
1913
1960
|
if (live && typeof live.captureFresh === 'function') {
|
|
@@ -1935,6 +1982,7 @@ export const device = {
|
|
|
1935
1982
|
label: stage.label,
|
|
1936
1983
|
offsetMs: stage.offsetMs,
|
|
1937
1984
|
actualMs,
|
|
1985
|
+
captureRequestedAtMs,
|
|
1938
1986
|
dataUrl,
|
|
1939
1987
|
})
|
|
1940
1988
|
} catch {
|
|
@@ -1942,6 +1990,7 @@ export const device = {
|
|
|
1942
1990
|
label: stage.label,
|
|
1943
1991
|
offsetMs: stage.offsetMs,
|
|
1944
1992
|
actualMs,
|
|
1993
|
+
captureRequestedAtMs,
|
|
1945
1994
|
dataUrl: null,
|
|
1946
1995
|
})
|
|
1947
1996
|
}
|
|
@@ -1950,7 +1999,10 @@ export const device = {
|
|
|
1950
1999
|
() => {
|
|
1951
2000
|
void fire()
|
|
1952
2001
|
},
|
|
1953
|
-
Math.max(
|
|
2002
|
+
Math.max(
|
|
2003
|
+
0,
|
|
2004
|
+
captureAnchorPerformanceMs + stage.offsetMs - performance.now(),
|
|
2005
|
+
),
|
|
1954
2006
|
)
|
|
1955
2007
|
}),
|
|
1956
2008
|
),
|
|
@@ -1959,6 +2011,7 @@ export const device = {
|
|
|
1959
2011
|
label: string
|
|
1960
2012
|
offsetMs: number
|
|
1961
2013
|
actualMs: number
|
|
2014
|
+
captureRequestedAtMs: number
|
|
1962
2015
|
dataUrl: string
|
|
1963
2016
|
}> = []
|
|
1964
2017
|
for (const snap of snaps) {
|
|
@@ -1967,14 +2020,101 @@ export const device = {
|
|
|
1967
2020
|
label: snap.label,
|
|
1968
2021
|
offsetMs: snap.offsetMs,
|
|
1969
2022
|
actualMs: snap.actualMs,
|
|
2023
|
+
captureRequestedAtMs: snap.captureRequestedAtMs,
|
|
1970
2024
|
dataUrl: snap.dataUrl,
|
|
1971
2025
|
})
|
|
1972
2026
|
}
|
|
1973
|
-
|
|
2027
|
+
delete registry[input.token]
|
|
2028
|
+
return { captureAnchorMs, frames: out }
|
|
1974
2029
|
},
|
|
1975
|
-
{ stages, skipWarmup: options
|
|
2030
|
+
{ stages, skipWarmup: options.skipWarmup === true, token },
|
|
1976
2031
|
)
|
|
1977
|
-
|
|
2032
|
+
|
|
2033
|
+
await page.waitForFunction(
|
|
2034
|
+
(captureToken) => {
|
|
2035
|
+
const registry = (
|
|
2036
|
+
window as Window & {
|
|
2037
|
+
__sootsimTimedCaptures?: Record<string, { ready: boolean }>
|
|
2038
|
+
}
|
|
2039
|
+
).__sootsimTimedCaptures
|
|
2040
|
+
return registry?.[captureToken]?.ready === true
|
|
2041
|
+
},
|
|
2042
|
+
token,
|
|
2043
|
+
{ timeout: 5000 },
|
|
2044
|
+
)
|
|
2045
|
+
|
|
2046
|
+
const armCapture = (anchorMs?: number) =>
|
|
2047
|
+
page.evaluate(
|
|
2048
|
+
({ anchorMs, captureToken }) => {
|
|
2049
|
+
const registry = (
|
|
2050
|
+
window as Window & {
|
|
2051
|
+
__sootsimTimedCaptures?: Record<
|
|
2052
|
+
string,
|
|
2053
|
+
{
|
|
2054
|
+
anchorPerformanceMs: number | null
|
|
2055
|
+
anchorWallMs: number | null
|
|
2056
|
+
ready: boolean
|
|
2057
|
+
}
|
|
2058
|
+
>
|
|
2059
|
+
}
|
|
2060
|
+
).__sootsimTimedCaptures
|
|
2061
|
+
const capture = registry?.[captureToken]
|
|
2062
|
+
if (!capture?.ready) throw new Error('rnx timed capture was not armed')
|
|
2063
|
+
const nowMs = Date.now()
|
|
2064
|
+
capture.anchorWallMs = anchorMs ?? nowMs
|
|
2065
|
+
capture.anchorPerformanceMs = performance.now() - (nowMs - capture.anchorWallMs)
|
|
2066
|
+
return capture.anchorWallMs
|
|
2067
|
+
},
|
|
2068
|
+
{ anchorMs, captureToken: token },
|
|
2069
|
+
)
|
|
2070
|
+
|
|
2071
|
+
let triggerStartMs = 0
|
|
2072
|
+
let triggerCompletedMs = 0
|
|
2073
|
+
try {
|
|
2074
|
+
let captureAnchorMs: number
|
|
2075
|
+
if (options.anchorAfterTrigger === false) {
|
|
2076
|
+
captureAnchorMs = await armCapture()
|
|
2077
|
+
triggerStartMs = captureAnchorMs
|
|
2078
|
+
const triggerPromise = Promise.resolve()
|
|
2079
|
+
.then(options.trigger)
|
|
2080
|
+
.then(() => {
|
|
2081
|
+
triggerCompletedMs = Date.now()
|
|
2082
|
+
})
|
|
2083
|
+
const [capture] = await Promise.all([capturePromise, triggerPromise])
|
|
2084
|
+
return {
|
|
2085
|
+
captureAnchorMs,
|
|
2086
|
+
frames: writeFastScreenshotFrames(namePrefix, capture.frames),
|
|
2087
|
+
triggerCompletedMs,
|
|
2088
|
+
triggerStartMs,
|
|
2089
|
+
}
|
|
2090
|
+
}
|
|
2091
|
+
|
|
2092
|
+
triggerStartMs = Date.now()
|
|
2093
|
+
await Promise.resolve(options.trigger())
|
|
2094
|
+
triggerCompletedMs = Date.now()
|
|
2095
|
+
captureAnchorMs = await armCapture(triggerCompletedMs)
|
|
2096
|
+
const capture = await capturePromise
|
|
2097
|
+
return {
|
|
2098
|
+
captureAnchorMs,
|
|
2099
|
+
frames: writeFastScreenshotFrames(namePrefix, capture.frames),
|
|
2100
|
+
triggerCompletedMs,
|
|
2101
|
+
triggerStartMs,
|
|
2102
|
+
}
|
|
2103
|
+
} catch (error) {
|
|
2104
|
+
await page
|
|
2105
|
+
.evaluate((captureToken) => {
|
|
2106
|
+
const registry = (
|
|
2107
|
+
window as Window & {
|
|
2108
|
+
__sootsimTimedCaptures?: Record<string, { cancelled: boolean }>
|
|
2109
|
+
}
|
|
2110
|
+
).__sootsimTimedCaptures
|
|
2111
|
+
const capture = registry?.[captureToken]
|
|
2112
|
+
if (capture) capture.cancelled = true
|
|
2113
|
+
}, token)
|
|
2114
|
+
.catch(() => {})
|
|
2115
|
+
await capturePromise.catch(() => {})
|
|
2116
|
+
throw error
|
|
2117
|
+
}
|
|
1978
2118
|
},
|
|
1979
2119
|
|
|
1980
2120
|
// batched multi-stage capture for animation diffs. all N captures happen
|
package/detox/jest-preset.cjs
CHANGED