peachsim 0.1.939 → 0.1.1399
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/README.md +28 -22
- package/cli/app-catalog.ts +29 -14
- package/cli/app-fonts.ts +5 -3
- package/cli/bridge-flow-runner.ts +40 -29
- package/cli/cloud-client.ts +57 -21
- package/cli/cloud-test-tunnel.ts +12 -18
- package/cli/commands/agent.ts +1 -1
- package/cli/commands/app-fonts.ts +3 -3
- package/cli/commands/assert.ts +8 -8
- package/cli/commands/auth.ts +8 -3
- package/cli/commands/box/bundle-plane.ts +13 -1
- package/cli/commands/box.ts +16 -5
- package/cli/commands/compat.ts +1 -1
- package/cli/commands/config.ts +2 -2
- package/cli/commands/control.ts +125 -71
- package/cli/commands/cpu-profile.ts +45 -1
- package/cli/commands/daemon.ts +131 -33
- package/cli/commands/debug.ts +24 -17
- package/cli/commands/desktop.ts +7 -1
- package/cli/commands/detect.ts +101 -0
- package/cli/commands/detox.ts +6 -6
- package/cli/commands/device.ts +12 -12
- package/cli/commands/electron.ts +32 -14
- package/cli/commands/flow.ts +49 -41
- package/cli/commands/guest-host.ts +39 -1
- package/cli/commands/inspect/core.ts +14 -8
- package/cli/commands/inspect/list.ts +1 -1
- package/cli/commands/inspect/settle.ts +5 -3
- package/cli/commands/inspect/settling.ts +229 -44
- package/cli/commands/inspect/wait-idle.ts +3 -2
- package/cli/commands/inspect.ts +105 -93
- package/cli/commands/install-cli.ts +36 -15
- package/cli/commands/install-desktop.ts +68 -195
- package/cli/commands/kotlin.ts +6 -5
- package/cli/commands/login.ts +5 -5
- package/cli/commands/maestro-compare.ts +554 -0
- package/cli/commands/maestro-generate.ts +6 -3
- package/cli/commands/maestro.ts +22 -0
- package/cli/commands/mode.ts +2 -2
- package/cli/commands/no-bridge-hint.ts +6 -2
- package/cli/commands/platform.ts +35 -6
- package/cli/commands/preview.ts +6 -0
- package/cli/commands/project-report.ts +10 -12
- package/cli/commands/record.ts +37 -37
- package/cli/commands/runtime.ts +9 -9
- package/cli/commands/screenshot-layers.ts +4 -4
- package/cli/commands/screenshot-mode.ts +2 -2
- package/cli/commands/screenshot.ts +8 -8
- package/cli/commands/screenshots-capture.ts +2 -2
- package/cli/commands/serve.ts +9 -12
- package/cli/commands/setup.ts +29 -14
- package/cli/commands/shell-boolean-mode.ts +2 -2
- package/cli/commands/show-touches-mode.ts +2 -2
- package/cli/commands/skills.ts +11 -11
- package/cli/commands/swift.ts +29 -11
- package/cli/commands/telemetry.ts +2 -2
- package/cli/commands/test.ts +5 -0
- package/cli/commands/three-mode.ts +3 -3
- package/cli/commands/timeline.ts +4 -4
- package/cli/commands/upgrade.ts +2 -2
- package/cli/commands/upload.ts +15 -15
- package/cli/commands/what-happened.ts +2 -2
- package/cli/current-sim.ts +6 -3
- package/cli/desktop-companion.ts +55 -149
- package/cli/dev-build-freshness.ts +2 -2
- package/cli/drivers/desktop.ts +17 -9
- package/cli/drivers/electron.ts +1 -2
- package/cli/drivers/playwright-sim-host.ts +11 -2
- package/cli/drivers/playwright.ts +35 -2
- package/cli/drivers/types.ts +8 -0
- package/cli/maestro-compare.ts +670 -0
- package/cli/outbound-endpoints.ts +46 -8
- package/cli/recording-access.ts +6 -6
- package/cli/run-registry.ts +1 -1
- package/cli/runtime-compat.ts +5 -1
- package/cli/send-to-box.ts +3 -3
- package/cli/shell-init.ts +2 -1
- package/cli/ws-bridge.ts +9 -5
- package/detox/element-types.ts +1 -0
- package/detox/gestures.ts +3 -3
- package/detox/index.ts +67 -38
- package/detox/navigation-lifecycle.ts +9 -6
- package/detox/proof-frame.cjs +6 -4
- package/dist-lib/agent-daemon-client.cjs +1 -1
- package/dist-lib/agent-events.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-input.cjs +42 -17
- package/dist-lib/bridge-contract-input.mjs +41 -16
- package/dist-lib/bridge-contract.cjs +1 -4
- package/dist-lib/bridge-contract.mjs +1 -3
- package/dist-lib/bundle-channel.cjs +2918 -550
- package/dist-lib/capture-contract.cjs +65 -24
- package/dist-lib/capture-contract.mjs +63 -24
- package/dist-lib/cloud-contract.cjs +2 -2
- package/dist-lib/cloud-contract.mjs +2 -2
- package/dist-lib/cloud-test-args.cjs +1 -1
- package/dist-lib/cloud-test-args.mjs +1 -1
- package/dist-lib/cloud.cjs +3 -3
- package/dist-lib/cloud.mjs +3 -3
- package/dist-lib/config.cjs +15 -5
- package/dist-lib/config.mjs +154 -0
- package/dist-lib/detox/index.cjs +495 -139
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/expo-swift-bundle.cjs +1168 -238
- package/dist-lib/expo-swift-metadata.cjs +34 -23
- package/dist-lib/expo-swift-metadata.mjs +32 -23
- package/dist-lib/home-paths.cjs +2 -2
- package/dist-lib/host/bridge-host.cjs +2938 -654
- package/dist-lib/host/fetch-proxy-handler.cjs +14 -1
- package/dist-lib/host/fetch-proxy-overrides.cjs +7 -1
- package/dist-lib/host/fetch-proxy-overrides.mjs +5 -1
- package/dist-lib/host/replacement-module-handler.cjs +2 -2
- package/dist-lib/host/websocket-proxy.cjs +1 -1
- package/dist-lib/index.cjs +999 -353
- package/dist-lib/jump-to-source-babel.cjs +1 -1
- package/dist-lib/jump-to-source-native.cjs +1 -1
- package/dist-lib/kotlin-host.cjs +332 -19
- package/dist-lib/menu.cjs +1 -1
- package/dist-lib/menu.mjs +1 -1
- package/dist-lib/metro-fingerprint-registry.cjs +1 -1
- package/dist-lib/metro-fingerprint-registry.mjs +1 -1
- package/dist-lib/metro-production-bundle.cjs +7 -7
- package/dist-lib/metro-production-bundle.mjs +5 -5
- package/dist-lib/metro.cjs +688 -250
- package/dist-lib/native-app-identity-project.cjs +2647 -0
- package/dist-lib/native-app-identity-project.mjs +1257 -0
- package/dist-lib/native-app-identity.cjs +325 -25
- package/dist-lib/native-app-identity.mjs +323 -25
- package/dist-lib/native-firebase-metadata.cjs +1 -1
- package/dist-lib/native-firebase-metadata.mjs +1 -1
- package/dist-lib/plist.cjs +1 -1
- package/dist-lib/plist.mjs +1 -1
- package/dist-lib/profiles.cjs +1 -1
- package/dist-lib/public-brand.cjs +1 -1
- package/dist-lib/react-native-host-modules.cjs +5 -1
- package/dist-lib/react-native-host-modules.mjs +5 -1
- package/dist-lib/scripts/dev-server-scanner.cjs +57 -32
- package/dist-lib/sdk.cjs +231 -51
- package/dist-lib/sdk.mjs +231 -51
- package/dist-lib/skills.cjs +4107 -1374
- package/dist-lib/swift-compile.cjs +290 -30
- package/dist-lib/swift-compile.mjs +290 -30
- package/dist-lib/swift-package.cjs +143 -12
- package/dist-lib/swift-package.mjs +137 -11
- package/dist-lib/swift-submit.cjs +47 -5
- package/dist-lib/swift-submit.mjs +42 -5
- package/dist-lib/swift-toolchain.cjs +7 -2
- package/dist-lib/swift.cjs +1 -1
- package/dist-lib/vite-swift.cjs +1392 -458
- package/dist-lib/vite.cjs +13 -17
- package/dist-lib/worklet-executable.cjs +248 -33
- package/dist-lib/worklet-executable.mjs +248 -33
- package/install.sh +10 -1
- package/kotlin/{AppSources → AndroidViewSources}/android/content/res/Resources.kt +9 -9
- package/kotlin/AndroidViewSources/android/graphics/Canvas.kt +20 -0
- package/kotlin/AndroidViewSources/android/view/View.kt +211 -0
- package/kotlin/AndroidViewSources/android/widget/FrameLayout.kt +61 -0
- package/kotlin/AndroidViewSources/android/widget/LinearLayout.kt +49 -0
- package/kotlin/AppSources/android/view/Window.kt +36 -0
- package/kotlin/AppSources/android/view/WindowInsets.kt +9 -0
- package/kotlin/AppSources/android/view/WindowInsetsController.kt +5 -0
- package/kotlin/AppSources/android/window/OnBackInvokedDispatcher.kt +48 -0
- package/kotlin/AppSources/androidx/activity/OnBackPressedDispatcher.kt +20 -5
- package/kotlin/AppSources/androidx/compose/foundation/layout/WindowInsets.kt +15 -0
- package/kotlin/AppSources/androidx/compose/ui/platform/ComposeView.kt +2 -1
- package/kotlin/AppSources/dev/peach/app/PeachApp.kt +42 -50
- package/kotlin/ComposeSources/PeachComposeHost.kt +200 -84
- package/kotlin/ExpoComposeSources/PeachAndroidView.kt +87 -0
- package/kotlin/ExpoComposeSources/PeachExpoViewMount.kt +24 -0
- package/kotlin/ExpoComposeSources/dev/peach/expo/PeachExpoCompose.kt +28 -0
- package/kotlin/ExpoComposeSources/expo/modules/kotlin/views/ExpoComposeView.kt +70 -0
- package/kotlin/ExpoSources/dev/peach/expo/PeachExpoRuntime.kt +513 -0
- package/kotlin/ExpoSources/dev/peach/expo/PeachExpoTypes.kt +173 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/AppContext.kt +20 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/Promise.kt +19 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/classcomponent/ClassComponentBuilder.kt +198 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/exception/CodedException.kt +126 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/functions/Functions.kt +132 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/jni/JavaScriptTypedArray.kt +81 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/modules/Module.kt +98 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/objects/ObjectDefinitionBuilder.kt +236 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/records/Record.kt +12 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/runtime/Runtime.kt +9 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/sharedobjects/SharedObject.kt +50 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/sharedobjects/SharedObjectRegistry.kt +57 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/sharedobjects/SharedRef.kt +19 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/typedarray/ConcreteTypedArrays.kt +158 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/typedarray/GenericTypedArray.kt +8 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/typedarray/TypedArray.kt +29 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/typedarray/TypedArrayIterator.kt +9 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/types/AnyType.kt +155 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/types/Either.kt +91 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/types/Enumerable.kt +6 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/viewevent/ViewEvent.kt +54 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/views/ExpoView.kt +23 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/views/ViewDefinitionBuilder.kt +71 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/views/ViewProps.kt +35 -0
- package/kotlin/README.md +13 -3
- package/kotlin/Sources/android/os/Build.kt +17 -0
- package/kotlin/Sources/android/os/Handler.kt +35 -0
- package/kotlin/Sources/android/os/Looper.kt +17 -0
- package/kotlin/Sources/android/os/MessageQueue.kt +56 -0
- package/kotlin/Sources/android/os/SystemClock.kt +14 -0
- package/kotlin/Sources/android/util/Log.kt +64 -0
- package/kotlin/Sources/java/security/MessageDigest.kt +114 -0
- package/kotlin/Sources/kotlin/text/StringFormat.kt +9 -0
- package/kotlin/Sources/org/json/JSON.kt +44 -0
- package/kotlin/fixtures/counter/Counter.d.kt.ts +1 -0
- package/kotlin/fixtures/counter/Counter.kt +10 -3
- package/kotlin/fixtures/counter/CounterApp.native.tsx +1 -1
- package/kotlin/fixtures/counter/vite.config.ts +2 -2
- package/kotlin/fixtures/headless-counter/Headless.kt +7 -6
- package/kotlin/fixtures/import-animation/Animation.d.kt.ts +7 -0
- package/kotlin/fixtures/import-animation/Animation.kt +80 -0
- package/kotlin/fixtures/import-animation/ImportAnimation.native.tsx +13 -0
- package/kotlin/fixtures/import-animation/README.md +24 -0
- package/kotlin/fixtures/import-animation/app/_layout.tsx +4 -0
- package/kotlin/fixtures/import-animation/app/index+spa.tsx +1 -0
- package/kotlin/fixtures/import-animation/app/routes.d.ts +18 -0
- package/kotlin/fixtures/import-animation/package.json +23 -0
- package/kotlin/fixtures/import-animation/tsconfig.json +20 -0
- package/kotlin/fixtures/import-animation/vite.config.ts +20 -0
- package/kotlin/fixtures/import-editor/Editor.d.kt.ts +7 -0
- package/kotlin/fixtures/import-editor/Editor.kt +59 -0
- package/kotlin/fixtures/import-editor/ImportEditor.native.tsx +23 -0
- package/kotlin/fixtures/import-editor/README.md +27 -0
- package/kotlin/fixtures/import-editor/app/_layout.tsx +4 -0
- package/kotlin/fixtures/import-editor/app/index+spa.tsx +1 -0
- package/kotlin/fixtures/import-editor/package.json +23 -0
- package/kotlin/fixtures/import-editor/tsconfig.json +20 -0
- package/kotlin/fixtures/import-editor/vite.config.ts +20 -0
- package/kotlin/fixtures/import-effects/Effects.d.kt.ts +7 -0
- package/kotlin/fixtures/import-effects/Effects.kt +87 -0
- package/kotlin/fixtures/import-effects/ImportEffects.native.tsx +13 -0
- package/kotlin/fixtures/import-effects/README.md +19 -0
- package/kotlin/fixtures/import-effects/app/_layout.tsx +4 -0
- package/kotlin/fixtures/import-effects/app/index+spa.tsx +1 -0
- package/kotlin/fixtures/import-effects/package.json +23 -0
- package/kotlin/fixtures/import-effects/tsconfig.json +20 -0
- package/kotlin/fixtures/import-effects/vite.config.ts +20 -0
- package/kotlin/fixtures/import-layout/ImportLayout.native.tsx +13 -0
- package/kotlin/fixtures/import-layout/Layout.d.kt.ts +7 -0
- package/kotlin/fixtures/import-layout/Layout.kt +72 -0
- package/kotlin/fixtures/import-layout/README.md +24 -0
- package/kotlin/fixtures/import-layout/app/_layout.tsx +4 -0
- package/kotlin/fixtures/import-layout/app/index+spa.tsx +1 -0
- package/kotlin/fixtures/import-layout/package.json +23 -0
- package/kotlin/fixtures/import-layout/tsconfig.json +20 -0
- package/kotlin/fixtures/import-layout/vite.config.ts +20 -0
- package/kotlin/fixtures/import-navigation/ImportNavigation.native.tsx +18 -0
- package/kotlin/fixtures/import-navigation/Navigation.d.kt.ts +7 -0
- package/kotlin/fixtures/import-navigation/Navigation.kt +104 -0
- package/kotlin/fixtures/import-navigation/README.md +31 -0
- package/kotlin/fixtures/import-navigation/app/_layout.tsx +4 -0
- package/kotlin/fixtures/import-navigation/app/index+spa.tsx +1 -0
- package/kotlin/fixtures/import-navigation/package.json +23 -0
- package/kotlin/fixtures/import-navigation/tsconfig.json +20 -0
- package/kotlin/fixtures/import-navigation/vite.config.ts +20 -0
- package/kotlin/fixtures/import-overlays/ImportOverlays.native.tsx +29 -0
- package/kotlin/fixtures/import-overlays/Overlays.d.kt.ts +7 -0
- package/kotlin/fixtures/import-overlays/Overlays.kt +93 -0
- package/kotlin/fixtures/import-overlays/README.md +34 -0
- package/kotlin/fixtures/import-overlays/app/_layout.tsx +4 -0
- package/kotlin/fixtures/import-overlays/app/index+spa.tsx +1 -0
- package/kotlin/fixtures/import-overlays/package.json +23 -0
- package/kotlin/fixtures/import-overlays/tsconfig.json +20 -0
- package/kotlin/fixtures/import-overlays/vite.config.ts +20 -0
- package/kotlin/fixtures/import-scroll/ImportScroll.native.tsx +13 -0
- package/kotlin/fixtures/import-scroll/README.md +23 -0
- package/kotlin/fixtures/import-scroll/Scroll.d.kt.ts +7 -0
- package/kotlin/fixtures/import-scroll/Scroll.kt +91 -0
- package/kotlin/fixtures/import-scroll/app/_layout.tsx +4 -0
- package/kotlin/fixtures/import-scroll/app/index+spa.tsx +1 -0
- package/kotlin/fixtures/import-scroll/package.json +23 -0
- package/kotlin/fixtures/import-scroll/tsconfig.json +20 -0
- package/kotlin/fixtures/import-scroll/vite.config.ts +20 -0
- package/kotlin/fixtures/import-selection/ImportSelection.native.tsx +44 -0
- package/kotlin/fixtures/import-selection/README.md +32 -0
- package/kotlin/fixtures/import-selection/Selection.d.kt.ts +8 -0
- package/kotlin/fixtures/import-selection/Selection.kt +78 -0
- package/kotlin/fixtures/import-selection/app/_layout.tsx +4 -0
- package/kotlin/fixtures/import-selection/app/index+spa.tsx +1 -0
- package/kotlin/fixtures/import-selection/package.json +23 -0
- package/kotlin/fixtures/import-selection/tsconfig.json +20 -0
- package/kotlin/fixtures/import-selection/vite.config.ts +20 -0
- package/kotlin/fixtures/import-surfaces/ImportSurfaces.native.tsx +13 -0
- package/kotlin/fixtures/import-surfaces/README.md +22 -0
- package/kotlin/fixtures/import-surfaces/Surfaces.d.kt.ts +7 -0
- package/kotlin/fixtures/import-surfaces/Surfaces.kt +64 -0
- package/kotlin/fixtures/import-surfaces/app/_layout.tsx +4 -0
- package/kotlin/fixtures/import-surfaces/app/index+spa.tsx +1 -0
- package/kotlin/fixtures/import-surfaces/package.json +23 -0
- package/kotlin/fixtures/import-surfaces/tsconfig.json +20 -0
- package/kotlin/fixtures/import-surfaces/vite.config.ts +20 -0
- package/kotlin/fixtures/import-values/ImportValues.native.tsx +35 -0
- package/kotlin/fixtures/import-values/README.md +23 -0
- package/kotlin/fixtures/import-values/Values.d.kt.ts +11 -0
- package/kotlin/fixtures/import-values/Values.kt +66 -0
- package/kotlin/fixtures/import-values/app/_layout.tsx +4 -0
- package/kotlin/fixtures/import-values/app/index+spa.tsx +1 -0
- package/kotlin/fixtures/import-values/package.json +23 -0
- package/kotlin/fixtures/import-values/tsconfig.json +20 -0
- package/kotlin/fixtures/import-values/vite.config.ts +20 -0
- package/kotlin/fixtures/kotlin-app-variants/BarBehavior.kt +38 -0
- package/kotlin/fixtures/kotlin-app-variants/BarVisibility.kt +36 -0
- package/kotlin/fixtures/kotlin-app-variants/Ime.kt +3 -1
- package/kotlin/fixtures/kotlin-app-variants/TransientInsets.kt +50 -0
- package/kotlin/fork/NOTICE +6 -1
- package/kotlin/fork/README.md +15 -7
- package/kotlin/fork/build.sh +2 -0
- package/kotlin/fork/compose-worker-globals.patch +186 -4
- package/kotlin/fork/fork.json +2 -2
- package/kotlin/fork/skiko-worker-clock.patch +12 -0
- package/kotlin/toolchain.json +12 -12
- package/kotlin/tools/expo-types.main.kts +115 -0
- package/package.json +17 -23
- package/scripts/dev-server-scanner.ts +92 -66
- package/skills/contrast/SKILL.md +2 -2
- package/skills/peach-debug/SKILL.md +1 -1
- package/skills/peach-perf/SKILL.md +1 -1
- package/skills/peach-setup/SKILL.md +2 -1
- package/skills/peach-test/SKILL.md +8 -0
- package/src/assetCatalogContract.ts +43 -1
- package/src/bridge-contract-input.ts +46 -19
- package/src/bridge-contract.ts +0 -1
- package/src/bundle-channel.mjs +197 -84
- package/src/bundleGlobalFooter.ts +38 -0
- package/src/capture-contract.ts +107 -33
- package/src/cloud-contract.ts +5 -1
- package/src/cloud.ts +5 -2
- package/src/config.ts +22 -3
- package/src/configured-bundle-producer.ts +1 -1
- package/src/desktop-host-delivery.ts +95 -1
- package/src/expo-kotlin-bundle.ts +29 -0
- package/src/expo-kotlin-host.ts +201 -0
- package/src/expo-swift-host.ts +96 -76
- package/src/expoKotlinContract.ts +70 -0
- package/src/expoSwiftContract.ts +4 -25
- package/src/home-paths.ts +7 -4
- package/src/host/bridge-host.ts +23 -3
- package/src/host/fetch-proxy-handler.ts +13 -0
- package/src/host/fetch-proxy-overrides.ts +11 -0
- package/src/host/replacement-module-handler.ts +5 -2
- package/src/index.ts +3 -1
- package/src/kotlin-host.ts +463 -19
- package/src/metro-plugin.ts +56 -28
- package/src/metro-production-bundle.ts +2 -2
- package/src/native-app-identity-project.ts +190 -0
- package/src/native-app-identity.ts +398 -34
- package/src/native-firebase-config.ts +69 -15
- package/src/native-seam-manifest.ts +6 -0
- package/src/one-widget-discovery.ts +2 -1
- package/src/openstep-plist.ts +107 -0
- package/src/react-native-host-modules.ts +4 -0
- package/src/runtime-assets.ts +2 -2
- package/src/sim-client.ts +2 -2
- package/src/swift-binary-modules.ts +3 -1
- package/src/swift-compile.ts +286 -38
- package/src/swift-distribution-contract.ts +4 -0
- package/src/swift-distribution.lock.json +123 -12
- package/src/swift-distribution.ts +7 -3
- package/src/swift-host.ts +298 -83
- package/src/swift-package-manifest.ts +29 -2
- package/src/swift-package.ts +180 -10
- package/src/swift-packages.ts +4 -0
- package/src/swift-standin-emit.ts +4 -1
- package/src/swift-standins.ts +274 -15
- package/src/swift-submit.ts +62 -7
- package/src/swift-toolchain.ts +6 -1
- package/src/swiftContract.ts +126 -3
- package/src/vite-plugin-one.ts +13 -16
- package/src/vite-plugin-swift.ts +4 -5
- package/src/vite-plugin.ts +360 -144
- package/src/vite.d.ts +1 -1
- package/src/worker-system-chunks.ts +221 -0
- package/src/worklet-executable.ts +348 -38
- package/src/worklets-babel.ts +1 -1
- package/src/xcode-project.ts +243 -127
- package/dist-lib/agent-identity.cjs +0 -39
- package/dist-lib/agent-sessions.cjs +0 -760
- package/dist-lib/cli-constants.cjs +0 -32
- package/dist-lib/render-mode.cjs +0 -44
- package/kotlin/AppSources/android/view/View.kt +0 -74
- package/kotlin/AppSources/android/widget/FrameLayout.kt +0 -6
- package/src/render-mode.ts +0 -15
- /package/kotlin/{AppSources → AndroidViewSources}/android/content/Context.kt +0 -0
- /package/kotlin/{AppSources → AndroidViewSources}/android/content/res/Configuration.kt +0 -0
- /package/kotlin/{AppSources → AndroidViewSources}/android/graphics/Color.kt +0 -0
- /package/kotlin/{AppSources → AndroidViewSources}/android/util/DisplayMetrics.kt +0 -0
- /package/kotlin/{AppSources → AndroidViewSources}/dev/peach/app/JavaFormat.kt +0 -0
- /package/kotlin/{AppSources → Sources}/java/lang/Runnable.kt +0 -0
package/dist-lib/detox/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*!
|
|
1
|
+
/*! peach v0.1.1399 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
@@ -1252,6 +1252,7 @@ var require_attempt_events = __commonJS({
|
|
|
1252
1252
|
var require_proof_frame = __commonJS({
|
|
1253
1253
|
"detox/proof-frame.cjs"(exports2, module2) {
|
|
1254
1254
|
"use strict";
|
|
1255
|
+
var { abs, max } = Math;
|
|
1255
1256
|
var PROOF_CONTENT_DEFINITION = Object.freeze({
|
|
1256
1257
|
channelThreshold: 24,
|
|
1257
1258
|
contentBandInsetFraction: 0.08,
|
|
@@ -1296,10 +1297,10 @@ var require_proof_frame = __commonJS({
|
|
|
1296
1297
|
for (let y = yStart; y < yEnd; y++) {
|
|
1297
1298
|
for (let x = 0; x < width; x++) {
|
|
1298
1299
|
const offset = (y * width + x) * 4;
|
|
1299
|
-
if (
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1300
|
+
if (max(
|
|
1301
|
+
abs(data[offset] - dominant.red),
|
|
1302
|
+
abs(data[offset + 1] - dominant.green),
|
|
1303
|
+
abs(data[offset + 2] - dominant.blue)
|
|
1303
1304
|
) >= PROOF_CONTENT_DEFINITION.channelThreshold) {
|
|
1304
1305
|
contentPixels++;
|
|
1305
1306
|
}
|
|
@@ -1954,9 +1955,19 @@ function readBrowserCompositeCaptureRequest(value) {
|
|
|
1954
1955
|
|
|
1955
1956
|
// ../peach-compat/src/stubs/native-seams/react-native-cookies.ts
|
|
1956
1957
|
var cookieListeners = /* @__PURE__ */ new WeakMap();
|
|
1958
|
+
var cookiePolicies = /* @__PURE__ */ new WeakMap();
|
|
1959
|
+
var cookieBatches = /* @__PURE__ */ new WeakMap();
|
|
1960
|
+
function notifyCookieListeners(store) {
|
|
1961
|
+
const batch = cookieBatches.get(store);
|
|
1962
|
+
if (batch) {
|
|
1963
|
+
batch.changed = true;
|
|
1964
|
+
return;
|
|
1965
|
+
}
|
|
1966
|
+
for (const listener of cookieListeners.get(store) ?? []) listener();
|
|
1967
|
+
}
|
|
1957
1968
|
var WebKitCookieJar = class extends Map {
|
|
1958
1969
|
changed() {
|
|
1959
|
-
|
|
1970
|
+
notifyCookieListeners(this);
|
|
1960
1971
|
}
|
|
1961
1972
|
set(key, value) {
|
|
1962
1973
|
super.set(key, value);
|
|
@@ -1981,15 +1992,18 @@ var cookieStores = {
|
|
|
1981
1992
|
function createCookieOperations() {
|
|
1982
1993
|
const INVALID_URL_MISSING_HTTP = "Invalid URL: It may be missing a protocol (ex. http:// or https://).";
|
|
1983
1994
|
const INVALID_COOKIE_VALUES = "Unable to add cookie - invalid values";
|
|
1995
|
+
function cookieError(kind, message) {
|
|
1996
|
+
return Object.assign(new Error(message), { kind });
|
|
1997
|
+
}
|
|
1984
1998
|
function parseCookieUrl2(url) {
|
|
1985
1999
|
try {
|
|
1986
2000
|
const parsed = new URL(url);
|
|
1987
2001
|
if (!parsed.hostname || parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
1988
|
-
throw
|
|
2002
|
+
throw cookieError("invalid-url", INVALID_URL_MISSING_HTTP);
|
|
1989
2003
|
}
|
|
1990
2004
|
return parsed;
|
|
1991
2005
|
} catch {
|
|
1992
|
-
throw
|
|
2006
|
+
throw cookieError("invalid-url", INVALID_URL_MISSING_HTTP);
|
|
1993
2007
|
}
|
|
1994
2008
|
}
|
|
1995
2009
|
function normalizedDomain2(domain) {
|
|
@@ -2036,12 +2050,13 @@ function createCookieOperations() {
|
|
|
2036
2050
|
function setCookie2(store, url, cookie) {
|
|
2037
2051
|
const parsed = parseCookieUrl2(url);
|
|
2038
2052
|
if (!cookie || typeof cookie.name !== "string" || cookie.name.length === 0 || typeof cookie.value !== "string") {
|
|
2039
|
-
throw
|
|
2053
|
+
throw cookieError("invalid-cookie", INVALID_COOKIE_VALUES);
|
|
2040
2054
|
}
|
|
2041
2055
|
const suppliedDomain = typeof cookie.domain === "string" && cookie.domain.length > 0 ? cookie.domain : null;
|
|
2042
2056
|
const domain = suppliedDomain ?? parsed.hostname;
|
|
2043
2057
|
if (!domainMatches2(parsed.hostname, domain, suppliedDomain === null)) {
|
|
2044
|
-
throw
|
|
2058
|
+
throw cookieError(
|
|
2059
|
+
"domain-mismatch",
|
|
2045
2060
|
`Cookie URL host ${parsed.hostname} and domain ${domain} mismatched. The cookie won't set correctly.`
|
|
2046
2061
|
);
|
|
2047
2062
|
}
|
|
@@ -2064,16 +2079,16 @@ function createCookieOperations() {
|
|
|
2064
2079
|
storeCookie2(store, stored);
|
|
2065
2080
|
return true;
|
|
2066
2081
|
}
|
|
2067
|
-
function
|
|
2068
|
-
const parsed = parseCookieUrl2(url);
|
|
2082
|
+
function cookiesMatching2(store, parsed) {
|
|
2069
2083
|
purgeExpired2(store);
|
|
2084
|
+
return [...store.values()].filter(
|
|
2085
|
+
(cookie) => domainMatches2(parsed.hostname, cookie.domain, cookie.hostOnly) && pathMatches2(parsed.pathname || "/", cookie.path) && (!cookie.secure || parsed.protocol === "https:" || parsed.protocol === "wss:")
|
|
2086
|
+
);
|
|
2087
|
+
}
|
|
2088
|
+
function getCookies2(store, url) {
|
|
2070
2089
|
const cookies = {};
|
|
2071
|
-
for (const cookie of store
|
|
2072
|
-
if (!domainMatches2(parsed.hostname, cookie.domain, cookie.hostOnly)) continue;
|
|
2073
|
-
if (!pathMatches2(parsed.pathname || "/", cookie.path)) continue;
|
|
2074
|
-
if (cookie.secure && parsed.protocol !== "https:") continue;
|
|
2090
|
+
for (const cookie of cookiesMatching2(store, parseCookieUrl2(url)))
|
|
2075
2091
|
cookies[cookie.name] = publicCookie2(cookie);
|
|
2076
|
-
}
|
|
2077
2092
|
return cookies;
|
|
2078
2093
|
}
|
|
2079
2094
|
function getAllCookies2(store) {
|
|
@@ -2084,12 +2099,12 @@ function createCookieOperations() {
|
|
|
2084
2099
|
}
|
|
2085
2100
|
function cookieFromResponse2(cookieString) {
|
|
2086
2101
|
if (typeof cookieString !== "string" || cookieString.length === 0) {
|
|
2087
|
-
throw
|
|
2102
|
+
throw cookieError("invalid-cookie", INVALID_COOKIE_VALUES);
|
|
2088
2103
|
}
|
|
2089
2104
|
const parts = cookieString.split(";");
|
|
2090
2105
|
const nameValue = parts.shift()?.trim() ?? "";
|
|
2091
2106
|
const separator = nameValue.indexOf("=");
|
|
2092
|
-
if (separator <= 0) throw
|
|
2107
|
+
if (separator <= 0) throw cookieError("invalid-cookie", INVALID_COOKIE_VALUES);
|
|
2093
2108
|
const cookie = {
|
|
2094
2109
|
name: nameValue.slice(0, separator).trim(),
|
|
2095
2110
|
value: nameValue.slice(separator + 1).trim()
|
|
@@ -2167,6 +2182,7 @@ function createCookieOperations() {
|
|
|
2167
2182
|
}
|
|
2168
2183
|
return {
|
|
2169
2184
|
restore,
|
|
2185
|
+
cookiesMatching: cookiesMatching2,
|
|
2170
2186
|
parseCookieUrl: parseCookieUrl2,
|
|
2171
2187
|
normalizedDomain: normalizedDomain2,
|
|
2172
2188
|
domainMatches: domainMatches2,
|
|
@@ -2184,6 +2200,7 @@ function createCookieOperations() {
|
|
|
2184
2200
|
};
|
|
2185
2201
|
}
|
|
2186
2202
|
var {
|
|
2203
|
+
cookiesMatching,
|
|
2187
2204
|
parseCookieUrl,
|
|
2188
2205
|
normalizedDomain,
|
|
2189
2206
|
domainMatches,
|
|
@@ -2199,7 +2216,10 @@ var {
|
|
|
2199
2216
|
clearCookiesByName,
|
|
2200
2217
|
removeSessionCookies
|
|
2201
2218
|
} = createCookieOperations();
|
|
2202
|
-
var webKitCookieOperationsSource = `(
|
|
2219
|
+
var webKitCookieOperationsSource = `(() => {
|
|
2220
|
+
function __name(fn, name) { Object.defineProperty(fn, 'name', { value: name, configurable: true }); return fn; }
|
|
2221
|
+
return (${createCookieOperations.toString()})();
|
|
2222
|
+
})()`;
|
|
2203
2223
|
var webKitCookieStorage = {
|
|
2204
2224
|
default: cookieStores.webKit,
|
|
2205
2225
|
isolated: () => new WebKitCookieJar(),
|
|
@@ -2216,6 +2236,7 @@ var webKitCookieStorage = {
|
|
|
2216
2236
|
return Object.values(getCookies(store, url)).filter((cookie) => !script || !cookie.httpOnly).map((cookie) => `${cookie.name}=${cookie.value}`).join("; ");
|
|
2217
2237
|
},
|
|
2218
2238
|
script(store, url, line) {
|
|
2239
|
+
if (cookiePolicies.get(store) === 1) return;
|
|
2219
2240
|
const cookie = cookieFromResponse(line);
|
|
2220
2241
|
cookie.httpOnly = false;
|
|
2221
2242
|
const parsed = parseCookieUrl(url);
|
|
@@ -2227,6 +2248,31 @@ var webKitCookieStorage = {
|
|
|
2227
2248
|
if (store.get(key)?.httpOnly) return;
|
|
2228
2249
|
setCookie(store, url, cookie);
|
|
2229
2250
|
},
|
|
2251
|
+
policy(store) {
|
|
2252
|
+
return cookiePolicies.get(store) ?? 0;
|
|
2253
|
+
},
|
|
2254
|
+
setPolicy(store, policy) {
|
|
2255
|
+
cookiePolicies.set(store, policy);
|
|
2256
|
+
},
|
|
2257
|
+
matching(store, url) {
|
|
2258
|
+
let parsed;
|
|
2259
|
+
try {
|
|
2260
|
+
parsed = new URL(url);
|
|
2261
|
+
} catch {
|
|
2262
|
+
return [];
|
|
2263
|
+
}
|
|
2264
|
+
return cookiesMatching(store, parsed);
|
|
2265
|
+
},
|
|
2266
|
+
setMany(store, cookies) {
|
|
2267
|
+
const batch = { changed: false };
|
|
2268
|
+
cookieBatches.set(store, batch);
|
|
2269
|
+
try {
|
|
2270
|
+
for (const cookie of cookies) webKitCookieStorage.set(store, cookie);
|
|
2271
|
+
} finally {
|
|
2272
|
+
cookieBatches.delete(store);
|
|
2273
|
+
if (batch.changed) notifyCookieListeners(store);
|
|
2274
|
+
}
|
|
2275
|
+
},
|
|
2230
2276
|
all(store) {
|
|
2231
2277
|
purgeExpired(store);
|
|
2232
2278
|
return [...store.values()];
|
|
@@ -2247,6 +2293,7 @@ var webKitCookieStorage = {
|
|
|
2247
2293
|
// ../peach-engine/src/webview-automation-host.ts
|
|
2248
2294
|
var WEBVIEW_INSTANCE_ATTRIBUTE = "data-peach-webview";
|
|
2249
2295
|
var WEBVIEW_HOST_BINDING = "__peachWebViewHost";
|
|
2296
|
+
var WEBVIEW_EXPO_DOM_PROMPT_CAPABILITY = "peach.webview.expoDomPrompt";
|
|
2250
2297
|
var WEBVIEW_SCHEME_NAVIGATION_EVENT = "peach:webview-scheme-navigation";
|
|
2251
2298
|
var WEBVIEW_LOAD_EVENT = "peach:webview-load";
|
|
2252
2299
|
var WEBVIEW_NETWORK_NAVIGATION_EVENT = "peach:webview-network-navigation";
|
|
@@ -2273,7 +2320,9 @@ function readWebViewHostRequest(value) {
|
|
|
2273
2320
|
if (kind === "detach") return { kind, instanceId };
|
|
2274
2321
|
if (kind === "evaluate") {
|
|
2275
2322
|
const js = text("js");
|
|
2276
|
-
|
|
2323
|
+
const userAgent = field("userAgent");
|
|
2324
|
+
if (userAgent !== void 0 && typeof userAgent !== "string") return null;
|
|
2325
|
+
return js === null ? null : { kind, instanceId, js, ...typeof userAgent === "string" ? { userAgent } : {} };
|
|
2277
2326
|
}
|
|
2278
2327
|
if (kind === "tap") {
|
|
2279
2328
|
const x = field("x");
|
|
@@ -2289,6 +2338,21 @@ function readWebViewHostRequest(value) {
|
|
|
2289
2338
|
const afterContent = text("afterContent");
|
|
2290
2339
|
const incognito = field("incognito");
|
|
2291
2340
|
const rawHeaders = field("headers");
|
|
2341
|
+
const method = field("method");
|
|
2342
|
+
const bodyBase64 = field("bodyBase64");
|
|
2343
|
+
const data = field("documentData");
|
|
2344
|
+
let documentData;
|
|
2345
|
+
if (data !== void 0) {
|
|
2346
|
+
if (!data || typeof data !== "object" || !("bytesBase64" in data) || typeof data.bytesBase64 !== "string" || !("mimeType" in data) || typeof data.mimeType !== "string" || !("characterEncodingName" in data) || typeof data.characterEncodingName !== "string")
|
|
2347
|
+
return null;
|
|
2348
|
+
documentData = {
|
|
2349
|
+
bytesBase64: data.bytesBase64,
|
|
2350
|
+
mimeType: data.mimeType,
|
|
2351
|
+
characterEncodingName: data.characterEncodingName
|
|
2352
|
+
};
|
|
2353
|
+
}
|
|
2354
|
+
if (method !== void 0 && typeof method !== "string") return null;
|
|
2355
|
+
if (bodyBase64 !== void 0 && typeof bodyBase64 !== "string") return null;
|
|
2292
2356
|
if (frameName === null || url === null || config === null || beforeKey === null || beforeContent === null || afterContent === null || typeof incognito !== "boolean" || !rawHeaders || typeof rawHeaders !== "object") {
|
|
2293
2357
|
return null;
|
|
2294
2358
|
}
|
|
@@ -2302,6 +2366,9 @@ function readWebViewHostRequest(value) {
|
|
|
2302
2366
|
frameName,
|
|
2303
2367
|
url,
|
|
2304
2368
|
headers,
|
|
2369
|
+
...typeof method === "string" ? { method } : {},
|
|
2370
|
+
...typeof bodyBase64 === "string" ? { bodyBase64 } : {},
|
|
2371
|
+
...documentData ? { documentData } : {},
|
|
2305
2372
|
config,
|
|
2306
2373
|
beforeKey,
|
|
2307
2374
|
beforeContent,
|
|
@@ -2418,6 +2485,14 @@ function isSameDocumentRequest(requested, url) {
|
|
|
2418
2485
|
return false;
|
|
2419
2486
|
}
|
|
2420
2487
|
}
|
|
2488
|
+
function redirectRequestHeaders(headers, from, to, discardBody = false) {
|
|
2489
|
+
const sameOrigin = new URL(from).origin === new URL(to).origin;
|
|
2490
|
+
return Object.fromEntries(
|
|
2491
|
+
Object.entries(headers).filter(
|
|
2492
|
+
([name2]) => (sameOrigin || !/^(authorization|cookie)$/i.test(name2)) && (!discardBody || !/^content-(type|length)$/i.test(name2))
|
|
2493
|
+
)
|
|
2494
|
+
);
|
|
2495
|
+
}
|
|
2421
2496
|
var webViewAutomationHelpers = {
|
|
2422
2497
|
cookieOperations: createCookieOperations,
|
|
2423
2498
|
readRequest: readWebViewHostRequest,
|
|
@@ -2427,7 +2502,8 @@ var webViewAutomationHelpers = {
|
|
|
2427
2502
|
beforeContentScript: webViewBeforeContentScript,
|
|
2428
2503
|
evaluationScripts: webViewEvaluationScripts,
|
|
2429
2504
|
isAppScheme: isAppSchemeUrl,
|
|
2430
|
-
isSameDocument: isSameDocumentRequest
|
|
2505
|
+
isSameDocument: isSameDocumentRequest,
|
|
2506
|
+
redirectRequestHeaders
|
|
2431
2507
|
};
|
|
2432
2508
|
function webViewAutomationNames(timingName, bootstrapSource) {
|
|
2433
2509
|
return {
|
|
@@ -2459,6 +2535,96 @@ async function automateWebViewFrames(context, names, helpers) {
|
|
|
2459
2535
|
}
|
|
2460
2536
|
return session;
|
|
2461
2537
|
};
|
|
2538
|
+
const expoPromptHeader = "__EXPO_DOM_WEBVIEW_JS_EVAL__";
|
|
2539
|
+
const evaluateExpoPrompt = (page, instanceId, webViewId, message) => {
|
|
2540
|
+
return new Promise((resolve2) => {
|
|
2541
|
+
const workers = page.workers();
|
|
2542
|
+
let pending = workers.length;
|
|
2543
|
+
if (pending === 0) resolve2(null);
|
|
2544
|
+
for (const worker of workers) {
|
|
2545
|
+
void worker.evaluate(
|
|
2546
|
+
({ instanceId: instanceId2, webViewId: webViewId2, message: message2 }) => {
|
|
2547
|
+
const expo = Reflect.get(globalThis, "expo");
|
|
2548
|
+
if (!expo || typeof expo !== "object") return null;
|
|
2549
|
+
const modules = Reflect.get(expo, "modules");
|
|
2550
|
+
if (!modules || typeof modules !== "object") return null;
|
|
2551
|
+
const module2 = Reflect.get(modules, "ExpoDomWebViewModule");
|
|
2552
|
+
if (!module2 || typeof module2 !== "object") return null;
|
|
2553
|
+
const handler = Reflect.get(module2, "evalJsForWebViewPrompt");
|
|
2554
|
+
if (typeof handler !== "function") return null;
|
|
2555
|
+
const result = Reflect.apply(handler, module2, [
|
|
2556
|
+
instanceId2,
|
|
2557
|
+
webViewId2,
|
|
2558
|
+
message2
|
|
2559
|
+
]);
|
|
2560
|
+
if (!result || typeof result !== "object") return null;
|
|
2561
|
+
if (Reflect.get(result, "handled") !== true) return null;
|
|
2562
|
+
const response = Reflect.get(result, "response");
|
|
2563
|
+
return typeof response === "string" ? response : null;
|
|
2564
|
+
},
|
|
2565
|
+
{ instanceId, webViewId, message }
|
|
2566
|
+
).then(
|
|
2567
|
+
(response) => {
|
|
2568
|
+
if (typeof response === "string") resolve2(response);
|
|
2569
|
+
},
|
|
2570
|
+
() => {
|
|
2571
|
+
}
|
|
2572
|
+
).finally(() => {
|
|
2573
|
+
pending -= 1;
|
|
2574
|
+
if (pending === 0) resolve2(null);
|
|
2575
|
+
});
|
|
2576
|
+
}
|
|
2577
|
+
});
|
|
2578
|
+
};
|
|
2579
|
+
const observePageDialogs = (page) => {
|
|
2580
|
+
page.on("dialog", (dialog) => {
|
|
2581
|
+
const message = dialog.message();
|
|
2582
|
+
if (dialog.type() !== "prompt" || !message.startsWith(expoPromptHeader)) {
|
|
2583
|
+
void dialog.dismiss().catch(() => {
|
|
2584
|
+
});
|
|
2585
|
+
return;
|
|
2586
|
+
}
|
|
2587
|
+
let envelope;
|
|
2588
|
+
try {
|
|
2589
|
+
envelope = JSON.parse(message.slice(expoPromptHeader.length));
|
|
2590
|
+
} catch {
|
|
2591
|
+
void dialog.dismiss().catch(() => {
|
|
2592
|
+
});
|
|
2593
|
+
return;
|
|
2594
|
+
}
|
|
2595
|
+
if (!envelope || typeof envelope !== "object" && typeof envelope !== "function") {
|
|
2596
|
+
void dialog.dismiss().catch(() => {
|
|
2597
|
+
});
|
|
2598
|
+
return;
|
|
2599
|
+
}
|
|
2600
|
+
const instanceId = Reflect.get(envelope, "instanceId");
|
|
2601
|
+
const webViewId = Reflect.get(envelope, "webViewId");
|
|
2602
|
+
const params = Reflect.get(envelope, "params");
|
|
2603
|
+
if (typeof instanceId !== "string" || typeof webViewId !== "number" || !Number.isSafeInteger(webViewId) || webViewId < 0 || typeof params !== "string") {
|
|
2604
|
+
void dialog.dismiss().catch(() => {
|
|
2605
|
+
});
|
|
2606
|
+
return;
|
|
2607
|
+
}
|
|
2608
|
+
const bound = byInstance.get(instanceId);
|
|
2609
|
+
if (!bound || bound.page !== page) {
|
|
2610
|
+
void dialog.dismiss().catch(() => {
|
|
2611
|
+
});
|
|
2612
|
+
return;
|
|
2613
|
+
}
|
|
2614
|
+
const response = evaluateExpoPrompt(
|
|
2615
|
+
page,
|
|
2616
|
+
instanceId,
|
|
2617
|
+
webViewId,
|
|
2618
|
+
expoPromptHeader + params
|
|
2619
|
+
);
|
|
2620
|
+
void response.then(
|
|
2621
|
+
(response2) => response2 === null ? dialog.dismiss() : dialog.accept(response2)
|
|
2622
|
+
).catch(() => dialog.dismiss()).catch(() => {
|
|
2623
|
+
});
|
|
2624
|
+
});
|
|
2625
|
+
};
|
|
2626
|
+
for (const page of context.pages()) observePageDialogs(page);
|
|
2627
|
+
context.on("page", observePageDialogs);
|
|
2462
2628
|
const instanceOf = async (frame) => {
|
|
2463
2629
|
const page = frame.page();
|
|
2464
2630
|
if (frame.parentFrame() !== page.mainFrame()) return null;
|
|
@@ -2478,16 +2644,6 @@ async function automateWebViewFrames(context, names, helpers) {
|
|
|
2478
2644
|
).catch(() => {
|
|
2479
2645
|
});
|
|
2480
2646
|
};
|
|
2481
|
-
context.on("request", (request) => {
|
|
2482
|
-
if (request.serviceWorker()) return;
|
|
2483
|
-
if (!request.isNavigationRequest() || request.redirectedFrom()) return;
|
|
2484
|
-
if (!helpers.isAppScheme(request.url())) return;
|
|
2485
|
-
const frame = request.frame();
|
|
2486
|
-
void instanceOf(frame).then((instanceId) => {
|
|
2487
|
-
if (instanceId !== null)
|
|
2488
|
-
reportSchemeNavigation(frame.page(), instanceId, request.url());
|
|
2489
|
-
});
|
|
2490
|
-
});
|
|
2491
2647
|
const storeFirstPartyCookies = async (lines, url) => {
|
|
2492
2648
|
const now = Math.floor(Date.now() / 1e3);
|
|
2493
2649
|
for (const line of lines) {
|
|
@@ -2504,24 +2660,6 @@ async function automateWebViewFrames(context, names, helpers) {
|
|
|
2504
2660
|
}
|
|
2505
2661
|
}
|
|
2506
2662
|
};
|
|
2507
|
-
context.on("response", (response) => {
|
|
2508
|
-
const request = response.request();
|
|
2509
|
-
if (request.serviceWorker()) return;
|
|
2510
|
-
const frame = request.frame();
|
|
2511
|
-
if (request.isNavigationRequest()) return;
|
|
2512
|
-
if (frame.parentFrame() !== frame.page().mainFrame()) return;
|
|
2513
|
-
void (async () => {
|
|
2514
|
-
const lines = await response.headerValues("set-cookie");
|
|
2515
|
-
if (lines.length === 0) return;
|
|
2516
|
-
const instanceId = await instanceOf(frame);
|
|
2517
|
-
const bound = instanceId === null ? void 0 : byInstance.get(instanceId);
|
|
2518
|
-
if (!bound || bound.incognito) return;
|
|
2519
|
-
const fetchSite = await request.headerValue("sec-fetch-site");
|
|
2520
|
-
if (fetchSite !== "same-origin" && fetchSite !== "same-site") return;
|
|
2521
|
-
await storeFirstPartyCookies(lines, response.url());
|
|
2522
|
-
})().catch(() => {
|
|
2523
|
-
});
|
|
2524
|
-
});
|
|
2525
2663
|
const reportDocumentLoad = async (frameId, url, result) => {
|
|
2526
2664
|
const bound = byFrameId.get(frameId);
|
|
2527
2665
|
if (!bound || bound.navigation) return;
|
|
@@ -2535,22 +2673,45 @@ async function automateWebViewFrames(context, names, helpers) {
|
|
|
2535
2673
|
]
|
|
2536
2674
|
);
|
|
2537
2675
|
};
|
|
2676
|
+
const schemeNavigations = /* @__PURE__ */ new Set();
|
|
2538
2677
|
const watchDocumentNetwork = async (session) => {
|
|
2539
2678
|
const documents = /* @__PURE__ */ new Map();
|
|
2679
|
+
const loads = /* @__PURE__ */ new Map();
|
|
2680
|
+
const fetchSites = /* @__PURE__ */ new Map();
|
|
2540
2681
|
session.on(
|
|
2541
2682
|
"Network.requestWillBeSent",
|
|
2542
2683
|
(event) => {
|
|
2543
|
-
if (event.
|
|
2684
|
+
if (!event.frameId) return;
|
|
2685
|
+
if (event.type === "Document") {
|
|
2544
2686
|
documents.set(event.requestId, {
|
|
2545
2687
|
frameId: event.frameId,
|
|
2546
2688
|
url: event.request.url
|
|
2547
2689
|
});
|
|
2690
|
+
const bound = byFrameId.get(event.frameId);
|
|
2691
|
+
if (bound && !event.redirectResponse && helpers.isAppScheme(event.request.url) && !schemeNavigations.has(event.requestId)) {
|
|
2692
|
+
schemeNavigations.add(event.requestId);
|
|
2693
|
+
reportSchemeNavigation(bound.page, bound.instanceId, event.request.url);
|
|
2694
|
+
}
|
|
2695
|
+
} else if (byFrameId.has(event.frameId)) {
|
|
2696
|
+
loads.set(event.requestId, { frameId: event.frameId, url: event.request.url });
|
|
2697
|
+
}
|
|
2698
|
+
}
|
|
2699
|
+
);
|
|
2700
|
+
session.on(
|
|
2701
|
+
"Network.requestWillBeSentExtraInfo",
|
|
2702
|
+
(event) => {
|
|
2703
|
+
const site = Object.entries(event.headers).find(
|
|
2704
|
+
([name2]) => name2.toLowerCase() === "sec-fetch-site"
|
|
2705
|
+
);
|
|
2706
|
+
if (site) fetchSites.set(event.requestId, site[1]);
|
|
2548
2707
|
}
|
|
2549
2708
|
);
|
|
2550
2709
|
session.on(
|
|
2551
2710
|
"Network.responseReceivedExtraInfo",
|
|
2552
2711
|
(event) => {
|
|
2553
|
-
const
|
|
2712
|
+
const subresource = loads.get(event.requestId);
|
|
2713
|
+
const site = fetchSites.get(event.requestId);
|
|
2714
|
+
const load = subresource && (site === "same-origin" || site === "same-site") ? subresource : documents.get(event.requestId);
|
|
2554
2715
|
if (!load) return;
|
|
2555
2716
|
const bound = byFrameId.get(load.frameId);
|
|
2556
2717
|
if (!bound || bound.incognito) return;
|
|
@@ -2581,12 +2742,16 @@ async function automateWebViewFrames(context, names, helpers) {
|
|
|
2581
2742
|
);
|
|
2582
2743
|
session.on("Network.loadingFinished", (event) => {
|
|
2583
2744
|
documents.delete(event.requestId);
|
|
2745
|
+
loads.delete(event.requestId);
|
|
2746
|
+
fetchSites.delete(event.requestId);
|
|
2584
2747
|
});
|
|
2585
2748
|
session.on(
|
|
2586
2749
|
"Network.loadingFailed",
|
|
2587
2750
|
(event) => {
|
|
2588
2751
|
const load = documents.get(event.requestId);
|
|
2589
2752
|
documents.delete(event.requestId);
|
|
2753
|
+
loads.delete(event.requestId);
|
|
2754
|
+
fetchSites.delete(event.requestId);
|
|
2590
2755
|
if (!load || event.canceled) return;
|
|
2591
2756
|
const result = event.errorText === "net::ERR_CONNECTION_REFUSED" ? { kind: "refused" } : event.errorText === "net::ERR_UNSAFE_PORT" ? { kind: "restrictedPort" } : { kind: "ok" };
|
|
2592
2757
|
void reportDocumentLoad(load.frameId, load.url, result).catch(() => {
|
|
@@ -2696,6 +2861,25 @@ async function automateWebViewFrames(context, names, helpers) {
|
|
|
2696
2861
|
void fulfill(requestId, event, helpers.withFrameEmbedderHeaders(received2));
|
|
2697
2862
|
return;
|
|
2698
2863
|
}
|
|
2864
|
+
if (requestStage && event.resourceType === "Document" && bound.load?.documentData && helpers.isSameDocument(event.request.url, bound.load.url)) {
|
|
2865
|
+
const documentData = bound.load.documentData;
|
|
2866
|
+
bound.load = null;
|
|
2867
|
+
void settle("Fetch.fulfillRequest", {
|
|
2868
|
+
responseCode: 200,
|
|
2869
|
+
responseHeaders: helpers.withFrameEmbedderHeaders([
|
|
2870
|
+
{
|
|
2871
|
+
name: "Content-Type",
|
|
2872
|
+
value: documentData.mimeType + "; charset=" + documentData.characterEncodingName
|
|
2873
|
+
},
|
|
2874
|
+
{
|
|
2875
|
+
name: "Server-Timing",
|
|
2876
|
+
value: `${names.configTimingName};desc="${encodeURIComponent(bound.config)}"`
|
|
2877
|
+
}
|
|
2878
|
+
]),
|
|
2879
|
+
body: documentData.bytesBase64
|
|
2880
|
+
});
|
|
2881
|
+
return;
|
|
2882
|
+
}
|
|
2699
2883
|
if (requestStage && bound.navigation) {
|
|
2700
2884
|
const operations = cookieOperations;
|
|
2701
2885
|
const config = JSON.parse(bound.config);
|
|
@@ -2703,9 +2887,51 @@ async function automateWebViewFrames(context, names, helpers) {
|
|
|
2703
2887
|
const store = operations.restore(cookies);
|
|
2704
2888
|
const cookie = Object.values(operations.getCookies(store, event.request.url)).map((entry) => `${entry.name}=${entry.value}`).join("; ");
|
|
2705
2889
|
const headers = Object.entries(event.request.headers).filter(([name2]) => name2.toLowerCase() !== "cookie").map(([name2, value]) => ({ name: name2, value: String(value) }));
|
|
2890
|
+
if (typeof config.webKit.userAgent === "string") {
|
|
2891
|
+
for (let index = headers.length - 1; index >= 0; index--)
|
|
2892
|
+
if (headers[index].name.toLowerCase() === "user-agent") headers.splice(index, 1);
|
|
2893
|
+
headers.push({ name: "User-Agent", value: config.webKit.userAgent });
|
|
2894
|
+
}
|
|
2706
2895
|
if (cookie) headers.push({ name: "Cookie", value: cookie });
|
|
2896
|
+
const load = event.resourceType === "Document" ? bound.load : null;
|
|
2897
|
+
if (load && load.method === "GET" && load.bodyBase64 !== void 0) {
|
|
2898
|
+
bound.load = null;
|
|
2899
|
+
const navigation = bound.navigation.id;
|
|
2900
|
+
void (async () => {
|
|
2901
|
+
await bound.page.evaluate(
|
|
2902
|
+
([eventName, detail]) => window.dispatchEvent(new CustomEvent(eventName, { detail })),
|
|
2903
|
+
[
|
|
2904
|
+
names.networkNavigationEvent,
|
|
2905
|
+
{
|
|
2906
|
+
instanceId: bound.instanceId,
|
|
2907
|
+
navigation,
|
|
2908
|
+
phase: "failure",
|
|
2909
|
+
url: event.request.url,
|
|
2910
|
+
domain: "NSURLErrorDomain",
|
|
2911
|
+
code: -1103,
|
|
2912
|
+
description: "resource exceeds maximum size"
|
|
2913
|
+
}
|
|
2914
|
+
]
|
|
2915
|
+
);
|
|
2916
|
+
await settle("Fetch.failRequest", { errorReason: "Aborted" });
|
|
2917
|
+
})();
|
|
2918
|
+
return;
|
|
2919
|
+
}
|
|
2920
|
+
if (load) {
|
|
2921
|
+
for (const [name2, value] of Object.entries(load.headers)) {
|
|
2922
|
+
if (name2.toLowerCase() === "user-agent") continue;
|
|
2923
|
+
for (let index = headers.length - 1; index >= 0; index--)
|
|
2924
|
+
if (headers[index].name.toLowerCase() === name2.toLowerCase())
|
|
2925
|
+
headers.splice(index, 1);
|
|
2926
|
+
headers.push({ name: name2, value });
|
|
2927
|
+
}
|
|
2928
|
+
}
|
|
2707
2929
|
void settle("Fetch.continueRequest", {
|
|
2708
2930
|
headers,
|
|
2931
|
+
...load ? {
|
|
2932
|
+
method: load.method,
|
|
2933
|
+
...load.bodyBase64 !== void 0 ? { postData: load.bodyBase64 } : {}
|
|
2934
|
+
} : {},
|
|
2709
2935
|
interceptResponse: event.resourceType === "Document"
|
|
2710
2936
|
});
|
|
2711
2937
|
return;
|
|
@@ -2751,11 +2977,28 @@ async function automateWebViewFrames(context, names, helpers) {
|
|
|
2751
2977
|
}
|
|
2752
2978
|
if (bound.navigation && location) {
|
|
2753
2979
|
const target = new URL(location.value, event.request.url).href;
|
|
2980
|
+
if (bound.load) {
|
|
2981
|
+
const discardBody = (status === 301 || status === 302) && bound.load.method === "POST" || status === 303 && bound.load.method !== "HEAD";
|
|
2982
|
+
bound.load = {
|
|
2983
|
+
method: discardBody ? "GET" : bound.load.method,
|
|
2984
|
+
bodyBase64: discardBody ? void 0 : bound.load.bodyBase64,
|
|
2985
|
+
url: target,
|
|
2986
|
+
headers: helpers.redirectRequestHeaders(
|
|
2987
|
+
bound.load.headers,
|
|
2988
|
+
event.request.url,
|
|
2989
|
+
target,
|
|
2990
|
+
discardBody
|
|
2991
|
+
)
|
|
2992
|
+
};
|
|
2993
|
+
}
|
|
2754
2994
|
void decideNavigation(bound, {
|
|
2755
2995
|
phase: "redirect",
|
|
2756
2996
|
url: target,
|
|
2757
2997
|
status,
|
|
2758
|
-
mime: ""
|
|
2998
|
+
mime: "",
|
|
2999
|
+
headers: bound.load?.headers ?? {},
|
|
3000
|
+
method: bound.load?.method ?? event.request.method,
|
|
3001
|
+
bodyBase64: bound.load?.bodyBase64
|
|
2759
3002
|
}).then(
|
|
2760
3003
|
(allow) => allow ? continueRedirect() : settle("Fetch.failRequest", { errorReason: "Aborted" })
|
|
2761
3004
|
);
|
|
@@ -2777,6 +3020,7 @@ async function automateWebViewFrames(context, names, helpers) {
|
|
|
2777
3020
|
}
|
|
2778
3021
|
}
|
|
2779
3022
|
if (bound.navigation) {
|
|
3023
|
+
bound.load = null;
|
|
2780
3024
|
const config = JSON.parse(bound.config);
|
|
2781
3025
|
config.documentUrl = event.request.url;
|
|
2782
3026
|
bound.config = JSON.stringify(config);
|
|
@@ -2797,32 +3041,11 @@ async function automateWebViewFrames(context, names, helpers) {
|
|
|
2797
3041
|
if (await instanceOf(candidate) === bound.instanceId) frame = candidate;
|
|
2798
3042
|
}
|
|
2799
3043
|
if (!frame) return;
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
session = await pageSession(bound.page);
|
|
2806
|
-
const contexts = [];
|
|
2807
|
-
const collect = (event) => {
|
|
2808
|
-
contexts.push(event.context);
|
|
2809
|
-
};
|
|
2810
|
-
session.on("Runtime.executionContextCreated", collect);
|
|
2811
|
-
await session.send("Runtime.enable");
|
|
2812
|
-
await session.send("Runtime.disable");
|
|
2813
|
-
session.off("Runtime.executionContextCreated", collect);
|
|
2814
|
-
contextId = contexts.find(
|
|
2815
|
-
(entry) => entry.auxData?.frameId === bound.frameId && entry.auxData.isDefault
|
|
2816
|
-
)?.id;
|
|
2817
|
-
if (contextId === void 0) return;
|
|
2818
|
-
}
|
|
2819
|
-
try {
|
|
2820
|
-
for (const expression of scripts) {
|
|
2821
|
-
await session.send("Runtime.evaluate", { expression, contextId });
|
|
2822
|
-
}
|
|
2823
|
-
} finally {
|
|
2824
|
-
if (contextId === void 0) await session.detach().catch(() => {
|
|
2825
|
-
});
|
|
3044
|
+
for (const expression of scripts) {
|
|
3045
|
+
await frame.evaluate((source) => {
|
|
3046
|
+
;
|
|
3047
|
+
(0, eval)(source);
|
|
3048
|
+
}, expression);
|
|
2826
3049
|
}
|
|
2827
3050
|
};
|
|
2828
3051
|
await context.exposeBinding(names.hostBinding, async (source, value) => {
|
|
@@ -2874,6 +3097,12 @@ async function automateWebViewFrames(context, names, helpers) {
|
|
|
2874
3097
|
if (request.kind === "evaluate") {
|
|
2875
3098
|
const bound2 = byInstance.get(request.instanceId);
|
|
2876
3099
|
if (!bound2) return;
|
|
3100
|
+
if (request.userAgent !== void 0) {
|
|
3101
|
+
const config2 = JSON.parse(bound2.config);
|
|
3102
|
+
config2.webKit.userAgent = request.userAgent;
|
|
3103
|
+
bound2.config = JSON.stringify(config2);
|
|
3104
|
+
if (request.js === "") return;
|
|
3105
|
+
}
|
|
2877
3106
|
const scripts = helpers.evaluationScripts(request.js);
|
|
2878
3107
|
bound2.evaluations = bound2.evaluations.then(() => evaluateIn(bound2, scripts)).catch(() => {
|
|
2879
3108
|
});
|
|
@@ -2910,7 +3139,13 @@ async function automateWebViewFrames(context, names, helpers) {
|
|
|
2910
3139
|
incognito: request.incognito,
|
|
2911
3140
|
navigation: config.webKit ? { id: config.webKit.navigation, type: config.webKit.navigationType } : null,
|
|
2912
3141
|
decisions: /* @__PURE__ */ new Map(),
|
|
2913
|
-
load: {
|
|
3142
|
+
load: {
|
|
3143
|
+
url: request.url,
|
|
3144
|
+
headers: request.headers,
|
|
3145
|
+
method: request.method ?? "GET",
|
|
3146
|
+
bodyBase64: request.bodyBase64,
|
|
3147
|
+
documentData: request.documentData
|
|
3148
|
+
},
|
|
2914
3149
|
evaluations: Promise.resolve(),
|
|
2915
3150
|
frameSession: null
|
|
2916
3151
|
};
|
|
@@ -3063,6 +3298,14 @@ var WEBVIEW_FRAME_BRIDGE_SOURCE = `function (config) {
|
|
|
3063
3298
|
// originWhitelist and Linking handling) has to speak that url, so map the
|
|
3064
3299
|
// frame's own search and hash onto it.
|
|
3065
3300
|
var documentUrl = config.documentUrl;
|
|
3301
|
+
// document.write parses decoded Unicode; native retains the source byte metadata.
|
|
3302
|
+
if (config.dataDocumentMetadata) {
|
|
3303
|
+
var dataMetadata = config.dataDocumentMetadata;
|
|
3304
|
+
['characterSet', 'charset', 'inputEncoding'].forEach(function(name) {
|
|
3305
|
+
Object.defineProperty(document, name, { configurable: true, get: function() { return dataMetadata.encoding; } });
|
|
3306
|
+
});
|
|
3307
|
+
Object.defineProperty(document, 'contentType', { configurable: true, get: function() { return dataMetadata.mimeType; } });
|
|
3308
|
+
}
|
|
3066
3309
|
${WEBVIEW_FRAME_COLOR_SCHEME_SOURCE} var webKit = config.webKit || null;
|
|
3067
3310
|
function nativeValue(value, seen) {
|
|
3068
3311
|
if (value === null) return { type: 'null' };
|
|
@@ -3091,6 +3334,8 @@ ${WEBVIEW_FRAME_COLOR_SCHEME_SOURCE} var webKit = config.webKit || null;
|
|
|
3091
3334
|
var scriptReplies = new Map();
|
|
3092
3335
|
var nextScriptReply = 0;
|
|
3093
3336
|
function setMessageHandlers(names) {
|
|
3337
|
+
if (names.length === 0) { delete window.webkit; return; }
|
|
3338
|
+
if (!window.webkit) window.webkit = { messageHandlers: Object.create(null) };
|
|
3094
3339
|
Object.keys(window.webkit.messageHandlers).forEach(function(name) { if (names.indexOf(name) === -1) delete window.webkit.messageHandlers[name]; });
|
|
3095
3340
|
names.forEach(function(name) {
|
|
3096
3341
|
if (Object.hasOwn(window.webkit.messageHandlers, name)) return;
|
|
@@ -3115,11 +3360,13 @@ ${WEBVIEW_FRAME_COLOR_SCHEME_SOURCE} var webKit = config.webKit || null;
|
|
|
3115
3360
|
fontHeadObserver.observe(document, { childList: true, subtree: true });
|
|
3116
3361
|
if (document.head) { document.head.prepend(defaultStyle); fontHeadObserver.disconnect(); }
|
|
3117
3362
|
}
|
|
3363
|
+
var nativeUserAgent = webKit && webKit.userAgent;
|
|
3364
|
+
if (typeof nativeUserAgent === 'string') {
|
|
3365
|
+
Object.defineProperty(navigator, 'userAgent', { configurable: true, get: function() { return nativeUserAgent; } });
|
|
3366
|
+
}
|
|
3118
3367
|
if (webKit) {
|
|
3119
3368
|
Object.defineProperty(window, 'devicePixelRatio', { configurable: true, get: function() { return config.deviceScale; } });
|
|
3120
3369
|
window.parent.postMessage({ __sootsimWebViewKind: 'webKitCommit', url: config.documentUrl }, '*');
|
|
3121
|
-
window.webkit = window.webkit || {};
|
|
3122
|
-
window.webkit.messageHandlers = Object.create(null);
|
|
3123
3370
|
setMessageHandlers(webKit.messageHandlers);
|
|
3124
3371
|
}
|
|
3125
3372
|
var userScripts = (webKit ? webKit.userScripts : []).slice();
|
|
@@ -3154,6 +3401,12 @@ ${WEBVIEW_FRAME_COLOR_SCHEME_SOURCE} var webKit = config.webKit || null;
|
|
|
3154
3401
|
return injectedObjectJson;
|
|
3155
3402
|
};
|
|
3156
3403
|
}
|
|
3404
|
+
if (
|
|
3405
|
+
typeof config.expoDomWebViewGlobalsSource === 'string' &&
|
|
3406
|
+
window[Symbol.for(${JSON.stringify(WEBVIEW_EXPO_DOM_PROMPT_CAPABILITY)})] === true
|
|
3407
|
+
) {
|
|
3408
|
+
(0, eval)(config.expoDomWebViewGlobalsSource);
|
|
3409
|
+
}
|
|
3157
3410
|
// the page is top-level in a WKWebView, so a cookie it sets from script is
|
|
3158
3411
|
// first-party there; under the sim page it is cross-site, where only
|
|
3159
3412
|
// SameSite=None sticks. a secure context can state that; an insecure one
|
|
@@ -3166,7 +3419,8 @@ ${WEBVIEW_FRAME_COLOR_SCHEME_SOURCE} var webKit = config.webKit || null;
|
|
|
3166
3419
|
if (webKit) {
|
|
3167
3420
|
var cookieOperations = ${webKitCookieOperationsSource};
|
|
3168
3421
|
var pageCookies = cookieOperations.restore(JSON.parse(webKit.cookies || '[]'));
|
|
3169
|
-
window.__peachUpdateWebKitCookies = function(cookies) {
|
|
3422
|
+
window.__peachUpdateWebKitCookies = function(cookies, policy) {
|
|
3423
|
+
webKit.cookiePolicy = policy;
|
|
3170
3424
|
pageCookies = cookieOperations.restore(cookies);
|
|
3171
3425
|
window.parent.postMessage({ __sootsimWebViewKind: 'webKitCookieSnapshot', cookies: JSON.stringify(cookies) }, '*');
|
|
3172
3426
|
};
|
|
@@ -3176,6 +3430,7 @@ ${WEBVIEW_FRAME_COLOR_SCHEME_SOURCE} var webKit = config.webKit || null;
|
|
|
3176
3430
|
return Object.values(cookieOperations.getCookies(pageCookies, documentUrl)).filter(function(cookie) { return !cookie.httpOnly; }).map(function(cookie) { return cookie.name + '=' + cookie.value; }).join('; ');
|
|
3177
3431
|
},
|
|
3178
3432
|
set: function(value) {
|
|
3433
|
+
if (webKit.cookiePolicy === 1) return;
|
|
3179
3434
|
var line = String(value);
|
|
3180
3435
|
var cookie = cookieOperations.cookieFromResponse(line);
|
|
3181
3436
|
cookie.httpOnly = false;
|
|
@@ -3515,11 +3770,32 @@ ${WEBVIEW_FRAME_COLOR_SCHEME_SOURCE} var webKit = config.webKit || null;
|
|
|
3515
3770
|
}, '*');
|
|
3516
3771
|
});
|
|
3517
3772
|
var lastEditable = null;
|
|
3518
|
-
function
|
|
3519
|
-
|
|
3520
|
-
|
|
3521
|
-
:
|
|
3522
|
-
|
|
3773
|
+
function editorState(editor) {
|
|
3774
|
+
if ('value' in editor) return {
|
|
3775
|
+
text: String(editor.value), selectionStart: editor.selectionStart === null ? 0 : editor.selectionStart,
|
|
3776
|
+
selectionEnd: editor.selectionEnd === null ? 0 : editor.selectionEnd
|
|
3777
|
+
};
|
|
3778
|
+
var selection = window.getSelection();
|
|
3779
|
+
var whole = document.createRange();
|
|
3780
|
+
whole.selectNodeContents(editor);
|
|
3781
|
+
var prefix = whole.cloneRange();
|
|
3782
|
+
var start = 0, end = 0;
|
|
3783
|
+
if (selection && selection.rangeCount && editor.contains(selection.anchorNode) && editor.contains(selection.focusNode)) {
|
|
3784
|
+
var range = selection.getRangeAt(0);
|
|
3785
|
+
prefix.setEnd(range.startContainer, range.startOffset);
|
|
3786
|
+
start = prefix.toString().length;
|
|
3787
|
+
prefix.setEnd(range.endContainer, range.endOffset);
|
|
3788
|
+
end = prefix.toString().length;
|
|
3789
|
+
}
|
|
3790
|
+
return { text: whole.toString(), selectionStart: start, selectionEnd: end };
|
|
3791
|
+
}
|
|
3792
|
+
function postEditorState(edited) {
|
|
3793
|
+
if (!lastEditable || lastEditable !== document.activeElement) return;
|
|
3794
|
+
window.parent.postMessage(Object.assign({
|
|
3795
|
+
__sootsimWebViewKind: 'webViewEditorState', edited: edited === true
|
|
3796
|
+
}, editorState(lastEditable)), '*');
|
|
3797
|
+
}
|
|
3798
|
+
document.addEventListener('selectionchange', function () { postEditorState(false); }, true);
|
|
3523
3799
|
document.addEventListener('focusin', function (event) {
|
|
3524
3800
|
var element = event.target;
|
|
3525
3801
|
if (!element || !element.closest) return;
|
|
@@ -3542,7 +3818,7 @@ ${WEBVIEW_FRAME_COLOR_SCHEME_SOURCE} var webKit = config.webKit || null;
|
|
|
3542
3818
|
try {
|
|
3543
3819
|
hasActivation = !!(navigator.userActivation && navigator.userActivation.isActive);
|
|
3544
3820
|
} catch (_) {}
|
|
3545
|
-
window.parent.postMessage({
|
|
3821
|
+
window.parent.postMessage(Object.assign({
|
|
3546
3822
|
__sootsimWebViewKind: 'webViewEditorFocus',
|
|
3547
3823
|
inputType: editor.type || '',
|
|
3548
3824
|
inputMode: editor.inputMode || '',
|
|
@@ -3550,9 +3826,8 @@ ${WEBVIEW_FRAME_COLOR_SCHEME_SOURCE} var webKit = config.webKit || null;
|
|
|
3550
3826
|
autoCapitalize: editor.autocapitalize || editor.getAttribute('autocapitalize') || '',
|
|
3551
3827
|
autoCorrect: editor.autocorrect || editor.getAttribute('autocorrect') || '',
|
|
3552
3828
|
spellCheck: editor.spellcheck,
|
|
3553
|
-
empty: editorIsEmpty(editor),
|
|
3554
3829
|
userGesture: hasActivation && !evaluatingInjectedScript
|
|
3555
|
-
}, '*');
|
|
3830
|
+
}, editorState(editor)), '*');
|
|
3556
3831
|
}, true);
|
|
3557
3832
|
document.addEventListener('focusout', function (event) {
|
|
3558
3833
|
var element = event.target;
|
|
@@ -3583,10 +3858,7 @@ ${WEBVIEW_FRAME_COLOR_SCHEME_SOURCE} var webKit = config.webKit || null;
|
|
|
3583
3858
|
// execCommand from an injected script. the native oracle raises the
|
|
3584
3859
|
// keyboard on an insert into a focused field even when the focus
|
|
3585
3860
|
// itself was programmatic, so the host needs this to match.
|
|
3586
|
-
|
|
3587
|
-
__sootsimWebViewKind: 'webViewEditorState',
|
|
3588
|
-
empty: editorIsEmpty(editor)
|
|
3589
|
-
}, '*');
|
|
3861
|
+
postEditorState(true);
|
|
3590
3862
|
}, true);
|
|
3591
3863
|
window.addEventListener('message', function (event) {
|
|
3592
3864
|
// only the shell host drives this frame. the host already checks that an
|
|
@@ -3624,6 +3896,34 @@ ${WEBVIEW_FRAME_COLOR_SCHEME_SOURCE} var webKit = config.webKit || null;
|
|
|
3624
3896
|
lastEditable = null;
|
|
3625
3897
|
return;
|
|
3626
3898
|
}
|
|
3899
|
+
if (payload.__sootsimWebViewKind === 'keyboardAcceptCandidate') {
|
|
3900
|
+
event.stopImmediatePropagation();
|
|
3901
|
+
if (!lastEditable || !lastEditable.isConnected) return;
|
|
3902
|
+
var state = editorState(lastEditable);
|
|
3903
|
+
var candidate = payload.candidate;
|
|
3904
|
+
if (!candidate || state.selectionStart !== state.selectionEnd ||
|
|
3905
|
+
state.selectionEnd !== candidate.end || candidate.end !== state.text.length ||
|
|
3906
|
+
state.text.slice(candidate.start, candidate.end) !== candidate.text) return;
|
|
3907
|
+
if ('value' in lastEditable) lastEditable.setSelectionRange(candidate.start, candidate.end);
|
|
3908
|
+
else {
|
|
3909
|
+
var walker = document.createTreeWalker(lastEditable, NodeFilter.SHOW_TEXT);
|
|
3910
|
+
var textNode, offset = 0, range = document.createRange();
|
|
3911
|
+
range.selectNodeContents(lastEditable);
|
|
3912
|
+
while ((textNode = walker.nextNode())) {
|
|
3913
|
+
if (offset + textNode.length >= candidate.start) {
|
|
3914
|
+
range.setStart(textNode, candidate.start - offset);
|
|
3915
|
+
break;
|
|
3916
|
+
}
|
|
3917
|
+
offset += textNode.length;
|
|
3918
|
+
}
|
|
3919
|
+
var selection = window.getSelection();
|
|
3920
|
+
selection.removeAllRanges();
|
|
3921
|
+
selection.addRange(range);
|
|
3922
|
+
}
|
|
3923
|
+
document.execCommand('insertText', false, candidate.text + ' ');
|
|
3924
|
+
postEditorState();
|
|
3925
|
+
return;
|
|
3926
|
+
}
|
|
3627
3927
|
if (payload.__sootsimWebViewKind === 'keyboardKeyPress') {
|
|
3628
3928
|
event.stopImmediatePropagation();
|
|
3629
3929
|
if (!lastEditable || !lastEditable.isConnected) return;
|
|
@@ -3735,25 +4035,43 @@ ${WEBVIEW_FRAME_COLOR_SCHEME_SOURCE} var webKit = config.webKit || null;
|
|
|
3735
4035
|
}
|
|
3736
4036
|
if (payload.__sootsimWebViewKind === 'evaluateJavaScript') {
|
|
3737
4037
|
event.stopImmediatePropagation();
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
|
|
3741
|
-
|
|
4038
|
+
if (typeof payload.userAgent === 'string') nativeUserAgent = payload.userAgent;
|
|
4039
|
+
var evaluationMetadata = {};
|
|
4040
|
+
window[Symbol.for('peach.webkitException')] = evaluationMetadata;
|
|
4041
|
+
function sendEvaluation(result) {
|
|
4042
|
+
result.title = String(document.title || '');
|
|
4043
|
+
window.parent.postMessage({ __sootsimWebViewKind: 'webKitEvaluation', requestId: payload.requestId, result: result }, '*');
|
|
4044
|
+
}
|
|
4045
|
+
function evaluationSuccess(value) {
|
|
4046
|
+
var result;
|
|
3742
4047
|
try { result = value === undefined ? { undefined: true } : { value: nativeValue(value, []) }; }
|
|
3743
4048
|
catch (_) { result = { errorCode: 5, errorInfo: { NSLocalizedDescription: 'JavaScript execution returned a result of an unsupported type' } }; }
|
|
3744
|
-
|
|
3745
|
-
|
|
4049
|
+
sendEvaluation(result);
|
|
4050
|
+
}
|
|
4051
|
+
function evaluationFailure(error) {
|
|
4052
|
+
var metadata = evaluationMetadata.asyncFunction ? evaluationMetadata : window[Symbol.for('peach.webkitException')] || {};
|
|
3746
4053
|
var exceptionLocation = metadata.value === error && metadata.thrown ? metadata.thrown : error instanceof SyntaxError ? metadata.thrown : error instanceof ReferenceError ? metadata.read : metadata.call;
|
|
3747
4054
|
var message = String(error);
|
|
3748
4055
|
if (error instanceof ReferenceError && metadata.read) message = "ReferenceError: Can't find variable: " + metadata.read.name;
|
|
3749
4056
|
if (error instanceof TypeError && metadata.call && metadata.call.property && metadata.receiver != null && !Reflect.has(Object(metadata.receiver), metadata.call.property)) {
|
|
3750
4057
|
message = "TypeError: " + metadata.call.callee + " is not a function. (In '" + metadata.call.source + "', '" + metadata.call.callee + "' is undefined)";
|
|
3751
4058
|
}
|
|
3752
|
-
result = { errorCode: 4, errorInfo: { NSLocalizedDescription: 'A JavaScript exception occurred', WKJavaScriptExceptionMessage: message
|
|
3753
|
-
if (
|
|
4059
|
+
var result = { errorCode: 4, errorInfo: { NSLocalizedDescription: 'A JavaScript exception occurred', WKJavaScriptExceptionMessage: message } };
|
|
4060
|
+
if (metadata.asyncFunction) {
|
|
4061
|
+
result.errorInfo.WKJavaScriptExceptionLineNumber = 0;
|
|
4062
|
+
result.errorInfo.WKJavaScriptExceptionColumnNumber = 0;
|
|
4063
|
+
} else {
|
|
4064
|
+
result.errorInfo.WKJavaScriptExceptionSourceURL = String(document.baseURI);
|
|
4065
|
+
if (exceptionLocation) { result.errorInfo.WKJavaScriptExceptionLineNumber = exceptionLocation.line; result.errorInfo.WKJavaScriptExceptionColumnNumber = exceptionLocation.column; }
|
|
4066
|
+
}
|
|
4067
|
+
sendEvaluation(result);
|
|
3754
4068
|
}
|
|
3755
|
-
|
|
3756
|
-
|
|
4069
|
+
try {
|
|
4070
|
+
var value = (0, eval)(String(payload.js || ''));
|
|
4071
|
+
if (evaluationMetadata.asyncFunction && value instanceof Promise) {
|
|
4072
|
+
Promise.resolve(value).then(evaluationSuccess, evaluationFailure);
|
|
4073
|
+
} else evaluationSuccess(value);
|
|
4074
|
+
} catch (error) { evaluationFailure(error); }
|
|
3757
4075
|
return;
|
|
3758
4076
|
}
|
|
3759
4077
|
if (payload.__sootsimWebViewKind !== 'injectJavaScript') return;
|
|
@@ -3781,6 +4099,8 @@ var WEBVIEW_SAME_ORIGIN_BOOTSTRAP_SOURCE = `(function () {
|
|
|
3781
4099
|
if (config.beforeContent) (0, eval)(config.beforeContent);
|
|
3782
4100
|
})();`;
|
|
3783
4101
|
var WEBVIEW_HOST_BOOTSTRAP_SOURCE = `function (timingName) {
|
|
4102
|
+
window[Symbol.for(${JSON.stringify(WEBVIEW_EXPO_DOM_PROMPT_CAPABILITY)})] = true;
|
|
4103
|
+
var host = window[${JSON.stringify(WEBVIEW_HOST_BINDING)}];
|
|
3784
4104
|
if (window === window.top || window.parent !== window.top) return;
|
|
3785
4105
|
var entry = performance.getEntriesByType('navigation')[0];
|
|
3786
4106
|
var timings = (entry && entry.serverTiming) || [];
|
|
@@ -3791,7 +4111,6 @@ var WEBVIEW_HOST_BOOTSTRAP_SOURCE = `function (timingName) {
|
|
|
3791
4111
|
// the host runs injectedJavaScript once the document is parsed, after the
|
|
3792
4112
|
// page's own DOMContentLoaded listeners, as WebKit runs a document-end
|
|
3793
4113
|
// WKUserScript after it dispatches DOMContentLoaded.
|
|
3794
|
-
var host = window[${JSON.stringify(WEBVIEW_HOST_BINDING)}];
|
|
3795
4114
|
var hook = window[Symbol.for(${JSON.stringify(WEBVIEW_FRAME_HOOK)})];
|
|
3796
4115
|
window.addEventListener('DOMContentLoaded', function () {
|
|
3797
4116
|
hook.documentEnd = host({ kind: 'documentEnd' });
|
|
@@ -3800,6 +4119,9 @@ var WEBVIEW_HOST_BOOTSTRAP_SOURCE = `function (timingName) {
|
|
|
3800
4119
|
}
|
|
3801
4120
|
}`;
|
|
3802
4121
|
|
|
4122
|
+
// ../peach-engine/src/render-worker/app-load.ts
|
|
4123
|
+
var import_config = require("peachsim/config");
|
|
4124
|
+
|
|
3803
4125
|
// ../peach-engine/src/remote-stream/remoteEngineParam.ts
|
|
3804
4126
|
function readRemoteEngineParam(search, hash) {
|
|
3805
4127
|
const fromQuery = new URLSearchParams(search).get("remoteEngine");
|
|
@@ -3818,11 +4140,13 @@ function getVisibleHarnessAppForUrl(initUrl) {
|
|
|
3818
4140
|
const parsed = new URL(initUrl);
|
|
3819
4141
|
const testName = parsed.searchParams.get("test");
|
|
3820
4142
|
if (testName) {
|
|
4143
|
+
const iconImage = parsed.searchParams.get("fixtureIcon");
|
|
3821
4144
|
return {
|
|
3822
4145
|
id: TEST_FIXTURE_SHELL_APP_ID,
|
|
3823
4146
|
name: testName,
|
|
3824
4147
|
color: "#0f172a",
|
|
3825
4148
|
icon: "T",
|
|
4149
|
+
...iconImage ? { iconImage } : {},
|
|
3826
4150
|
hidden: true
|
|
3827
4151
|
};
|
|
3828
4152
|
}
|
|
@@ -3911,7 +4235,6 @@ var import_metro_production_bundle = require("peachsim/metro-production-bundle")
|
|
|
3911
4235
|
var import_react_native_host_modules = require("peachsim/react-native-host-modules");
|
|
3912
4236
|
|
|
3913
4237
|
// src/cloud-contract.ts
|
|
3914
|
-
var RNX_CLOUD_MAX_ARTIFACT_BYTES = 20 * 1024 * 1024;
|
|
3915
4238
|
var RNX_CLOUD_DESIGN_MAX_STORAGE_BYTES = 1024 * 1024;
|
|
3916
4239
|
var RNX_CLOUD_COMMAND_SCOPES = {
|
|
3917
4240
|
state: "read",
|
|
@@ -6496,7 +6819,8 @@ function writeSecureJsonAtomic(filepath, value) {
|
|
|
6496
6819
|
|
|
6497
6820
|
// cli/current-sim.ts
|
|
6498
6821
|
var CURRENT_SIM_VERSION = 2;
|
|
6499
|
-
var CURRENT_SIM_PATH_ENV = "
|
|
6822
|
+
var CURRENT_SIM_PATH_ENV = "PEACH_CLI_CURRENT_SIM_PATH";
|
|
6823
|
+
var LEGACY_CURRENT_SIM_PATH_ENV = "SOOTSIM_CLI_CURRENT_SIM_PATH";
|
|
6500
6824
|
var IDENTITY_ENV_VARS = [
|
|
6501
6825
|
"PEACH_CLI_IDENTITY",
|
|
6502
6826
|
// explicit override — fastest path, skips all pid lookups
|
|
@@ -6575,8 +6899,9 @@ function getOwnerProcessGroupId() {
|
|
|
6575
6899
|
return pgid !== null && pgid > 1 ? pgid : null;
|
|
6576
6900
|
}
|
|
6577
6901
|
function getCurrentSimPath() {
|
|
6578
|
-
|
|
6579
|
-
|
|
6902
|
+
const envPath = process.env[CURRENT_SIM_PATH_ENV] || process.env[LEGACY_CURRENT_SIM_PATH_ENV];
|
|
6903
|
+
if (envPath) {
|
|
6904
|
+
return (0, import_path.resolve)(envPath);
|
|
6580
6905
|
}
|
|
6581
6906
|
const key = getCliIdentityKey();
|
|
6582
6907
|
return (0, import_path.join)((0, import_os.tmpdir)(), `peach-current-sim-${key}.json`);
|
|
@@ -6744,7 +7069,8 @@ function createBridge(wsPort, opts = {}) {
|
|
|
6744
7069
|
}
|
|
6745
7070
|
function maybeNoticeTarget(cmdType, simId) {
|
|
6746
7071
|
if (noticedTarget) return;
|
|
6747
|
-
if (process.env.SOOTSIM_QUIET_TARGET_NOTICE === "1")
|
|
7072
|
+
if (process.env.PEACH_QUIET_TARGET_NOTICE === "1" || process.env.SOOTSIM_QUIET_TARGET_NOTICE === "1")
|
|
7073
|
+
return;
|
|
6748
7074
|
if (cmdType.startsWith("bridge:") || cmdType === "focus" || cmdType === "close")
|
|
6749
7075
|
return;
|
|
6750
7076
|
noticedTarget = true;
|
|
@@ -7225,7 +7551,7 @@ async function dragScrollNode(page, node, pixels, direction, startPositionX, sta
|
|
|
7225
7551
|
let recognitionSootSimY = startSootSimY;
|
|
7226
7552
|
let endSootSimX = startSootSimX;
|
|
7227
7553
|
let endSootSimY = startSootSimY;
|
|
7228
|
-
const slop =
|
|
7554
|
+
const slop = scrollTouchSlop(DETOX_PLATFORM, 1);
|
|
7229
7555
|
const travel = pixels + slop;
|
|
7230
7556
|
switch (direction) {
|
|
7231
7557
|
case "down":
|
|
@@ -7847,7 +8173,14 @@ function recordPageDiagnostic(page, diagnostic, persist = false) {
|
|
|
7847
8173
|
if (persist) (0, import_attempt_events.writeAttemptEvent)(diagnostic);
|
|
7848
8174
|
}
|
|
7849
8175
|
function isTopLevelDocumentRequest(page, request) {
|
|
7850
|
-
|
|
8176
|
+
if (!request.isNavigationRequest() || request.resourceType() !== "document") {
|
|
8177
|
+
return false;
|
|
8178
|
+
}
|
|
8179
|
+
try {
|
|
8180
|
+
return request.frame() === page.mainFrame();
|
|
8181
|
+
} catch {
|
|
8182
|
+
return false;
|
|
8183
|
+
}
|
|
7851
8184
|
}
|
|
7852
8185
|
function recordNavigationMilestoneFor(page, active, milestone, details = {}) {
|
|
7853
8186
|
recordPageDiagnostic(
|
|
@@ -8013,7 +8346,7 @@ function getSootsimNavigationDiagnostics(page) {
|
|
|
8013
8346
|
// detox/index.ts
|
|
8014
8347
|
var import_proof_frame = __toESM(require_proof_frame(), 1);
|
|
8015
8348
|
var BASE_URL = process.env.PEACH_URL || "http://localhost:5173";
|
|
8016
|
-
var SCREENSHOT_DIR = process.env.PEACH_SCREENSHOT_DIR || path.join(process.cwd(), "test", "detox-driver", "screenshots");
|
|
8349
|
+
var SCREENSHOT_DIR = process.env.PEACH_SCREENSHOT_DIR || path.join(process.cwd(), "test", "detox-driver", "screenshots", String(process.pid));
|
|
8017
8350
|
var _browser = null;
|
|
8018
8351
|
var _reapBrowserNow = null;
|
|
8019
8352
|
var _context = null;
|
|
@@ -8378,7 +8711,9 @@ async function waitForSootsimIdle(page, maxMs = 3e3, strict = false, transitionS
|
|
|
8378
8711
|
} catch {
|
|
8379
8712
|
}
|
|
8380
8713
|
}
|
|
8714
|
+
let webViewStarting = false;
|
|
8381
8715
|
if (root) {
|
|
8716
|
+
const PREVIEW_PROGRESS_REGEX = /^(creating webview|loading html|fetching bundle|waiting for first render|starting preview|loading simulator|fetching app code|waiting for native preview|starting design|loading canvas|fetching screens|painting the canvas|waiting for webview|waiting for preview|waiting for canvas|preview stalled)/i;
|
|
8382
8717
|
const walk = (node) => {
|
|
8383
8718
|
if (node.layout && node.layout.width > 0) {
|
|
8384
8719
|
layout.push(
|
|
@@ -8388,16 +8723,32 @@ async function waitForSootsimIdle(page, maxMs = 3e3, strict = false, transitionS
|
|
|
8388
8723
|
Math.round(node.layout.height)
|
|
8389
8724
|
);
|
|
8390
8725
|
}
|
|
8726
|
+
const tid = node.testID || node.props?.testID || node.props?.testId;
|
|
8727
|
+
if (typeof tid === "string" && (tid === "web-preview-progress" || tid.endsWith("-preview-progress"))) {
|
|
8728
|
+
webViewStarting = true;
|
|
8729
|
+
}
|
|
8730
|
+
const text = node.textContent || (typeof node.props?.children === "string" ? node.props.children : "");
|
|
8731
|
+
if (typeof text === "string" && PREVIEW_PROGRESS_REGEX.test(text.trim())) {
|
|
8732
|
+
webViewStarting = true;
|
|
8733
|
+
}
|
|
8391
8734
|
for (const child of node.children || []) walk(child);
|
|
8392
8735
|
};
|
|
8393
8736
|
walk(root);
|
|
8394
8737
|
}
|
|
8738
|
+
if (!webViewStarting && typeof document !== "undefined") {
|
|
8739
|
+
if (document.querySelector(
|
|
8740
|
+
'[data-testid$="-preview-progress"], [data-testid="web-preview-progress"], [data-testid="ios-preview-progress"], [data-testid="design-preview-progress"], [data-sootsim-webview-loading="true"], [data-sootsim-webview-mode="placeholder"]'
|
|
8741
|
+
)) {
|
|
8742
|
+
webViewStarting = true;
|
|
8743
|
+
}
|
|
8744
|
+
}
|
|
8395
8745
|
return {
|
|
8396
8746
|
animating,
|
|
8397
8747
|
auxSurfaceDebug,
|
|
8398
8748
|
layout,
|
|
8399
8749
|
layoutDirty,
|
|
8400
|
-
renderStatsAvailable
|
|
8750
|
+
renderStatsAvailable,
|
|
8751
|
+
webViewStarting
|
|
8401
8752
|
};
|
|
8402
8753
|
};
|
|
8403
8754
|
let stableLayout = null;
|
|
@@ -8406,7 +8757,7 @@ async function waitForSootsimIdle(page, maxMs = 3e3, strict = false, transitionS
|
|
|
8406
8757
|
while (Date.now() < deadline) {
|
|
8407
8758
|
const snapshot = await readSnapshot();
|
|
8408
8759
|
lastSnapshot = snapshot;
|
|
8409
|
-
if ((!strict2 || snapshot.renderStatsAvailable) && !snapshot.animating && !snapshot.layoutDirty && isLayoutStable(stableLayout, snapshot.layout)) {
|
|
8760
|
+
if ((!strict2 || snapshot.renderStatsAvailable) && !snapshot.animating && !snapshot.layoutDirty && !snapshot.webViewStarting && isLayoutStable(stableLayout, snapshot.layout)) {
|
|
8410
8761
|
stable++;
|
|
8411
8762
|
if (stable >= requiredStablePolls) {
|
|
8412
8763
|
return { settled: true, elapsed: Date.now() - start };
|
|
@@ -8420,7 +8771,7 @@ async function waitForSootsimIdle(page, maxMs = 3e3, strict = false, transitionS
|
|
|
8420
8771
|
return {
|
|
8421
8772
|
settled: false,
|
|
8422
8773
|
elapsed: Date.now() - start,
|
|
8423
|
-
reason: transitionError ? `layout fallback after screen transition wait failed: ${transitionError}` : !lastSnapshot ? "deadline spent before the first idle poll" : strict2 ? `strict idle state unavailable: renderStats=${lastSnapshot?.renderStatsAvailable === true} animating=${lastSnapshot?.animating === true} layoutDirty=${lastSnapshot?.layoutDirty === true} layoutNodes=${(lastSnapshot?.layout.length ?? 0) / 4} aux=${JSON.stringify(lastSnapshot?.auxSurfaceDebug)}` : "layout fallback"
|
|
8774
|
+
reason: transitionError ? `layout fallback after screen transition wait failed: ${transitionError}` : !lastSnapshot ? "deadline spent before the first idle poll" : strict2 ? `strict idle state unavailable: renderStats=${lastSnapshot?.renderStatsAvailable === true} animating=${lastSnapshot?.animating === true} layoutDirty=${lastSnapshot?.layoutDirty === true} webViewStarting=${lastSnapshot?.webViewStarting === true} layoutNodes=${(lastSnapshot?.layout.length ?? 0) / 4} aux=${JSON.stringify(lastSnapshot?.auxSurfaceDebug)}` : "layout fallback"
|
|
8424
8775
|
};
|
|
8425
8776
|
},
|
|
8426
8777
|
{ maxMs, strict, transitionStartWindowMs }
|
|
@@ -8509,9 +8860,9 @@ async function dispatchTapAtSootsimPoint(page, x, y, token) {
|
|
|
8509
8860
|
async ({ x: x2, y: y2, token: token2 }) => {
|
|
8510
8861
|
const interactTap = window.SootSim?.bridges?.interact?.tap;
|
|
8511
8862
|
if (typeof interactTap === "function") {
|
|
8863
|
+
if (token2) window.__sootsimAnchorTimedInput?.(token2);
|
|
8512
8864
|
const result = await interactTap(x2, y2);
|
|
8513
8865
|
if (result && (typeof result !== "object" || result.hit !== false)) {
|
|
8514
|
-
if (token2) window.__sootsimAnchorTimedInput?.(token2);
|
|
8515
8866
|
return;
|
|
8516
8867
|
}
|
|
8517
8868
|
}
|
|
@@ -8519,8 +8870,8 @@ async function dispatchTapAtSootsimPoint(page, x, y, token) {
|
|
|
8519
8870
|
if (typeof tap !== "function") {
|
|
8520
8871
|
throw new Error("sootsim tap bridge is not installed");
|
|
8521
8872
|
}
|
|
8522
|
-
await tap(x2, y2);
|
|
8523
8873
|
if (token2) window.__sootsimAnchorTimedInput?.(token2);
|
|
8874
|
+
await tap(x2, y2);
|
|
8524
8875
|
},
|
|
8525
8876
|
{ x, y, token }
|
|
8526
8877
|
);
|
|
@@ -8829,8 +9180,8 @@ function createSootSimElement(matcher) {
|
|
|
8829
9180
|
if (typeof longPress !== "function") {
|
|
8830
9181
|
throw new Error("sootsim longPress bridge is not installed");
|
|
8831
9182
|
}
|
|
8832
|
-
await longPress(x, y, duration2);
|
|
8833
9183
|
if (token) window.__sootsimAnchorTimedInput?.(token);
|
|
9184
|
+
await longPress(x, y, duration2);
|
|
8834
9185
|
},
|
|
8835
9186
|
{ duration, x: target.x, y: target.y, token: captureToken }
|
|
8836
9187
|
);
|
|
@@ -8883,6 +9234,11 @@ function createSootSimElement(matcher) {
|
|
|
8883
9234
|
await focusElementForTextEntry(el);
|
|
8884
9235
|
await page.keyboard.type(text);
|
|
8885
9236
|
},
|
|
9237
|
+
async tapReturnKey() {
|
|
9238
|
+
const page = getPage();
|
|
9239
|
+
await focusElementForTextEntry(el);
|
|
9240
|
+
await page.keyboard.press("Enter");
|
|
9241
|
+
},
|
|
8886
9242
|
async replaceText(text) {
|
|
8887
9243
|
const page = getPage();
|
|
8888
9244
|
const node = await findNodeByMatcher(matcher);
|
|
@@ -9012,8 +9368,8 @@ function createSootSimElement(matcher) {
|
|
|
9012
9368
|
if (typeof drag !== "function") {
|
|
9013
9369
|
throw new Error("sootsim interact bridge is not installed");
|
|
9014
9370
|
}
|
|
9015
|
-
await drag(fromX, fromY, toX, toY, steps2, stepMs);
|
|
9016
9371
|
if (token) window.__sootsimAnchorTimedInput?.(token);
|
|
9372
|
+
await drag(fromX, fromY, toX, toY, steps2, stepMs);
|
|
9017
9373
|
},
|
|
9018
9374
|
{
|
|
9019
9375
|
fromX: startSootSimX,
|
|
@@ -9540,8 +9896,10 @@ var device = {
|
|
|
9540
9896
|
_lastRecordingPath: "",
|
|
9541
9897
|
// park every render clock before the interaction, detect the first changed
|
|
9542
9898
|
// stepped frame inside the named component, then advance exact 60fps frames
|
|
9543
|
-
// to each requested offset. native extraction
|
|
9544
|
-
//
|
|
9899
|
+
// to each requested offset from that frame. native extraction anchors at
|
|
9900
|
+
// its detection frame's pts, so both legs zero at the first painted change
|
|
9901
|
+
// and native also chooses the first frame at or after an offset, which is
|
|
9902
|
+
// the same rounding convention from the same zero.
|
|
9545
9903
|
async takeScreenshotStagesFromVisibleChangeFast(namePrefix, stages, options) {
|
|
9546
9904
|
const page = getPage();
|
|
9547
9905
|
const token = `motion-${process.pid}-${Date.now()}-${Math.random()}`;
|
|
@@ -9711,7 +10069,6 @@ var device = {
|
|
|
9711
10069
|
}
|
|
9712
10070
|
let visibleStart = null;
|
|
9713
10071
|
let detectedMeasurement = null;
|
|
9714
|
-
let previousReceipt = null;
|
|
9715
10072
|
let previousBitmap = null;
|
|
9716
10073
|
if (input.platform === "android") {
|
|
9717
10074
|
const candidateBitmap = await captureBitmap();
|
|
@@ -9748,24 +10105,23 @@ var device = {
|
|
|
9748
10105
|
width: bounds.width
|
|
9749
10106
|
});
|
|
9750
10107
|
if (measurement.passedMinimum) {
|
|
9751
|
-
|
|
10108
|
+
previousBitmap?.close();
|
|
10109
|
+
previousBitmap = null;
|
|
9752
10110
|
visibleStart = receipt;
|
|
9753
10111
|
detectedMeasurement = measurement;
|
|
10112
|
+
keptFrames.set(receipt.frameIndex, candidateBitmap);
|
|
9754
10113
|
break;
|
|
9755
10114
|
}
|
|
9756
10115
|
previousBitmap?.close();
|
|
9757
10116
|
previousBitmap = candidateBitmap;
|
|
9758
|
-
previousReceipt = receipt;
|
|
9759
|
-
}
|
|
9760
|
-
if (previousReceipt && previousBitmap) {
|
|
9761
|
-
keptFrames.set(previousReceipt.frameIndex, previousBitmap);
|
|
9762
10117
|
}
|
|
9763
10118
|
if (!visibleStart || !detectedMeasurement) {
|
|
10119
|
+
previousBitmap?.close();
|
|
9764
10120
|
throw new Error(
|
|
9765
10121
|
`peach motion had no visible change before ${input.detectionTimeoutMs}ms`
|
|
9766
10122
|
);
|
|
9767
10123
|
}
|
|
9768
|
-
const driveStart =
|
|
10124
|
+
const driveStart = visibleStart;
|
|
9769
10125
|
let currentReceipt = visibleStart;
|
|
9770
10126
|
const resolvedAnchors = /* @__PURE__ */ new Map();
|
|
9771
10127
|
const anchorRecords = [];
|
|
@@ -9824,14 +10180,14 @@ var device = {
|
|
|
9824
10180
|
} else {
|
|
9825
10181
|
latePeakPercent = Math.max(latePeakPercent, measurement.changePercent);
|
|
9826
10182
|
}
|
|
9827
|
-
|
|
9828
|
-
candidateBitmap.close();
|
|
9829
|
-
onsetMeasurement = measurement;
|
|
9830
|
-
break;
|
|
9831
|
-
}
|
|
10183
|
+
const passed = measurement.passedMinimum;
|
|
9832
10184
|
anchorBitmap.close();
|
|
9833
10185
|
anchorBitmap = candidateBitmap;
|
|
9834
10186
|
anchorReceipt = receipt;
|
|
10187
|
+
if (passed) {
|
|
10188
|
+
onsetMeasurement = measurement;
|
|
10189
|
+
break;
|
|
10190
|
+
}
|
|
9835
10191
|
}
|
|
9836
10192
|
if (!onsetMeasurement) {
|
|
9837
10193
|
anchorBitmap.close();
|
|
@@ -10229,7 +10585,7 @@ var device = {
|
|
|
10229
10585
|
const simId = await page.evaluate(() => window.SootSim?.state.simId);
|
|
10230
10586
|
if (!simId) throw new Error("peach location requires a registered harness sim");
|
|
10231
10587
|
const port = resolveSootsimBridgePortForHttpPort({
|
|
10232
|
-
explicitPort: process.env.
|
|
10588
|
+
explicitPort: process.env.PEACH_BRIDGE_PORT,
|
|
10233
10589
|
httpPort: new URL(page.url()).port,
|
|
10234
10590
|
baseHttpPort: 5173
|
|
10235
10591
|
});
|
|
@@ -10304,9 +10660,9 @@ var device = {
|
|
|
10304
10660
|
async ({ x: tx, y: ty, token }) => {
|
|
10305
10661
|
const interactTap = window.SootSim?.bridges?.interact?.tap;
|
|
10306
10662
|
if (typeof interactTap === "function") {
|
|
10663
|
+
if (token) window.__sootsimAnchorTimedInput?.(token);
|
|
10307
10664
|
const result = await interactTap(tx, ty);
|
|
10308
10665
|
if (result && (typeof result !== "object" || result.hit !== false)) {
|
|
10309
|
-
if (token) window.__sootsimAnchorTimedInput?.(token);
|
|
10310
10666
|
return;
|
|
10311
10667
|
}
|
|
10312
10668
|
}
|
|
@@ -10314,8 +10670,8 @@ var device = {
|
|
|
10314
10670
|
if (typeof tap !== "function") {
|
|
10315
10671
|
throw new Error("sootsim tap bridge is not installed");
|
|
10316
10672
|
}
|
|
10317
|
-
await tap(tx, ty);
|
|
10318
10673
|
if (token) window.__sootsimAnchorTimedInput?.(token);
|
|
10674
|
+
await tap(tx, ty);
|
|
10319
10675
|
},
|
|
10320
10676
|
{ x, y, token: captureToken }
|
|
10321
10677
|
);
|
|
@@ -10336,11 +10692,11 @@ var device = {
|
|
|
10336
10692
|
if (typeof longPress !== "function") {
|
|
10337
10693
|
throw new Error("sootsim longPress bridge is not installed");
|
|
10338
10694
|
}
|
|
10695
|
+
if (token) window.__sootsimAnchorTimedInput?.(token);
|
|
10339
10696
|
const hit = await longPress(px, py, ms);
|
|
10340
10697
|
if (!hit) {
|
|
10341
10698
|
throw new Error(`sootsim longPress missed at ${px},${py}`);
|
|
10342
10699
|
}
|
|
10343
|
-
if (token) window.__sootsimAnchorTimedInput?.(token);
|
|
10344
10700
|
},
|
|
10345
10701
|
{ x, y, ms: durationMs, token: captureToken }
|
|
10346
10702
|
);
|