agent-device 0.21.23 → 0.21.24
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 +6 -6
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.23.apk → agent-device-android-ime-helper-0.21.24.apk} +0 -0
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.24.apk.sha256 +1 -0
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.23.manifest.json → agent-device-android-ime-helper-0.21.24.manifest.json} +4 -4
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.21.23.apk → agent-device-android-snapshot-helper-0.21.24.apk} +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.24.apk.sha256 +1 -0
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.21.23.manifest.json → agent-device-android-snapshot-helper-0.21.24.manifest.json} +6 -6
- package/apple/macos-helper/Sources/AgentDeviceMacOSHelper/SnapshotTraversal.swift +12 -6
- package/apple/macos-helper/Tests/AgentDeviceMacOSHelperTests/RectResponseTests.swift +21 -0
- package/apple/snapshot-bridge/README.md +9 -7
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandDispatch.swift +56 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +14 -5
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +8 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +12 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCaptureTarget.swift +1 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotExecution.swift +29 -5
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +34 -10
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntryFocus.swift +19 -5
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextTyping.swift +3 -3
- package/dist/src/adapter.js +1 -1
- package/dist/src/adb.js +1 -1
- package/dist/src/agent-browser-lifecycle.js +1 -1
- package/dist/src/agent-browser-process-record.js +1 -1
- package/dist/src/agent-browser-provider.js +1 -1
- package/dist/src/agent-device-client.js +2 -2
- package/dist/src/alert-runtime.js +1 -1
- package/dist/src/alert.js +1 -1
- package/dist/src/android-adb.d.ts +3 -2
- package/dist/src/android-input-ownership.js +1 -1
- package/dist/src/app-backend.js +1 -1
- package/dist/src/app-inventory.d.ts +4 -0
- package/dist/src/app-launch.js +1 -1
- package/dist/src/app-lifecycle.js +1 -1
- package/dist/src/app-log-runtime2.js +3 -3
- package/dist/src/app-resolution.js +2 -2
- package/dist/src/app-state-runtime.d.ts +15 -0
- package/dist/src/apple-runner-platform.js +1 -1
- package/dist/src/application-lifecycle-interaction.js +1 -1
- package/dist/src/aws-device-farm-connection.js +1 -0
- package/dist/src/back-mode.js +1 -1
- package/dist/src/backend-snapshot-options.js +1 -1
- package/dist/src/browserstack-connection.js +1 -0
- package/dist/src/browserstack-device-features.js +1 -0
- package/dist/src/browserstack.js +1 -0
- package/dist/src/cache.js +1 -1
- package/dist/src/cli-config.js +1 -1
- package/dist/src/cli-help.js +35 -19
- package/dist/src/cli-runner.js +1 -1
- package/dist/src/cli.js +3 -4
- package/dist/src/client-companion-tunnel.js +1 -0
- package/dist/src/client-metro-companion.js +1 -1
- package/dist/src/client-metro.js +1 -1
- package/dist/src/client-types.d.ts +7 -5
- package/dist/src/cloud-artifacts.d.ts +3 -2
- package/dist/src/command-metadata.js +1 -1
- package/dist/src/command-schema.js +1 -1
- package/dist/src/command-tools.js +2 -2
- package/dist/src/connection-runtime.js +1 -1
- package/dist/src/connection-verification.js +1 -0
- package/dist/src/connection.js +5 -5
- package/dist/src/contracts.d.ts +1 -1
- package/dist/src/daemon-client-lease-beat.js +1 -1
- package/dist/src/daemon-client-lifecycle.js +1 -1
- package/dist/src/daemon-client-transport.js +1 -1
- package/dist/src/daemon-http.js +1 -1
- package/dist/src/daemon-policy-file.js +1 -1
- package/dist/src/daemon-registration-owner.js +1 -1
- package/dist/src/device-claim-inspection.js +1 -1
- package/dist/src/device-input-state.d.ts +2 -15
- package/dist/src/device-readiness-runtime.js +1 -1
- package/dist/src/device-selection-resolver.js +1 -1
- package/dist/src/device.js +1 -1
- package/dist/src/device2.js +1 -1
- package/dist/src/device3.js +1 -1
- package/dist/src/dispatch-resolve.js +3 -3
- package/dist/src/doctor-facade.js +1 -1
- package/dist/src/durable-capture-resource.js +1 -1
- package/dist/src/durable-resource.js +1 -1
- package/dist/src/exec.js +1 -1
- package/dist/src/file.js +1 -1
- package/dist/src/find.js +1 -1
- package/dist/src/finders.js +1 -1
- package/dist/src/format.js +2 -1
- package/dist/src/gesture-admission.js +1 -1
- package/dist/src/gesture-plan-types.d.ts +2 -5
- package/dist/src/gesture-runtime.js +1 -1
- package/dist/src/human-control.js +1 -1
- package/dist/src/ime-rebind.js +1 -1
- package/dist/src/ime-settings-record.js +1 -0
- package/dist/src/ime-state.js +1 -1
- package/dist/src/index.d.ts +3 -3
- package/dist/src/input-actions.js +1 -1
- package/dist/src/input-actions2.js +1 -1
- package/dist/src/install-source2.js +1 -1
- package/dist/src/interaction-positionals.js +1 -1
- package/dist/src/interaction-ref-policy.js +1 -1
- package/dist/src/interaction.js +1 -1
- package/dist/src/interaction2.js +1 -1
- package/dist/src/interactor.js +5 -5
- package/dist/src/interactors.js +1 -1
- package/dist/src/internal/bin.js +1 -1
- package/dist/src/internal/daemon.js +1 -1
- package/dist/src/inventory2.js +1 -1
- package/dist/src/ios-snapshot-acquisition.js +1 -1
- package/dist/src/ios-snapshot-engine.js +1 -1
- package/dist/src/ios-snapshot-runtime.js +1 -1
- package/dist/src/launch-confirmation.js +1 -1
- package/dist/src/lease-scope.js +1 -1
- package/dist/src/lease.js +1 -1
- package/dist/src/limrun.d.ts +4 -555
- package/dist/src/load.js +1 -1
- package/dist/src/local-interactor-operation-set.js +1 -1
- package/dist/src/managed-device-scope.js +1 -1
- package/dist/src/manifest.js +1 -0
- package/dist/src/mechanics.js +16 -16
- package/dist/src/mobile-snapshot-semantics.js +1 -1
- package/dist/src/observation.js +1 -2
- package/dist/src/overlay.js +3 -3
- package/dist/src/owner-identity.js +3 -3
- package/dist/src/perf-facade.js +1 -1
- package/dist/src/perf-runtime-plan.js +1 -1
- package/dist/src/perf-target.js +1 -1
- package/dist/src/physical-device-control.js +1 -1
- package/dist/src/platform-request-scope.js +1 -1
- package/dist/src/platform-runtime-open-target.js +1 -1
- package/dist/src/platform-runtime-operation-host.js +4 -4
- package/dist/src/platform-runtime-runtime-hints.js +1 -1
- package/dist/src/platform-runtime-screen-recording-finalizer-host.js +1 -1
- package/dist/src/platform-runtime-unavailable.js +1 -1
- package/dist/src/platform-runtime.js +1 -1
- package/dist/src/platform-runtime2.js +1 -1
- package/dist/src/plugin.js +1 -0
- package/dist/src/plugins/webdriver.d.ts +111 -0
- package/dist/src/plugins/webdriver.js +1 -0
- package/dist/src/plugins.d.ts +2 -1
- package/dist/src/plugins2.js +1 -1
- package/dist/src/process-exit.js +1 -1
- package/dist/src/process.js +1 -1
- package/dist/src/provider-credential-fingerprint.js +1 -1
- package/dist/src/provider-device-admission.js +1 -1
- package/dist/src/provider-device-runtime.d.ts +556 -0
- package/dist/src/provider-policy.js +1 -0
- package/dist/src/provider-profile-fields.js +1 -1
- package/dist/src/provider-webdriver.js +1 -2
- package/dist/src/providers.js +1 -1
- package/dist/src/react-devtools.js +2 -0
- package/dist/src/react-native.js +1 -1
- package/dist/src/record-runtime.js +1 -1
- package/dist/src/record-trace.js +1 -1
- package/dist/src/recording.js +1 -1
- package/dist/src/registry.js +24 -24
- package/dist/src/remote-bridge.js +1 -0
- package/dist/src/remote-config-core.js +1 -0
- package/dist/src/remote-config.js +1 -1
- package/dist/src/remote-config2.js +1 -1
- package/dist/src/remote-connection-state.js +1 -0
- package/dist/src/replay.js +2 -2
- package/dist/src/request-admission.js +1 -1
- package/dist/src/request-runtime-binding.js +1 -1
- package/dist/src/result-serialization.js +1 -1
- package/dist/src/retry.js +1 -1
- package/dist/src/retry2.js +1 -0
- package/dist/src/runner-artifact-manifest.js +1 -1
- package/dist/src/runner-cache-metadata.js +2 -3
- package/dist/src/runner-cache-retention.js +1 -0
- package/dist/src/runner-cache-trim.js +1 -0
- package/dist/src/runner-client.js +1 -1
- package/dist/src/runner-dev-tools-security.js +1 -1
- package/dist/src/runner-device-readiness.js +1 -1
- package/dist/src/runner-device-set.js +1 -0
- package/dist/src/runner-disposal.js +1 -1
- package/dist/src/runner-error-classification.js +1 -1
- package/dist/src/runner-exchange.js +1 -1
- package/dist/src/runner-lease.js +1 -0
- package/dist/src/runner-operations-facade.js +1 -1
- package/dist/src/runner-session-types.js +1 -1
- package/dist/src/runner-start-budget.js +1 -1
- package/dist/src/runner-toolchain-probe.js +2 -0
- package/dist/src/runner.js +1 -1
- package/dist/src/runtime-deployment.js +1 -0
- package/dist/src/runtime.js +1 -1
- package/dist/src/runtime10.js +1 -2
- package/dist/src/runtime11.js +2 -0
- package/dist/src/runtime2.js +2 -5
- package/dist/src/runtime3.js +5 -1
- package/dist/src/runtime4.js +1 -5
- package/dist/src/runtime5.js +5 -1
- package/dist/src/runtime6.js +1 -1
- package/dist/src/runtime7.js +1 -1
- package/dist/src/runtime8.js +1 -1
- package/dist/src/runtime9.js +1 -1
- package/dist/src/screen-recording-transport.js +1 -1
- package/dist/src/screenshot-density.js +1 -1
- package/dist/src/screenshot3.js +2 -2
- package/dist/src/script.js +1 -1
- package/dist/src/scroll-gesture.js +1 -1
- package/dist/src/sdk-batch.js +2 -2
- package/dist/src/sdk-contracts.d.ts +20 -29
- package/dist/src/sdk-contracts.js +2 -2
- package/dist/src/sdk-device.js +1 -1
- package/dist/src/sdk-finders.d.ts +1 -1
- package/dist/src/sdk-finders.js +1 -1
- package/dist/src/sdk-remote-config.d.ts +4 -0
- package/dist/src/sdk-remote-config.js +1 -1
- package/dist/src/sdk-selectors.d.ts +1 -1
- package/dist/src/sdk-selectors.js +1 -1
- package/dist/src/selection.js +0 -0
- package/dist/src/selector-pipeline-policy.js +1 -1
- package/dist/src/selector-runtime.js +1 -1
- package/dist/src/selectors.js +1 -1
- package/dist/src/server.js +2 -2
- package/dist/src/session-snapshot.js +1 -1
- package/dist/src/session2.js +5 -5
- package/dist/src/simctl.js +1 -1
- package/dist/src/simulator-boot.js +1 -1
- package/dist/src/simulator-state.js +1 -1
- package/dist/src/simulator.js +1 -1
- package/dist/src/snapshot-capture-annotations.js +1 -1
- package/dist/src/snapshot-desktop-projection.js +1 -1
- package/dist/src/snapshot-private-evidence.js +1 -0
- package/dist/src/snapshot-runtime-binding.js +1 -1
- package/dist/src/snapshot-runtime.js +1 -1
- package/dist/src/snapshot-state.js +1 -1
- package/dist/src/snapshot4.js +1 -1
- package/dist/src/src2.js +1 -1
- package/dist/src/src3.js +1 -1
- package/dist/src/src4.js +1 -1
- package/dist/src/src5.js +1 -1
- package/dist/src/src6.js +1 -1
- package/dist/src/src7.js +1 -1
- package/dist/src/src8.js +20 -20
- package/dist/src/store.js +1 -1
- package/dist/src/target-evidence.js +1 -1
- package/dist/src/text-entry-focus.js +1 -1
- package/dist/src/tool-provider2.js +1 -1
- package/dist/src/touch-runtime2.js +1 -1
- package/dist/src/tree.js +1 -1
- package/dist/src/type-text-runtime.js +1 -1
- package/dist/src/video.js +1 -1
- package/package.json +15 -10
- package/server.json +2 -2
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.23.apk.sha256 +0 -1
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.23.apk.sha256 +0 -1
- package/dist/src/capabilities.js +0 -1
- package/dist/src/compatibility-policy.js +0 -1
- package/dist/src/daemon-artifacts.js +0 -1
- package/dist/src/device-claim-rule.js +0 -1
- package/dist/src/human-control-contract.js +0 -1
- package/dist/src/prepare-kind.js +0 -1
- package/dist/src/provider-device-runtimes.js +0 -1
- package/dist/src/screen-recording-admission-ledger.js +0 -1
- package/dist/src/screenshot-runtime.js +0 -1
- package/dist/src/session-routing.js +0 -1
- package/dist/src/session-runtime-admission.js +0 -1
- package/dist/src/timeouts.js +0 -1
- package/dist/src/touch-reference-frame.js +0 -1
- package/dist/src/vars.js +0 -2
- package/dist/src/viewport.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime.js";import{F as t,I as n,K as r,P as i}from"./sdk-contracts.js";import{m as a}from"./sdk-device.js";import{t as o}from"./parser.js";import{A as s,B as c,D as l,F as u,G as d,H as f,L as p,N as m,O as h,R as ee,S as te,T as g,W as ne,_ as re,a as ie,b as _,d as ae,f as v,g as oe,m as se,n as ce,s as le,u as y,v as b,w as ue,y as de,z as fe}from"./host.js";import{d as pe,r as me}from"./apple-runner-platform.js";import{_ as he,a as ge,b as _e,c as ve,d as ye,f as be,g as xe,h as Se,l as Ce,m as we,n as Te,p as Ee,r as De,t as Oe,v as ke,x as Ae,y as je}from"./runner-cache-metadata.js";import{S as Me,_ as Ne,g as Pe,h as Fe,m as Ie,n as x,u as Le,v as S}from"./runner-session-types.js";import{P as Re,r as ze}from"./runner-error-classification.js";import Be from"node:crypto";import C from"node:fs";import Ve from"node:os";import w from"node:path";const T=new Set;function He(e){return w.join(e,Te)}function Ue(e,t){C.mkdirSync(e,{recursive:!0}),C.writeFileSync(He(e),`${JSON.stringify(t,null,2)}\n`)}async function We(e,t){if(e.cache===`external`){A(`preserve`,`external_bad_artifact`,{derived:e.derived,xctestrunPath:e.xctestrunPath,reason:t});return}T.add(e.derived),await d({acquire:()=>Ge(e.derived),task:async()=>{A(`clean`,`bad_artifact`,{derived:e.derived,xctestrunPath:e.xctestrunPath,reason:t}),k(e.derived),O(e.derived)}})}async function Ge(e){return await ce({lockDirPath:Ke(e),owner:{pid:process.pid,startTime:h(process.pid),acquiredAtMs:Date.now()},timeoutMs:6e5,pollMs:100,description:`iOS runner cache lock`})}function Ke(e){return w.join(w.dirname(e),`${w.basename(e)}.lock`)}function qe(e,t){!Qe()&&!t&&!T.has(e)||(A(`clean`,t?`forced_rebuild`:`forced_clean`,{derived:e}),k(e),O(e),T.delete(e))}async function E(e,t,n,r){let{buildRunnerCacheArtifactManifest:i}=await import(`./runner-artifact-manifest.js`),a=i(e,n,r);return Ue(e,a.ok?{...t,artifacts:a.artifacts}:t),a.ok?null:(A(`preserve`,`uncertifiable_products`,{derived:e,xctestrunPath:n,...a.refusal?{refusal:a.refusal}:{}}),a.refusal)}function D(e,t){if(e)throw new i(`COMMAND_FAILED`,`The Apple runner products cannot be certified for cache reuse`,{reason:`runner_cache_uncertifiable`,refusalReason:e.reason,refusingPath:e.path??t,...e.reason===`root_unusable`?{}:{resolvesTo:e.target},derived:t,hint:`Inspect ${e.path??t} under ${t}. A symlinked or unreadable product tree must be replaced; run pnpm build:xcuitest with a clean AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH.`})}function O(e){try{if(!C.existsSync(e))return;if(w.basename(e)!==`derived`){C.rmSync(e,{recursive:!0,force:!0});return}for(let t of C.readdirSync(e,{withFileTypes:!0}))Ye(t.name)&&C.rmSync(w.join(e,t.name),{recursive:!0,force:!0})}catch{}}const Je=new Set([Te,`Build`,`BuildCache.noindex`,`Index.noindex`,`Logs`,`ModuleCache.noindex`,`SDKStatCaches.noindex`,`SourcePackages`,`TextBasedInstallAPI`,`info.plist`]);function Ye(e){return Je.has(e)}function Xe(e){try{let t=JSON.parse(C.readFileSync(He(e),`utf8`));return!t||typeof t!=`object`||Array.isArray(t)?null:t}catch{return null}}function Ze(e,t){let n=Xe(e);return n?_e(De(n))===_e(De(t))?{ok:!0,metadata:n}:{ok:!1,reason:`cache_metadata_mismatch`,differences:ge(t,n)}:{ok:!1,reason:`cache_metadata_missing`}}function Qe(){return re(process.env.AGENT_DEVICE_IOS_CLEAN_DERIVED)}function k(e,t=process.env){if(t.AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH?.trim()&&!$e(e))throw new i(`COMMAND_FAILED`,`Refusing to clean AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH automatically`,{derivedPath:e,hint:`Unset AGENT_DEVICE_IOS_CLEAN_DERIVED, or move AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH under a subdirectory of ${w.join(v(),`.tmp`)}.`})}function $e(e){let t=w.resolve(v(),`.tmp`),n=w.relative(t,w.resolve(e));return n!==``&&!n.startsWith(`..`)&&!w.isAbsolute(n)}async function et(e){let t=Ze(e.derived,e.expectedCacheMetadata);if(!t.ok)return t.reason===`cache_metadata_mismatch`?{reason:t.reason,xctestrunPath:null,productPaths:[],metadataDifferences:t.differences}:{reason:t.reason,xctestrunPath:null,productPaths:[]};let{validateRunnerCacheArtifactManifest:n}=await import(`./runner-artifact-manifest.js`),r=n(e.derived,t.metadata);return r.ok?{reason:`reuse_ready`,xctestrunPath:r.xctestrunPath,productPaths:r.productPaths}:r.mismatch?{reason:`artifact_content_mismatch`,xctestrunPath:null,productPaths:[],mismatch:r.mismatch}:{reason:`artifact_manifest_missing`,xctestrunPath:null,productPaths:[]}}function tt(e,t){A(`rebuild`,e.reason,{derived:t,...e.reason===`cache_metadata_mismatch`?{metadataDifferences:e.metadataDifferences}:{},...e.reason===`artifact_content_mismatch`?{mismatch:e.mismatch}:{}})}function A(e,t,n){y({level:e===`rebuild`||e===`preserve`?`warn`:`info`,phase:`runner_xctestrun_cache`,data:{action:e,reason:t,...n}})}const nt=new Set([`RUNNER_PRODUCT_MISSING`,`RUNNER_PRODUCT_REPAIR_FAILED`]),rt=[`--force`,`--preserve-metadata=identifier,entitlements,flags,runtime`,`--sign`,`-`];async function it(e,t,n){if(!a(e))return;if(t.length===0)throw new i(`COMMAND_FAILED`,`Missing macOS runner product`,{reason:`RUNNER_PRODUCT_MISSING`,xctestrunPath:n});let r=Array.from(new Set(t)).sort((e,t)=>t.length-e.length);for(let e of r)if(!C.existsSync(e))throw new i(`COMMAND_FAILED`,`Missing macOS runner product`,{reason:`RUNNER_PRODUCT_MISSING`,productPath:e,xctestrunPath:n});for(let e of r)await ct(e)||await at(e,n)}async function at(e,n){try{let t=w.join(e,`Contents`,`Frameworks`),n=C.existsSync(t)?C.readdirSync(t).sort().map(e=>w.join(t,e)):[];for(let e of n)await m(`codesign`,[...rt,e]);await m(`codesign`,[...rt,e])}catch(r){let i=t(r,`COMMAND_FAILED`);throw ot(e,n,i.message,i.details)}if(!await ct(e))throw ot(e,n,`Product still fails code signature verification after re-signing`)}function ot(e,t,n,r){return new i(`COMMAND_FAILED`,`Failed to repair macOS runner product signature`,{reason:`RUNNER_PRODUCT_REPAIR_FAILED`,productPath:e,xctestrunPath:t,error:n,details:r})}function st(e){if(!(e instanceof i))return!1;let t=e.details&&typeof e.details==`object`?e.details.reason:void 0;return typeof t==`string`&&nt.has(t)}async function ct(e){return(await m(`codesign`,[`--verify`,`--deep`,`--strict`,e],{allowFailure:!0})).exitCode===0}const lt=new Set([`ProductPaths`,`DependentProductPaths`,`TestHostPath`,`TestBundlePath`,`UITargetAppPath`]);async function ut(e){let t=await pt(e);if(!t||t.length===0)return null;let n=w.dirname(e),r=new Set,i=dt(t,n);for(let e of i.testRootPaths){if(!C.existsSync(e))return null;r.add(e)}for(let e of ft(i)){if(!e)return null;r.add(e)}return Array.from(r)}function dt(e,t){let n=[],r=new Set,i=[];for(let a of e){if(a.startsWith(`__TESTHOST__/`)){i.push(a.slice(13));continue}if(!a.startsWith(`__TESTROOT__/`))continue;let e=a.slice(13);n.push(w.join(t,e));let o=bt(e);o&&r.add(w.join(t,o))}return{testRootPaths:n,hostRoots:Array.from(r),hostRelativePaths:i}}function ft(e){return e.hostRelativePaths.map(t=>{let n=e.hostRoots.find(e=>C.existsSync(w.join(e,t)));return n?w.join(n,t):null})}async function pt(e){let t=await g(e);if(t)return mt(t);if(process.platform===`darwin`)return null;try{return vt(C.readFileSync(e,`utf8`))}catch{return null}}function mt(e){let t=new Set;for(let n of[e,...ht(e),...gt(e)])for(let e of _t(n))t.add(e);return Array.from(t)}function ht(e){let t=e.TestConfigurations;if(!Array.isArray(t))return[];let n=[];for(let e of t){if(!_(e))continue;let t=e.TestTargets;Array.isArray(t)&&n.push(...t.filter(_))}return n}function gt(e){return Object.values(e).filter(e=>_(e)&&`TestBundlePath`in e)}function _t(e){let t=new Set;for(let[n,r]of Object.entries(e))if(lt.has(n)){if(typeof r==`string`){t.add(r);continue}if(Array.isArray(r))for(let e of r)typeof e==`string`&&t.add(e)}return Array.from(t)}function vt(e){return yt(o(e))}function yt(e){let t=new Set;return f(e,(e,n)=>{if(lt.has(e)){if(n.name===`string`&&n.text){t.add(n.text);return}if(n.name===`array`)for(let e of n.children)e.name===`string`&&e.text&&t.add(e.text)}}),Array.from(t)}function bt(e){let t=/\.app(?:\/|$)/.exec(e);return!t||t.index===void 0?null:e.slice(0,t.index+4)}const xt=[`CFBundleIcons`,`CFBundleIcons~ipad`];async function St(e){await Ct(It(e))}async function Ct(e){let t=e.filter(Pt);if(t.length===0)return;let n=e.filter(e=>j(e)&&!Ft(e));for(let e of t){let t=Nt(e,n);t&&await wt(t,e)}}async function wt(e,t){let n=Tt(e,t),r=await Et(e,t);(n||r)&&(await kt(t),Mt(t))}function Tt(e,t){let n=!1;for(let r of C.readdirSync(e,{withFileTypes:!0}))!r.isFile()||!jt(r.name)||At(w.join(e,r.name),w.join(t,r.name))&&(n=!0);return n}async function Et(e,t){let n=w.join(e,`Info.plist`),r=w.join(t,`Info.plist`),i=await g(n),a=await g(r);if(!i||!a)return!1;let o=Dt(i,a);if(o.length===0)return!1;for(let e of o)await Ot(r,e.key,e.value,e.shouldInsert);return!0}function Dt(e,t){return xt.flatMap(n=>{let r=e[n];return r===void 0||JSON.stringify(t[n])===JSON.stringify(r)?[]:[{key:n,value:r,shouldInsert:t[n]===void 0}]})}async function Ot(e,t,n,r){s(await m(`plutil`,[r?`-insert`:`-replace`,t,`-json`,JSON.stringify(n),e],{allowFailure:!0}),`Failed to update XCTest runner icon plist`,{key:t,plistPath:e})}async function kt(e){s(await m(`codesign`,[`--force`,`--sign`,`-`,`--timestamp=none`,`--generate-entitlement-der`,e],{allowFailure:!0}),`Failed to sign XCTest runner app after icon update`,{runnerAppPath:e})}function At(e,t){if(C.existsSync(t)){let n=C.readFileSync(e),r=C.readFileSync(t);return!n.equals(r)&&(C.copyFileSync(e,t),!0)}return C.copyFileSync(e,t),!0}function jt(e){return/^AppIcon.*\.png$/.test(e)||e===`Assets.car`}function Mt(e){let t=new Date;C.utimesSync(e,t,t)}function Nt(e,t){let n=w.dirname(e);return t.find(e=>w.dirname(e)===n&&w.basename(e)===`AgentDeviceRunner.app`)??t.find(t=>w.dirname(t)===n&&t!==e)??null}function Pt(e){return j(e)&&Ft(e)&&(e.includes(`Debug-iphonesimulator`)||e.includes(`Release-iphonesimulator`)||e.includes(`Debug-appletvsimulator`)||e.includes(`Release-appletvsimulator`))}function Ft(e){return w.basename(e).endsWith(`-Runner.app`)}function j(e){return w.basename(e).endsWith(`.app`)}function It(e){if(!C.existsSync(e))return[];let t=[],n=[e];for(;n.length>0;){let e=n.pop();for(let r of C.readdirSync(e,{withFileTypes:!0})){if(!r.isDirectory())continue;let i=w.join(e,r.name);if(j(i)){t.push(i);continue}n.push(i)}}return t.sort((e,t)=>e.localeCompare(t))}const M=`AgentDeviceRunner.env`,Lt=`session`,Rt=`${P(`${M}.${Lt}`)}-`;function zt(e){return N(`${Lt}-${e.deviceId}-${e.ownerToken}-${e.port}`)}function Bt(e){return`${Rt}${P(N(e))}-[0-9]`}function Vt(e){let t=e?w.basename(e):``;if(t.startsWith(`${M}.`))return P(t)}function N(e){return e.replaceAll(/[^a-zA-Z0-9._-]/g,`_`)}function P(e){return e.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`)}const Ht={PreferredScreenCaptureFormat:`screenshots`,SystemAttachmentLifetime:`keepNever`,UserAttachmentLifetime:`keepNever`};async function Ut(e,t,n,r={}){let i=r.iosXctestEnvDir?.trim(),a=i?w.resolve(i):w.dirname(e);C.mkdirSync(a,{recursive:!0});let o=N(n),s=w.join(a,`${M}.${o}.json`),c=w.join(a,`${M}.${o}.xctestrun`),l=await Wt(e);return Jt(l,e=>Kt(e,t)),qt(l),await Gt(l,s,c),{xctestrunPath:c,jsonPath:s}}async function Wt(e){let t=await m(`plutil`,[`-convert`,`json`,`-o`,`-`,e],{allowFailure:!0});if(t.exitCode!==0||!t.stdout.trim())throw new i(`COMMAND_FAILED`,`Failed to read xctestrun plist`,{xctestrunPath:e,stderr:t.stderr});try{let e=JSON.parse(t.stdout);if(!e||typeof e!=`object`||Array.isArray(e))throw Error(`Root must be an object`);return e}catch(t){throw new i(`COMMAND_FAILED`,`Failed to parse xctestrun JSON`,{xctestrunPath:e,error:String(t)})}}async function Gt(e,t,n){C.writeFileSync(t,JSON.stringify(e,null,2)),s(await m(`plutil`,[`-convert`,`xml1`,`-o`,n,t],{allowFailure:!0}),`Failed to write xctestrun plist`,{tmpXctestrunPath:n})}function Kt(e,t){e.EnvironmentVariables={...e.EnvironmentVariables??{},...t},e.UITestEnvironmentVariables={...e.UITestEnvironmentVariables??{},...t},e.UITargetAppEnvironmentVariables={...e.UITargetAppEnvironmentVariables??{},...t},e.TestingEnvironmentVariables={...e.TestingEnvironmentVariables??{},...t}}function qt(e){Jt(e,e=>Object.assign(e,Ht),{requireTestBundlePath:!0})}function Jt(e,t,n={}){let r=e.TestConfigurations;if(Array.isArray(r))for(let e of r)!e||typeof e!=`object`||Yt(e.TestTargets,t,n);for(let n of Object.values(e)){let e=Xt(n,{requireTestBundlePath:!0});e&&t(e)}}function Yt(e,t,n){if(Array.isArray(e))for(let r of e){let e=Xt(r,n);e&&t(e)}}function Xt(e,t){if(!e||typeof e!=`object`||Array.isArray(e))return null;let n=e;return t.requireTestBundlePath&&!n.TestBundlePath?null:n}const Zt=new Map,F=new Map;function Qt(e){return mn(hn(e,!0))}function $t(e){return mn(hn(e,!1))}function en(e){e.retryPending=!1;let t=F.get(e.deviceId);t&&(t.inFlight.delete(e),pn(e.deviceId,t))}function tn(e){let t=fn(e);t.pendingTeardowns+=1;for(let e of t.inFlight)e.close(`device_teardown`);let n=!1;return()=>{n||(n=!0,--t.pendingTeardowns,pn(e,t))}}function nn(e){let t=[...new Set([...F.keys(),...e??[]])].map(e=>tn(e));return()=>{for(let e of t.splice(0))e()}}function rn(e){return(F.get(e)?.pendingTeardowns??0)>0}function an(e){let t=e;return!t.mintedByStart||t.admitted||t.retired!==`device_teardown`||rn(t.deviceId)?!1:(t.readmit(),!0)}function on(e,t){return t&&!t.admitted?!1:!rn(e)}function sn(e){return n({runnerStartRetired:!0,runnerStartRetirementReason:e})}function cn(e,t){if(!on(e,t))throw sn(t?.retired??`device_teardown`)}function ln(e,t){return t.aborted?`already-spent`:(e.interestedWaiters.add(t),`interested`)}function un(e,t){let n=e;return n.interestedWaiters.delete(t),!n.admitted||n.interestedWaiters.size>0?!1:n.close(`last_waiter_canceled`)}function dn(e,t){e.interestedWaiters.delete(t)}function fn(e){let t=F.get(e);if(t)return t;let n={pendingTeardowns:0,inFlight:new Set};return F.set(e,n),n}function pn(e,t){t.pendingTeardowns<=0&&t.inFlight.size===0&&F.delete(e)}function mn(e){return fn(e.deviceId).inFlight.add(e),e}function hn(e,t){let n=new Set,r;return{deviceId:e,interestedWaiters:n,mintedByStart:t,retryPending:!1,get admitted(){return r===void 0},get retired(){return r},close(t){return!r&&(r=t,y({level:`debug`,phase:`ios_runner_start_admission_retired`,data:{deviceId:e,reason:t}}),!0)},readmit(){r=void 0,y({level:`debug`,phase:`ios_runner_start_admission_readmitted`,data:{deviceId:e}})}}}const I=new Set;function gn(e,t,n){let r={deviceId:e,startAdmission:n,child:t};I.add(r),t.on(`close`,()=>{I.delete(r)})}function _n(e){return xn(e).map(e=>e.child)}function vn(e){return xn(e).filter(e=>e.startAdmission===void 0||!yn(e.startAdmission)).map(e=>e.child)}function yn(e){let t=e;return t.interestedWaiters.size>0||t.retryPending}function bn(e){e.retryPending=!0}function xn(e){return[...I].filter(t=>e===void 0||t.deviceId===e)}function Sn(e){for(let t of I)t.child===e&&I.delete(t)}async function Cn(e,t){let n=wn(t);if(n)return n;let r=v(),i=Ce(e,r,t.budget),a=Se(e,i);return await ne(Zt,a,async()=>await d({acquire:()=>Ge(a),task:()=>En({device:e,options:t,projectRoot:r,expectedCacheMetadata:i,derived:a,forceRebuild:t.forceRunnerXctestrunRebuild===!0})}))}function wn(e){let t=e.iosXctestrunFile?.trim();if(!t)return null;let n=w.resolve(t);if(!C.existsSync(n))throw new i(`COMMAND_FAILED`,`Configured iOS XCTest runner .xctestrun file not found`,{configKey:`iosXctestrunFile`,xctestrunPath:n});let r=e.iosXctestDerivedDataPath?.trim(),a=r?w.resolve(r):Tn(n);return A(`reuse`,`external_xctestrun`,{derived:a,xctestrunPath:n}),{xctestrunPath:n,derived:a,cache:`external`,artifact:`valid`,buildMs:0,xctestrunPathSource:`external`}}function Tn(e){let t=Be.createHash(`sha1`);t.update(e);let n=t.digest(`hex`).slice(0,12);return w.join(Ve.tmpdir(),`agent-device-ios-xctest-derived`,n)}async function En(e){let{device:t,options:n,projectRoot:r,expectedCacheMetadata:i,derived:a}=e;qe(a,e.forceRebuild);let o=await et({derived:a,expectedCacheMetadata:i}),s=o.reason===`reuse_ready`?`exact`:`miss`;return await Dn({device:t,derived:a,expectedCacheMetadata:i,existing:o,cache:s})||(o.reason!==`reuse_ready`&&tt(o,a),o.reason!==`cache_metadata_missing`&&(k(a),O(a)),await On({device:t,options:n,projectRoot:r,expectedCacheMetadata:i,derived:a,cache:s,reason:o.reason}))}async function Dn(e){let{device:t,derived:n,expectedCacheMetadata:r,existing:i,cache:a}=e;if(i.reason!==`reuse_ready`)return null;let o=await kn(t,n,r,i);return o?{xctestrunPath:o,derived:n,cache:a,cacheKey:we(r),artifact:`valid`,buildMs:0,xctestrunPathSource:`manifest`}:null}async function On(e){let{device:t,options:n,projectRoot:r,expectedCacheMetadata:a,derived:o,cache:s,reason:c}=e,l=Ae(r);if(!C.existsSync(l))throw new i(`COMMAND_FAILED`,`iOS runner project not found`,{projectPath:l});let u=ve(n.budget,`runner_xctestrun_build`),d=Date.now();ae({type:`command`,status:`progress`,message:`Building Apple runner...`}),await Fn(t,l,o,n,u);let f=Math.max(0,Date.now()-d),p=jn(o,t);if(!p)throw new i(`COMMAND_FAILED`,`Failed to locate .xctestrun after build`);let m=await ut(p);if(!m)throw new i(`COMMAND_FAILED`,`Runner build is missing expected products`,{xctestrunPath:p});return await it(t,m,p),await Ct(m),D(await E(o,a,p,m),o),A(`build`,`built_new`,{derived:o,xctestrunPath:p}),{xctestrunPath:p,derived:o,cache:s,cacheKey:we(a),artifact:`rebuilt`,buildMs:f,xctestrunPathSource:`build`,reason:c}}async function kn(e,t,n,r){try{return await it(e,r.productPaths,r.xctestrunPath),D(await E(t,n,r.xctestrunPath,r.productPaths),t),A(`reuse`,`reuse_ready`,{derived:t,xctestrunPath:r.xctestrunPath}),r.xctestrunPath}catch(e){if(!st(e))throw e;return A(`rebuild`,`repair_failed`,{derived:t,xctestrunPath:r.xctestrunPath}),null}}async function An(e){try{let t=v(),n=Ce(e,t);return(await et({derived:Se(e,n),expectedCacheMetadata:n})).reason===`reuse_ready`}catch{return!1}}function jn(e,t){let n=Mn(e);return n.length===0?null:(n.sort((e,n)=>Nn(e,n,t)),n[0]?.path??null)}function Mn(e){if(!C.existsSync(e))return[];let t=[],n=[e];for(;n.length>0;){let e=n.pop(),r=C.readdirSync(e,{withFileTypes:!0});for(let i of r){let r=w.join(e,i.name);if(i.isDirectory()){n.push(r);continue}if(i.isFile()&&i.name.endsWith(`.xctestrun`))try{let e=C.statSync(r);t.push({path:r,mtimeMs:e.mtimeMs})}catch{}}}return t}function Nn(e,t,n){if(n){let r=Pn(t.path,n)-Pn(e.path,n);if(r!==0)return r}return t.mtimeMs-e.mtimeMs||e.path.localeCompare(t.path)}function Pn(e,t){let n=0,r=e.toLowerCase();w.basename(r).startsWith(`agentdevicerunner.env.`)&&(n-=1e3),r.includes(`${w.sep}macos${w.sep}`)&&(n-=5e3);let i=pe(t);return i.preferred.length>0&&(i.preferred.some(e=>r.includes(e))?n+=2e3:n-=500),i.disallowed.some(e=>r.includes(e))&&(n-=2500),n}async function Fn(e,t,n,a,o){cn(e.id,a.startAdmission);let s=Ee(process.env),c=je(process.env,e.kind===`device`,e),l=e.kind===`device`?[`-allowProvisioningUpdates`]:[],d=he(),f=ye(process.env),p=ke();try{await u(`xcodebuild`,[`build-for-testing`,`-project`,t,`-scheme`,`AgentDeviceRunner`,`-parallel-testing-enabled`,`NO`,xe(e),`1`,...Ne(e,me(e)),`-derivedDataPath`,n,...be(n),...d,...f,...p,...s,...l,...c],{detached:!0,timeoutMs:o,signal:a.budget?.signal,onSpawn:t=>{gn(e.id,t,a.startAdmission)},onStdoutChunk:e=>{Me(e,a.logPath,a.traceLogPath,a.verbose)},onStderrChunk:e=>{Me(e,a.logPath,a.traceLogPath,a.verbose)}})}catch(t){if(r(t))throw t;let n=t instanceof i?t:new i(`COMMAND_FAILED`,String(t)),o=Ie(e),{reason:s,hint:c,matched:l}=ze(new i(n.code,n.message,{...n.details,...o})),u=oe(n),d=`xcodebuild build-for-testing failed`;throw new i(`COMMAND_FAILED`,s===`simulator_set_destination_not_found`?Pe(d,e,o):d,{reason:s,error:n.message,details:n.details,logPath:a.logPath,hint:c,startupRuleMatched:l,startupHostDeadlineHit:u,...o})}}const L=process.pid;let In;function R(){return In??={value:h(process.pid)},In.value}function z(){return mr(L,R())}function Ln(e){let t=W(e.runnerLogPath);return{schemaVersion:1,deviceId:e.device.id,ownerToken:z(),ownerPid:L,ownerStartTime:R(),ownerStateDir:Wn(),sessionId:e.sessionId,runnerPid:e.runnerPid??null,runnerStartTime:e.runnerPid?h(e.runnerPid):null,port:e.port,xctestrunPath:e.xctestrunPath,cacheKey:e.cacheKey,jsonPath:e.jsonPath,...t?{runnerLogPath:t}:{},...lr(Fe(e.device)),createdAtMs:Date.now(),deviceClaimProtocol:1}}async function Rn(e,t){return await d({acquire:()=>ce({lockDirPath:`${H(e)}.lock`,owner:{pid:L,startTime:R(),acquiredAtMs:Date.now()},timeoutMs:3e4,pollMs:100,description:`iOS runner lease for ${e}`}),task:t})}function B(e){try{return sr(JSON.parse(C.readFileSync(H(e),`utf8`)),e)}catch{return null}}function V(e){if(!e)return{type:`empty`};if(e.ownerToken===z())return{type:`owned`,lease:e};let t=le({owner:{pid:e.ownerPid,startTime:e.ownerStartTime},...e.ownerStateDir?{stateDir:e.ownerStateDir}:{}});return t!==`live`&&t!==`unknown`?{type:`stale`,lease:e,staleReason:t}:{type:`busy`,lease:e}}async function zn(e,t,n){let r=e.id,a=V(B(r));if(a.type===`empty`){await t.cleanupRunnerXcodebuildProcesses({deviceId:r});return}if(a.type===`busy`){if(Bn(a.lease)){await q(a.lease,`same-state-dir`,t);return}if(Vn(a.lease,e)){await q(a.lease,`device-claim-takeover`,t);return}if(Hn(a.lease,n)){await q(a.lease,`logical-lease-takeover`,t);return}throw new i(`COMMAND_FAILED`,n?`iOS runner for ${r} is busy after device lease admission`:`iOS runner for ${r} is already owned by another agent-device daemon`,{reason:`IOS_RUNNER_OWNED_BY_OTHER_DAEMON`,deviceId:r,logicalLeaseContext:n,ownerPid:a.lease.ownerPid,ownerStartTime:a.lease.ownerStartTime,ownerStateDir:a.lease.ownerStateDir,ownerToken:a.lease.ownerToken,sessionId:a.lease.sessionId,hint:Gn(a.lease,n)})}await q(a.lease,a.type,t)}function Bn(e){let t=Wn();return!t||!e.ownerStateDir?!1:w.resolve(t)===w.resolve(e.ownerStateDir)}function Vn(e,t){return e.deviceClaimProtocol===1&&e.deviceId===t.id&&se(t)}function Hn(e,t){return!t||t.leaseProvider!==`proxy`||!t.leaseId||!t.clientId?!1:Un(t.deviceKey,e.deviceId)}function Un(e,t){if(!e)return!1;if(e===t)return!0;let[,,n]=e.split(`:`,3);return n===t}function Wn(){return te()||process.env.AGENT_DEVICE_STATE_DIR?.trim()||void 0}function Gn(e,t){let n=Kn(e),r=qn(e);return t?[r,n,`The device is busy because another active device lease owns it, or the runner is owned by another daemon/process after lease admission.`,`Retry after the owning session closes or after the five-minute inactivity lease expires.`].join(` `):[r,n,`If the runner is still active, wait for it to finish. Do not run prepare ios-runner from another daemon/client to recover this.`].join(` `)}function Kn(e){let t=`Runner owner: PID ${e.ownerPid}`;return e.ownerStateDir?`${t} with AGENT_DEVICE_STATE_DIR=${e.ownerStateDir}`:`${t}.`}function qn(e){return e.ownerStateDir?`If it is stuck, stop the owning agent-device daemon for ${Jn(`AGENT_DEVICE_STATE_DIR`,e.ownerStateDir)} and retry.`:`If it is stuck, stop the owning agent-device daemon and retry.`}function Jn(e,t){return`${e}=${ee(t)}`}function Yn(e){let t=V(B(e));switch(t.type){case`empty`:return{type:`absent`};case`owned`:return{type:`refused`,reason:`lease_owned_by_this_daemon`,lease:t.lease};case`busy`:return{type:`refused`,reason:`lease_owner_live`,lease:t.lease};case`stale`:return t.staleReason===`owner-state-dir-gone`?{type:`refused`,reason:`lease_owner_state_dir_gone`,lease:t.lease}:{type:`adoptable`,lease:t.lease}}}function Xn(e){let t=Yn(e);return t.type===`adoptable`?t.lease:null}function Zn(e){return{...e,ownerToken:`detached-${e.ownerToken}`}}async function Qn(e,t){let n=V(B(e));n.type===`owned`&&await q(n.lease,`owned`,t)}async function $n(e,t){if(!Number.isInteger(e.pid)||e.pid<=0)return;let n=ar(e);await Promise.all(n.map(async e=>{await q(e,`owned`,t)}))}function er(e){return B(e)?.ownerToken??null}function tr(e){e&&rr({deviceId:e.deviceId,ownerToken:e.ownerToken,sessionId:e.sessionId})}function nr(e){let t=H(e.deviceId);C.mkdirSync(w.dirname(t),{recursive:!0}),ue({destination:t,contents:JSON.stringify(e,null,2)})}function rr(e){let t=B(e.deviceId);if(t&&!(e.ownerToken&&t.ownerToken!==e.ownerToken)&&!(e.sessionId&&t.sessionId!==e.sessionId))try{C.unlinkSync(H(e.deviceId))}catch{}}function H(e){return w.join(ir(),`${hr(e)}.json`)}function ir(){let e=process.env.AGENT_DEVICE_IOS_RUNNER_LEASE_DIR?.trim();return e?w.resolve(e):w.join(Ve.homedir(),`.agent-device`,`apple-runner`,`leases`)}function ar(e){let t,n=ir();try{t=C.readdirSync(n,{withFileTypes:!0})}catch{return[]}let r=[];for(let i of t){if(!i.isFile()||!i.name.endsWith(`.json`))continue;let t=or(w.join(n,i.name));t&&t.ownerPid===e.pid&&(e.startTime===void 0||t.ownerStartTime===e.startTime)&&r.push(t)}return r}function or(e){try{let t=JSON.parse(C.readFileSync(e,`utf8`)),n=U(t.deviceId);return n?sr(t,n):null}catch{return null}}function sr(e,t){if(!e||typeof e!=`object`||Array.isArray(e))return null;let n=e;if(n.schemaVersion!==1||n.deviceId!==t)return null;let r=cr(n);return r?{schemaVersion:1,deviceId:t,...r,ownerStartTime:G(n.ownerStartTime),ownerStateDir:G(n.ownerStateDir)??void 0,runnerPid:K(n.runnerPid),runnerStartTime:G(n.runnerStartTime),runnerLogPath:W(n.runnerLogPath),cacheKey:W(n.cacheKey),...lr(n.simulatorSetPath),...n.deviceClaimProtocol===1?{deviceClaimProtocol:1}:{}}:null}function cr(e){let t={ownerToken:U(e.ownerToken),ownerPid:K(e.ownerPid),sessionId:U(e.sessionId),port:K(e.port),xctestrunPath:U(e.xctestrunPath),jsonPath:U(e.jsonPath),createdAtMs:ur(e.createdAtMs)};return Object.values(t).some(e=>e===null)?null:t}function U(e){return typeof e==`string`&&e.length>0?e:null}function W(e){return U(e)??void 0}function lr(e){let t=U(e);return t?{simulatorSetPath:t}:{}}function G(e){return typeof e==`string`?e:null}function K(e){return typeof e==`number`&&Number.isInteger(e)&&e>0?e:null}function ur(e){return typeof e==`number`&&Number.isFinite(e)?e:null}async function q(e,t,n){y({level:t===`owned`?`debug`:`warn`,phase:`ios_runner_lease_cleanup`,data:{deviceId:e.deviceId,ownerPid:e.ownerPid,ownerStateDir:e.ownerStateDir,ownerToken:e.ownerToken,runnerPid:e.runnerPid,sessionId:e.sessionId,reason:t}}),await n.cleanupRunnerProcessTree(fr(e),`SIGTERM`),await n.cleanupRunnerXcodebuildProcesses({deviceId:e.deviceId,xctestrunPath:e.xctestrunPath}),await n.cleanupRunnerProcessTree(fr(e),`SIGKILL`),n.cleanupTempFile(e.xctestrunPath),n.cleanupTempFile(e.jsonPath),tr(e)}function dr(e,t){return b(t)&&J(e,t)}function fr(e){let t=e.runnerPid??void 0;if(!(!t||!b(t))){if(J(e,t))return t;y({level:`warn`,phase:`ios_runner_lease_recycled_pid_skipped`,data:{deviceId:e.deviceId,runnerPid:t,runnerStartTime:e.runnerStartTime??null,sessionId:e.sessionId}})}}function J(e,t){return e.runnerStartTime?h(t)===e.runnerStartTime:pr(l(t))}function pr(e){return!!e&&e.includes(`xcodebuild`)&&e.includes(`AgentDeviceRunner`)}function mr(e,t){let n=Be.createHash(`sha256`);return n.update(String(e)),n.update(`\0`),n.update(t??`unknown-start`),`owner-${e}-${n.digest(`hex`).slice(0,8)}`}function hr(e){return e.replaceAll(/[^A-Za-z0-9._-]/g,`-`)||`unknown-device`}var gr=e({RUNNER_INVALIDATE_WAIT_TIMEOUT_MS:()=>_r,abortRunnerSessionsAndPrepProcesses:()=>xr,cleanupOwnedIosRunnerLease:()=>br,disposeRunnerSession:()=>yr,isRunnerProcessAlive:()=>Mr,runnerLeaseCleanupAdapter:()=>Y,stopRunnerPrepProcesses:()=>Sr,stopRunnerPrepProcessesWithoutLiveOwner:()=>Cr});const _r=1e3,vr=2e3,Y={cleanupRunnerProcessTree:$,cleanupRunnerXcodebuildProcesses:Pr,cleanupTempFile:S};async function yr(e,t={}){x(e,`draining`);let n=!1;if(t.graceful!==!1)n=await Tr(e);else if(a(e.device)){await X([e]),await Z(e,t);return}else await $(e.child.pid,`SIGTERM`);n||(await Er(e,t.waitTimeoutMs??1e4),jr(e.child.pid)&&await $(e.child.pid,`SIGKILL`)),await Z(e,t)}async function br(e){await Qn(e,Y)}async function xr(e){let t=_n(),n=e.filter(e=>a(e.device)),r=e.filter(e=>!a(e.device));for(let t of e)x(t,`draining`);await Q(r,`SIGINT`),await Nr(t,`SIGINT`),await Q(r,`SIGTERM`),await Nr(t,`SIGTERM`),await Q(r,`SIGKILL`),await Nr(t,`SIGKILL`),await X(n),await Promise.allSettled(e.map(async e=>{await Z(e)}))}async function Sr(e){await wr(_n(e))}async function Cr(e){await wr(vn(e))}async function wr(e){await Promise.allSettled(e.map(async e=>{try{await $(e.pid,`SIGTERM`),await $(e.pid,`SIGKILL`)}finally{Sn(e)}}))}async function Tr(e){try{return await Le(e.device,e.port,Re({command:`shutdown`}),void 0,15e3),!1}catch{return a(e.device)?(await X([e]),!0):(await $(e.child.pid,`SIGTERM`),!1)}}async function Er(e,t){let n;try{return await Promise.race([e.testPromise.then(()=>!0,()=>!0),new Promise(e=>{n=setTimeout(()=>e(!1),t)})])||!jr(e.child.pid)}finally{n&&clearTimeout(n)}}async function X(e){if(e.length===0)return;await Q(e,`SIGINT`);let t=await Dr(e,5e3);await Q(t,`SIGTERM`),await Q(await Dr(t,2e3),`SIGKILL`)}async function Dr(e,t){let n=await Promise.all(e.map(async e=>await Er(e,t)));return e.filter((e,t)=>!n[t])}async function Z(e,t={}){await Or(e,t),S(e.xctestrunPath),S(e.jsonPath),x(e,`stopped`)}async function Or(e,t){let n=async()=>{if(!kr(e))try{await Ar(e.device)}finally{tr(e.lease)}};if(t.leaseLockHeld){await n();return}try{await Rn(e.deviceId,n)}catch(t){y({level:`warn`,phase:`ios_runner_disposal_lease_lock_unavailable`,data:{deviceId:e.deviceId,sessionId:e.sessionId,error:t instanceof Error?t.message:String(t)}})}}function kr(e){let t=er(e.deviceId);return t!==null&&t!==e.lease?.ownerToken}async function Ar(e){e.kind===`simulator`&&await Promise.allSettled(Oe.map(async t=>{try{await p(ie(e,[`terminate`,e.id,t]),{allowFailure:!0,timeoutMs:vr})}catch(n){y({level:`warn`,phase:`ios_runner_simulator_app_terminate_failed`,data:{deviceId:e.id,bundleId:t,timeoutMs:vr,error:n instanceof Error?n.message:String(n)}})}}))}function jr(e){return e?Mr(e)||de(e):!1}function Mr(e){return e?b(e):!1}async function Q(e,t){await Promise.allSettled(e.map(async e=>{await $(e.child.pid,t)}))}async function Nr(e,t){await Promise.allSettled(e.map(async e=>{await $(e.pid,t),t===`SIGKILL`&&Sn(e)}))}async function $(e,t){if(!e||e<=0)return;c(e,t),fe([e],t);let n=t===`SIGINT`?`INT`:t===`SIGTERM`?`TERM`:`KILL`;try{await m(`pkill`,[`-${n}`,`-P`,String(e)],{allowFailure:!0})}catch{}}async function Pr(e){let{deviceId:t}=e,n=`xcodebuild.*test-without-building.*${Vt(e.xctestrunPath)??Bt(t)}`;for(let e of[`TERM`,`KILL`])try{await m(`pkill`,[`-${e}`,`-f`,n],{allowFailure:!0,timeoutMs:2e3})}catch(n){y({level:`warn`,phase:`ios_runner_stale_xcodebuild_kill_failed`,data:{deviceId:t,signal:e,error:n instanceof Error?n.message:String(n)}})}}export{Qt as A,ut as B,un as C,en as D,jn as E,on as F,D as H,sn as I,zt as L,an as M,dn as N,An as O,nn as P,Ut as R,cn as S,tn as T,E as U,We as V,z as _,Mr as a,nr as b,Sr as c,Ln as d,$n as f,Xn as g,Yn as h,yr as i,$t as j,bn as k,Cr as l,zn as m,xr as n,Y as o,dr as p,br as r,gr as s,_r as t,Zn as u,J as v,Cn as w,ln as x,Rn as y,St as z};
|
|
1
|
+
import{r as e}from"./rolldown-runtime.js";import{F as t,I as n,K as r,P as i}from"./sdk-contracts.js";import{g as a}from"./sdk-device.js";import{t as o}from"./parser.js";import{A as s,B as c,F as l,G as u,H as d,L as f,N as p,T as m,W as ee,a as te,b as h,d as ne,f as g,g as re,u as _,v as ie,y as ae,z as oe}from"./host.js";import{d as se,r as ce}from"./apple-runner-platform.js";import{i as le}from"./runner-toolchain-probe.js";import{_ as ue,c as de,d as fe,f as pe,g as me,h as he,l as ge,m as _e,o as ve,p as ye,t as be,u as xe,y as Se}from"./runner-cache-metadata.js";import{_ as v,n as y,p as b,u as Ce}from"./runner-session-types.js";import{P as we,r as Te}from"./runner-error-classification.js";import{a as Ee,i as De,n as Oe}from"./runner-device-set.js";import{E as x,S,_ as ke,a as Ae,b as C,d as je,g as Me,m as Ne,r as Pe,v as Fe,w,x as Ie,y as Le}from"./runner-lease.js";import Re from"node:crypto";import T from"node:fs";import ze from"node:os";import E from"node:path";const Be=new Set([`RUNNER_PRODUCT_MISSING`,`RUNNER_PRODUCT_REPAIR_FAILED`]),D=[`--force`,`--preserve-metadata=identifier,entitlements,flags,runtime`,`--sign`,`-`];async function O(e,t,n){if(!a(e))return;if(t.length===0)throw new i(`COMMAND_FAILED`,`Missing macOS runner product`,{reason:`RUNNER_PRODUCT_MISSING`,xctestrunPath:n});let r=Array.from(new Set(t)).sort((e,t)=>t.length-e.length);for(let e of r)if(!T.existsSync(e))throw new i(`COMMAND_FAILED`,`Missing macOS runner product`,{reason:`RUNNER_PRODUCT_MISSING`,productPath:e,xctestrunPath:n});for(let e of r)await A(e)||await Ve(e,n)}async function Ve(e,n){try{let t=E.join(e,`Contents`,`Frameworks`),n=T.existsSync(t)?T.readdirSync(t).sort().map(e=>E.join(t,e)):[];for(let e of n)await p(`codesign`,[...D,e]);await p(`codesign`,[...D,e])}catch(r){let i=t(r,`COMMAND_FAILED`);throw k(e,n,i.message,i.details)}if(!await A(e))throw k(e,n,`Product still fails code signature verification after re-signing`)}function k(e,t,n,r){return new i(`COMMAND_FAILED`,`Failed to repair macOS runner product signature`,{reason:`RUNNER_PRODUCT_REPAIR_FAILED`,productPath:e,xctestrunPath:t,error:n,details:r})}function He(e){if(!(e instanceof i))return!1;let t=e.details&&typeof e.details==`object`?e.details.reason:void 0;return typeof t==`string`&&Be.has(t)}async function A(e){return(await p(`codesign`,[`--verify`,`--deep`,`--strict`,e],{allowFailure:!0})).exitCode===0}const j=new Set([`ProductPaths`,`DependentProductPaths`,`TestHostPath`,`TestBundlePath`,`UITargetAppPath`]);async function M(e){let t=await Ge(e);if(!t||t.length===0)return null;let n=E.dirname(e),r=new Set,i=Ue(t,n);for(let e of i.testRootPaths){if(!T.existsSync(e))return null;r.add(e)}for(let e of We(i)){if(!e)return null;r.add(e)}return Array.from(r)}function Ue(e,t){let n=[],r=new Set,i=[];for(let a of e){if(a.startsWith(`__TESTHOST__/`)){i.push(a.slice(13));continue}if(!a.startsWith(`__TESTROOT__/`))continue;let e=a.slice(13);n.push(E.join(t,e));let o=Qe(e);o&&r.add(E.join(t,o))}return{testRootPaths:n,hostRoots:Array.from(r),hostRelativePaths:i}}function We(e){return e.hostRelativePaths.map(t=>{let n=e.hostRoots.find(e=>T.existsSync(E.join(e,t)));return n?E.join(n,t):null})}async function Ge(e){let t=await m(e);if(t)return Ke(t);if(process.platform===`darwin`)return null;try{return Xe(T.readFileSync(e,`utf8`))}catch{return null}}function Ke(e){let t=new Set;for(let n of[e,...qe(e),...Je(e)])for(let e of Ye(n))t.add(e);return Array.from(t)}function qe(e){let t=e.TestConfigurations;if(!Array.isArray(t))return[];let n=[];for(let e of t){if(!h(e))continue;let t=e.TestTargets;Array.isArray(t)&&n.push(...t.filter(h))}return n}function Je(e){return Object.values(e).filter(e=>h(e)&&`TestBundlePath`in e)}function Ye(e){let t=new Set;for(let[n,r]of Object.entries(e))if(j.has(n)){if(typeof r==`string`){t.add(r);continue}if(Array.isArray(r))for(let e of r)typeof e==`string`&&t.add(e)}return Array.from(t)}function Xe(e){return Ze(o(e))}function Ze(e){let t=new Set;return d(e,(e,n)=>{if(j.has(e)){if(n.name===`string`&&n.text){t.add(n.text);return}if(n.name===`array`)for(let e of n.children)e.name===`string`&&e.text&&t.add(e.text)}}),Array.from(t)}function Qe(e){let t=/\.app(?:\/|$)/.exec(e);return!t||t.index===void 0?null:e.slice(0,t.index+4)}const $e=[`CFBundleIcons`,`CFBundleIcons~ipad`];async function et(e){await N(ft(e))}async function N(e){let t=e.filter(dt);if(t.length===0)return;let n=e.filter(e=>F(e)&&!P(e));for(let e of t){let t=ut(e,n);t&&await tt(t,e)}}async function tt(e,t){let n=nt(e,t),r=await rt(e,t);(n||r)&&(await ot(t),lt(t))}function nt(e,t){let n=!1;for(let r of T.readdirSync(e,{withFileTypes:!0}))!r.isFile()||!ct(r.name)||st(E.join(e,r.name),E.join(t,r.name))&&(n=!0);return n}async function rt(e,t){let n=E.join(e,`Info.plist`),r=E.join(t,`Info.plist`),i=await m(n),a=await m(r);if(!i||!a)return!1;let o=it(i,a);if(o.length===0)return!1;for(let e of o)await at(r,e.key,e.value,e.shouldInsert);return!0}function it(e,t){return $e.flatMap(n=>{let r=e[n];return r===void 0||JSON.stringify(t[n])===JSON.stringify(r)?[]:[{key:n,value:r,shouldInsert:t[n]===void 0}]})}async function at(e,t,n,r){s(await p(`plutil`,[r?`-insert`:`-replace`,t,`-json`,JSON.stringify(n),e],{allowFailure:!0}),`Failed to update XCTest runner icon plist`,{key:t,plistPath:e})}async function ot(e){s(await p(`codesign`,[`--force`,`--sign`,`-`,`--timestamp=none`,`--generate-entitlement-der`,e],{allowFailure:!0}),`Failed to sign XCTest runner app after icon update`,{runnerAppPath:e})}function st(e,t){if(T.existsSync(t)){let n=T.readFileSync(e),r=T.readFileSync(t);return!n.equals(r)&&(T.copyFileSync(e,t),!0)}return T.copyFileSync(e,t),!0}function ct(e){return/^AppIcon.*\.png$/.test(e)||e===`Assets.car`}function lt(e){let t=new Date;T.utimesSync(e,t,t)}function ut(e,t){let n=E.dirname(e);return t.find(e=>E.dirname(e)===n&&E.basename(e)===`AgentDeviceRunner.app`)??t.find(t=>E.dirname(t)===n&&t!==e)??null}function dt(e){return F(e)&&P(e)&&(e.includes(`Debug-iphonesimulator`)||e.includes(`Release-iphonesimulator`)||e.includes(`Debug-appletvsimulator`)||e.includes(`Release-appletvsimulator`))}function P(e){return E.basename(e).endsWith(`-Runner.app`)}function F(e){return E.basename(e).endsWith(`.app`)}function ft(e){if(!T.existsSync(e))return[];let t=[],n=[e];for(;n.length>0;){let e=n.pop();for(let r of T.readdirSync(e,{withFileTypes:!0})){if(!r.isDirectory())continue;let i=E.join(e,r.name);if(F(i)){t.push(i);continue}n.push(i)}}return t.sort((e,t)=>e.localeCompare(t))}const I=`AgentDeviceRunner.env`,L=`session`,pt=`${z(`${I}.${L}`)}-`;function mt(e){return R(`${L}-${e.deviceId}-${e.ownerToken}-${e.port}`)}function ht(e){return`${pt}${z(R(e))}-[0-9]`}function gt(e){let t=e?E.basename(e):``;if(t.startsWith(`${I}.`))return z(t)}function R(e){return e.replaceAll(/[^a-zA-Z0-9._-]/g,`_`)}function z(e){return e.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`)}const _t={PreferredScreenCaptureFormat:`screenshots`,SystemAttachmentLifetime:`keepNever`,UserAttachmentLifetime:`keepNever`};async function vt(e,t,n,r={}){let i=r.iosXctestEnvDir?.trim(),a=i?E.resolve(i):E.dirname(e);T.mkdirSync(a,{recursive:!0});let o=R(n),s=E.join(a,`${I}.${o}.json`),c=E.join(a,`${I}.${o}.xctestrun`),l=await yt(e);return B(l,e=>xt(e,t)),St(l),await bt(l,s,c),{xctestrunPath:c,jsonPath:s}}async function yt(e){let t=await p(`plutil`,[`-convert`,`json`,`-o`,`-`,e],{allowFailure:!0});if(t.exitCode!==0||!t.stdout.trim())throw new i(`COMMAND_FAILED`,`Failed to read xctestrun plist`,{xctestrunPath:e,stderr:t.stderr});try{let e=JSON.parse(t.stdout);if(!e||typeof e!=`object`||Array.isArray(e))throw Error(`Root must be an object`);return e}catch(t){throw new i(`COMMAND_FAILED`,`Failed to parse xctestrun JSON`,{xctestrunPath:e,error:String(t)})}}async function bt(e,t,n){T.writeFileSync(t,JSON.stringify(e,null,2)),s(await p(`plutil`,[`-convert`,`xml1`,`-o`,n,t],{allowFailure:!0}),`Failed to write xctestrun plist`,{tmpXctestrunPath:n})}function xt(e,t){e.EnvironmentVariables={...e.EnvironmentVariables??{},...t},e.UITestEnvironmentVariables={...e.UITestEnvironmentVariables??{},...t},e.UITargetAppEnvironmentVariables={...e.UITargetAppEnvironmentVariables??{},...t},e.TestingEnvironmentVariables={...e.TestingEnvironmentVariables??{},...t}}function St(e){B(e,e=>Object.assign(e,_t),{requireTestBundlePath:!0})}function B(e,t,n={}){let r=e.TestConfigurations;if(Array.isArray(r))for(let e of r)!e||typeof e!=`object`||Ct(e.TestTargets,t,n);for(let n of Object.values(e)){let e=V(n,{requireTestBundlePath:!0});e&&t(e)}}function Ct(e,t,n){if(Array.isArray(e))for(let r of e){let e=V(r,n);e&&t(e)}}function V(e,t){if(!e||typeof e!=`object`||Array.isArray(e))return null;let n=e;return t.requireTestBundlePath&&!n.TestBundlePath?null:n}const wt=new Map,H=new Map;function Tt(e){return zt(Bt(e,!0))}function Et(e){return zt(Bt(e,!1))}function Dt(e){e.retryPending=!1;let t=H.get(e.deviceId);t&&(t.inFlight.delete(e),Rt(e.deviceId,t))}function U(e){let t=Lt(e);t.pendingTeardowns+=1;for(let e of t.inFlight)e.close(`device_teardown`);let n=!1;return()=>{n||(n=!0,--t.pendingTeardowns,Rt(e,t))}}function Ot(e){let t=[...new Set([...H.keys(),...e??[]])].map(e=>U(e));return()=>{for(let e of t.splice(0))e()}}function kt(e){return(H.get(e)?.pendingTeardowns??0)>0}function At(e){let t=e;return!t.mintedByStart||t.admitted||t.retired!==`device_teardown`||kt(t.deviceId)?!1:(t.readmit(),!0)}function jt(e,t){return t&&!t.admitted?!1:!kt(e)}function Mt(e){return n({runnerStartRetired:!0,runnerStartRetirementReason:e})}function Nt(e,t){if(!jt(e,t))throw Mt(t?.retired??`device_teardown`)}function Pt(e,t){return t.aborted?`already-spent`:(e.interestedWaiters.add(t),`interested`)}function Ft(e,t){let n=e;return n.interestedWaiters.delete(t),!n.admitted||n.interestedWaiters.size>0?!1:n.close(`last_waiter_canceled`)}function It(e,t){e.interestedWaiters.delete(t)}function Lt(e){let t=H.get(e);if(t)return t;let n={pendingTeardowns:0,inFlight:new Set};return H.set(e,n),n}function Rt(e,t){t.pendingTeardowns<=0&&t.inFlight.size===0&&H.delete(e)}function zt(e){return Lt(e.deviceId).inFlight.add(e),e}function Bt(e,t){let n=new Set,r;return{deviceId:e,interestedWaiters:n,mintedByStart:t,retryPending:!1,get admitted(){return r===void 0},get retired(){return r},close(t){return!r&&(r=t,_({level:`debug`,phase:`ios_runner_start_admission_retired`,data:{deviceId:e,reason:t}}),!0)},readmit(){r=void 0,_({level:`debug`,phase:`ios_runner_start_admission_readmitted`,data:{deviceId:e}})}}}const W=new Set;function Vt(e,t,n){let r={deviceId:e,startAdmission:n,child:t};W.add(r),t.on(`close`,()=>{W.delete(r)})}function Ht(e){return Kt(e).map(e=>e.child)}function Ut(e){return Kt(e).filter(e=>e.startAdmission===void 0||!Wt(e.startAdmission)).map(e=>e.child)}function Wt(e){let t=e;return t.interestedWaiters.size>0||t.retryPending}function Gt(e){e.retryPending=!0}function Kt(e){return[...W].filter(t=>e===void 0||t.deviceId===e)}function qt(e){for(let t of W)t.child===e&&W.delete(t)}async function Jt(e,t){let n=Xt(t);if(n)return n;let r=g(),i=ve(e,r,t.budget),a=pe(e,i),o=await ee(wt,a,async()=>await u({acquire:()=>Me(a),task:()=>Qt({device:e,options:t,projectRoot:r,expectedCacheMetadata:i,derived:a,forceRebuild:t.forceRunnerXctestrunRebuild===!0})}));return o.artifact===`rebuilt`&&Yt(a),o}async function Yt(e){try{let{evictStaleRunnerCaches:t}=await import(`./runner-cache-retention.js`);await t(e)}catch(t){_({level:`warn`,phase:`runner_xctestrun_cache_eviction_unavailable`,data:{derived:e,error:t instanceof Error?t.message:String(t)}})}}function Xt(e){let t=e.iosXctestrunFile?.trim();if(!t)return null;let n=E.resolve(t);if(!T.existsSync(n))throw new i(`COMMAND_FAILED`,`Configured iOS XCTest runner .xctestrun file not found`,{configKey:`iosXctestrunFile`,xctestrunPath:n});let r=e.iosXctestDerivedDataPath?.trim(),a=r?E.resolve(r):Zt(n);return C(`reuse`,`external_xctestrun`,{derived:a,xctestrunPath:n}),{xctestrunPath:n,derived:a,cache:`external`,artifact:`valid`,buildMs:0,xctestrunPathSource:`external`}}function Zt(e){let t=Re.createHash(`sha1`);t.update(e);let n=t.digest(`hex`).slice(0,12);return E.join(ze.tmpdir(),`agent-device-ios-xctest-derived`,n)}async function Qt(e){let{device:t,options:n,projectRoot:r,expectedCacheMetadata:i,derived:a}=e;Le(a,e.forceRebuild);let o=await S({derived:a,expectedCacheMetadata:i}),s=o.reason===`reuse_ready`?`exact`:`miss`;return await $t({device:t,derived:a,expectedCacheMetadata:i,existing:o,cache:s})||(o.reason!==`reuse_ready`&&Ie(o,a),o.reason!==`cache_metadata_missing`&&(ke(a),Fe(a)),await en({device:t,options:n,projectRoot:r,expectedCacheMetadata:i,derived:a,cache:s,reason:o.reason}))}async function $t(e){let{device:t,derived:n,expectedCacheMetadata:r,existing:i,cache:a}=e;if(i.reason!==`reuse_ready`)return null;let o=await nn(t,n,r,i);return o?{xctestrunPath:o,derived:n,cache:a,cacheKey:fe(r),artifact:`valid`,buildMs:0,xctestrunPathSource:`manifest`}:null}async function en(e){let{device:t,options:n,projectRoot:r,expectedCacheMetadata:a,derived:o,cache:s,reason:c}=e,l=Se(r);if(!T.existsSync(l))throw new i(`COMMAND_FAILED`,`iOS runner project not found`,{projectPath:l});let u=le(n.budget,`runner_xctestrun_build`),d=Date.now();ne({type:`command`,status:`progress`,message:`Building Apple runner...`}),await ln(t,l,o,n,u);let f=Math.max(0,Date.now()-d),p=an(o,t);if(!p)throw new i(`COMMAND_FAILED`,`Failed to locate .xctestrun after build`);let m=await M(p);if(!m)throw new i(`COMMAND_FAILED`,`Runner build is missing expected products`,{xctestrunPath:p});return await O(t,m,p),await N(m),w(await x(o,a,p,m),o),await tn(ye(t,a),o,[p,...m]),C(`build`,`built_new`,{derived:o,xctestrunPath:p}),{xctestrunPath:p,derived:o,cache:s,cacheKey:fe(a),artifact:`rebuilt`,buildMs:f,xctestrunPathSource:`build`,reason:c}}async function tn(e,t,n){try{let{trimRunnerBuildScratch:r}=await import(`./runner-cache-trim.js`);(await r(t,n,e)).length>0&&C(`clean`,`build_scratch_trimmed`,{derived:t})}catch(e){_({level:`warn`,phase:`runner_xctestrun_cache_trim_failed`,data:{derived:t,error:e instanceof Error?e.message:String(e)}})}}async function nn(e,t,n,r){try{return await O(e,r.productPaths,r.xctestrunPath),w(await x(t,n,r.xctestrunPath,r.productPaths),t),C(`reuse`,`reuse_ready`,{derived:t,xctestrunPath:r.xctestrunPath}),r.xctestrunPath}catch(e){if(!He(e))throw e;return C(`rebuild`,`repair_failed`,{derived:t,xctestrunPath:r.xctestrunPath}),null}}async function rn(e){try{let t=g(),n=ve(e,t),r=pe(e,n);return(await S({derived:r,expectedCacheMetadata:n})).reason===`reuse_ready`}catch{return!1}}function an(e,t){let n=on(e);return n.length===0?null:(n.sort((e,n)=>sn(e,n,t)),n[0]?.path??null)}function on(e){if(!T.existsSync(e))return[];let t=[],n=[e];for(;n.length>0;){let e=n.pop(),r=T.readdirSync(e,{withFileTypes:!0});for(let i of r){let r=E.join(e,i.name);if(i.isDirectory()){n.push(r);continue}if(i.isFile()&&i.name.endsWith(`.xctestrun`))try{let e=T.statSync(r);t.push({path:r,mtimeMs:e.mtimeMs})}catch{}}}return t}function sn(e,t,n){if(n){let r=cn(t.path,n)-cn(e.path,n);if(r!==0)return r}return t.mtimeMs-e.mtimeMs||e.path.localeCompare(t.path)}function cn(e,t){let n=0,r=e.toLowerCase();E.basename(r).startsWith(`agentdevicerunner.env.`)&&(n-=1e3),r.includes(`${E.sep}macos${E.sep}`)&&(n-=5e3);let i=se(t);return i.preferred.length>0&&(i.preferred.some(e=>r.includes(e))?n+=2e3:n-=500),i.disallowed.some(e=>r.includes(e))&&(n-=2500),n}async function ln(e,t,n,a,o){Nt(e.id,a.startAdmission);let s=xe(process.env),c=ue(process.env,e.kind===`device`,e),u=e.kind===`device`?[`-allowProvisioningUpdates`]:[],d=he(),f=de(process.env),p=me();try{await l(`xcodebuild`,[`build-for-testing`,`-project`,t,`-scheme`,`AgentDeviceRunner`,`-parallel-testing-enabled`,`NO`,_e(e),`1`,...Ee(e,ce(e)),`-derivedDataPath`,n,...ge(n),...d,...f,...p,...s,...u,...c],{detached:!0,timeoutMs:o,signal:a.budget?.signal,onSpawn:t=>{Vt(e.id,t,a.startAdmission)},onStdoutChunk:e=>{v(e,a.logPath,a.traceLogPath,a.verbose)},onStderrChunk:e=>{v(e,a.logPath,a.traceLogPath,a.verbose)}})}catch(t){if(r(t))throw t;let n=t instanceof i?t:new i(`COMMAND_FAILED`,String(t)),o=Oe(e),{reason:s,hint:c,matched:l}=Te(new i(n.code,n.message,{...n.details,...o})),u=re(n),d=`xcodebuild build-for-testing failed`;throw new i(`COMMAND_FAILED`,s===`simulator_set_destination_not_found`?De(d,e,o):d,{reason:s,error:n.message,details:n.details,logPath:a.logPath,hint:c,startupRuleMatched:l,startupHostDeadlineHit:u,...o})}}var un=e({RUNNER_INVALIDATE_WAIT_TIMEOUT_MS:()=>dn,abortRunnerSessionsAndPrepProcesses:()=>hn,cleanupOwnedIosRunnerLease:()=>mn,disposeRunnerSession:()=>pn,isRunnerProcessAlive:()=>X,runnerLeaseCleanupAdapter:()=>G,stopRunnerPrepProcesses:()=>K,stopRunnerPrepProcessesWithoutLiveOwner:()=>gn});const dn=1e3,fn=2e3,G={cleanupRunnerProcessTree:$,cleanupRunnerXcodebuildProcesses:wn,cleanupTempFile:b};async function pn(e,t={}){y(e,`draining`);let n=!1;if(t.graceful!==!1)n=await vn(e);else if(a(e.device)){await q([e]),await J(e,t);return}else await $(e.child.pid,`SIGTERM`);n||(await yn(e,t.waitTimeoutMs??1e4),Y(e.child.pid)&&await $(e.child.pid,`SIGKILL`)),await J(e,t)}async function mn(e){await Pe(e,G)}async function hn(e){let t=Ht(),n=e.filter(e=>a(e.device)),r=e.filter(e=>!a(e.device));for(let t of e)y(t,`draining`);await Z(r,`SIGINT`),await Q(t,`SIGINT`),await Z(r,`SIGTERM`),await Q(t,`SIGTERM`),await Z(r,`SIGKILL`),await Q(t,`SIGKILL`),await q(n),await Promise.allSettled(e.map(async e=>{await J(e)}))}async function K(e){await _n(Ht(e))}async function gn(e){await _n(Ut(e))}async function _n(e){await Promise.allSettled(e.map(async e=>{try{await $(e.pid,`SIGTERM`),await $(e.pid,`SIGKILL`)}finally{qt(e)}}))}async function vn(e){try{return await Ce(e.device,e.port,we({command:`shutdown`}),void 0,15e3),!1}catch{return a(e.device)?(await q([e]),!0):(await $(e.child.pid,`SIGTERM`),!1)}}async function yn(e,t){let n;try{return await Promise.race([e.testPromise.then(()=>!0,()=>!0),new Promise(e=>{n=setTimeout(()=>e(!1),t)})])||!Y(e.child.pid)}finally{n&&clearTimeout(n)}}async function q(e){if(e.length===0)return;await Z(e,`SIGINT`);let t=await bn(e,5e3);await Z(t,`SIGTERM`),await Z(await bn(t,2e3),`SIGKILL`)}async function bn(e,t){let n=await Promise.all(e.map(async e=>await yn(e,t)));return e.filter((e,t)=>!n[t])}async function J(e,t={}){await xn(e,t),b(e.xctestrunPath),b(e.jsonPath),y(e,`stopped`)}async function xn(e,t){let n=async()=>{if(!Sn(e))try{await Cn(e.device)}finally{je(e.lease)}};if(t.leaseLockHeld){await n();return}try{await Ne(e.deviceId,n)}catch(t){_({level:`warn`,phase:`ios_runner_disposal_lease_lock_unavailable`,data:{deviceId:e.deviceId,sessionId:e.sessionId,error:t instanceof Error?t.message:String(t)}})}}function Sn(e){let t=Ae(e.deviceId);return t!==null&&t!==e.lease?.ownerToken}async function Cn(e){e.kind===`simulator`&&await Promise.allSettled(be.map(async t=>{try{await f(te(e,[`terminate`,e.id,t]),{allowFailure:!0,timeoutMs:fn})}catch(n){_({level:`warn`,phase:`ios_runner_simulator_app_terminate_failed`,data:{deviceId:e.id,bundleId:t,timeoutMs:fn,error:n instanceof Error?n.message:String(n)}})}}))}function Y(e){return e?X(e)||ae(e):!1}function X(e){return e?ie(e):!1}async function Z(e,t){await Promise.allSettled(e.map(async e=>{await $(e.child.pid,t)}))}async function Q(e,t){await Promise.allSettled(e.map(async e=>{await $(e.pid,t),t===`SIGKILL`&&qt(e)}))}async function $(e,t){if(!e||e<=0)return;c(e,t),oe([e],t);let n=t===`SIGINT`?`INT`:t===`SIGTERM`?`TERM`:`KILL`;try{await p(`pkill`,[`-${n}`,`-P`,String(e)],{allowFailure:!0})}catch{}}async function wn(e){let{deviceId:t}=e,n=`xcodebuild.*test-without-building.*${gt(e.xctestrunPath)??ht(t)}`;for(let e of[`TERM`,`KILL`])try{await p(`pkill`,[`-${e}`,`-f`,n],{allowFailure:!0,timeoutMs:2e3})}catch(n){_({level:`warn`,phase:`ios_runner_stale_xcodebuild_kill_failed`,data:{deviceId:t,signal:e,error:n instanceof Error?n.message:String(n)}})}}export{Ot as C,vt as D,mt as E,et as O,It as S,Mt as T,rn as _,X as a,Et as b,K as c,Nt as d,Ft as f,Dt as g,an as h,pn as i,M as k,gn as l,U as m,hn as n,G as o,Jt as p,mn as r,un as s,dn as t,Pt as u,Gt as v,jt as w,At as x,Tt as y};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{G as e,I as t,P as n,rt as r}from"./sdk-contracts.js";import{i}from"./alert-contract.js";import{g as a,p as o,x as s}from"./host.js";import ee from"node:crypto";const c=`RUNNER_BUSY`,l=`RUNNER_WEDGED`,u=`APP_NOT_RUNNING`;function te(e){let t=o(e.requestId);return e.signal?!t||t===e.signal?e.signal:AbortSignal.any([t,e.signal]):t}function d(e){return e instanceof DOMException&&e.name===`TimeoutError`}function ne(e){return s(e.requestId)||o(e.requestId)?.aborted?!1:e.signal?.aborted===!0&&d(e.signal.reason)}function re(e){let t=o(e.requestId),n=e.signal;if(!n||n===t)return t;let r=new AbortController,i=()=>{d(n.reason)||r.abort(n.reason)};return n.aborted?i():n.addEventListener(`abort`,i,{once:!0}),t?AbortSignal.any([t,r.signal]):r.signal}const f=`SCROLL_KEYBOARD_OCCLUDES_SURFACE`,p=new Set([`APP_SCREEN_WINDOW_UNRESOLVED`,`APP_SCREEN_UNRESOLVED`,`APP_SCREEN_CAPTURE_UNRENDERABLE`]),ie=new Map([[c,{retriable:!0,reason:`runner_busy`}],[`MAIN_THREAD_TIMEOUT`,{reason:`runner_main_thread_timeout`}],[u,{retriable:!0}],[i,{}],[f,{}],...[...p].map(e=>[e,{}])]),ae=new Map([[`INVALID_ARGS`,`no`],[`ELEMENT_NOT_FOUND`,`no`],[`ELEMENT_OFFSCREEN`,`no`],[`AMBIGUOUS_MATCH`,`no`],[c,`no`],[l,`no`],[u,`no`],[f,`no`],[i,`no`],...[...p].map(e=>[e,`no`])]);function m(e){let t=e===void 0?void 0:ie.get(e);return Object.freeze({code:t?`COMMAND_FAILED`:r(e),details:Object.freeze({runnerErrorCode:e,...t,dispatched:(e===void 0?void 0:ae.get(e))??`unknown`})})}function oe(e){let t;try{t=JSON.parse(e)}catch{throw new n(`COMMAND_FAILED`,`Invalid runner response`,{text:e})}if(!h(t))throw new n(`COMMAND_FAILED`,`Invalid runner response`,{text:e});return t}function h(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function g(e){return e.ok===!0}function _(e){return!e.data||typeof e.data!=`object`||Array.isArray(e.data)?{}:e.data}function v(e,t){let r=y(e.error?.code),i=typeof e.error?.message==`string`?e.error.message:void 0,a=typeof e.error?.hint==`string`?e.error.hint:void 0,o=m(r);return new n(o.code,i??`Runner error`,{runner:e,...o.details,xcodebuild:{exitCode:1,stdout:``,stderr:``},hint:a,logPath:t})}function y(e){return typeof e==`string`&&e.trim().length>0?e.trim():void 0}function b(e){return e.command===`status`||e.commandId?.trim()?e:{...e,commandId:x()}}function x(){return`runner-${ee.randomUUID()}`}function S(e){if(s(e))throw t()}const C={readOnly:!1,readinessProbe:!1,readinessPreflightExempt:!1,readinessPreflightSkipEligibleAfterHealthyMutation:!1},w={...C,readinessPreflightExempt:!0},T={...C,readOnly:!0},E={...T,readinessProbe:!0},D={...C,readinessPreflightSkipEligibleAfterHealthyMutation:!0},se={tap:D,mouseClick:C,longPress:D,drag:D,remotePress:C,type:C,swipe:D,scroll:D,desktopScroll:D,findText:T,querySelector:T,readText:T,snapshot:T,screenshot:T,backInApp:C,backSystem:C,home:C,rotate:C,gesture:D,gestureViewport:T,appSwitcher:C,actionButton:C,keyboardDismiss:C,keyboardReturn:C,alert:e=>(e.action??`get`).toLowerCase()===`get`?T:C,sequence:D,recordStart:C,recordStop:C,status:E,uptime:E,appState:T,pasteboardWrite:C,activate:w,terminate:w,targetReset:w,shutdown:C};function O(e){return k(e).readOnly}function ce(e){return k(e).readinessProbe}function le(e){return k(e).readinessPreflightExempt}function ue(e){return k(e).readinessPreflightSkipEligibleAfterHealthyMutation}function k(e){let t=se[e.command];return typeof t==`function`?t(e):t}const A="If runner build products look stale or corrupted, run `pnpm clean:xcuitest` in a local checkout, or remove ~/.agent-device/apple-runner/derived, then retry.";function j(e){return{runnerConnectFailureReason:e}}const M=`runner_reply_lost`,N=e=>e.reason===M,P=e=>e.runnerErrorCode===c,F=e=>typeof e.devToolsSecurityStatus==`string`,I=e=>typeof e.simulatorSetPath==`string`,L=e=>e.usbmuxDeviceAttached===!1,R=e=>t=>t.runnerConnectFailureReason===e,z=t=>t.runnerReadinessPreflightFailed===!0&&!e(t),B=`build_failed_unclassified`,V={reason:`signing_provisioning_profile_missing`,hint:`Install/select a valid iOS provisioning profile, or set AGENT_DEVICE_IOS_PROVISIONING_PROFILE.`},H=[{reason:M,match:{code:`COMMAND_FAILED`,details:N},verdicts:{retryable:!1,drainResend:!1,connectRetry:!1,restartBeforeSend:!1,restartAfterReadinessPreflight:!1}},{reason:`usbmux_device_unattached`,match:{code:`DEVICE_NOT_FOUND`,details:L},verdicts:{connectRetry:!1}},{reason:`runner_busy_refusal`,match:{code:`COMMAND_FAILED`,details:P},verdicts:{retryable:!0,connectRetry:!0,drainResend:!0}},{reason:`xcodebuild_exited_early`,match:{code:`COMMAND_FAILED`,details:R(`xcodebuild_exited_early`)},verdicts:{retryable:!1,connectRetry:!1,artifactSuspect:!1}},{reason:`device_busy_connecting`,match:{code:`COMMAND_FAILED`,foreignMessageIncludesAll:[`device is busy`,`connecting`]},verdicts:{retryable:!1,connectRetry:!1}},{reason:`runner_readiness_preflight_failed`,match:{code:`COMMAND_FAILED`,details:z},verdicts:{restartAfterReadinessPreflight:!0}},{reason:`runner_connect_refused`,match:{code:`COMMAND_FAILED`,details:R(`runner_connect_refused`)},verdicts:{retryable:!0,connectRetry:!0,restartBeforeSend:!0,artifactSuspect:!0}},{reason:`runner_endpoint_probe_exhausted`,match:{code:`COMMAND_FAILED`,details:R(`runner_endpoint_probe_exhausted`)},verdicts:{artifactSuspect:!0}},{reason:`fetch_failed`,match:{code:`COMMAND_FAILED`,foreignMessageIncludesAll:[`fetch failed`]},verdicts:{retryable:!0,connectRetry:!0}},{reason:`econnrefused`,match:{code:`COMMAND_FAILED`,foreignMessageIncludesAll:[`econnrefused`]},verdicts:{retryable:!0,connectRetry:!0}},{reason:`socket_hang_up`,match:{code:`COMMAND_FAILED`,foreignMessageIncludesAll:[`socket hang up`]},verdicts:{retryable:!0,connectRetry:!0}},{reason:`ax_snapshot_failure`,match:{code:`IOS_AX_SNAPSHOT_FAILED`},verdicts:{sessionFatalReason:`ax_snapshot_failure`}},{reason:`xctest_recorded_failure`,match:{code:`XCTEST_RECORDED_FAILURE`},verdicts:{sessionFatalReason:`xctest_recorded_failure`}},{reason:`runner_main_thread_wedged`,match:{code:l},verdicts:{sessionFatalReason:`runner_main_thread_wedged`}},{reason:`simulator_set_destination_not_found`,match:{toolTextIncludesAll:[`matching the provided destination specifier`],details:I},verdicts:{},buildFailure:{reason:`simulator_set_destination_not_found`,hint:"Check that the simulator still exists in the --ios-simulator-device-set this error names (`xcrun simctl --set <set> list devices`). If it does, the Xcode this error names no longer honors -DVTSimulatorSetLocation, so use a simulator in the default set."}},{reason:`bundle_identifier_registration_failed`,match:{toolTextIncludesAll:[`failed registering bundle identifier`]},verdicts:{},buildFailure:{reason:`bundle_identifier_already_registered`,hint:`Set AGENT_DEVICE_IOS_BUNDLE_ID to a unique reverse-DNS value (for example, com.yourname.agentdevice.runner), then retry.`}},{reason:`bundle_identifier_unavailable`,match:{toolTextLineIncludesAll:[`app identifier`,`not available`]},verdicts:{},buildFailure:{reason:`bundle_identifier_already_registered`,hint:`Set AGENT_DEVICE_IOS_BUNDLE_ID to a unique reverse-DNS value (for example, com.yourname.agentdevice.runner), then retry.`}},{reason:`signing_requires_development_team`,match:{toolTextIncludesAll:[`requires a development team`]},verdicts:{},buildFailure:{reason:`signing_no_development_team`,hint:`Configure signing in Xcode or set AGENT_DEVICE_IOS_TEAM_ID for physical-device runs.`}},{reason:`conflicting_provisioning_settings_unproven`,match:{toolTextIncludesAll:[`conflicting provisioning settings`]},verdicts:{},buildFailure:{reason:B,hint:A}},{reason:`signing_no_profiles_for_bundle_id`,match:{toolTextIncludesAll:[`no profiles for`]},verdicts:{},buildFailure:V},{reason:`signing_provisioning_profile_xcode_error`,match:{toolTextLineIncludesAll:[`provisioning profile`,`ideprovisioningerrordomain`]},verdicts:{},buildFailure:V},{reason:`signing_provisioning_profile_does_not_cover`,match:{toolTextLineIncludesAll:[`provisioning profile`,`doesn't include`]},verdicts:{},buildFailure:V},{reason:`signing_provisioning_profile_expired`,match:{toolTextLineIncludesAll:[`provisioning profile`,`has expired`]},verdicts:{},buildFailure:V},{reason:`signing_unspecified`,match:{toolTextIncludesAll:[`code signing`]},verdicts:{},buildFailure:{reason:`signing_unspecified`,hint:`Enable Automatic Signing in Xcode or provide AGENT_DEVICE_IOS_TEAM_ID and optional AGENT_DEVICE_IOS_SIGNING_IDENTITY.`}},{reason:`devtools_security_refused`,match:{code:`COMMAND_FAILED`,details:F},verdicts:{},buildFailure:{reason:`devtools_security_developer_mode_disabled`,hint:"Run `sudo DevToolsSecurity -enable`, then retry the iOS runner. UI test runners start suspended until Xcode/testmanagerd can attach."}}];function U(e,t){return t.code!==void 0&&e.code!==t.code||!de(e,t.details)||!pe(e,t.toolTextIncludesAll)||!me(e,t.toolTextLineIncludesAll)?!1:fe(e,t.foreignMessageIncludesAll)}function de(e,t){return t===void 0||t(e.details??{})}function fe(e,t){if(!t)return!0;let n=`${e.message??``}`.toLowerCase();return t.every(e=>n.includes(e))}function W(e){let t=e.details??{};return[e.message,t.stdout,t.stderr].filter(e=>typeof e==`string`).join(`
|
|
1
|
+
import{G as e,I as t,P as n,rt as r}from"./sdk-contracts.js";import{i}from"./alert-contract.js";import{g as a,p as o,x as s}from"./host.js";import ee from"node:crypto";const c=`RUNNER_BUSY`,l=`RUNNER_WEDGED`,u=`APP_NOT_RUNNING`;function te(e){let t=o(e.requestId);return e.signal?!t||t===e.signal?e.signal:AbortSignal.any([t,e.signal]):t}function d(e){return e instanceof DOMException&&e.name===`TimeoutError`}function ne(e){return s(e.requestId)||o(e.requestId)?.aborted?!1:e.signal?.aborted===!0&&d(e.signal.reason)}function re(e){let t=o(e.requestId),n=e.signal;if(!n||n===t)return t;let r=new AbortController,i=()=>{d(n.reason)||r.abort(n.reason)};return n.aborted?i():n.addEventListener(`abort`,i,{once:!0}),t?AbortSignal.any([t,r.signal]):r.signal}const f=`SCROLL_KEYBOARD_OCCLUDES_SURFACE`,p=new Set([`APP_SCREEN_WINDOW_UNRESOLVED`,`APP_SCREEN_UNRESOLVED`,`APP_SCREEN_CAPTURE_UNRENDERABLE`]),ie=new Map([[c,{retriable:!0,reason:`runner_busy`}],[`MAIN_THREAD_TIMEOUT`,{reason:`runner_main_thread_timeout`}],[u,{retriable:!0}],[i,{}],[f,{}],...[...p].map(e=>[e,{}])]),ae=new Map([[`INVALID_ARGS`,`no`],[`ELEMENT_NOT_FOUND`,`no`],[`ELEMENT_OFFSCREEN`,`no`],[`AMBIGUOUS_MATCH`,`no`],[c,`no`],[l,`no`],[u,`no`],[`OBSERVATION_UNAVAILABLE`,`no`],[f,`no`],[i,`no`],...[...p].map(e=>[e,`no`])]);function m(e){let t=e===void 0?void 0:ie.get(e);return Object.freeze({code:t?`COMMAND_FAILED`:r(e),details:Object.freeze({runnerErrorCode:e,...t,dispatched:(e===void 0?void 0:ae.get(e))??`unknown`})})}function oe(e){let t;try{t=JSON.parse(e)}catch{throw new n(`COMMAND_FAILED`,`Invalid runner response`,{text:e})}if(!h(t))throw new n(`COMMAND_FAILED`,`Invalid runner response`,{text:e});return t}function h(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function g(e){return e.ok===!0}function _(e){return!e.data||typeof e.data!=`object`||Array.isArray(e.data)?{}:e.data}function v(e,t){let r=y(e.error?.code),i=typeof e.error?.message==`string`?e.error.message:void 0,a=typeof e.error?.hint==`string`?e.error.hint:void 0,o=m(r);return new n(o.code,i??`Runner error`,{runner:e,...o.details,xcodebuild:{exitCode:1,stdout:``,stderr:``},hint:a,logPath:t})}function y(e){return typeof e==`string`&&e.trim().length>0?e.trim():void 0}function b(e){return e.command===`status`||e.commandId?.trim()?e:{...e,commandId:x()}}function x(){return`runner-${ee.randomUUID()}`}function S(e){if(s(e))throw t()}const C={readOnly:!1,readinessProbe:!1,readinessPreflightExempt:!1,readinessPreflightSkipEligibleAfterHealthyMutation:!1},w={...C,readinessPreflightExempt:!0},T={...C,readOnly:!0},E={...T,readinessProbe:!0},D={...C,readinessPreflightSkipEligibleAfterHealthyMutation:!0},se={tap:D,mouseClick:C,longPress:D,drag:D,remotePress:C,type:C,swipe:D,scroll:D,desktopScroll:D,findText:T,querySelector:T,readText:T,snapshot:T,screenshot:T,backInApp:C,backSystem:C,home:C,rotate:C,gesture:D,gestureViewport:T,appSwitcher:C,actionButton:C,keyboardDismiss:C,keyboardReturn:C,alert:e=>(e.action??`get`).toLowerCase()===`get`?T:C,sequence:D,recordStart:C,recordStop:C,status:E,uptime:E,appState:T,pasteboardWrite:C,activate:w,terminate:w,targetReset:w,shutdown:C};function O(e){return k(e).readOnly}function ce(e){return k(e).readinessProbe}function le(e){return k(e).readinessPreflightExempt}function ue(e){return k(e).readinessPreflightSkipEligibleAfterHealthyMutation}function k(e){let t=se[e.command];return typeof t==`function`?t(e):t}const A="If runner build products look stale or corrupted, run `pnpm clean:xcuitest` in a local checkout, or remove ~/.agent-device/apple-runner/derived, then retry.";function j(e){return{runnerConnectFailureReason:e}}const M=`runner_reply_lost`,N=e=>e.reason===M,P=e=>e.runnerErrorCode===c,F=e=>typeof e.devToolsSecurityStatus==`string`,I=e=>typeof e.simulatorSetPath==`string`,L=e=>e.usbmuxDeviceAttached===!1,R=e=>t=>t.runnerConnectFailureReason===e,z=t=>t.runnerReadinessPreflightFailed===!0&&!e(t),B=`build_failed_unclassified`,V={reason:`signing_provisioning_profile_missing`,hint:`Install/select a valid iOS provisioning profile, or set AGENT_DEVICE_IOS_PROVISIONING_PROFILE.`},H=[{reason:M,match:{code:`COMMAND_FAILED`,details:N},verdicts:{retryable:!1,drainResend:!1,connectRetry:!1,restartBeforeSend:!1,restartAfterReadinessPreflight:!1}},{reason:`usbmux_device_unattached`,match:{code:`DEVICE_NOT_FOUND`,details:L},verdicts:{connectRetry:!1}},{reason:`runner_busy_refusal`,match:{code:`COMMAND_FAILED`,details:P},verdicts:{retryable:!0,connectRetry:!0,drainResend:!0}},{reason:`xcodebuild_exited_early`,match:{code:`COMMAND_FAILED`,details:R(`xcodebuild_exited_early`)},verdicts:{retryable:!1,connectRetry:!1,artifactSuspect:!1}},{reason:`device_busy_connecting`,match:{code:`COMMAND_FAILED`,foreignMessageIncludesAll:[`device is busy`,`connecting`]},verdicts:{retryable:!1,connectRetry:!1}},{reason:`runner_readiness_preflight_failed`,match:{code:`COMMAND_FAILED`,details:z},verdicts:{restartAfterReadinessPreflight:!0}},{reason:`runner_connect_refused`,match:{code:`COMMAND_FAILED`,details:R(`runner_connect_refused`)},verdicts:{retryable:!0,connectRetry:!0,restartBeforeSend:!0,artifactSuspect:!0}},{reason:`runner_endpoint_probe_exhausted`,match:{code:`COMMAND_FAILED`,details:R(`runner_endpoint_probe_exhausted`)},verdicts:{artifactSuspect:!0}},{reason:`fetch_failed`,match:{code:`COMMAND_FAILED`,foreignMessageIncludesAll:[`fetch failed`]},verdicts:{retryable:!0,connectRetry:!0}},{reason:`econnrefused`,match:{code:`COMMAND_FAILED`,foreignMessageIncludesAll:[`econnrefused`]},verdicts:{retryable:!0,connectRetry:!0}},{reason:`socket_hang_up`,match:{code:`COMMAND_FAILED`,foreignMessageIncludesAll:[`socket hang up`]},verdicts:{retryable:!0,connectRetry:!0}},{reason:`ax_snapshot_failure`,match:{code:`IOS_AX_SNAPSHOT_FAILED`},verdicts:{sessionFatalReason:`ax_snapshot_failure`}},{reason:`xctest_recorded_failure`,match:{code:`XCTEST_RECORDED_FAILURE`},verdicts:{sessionFatalReason:`xctest_recorded_failure`}},{reason:`runner_main_thread_wedged`,match:{code:l},verdicts:{sessionFatalReason:`runner_main_thread_wedged`}},{reason:`simulator_set_destination_not_found`,match:{toolTextIncludesAll:[`matching the provided destination specifier`],details:I},verdicts:{},buildFailure:{reason:`simulator_set_destination_not_found`,hint:"Check that the simulator still exists in the --ios-simulator-device-set this error names (`xcrun simctl --set <set> list devices`). If it does, the Xcode this error names no longer honors -DVTSimulatorSetLocation, so use a simulator in the default set."}},{reason:`bundle_identifier_registration_failed`,match:{toolTextIncludesAll:[`failed registering bundle identifier`]},verdicts:{},buildFailure:{reason:`bundle_identifier_already_registered`,hint:`Set AGENT_DEVICE_IOS_BUNDLE_ID to a unique reverse-DNS value (for example, com.yourname.agentdevice.runner), then retry.`}},{reason:`bundle_identifier_unavailable`,match:{toolTextLineIncludesAll:[`app identifier`,`not available`]},verdicts:{},buildFailure:{reason:`bundle_identifier_already_registered`,hint:`Set AGENT_DEVICE_IOS_BUNDLE_ID to a unique reverse-DNS value (for example, com.yourname.agentdevice.runner), then retry.`}},{reason:`signing_requires_development_team`,match:{toolTextIncludesAll:[`requires a development team`]},verdicts:{},buildFailure:{reason:`signing_no_development_team`,hint:`Configure signing in Xcode or set AGENT_DEVICE_IOS_TEAM_ID for physical-device runs.`}},{reason:`conflicting_provisioning_settings_unproven`,match:{toolTextIncludesAll:[`conflicting provisioning settings`]},verdicts:{},buildFailure:{reason:B,hint:A}},{reason:`signing_no_profiles_for_bundle_id`,match:{toolTextIncludesAll:[`no profiles for`]},verdicts:{},buildFailure:V},{reason:`signing_provisioning_profile_xcode_error`,match:{toolTextLineIncludesAll:[`provisioning profile`,`ideprovisioningerrordomain`]},verdicts:{},buildFailure:V},{reason:`signing_provisioning_profile_does_not_cover`,match:{toolTextLineIncludesAll:[`provisioning profile`,`doesn't include`]},verdicts:{},buildFailure:V},{reason:`signing_provisioning_profile_expired`,match:{toolTextLineIncludesAll:[`provisioning profile`,`has expired`]},verdicts:{},buildFailure:V},{reason:`signing_unspecified`,match:{toolTextIncludesAll:[`code signing`]},verdicts:{},buildFailure:{reason:`signing_unspecified`,hint:`Enable Automatic Signing in Xcode or provide AGENT_DEVICE_IOS_TEAM_ID and optional AGENT_DEVICE_IOS_SIGNING_IDENTITY.`}},{reason:`devtools_security_refused`,match:{code:`COMMAND_FAILED`,details:F},verdicts:{},buildFailure:{reason:`devtools_security_developer_mode_disabled`,hint:"Run `sudo DevToolsSecurity -enable`, then retry the iOS runner. UI test runners start suspended until Xcode/testmanagerd can attach."}}];function U(e,t){return t.code!==void 0&&e.code!==t.code||!de(e,t.details)||!pe(e,t.toolTextIncludesAll)||!me(e,t.toolTextLineIncludesAll)?!1:fe(e,t.foreignMessageIncludesAll)}function de(e,t){return t===void 0||t(e.details??{})}function fe(e,t){if(!t)return!0;let n=`${e.message??``}`.toLowerCase();return t.every(e=>n.includes(e))}function W(e){let t=e.details??{};return[e.message,t.stdout,t.stderr].filter(e=>typeof e==`string`).join(`
|
|
2
2
|
`).toLowerCase()}function pe(e,t){if(!t)return!0;let n=W(e);return t.every(e=>n.includes(e))}function me(e,t){return!t||W(e).split(`
|
|
3
3
|
`).some(e=>t.every(t=>e.includes(t)))}function G(e,t){if(e instanceof n){for(let n of H)if(n.verdicts[t]!==void 0&&U(e,n.match))return n.verdicts[t]}}function he(e){return!(e instanceof n)||e.code!==`COMMAND_FAILED`?!1:G(e,`retryable`)??!1}function ge(e){return K(e)?!0:e instanceof n&&e.details?.runnerErrorCode===`MAIN_THREAD_TIMEOUT`}function K(e){return G(e,`drainResend`)??!1}function _e(e){return e instanceof n&&e.details?.runner!==void 0}function ve(e){return!(e instanceof n)||e.code!==`DEVICE_NOT_FOUND`?!1:L(e.details??{})}function ye(e){return G(e,`connectRetry`)??!0}function q(e){return G(e,`restartAfterReadinessPreflight`)??!1}function be(e){return G(e,`artifactSuspect`)??!1}function xe(e){return G(e,`sessionFatalReason`)}function Se(e,t){return J(e)?X(e)===`no`||O(t):!1}function J(e){return G(e,`restartBeforeSend`)??!1}function Ce(e){return J(e)&&Y(e)||q(e)||K(e)}function Y(e){return e instanceof n&&e.details?.dispatched===`no`||Z(e,0)}function X(e){return Y(e)?`no`:`unknown`}function Z(e,t){return t>4||typeof e!=`object`||!e?!1:e.code===`ECONNREFUSED`?!0:e instanceof AggregateError&&e.errors.length>0?e.errors.every(e=>Z(e,t+1)):Z(e.cause,t+1)}function Q(e){if(e instanceof n)for(let t of H){let n=t.buildFailure;if(n&&U(e,t.match))return{reason:n.reason,hint:n.hint,matched:!0}}return{reason:B,hint:A,matched:!1}}function $(e,t){if(!t||!(e instanceof n))return e;let r=we(e)===void 0&&t.developerDiskImage===`unavailable`&&!Ee(e)&&!Te(e);return new n(e.code,e.message,{...e.details??{},...r?{reason:`device_developer_disk_image_unavailable`,hint:t.developerDiskImageHint}:{},developerDiskImage:t.developerDiskImage},e.cause)}function we(e){let t=e.details?.reason;if(typeof t==`string`&&t!==`build_failed_unclassified`)return t}function Te(e){let t=e.details?.startupHostDeadlineHit;return typeof t==`boolean`?t:a(e)}function Ee(e){let t=e.details?.startupRuleMatched;return typeof t==`boolean`?t:Q(e).matched}export{g as A,f as C,m as D,ne as E,te as M,re as N,oe as O,b as P,ce as S,v as T,Se as _,he as a,O as b,ge as c,ve as d,X as f,q as g,be as h,$ as i,_ as j,d as k,Ce as l,j as m,M as n,K as o,xe as p,Q as r,Y as s,A as t,_e as u,ye as v,S as w,le as x,ue as y};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{P as e}from"./sdk-contracts.js";import{U as t,t as n,u as r}from"./host.js";import{
|
|
1
|
+
import{P as e}from"./sdk-contracts.js";import{U as t,t as n,u as r}from"./host.js";import{f as i,h as a,l as o,n as s,u as c}from"./runner-session-types.js";import{A as l,O as u,P as d,S as f,T as p,b as m,c as h,j as g,p as _,u as v,x as y,y as b}from"./runner-error-classification.js";import x from"node:fs/promises";const S=2e3;async function C(e,t={}){if(e){try{await a(e,{timeoutMs:Math.min(S,t.timeoutMs??S),signal:t.signal})}catch{return}try{return{logPath:e,byteOffset:(await x.stat(e)).size}}catch{return{logPath:e,byteOffset:0}}}}async function w(t){let n=await T(t.logSince)??D(t.error);return n?new e(n.code??t.error.code,t.error.message,{...t.error.details??{},hint:typeof t.error.details?.hint==`string`?`${t.error.details.hint} ${n.hint}`:n.hint,runnerFailureReason:n.reason},t.error):t.error}async function T(e){if(!e)return;let t=await j(e,65536);if(t)return E(t)}function E(e){let t=e.toLowerCase();if(O(t))return{code:`IOS_TARGET_APP_CRASH`,reason:`target_app_axruntime_coretext_crash`,hint:`The target iOS app appears to have crashed while XCTest/AXRuntime read accessibility attributes. This is usually a simulator/XCTest/runtime or app accessibility payload issue, not a text-entry failure. Reproduce on the latest stable simulator runtime, reinstall the app, and capture the app crash from Console.app or ~/Library/Logs/DiagnosticReports with the exact command, selector/ref, app build, Xcode, and simulator runtime.`};if(k(t))return{code:`IOS_TARGET_APP_CRASH`,reason:`target_app_crash`,hint:`The target iOS app appears to have crashed while the runner was executing the command. Reopen or reinstall the app, retry on a fresh/latest stable simulator runtime, and capture the app crash from Console.app or ~/Library/Logs/DiagnosticReports with the exact command, selector/ref, app build, Xcode, and simulator runtime.`}}function D(e){if(A(e.message))return{reason:`runner_main_thread_execution_timeout`,hint:`XCTest timed out waiting for main-thread work on the current iOS screen. The app may still be visually responsive, especially on focused React Native overlays or animating screens. Use screenshot as visual truth, use coordinate presses only to prove or leave the state, and retry snapshot -i after the UI settles or after navigating away.`}}function O(e){return e.includes(`axruntime`)&&e.includes(`coretext`)&&(e.includes(`attributesforelement`)||e.includes(`axuielementcopymultipleattributevalues`)||e.includes(`reconstitutedsmuggledctfontfromdictionary`)||e.includes(`reconstitutedsmuggledattributedstringfromdictionary`))}function k(e){return e.includes(`process crashed`)||e.includes(`the application under test`)||e.includes(`terminated unexpectedly`)||e.includes(`exception type:`)&&e.includes(`thread 0 crashed`)}function A(e){return e.toLowerCase().includes(`main thread execution timed out`)}async function j(e,t){let n;try{let r=await x.stat(e.logPath),i=Math.max(e.byteOffset,r.size-t),a=r.size-i;if(a<=0)return;n=await x.open(e.logPath,`r`);let o=Buffer.alloc(a);return await n.read(o,0,a,i),o.toString(`utf8`)}catch{return}finally{await n?.close().catch(()=>{})}}async function M(e,t,r,i,a,o,s){let c=await C(i,{timeoutMs:a,signal:s}),l=d(r),u=m(l),f=n.fromTimeoutMs(a),p=U(t,l);p.action===`run`?await R({device:e,session:t,runnerCommand:l,logAttempt:c,deadline:f,signal:s,decision:p}):z(l,t,p);let h;try{h=await L({device:e,session:t,runnerCommand:l,logPath:i,deadline:f,timeoutMs:a,signal:s,readOnlyCommand:u})}catch(e){throw I(e,t,p)}try{let e=await B(h,t,c);return await N(t,l,e,o),e}catch(e){let n=P(t,l,e),r=_(e);throw r?(t.lastHealthyMutation=void 0,await o(r),e):n?e:I(e,t,p)}}async function N(e,t,n,r){e.commandCharges.settleAnswered(t.commandId);let i=F(n);i!==void 0&&(e.runnerMainThreadBusy=i);let a=H(n);a?(e.lastHealthyMutation=void 0,await r(a)):b(t)&&(e.lastHealthyMutation={atMs:Date.now(),appBundleId:t.appBundleId})}function P(e,t,n){let r=v(n);return r?e.commandCharges.settleAnswered(t.commandId):e.commandCharges.markAbandoned(t.commandId),h(n)?e.runnerMainThreadBusy=!0:r&&(e.runnerMainThreadBusy=!1),r}function F(e){return typeof e.runnerMainThreadBusy==`boolean`?e.runnerMainThreadBusy:void 0}function I(e,t,n){return n.action!==`skip`||n.reason!==`recent_healthy_mutation`?e:(t.lastHealthyMutation=void 0,G(e,{runnerReadinessPreflightSkipped:!0,runnerReadinessPreflightSkipReason:n.reason,runnerReadinessPreflightSkippedAgeMs:n.lastHealthyMutationAgeMs}))}async function L(n){let{device:r,session:a,runnerCommand:o,logPath:s,deadline:l,timeoutMs:u,signal:d,readOnlyCommand:p}=n,m=l.remainingMs();if(m<=0)throw new e(`COMMAND_FAILED`,`Runner command deadline exceeded`,{timeoutMs:u});let h=p?{command:o.command,commandId:o.commandId,readOnly:!0,sessionReady:a.state===`ready`,timeoutMs:m}:{command:o.command,commandId:o.commandId},g=!f(o);g&&a.commandCharges.charge(o.commandId);try{return await t(`ios_runner_command_send`,async()=>p?await c(r,a.port,o,s,m,a,d):await i(r,a.port,o,m,d),h)}catch(e){throw g&&a.commandCharges.markAbandoned(o.commandId),e}}async function R(e){let{device:n,session:r,runnerCommand:i,logAttempt:a,deadline:o,signal:s,decision:l}=e,u=a?.logPath,f=r.state===`ready`?Math.min(1e3,o.remainingMs()):Math.min(K(r),o.remainingMs());try{let e=F(await B(await t(`ios_runner_readiness_preflight`,async()=>await c(n,r.port,d({command:`uptime`}),u,f,r,s),{command:i.command,commandId:i.commandId,reason:l.reason,lastHealthyMutationAgeMs:l.lastHealthyMutationAgeMs,sessionReady:r.state===`ready`,timeoutMs:f}),r,a));e!==void 0&&(r.runnerMainThreadBusy=e)}catch(e){throw W(e)}}function z(e,t,n){r({level:`debug`,phase:`ios_runner_readiness_preflight_skipped`,data:{command:e.command,commandId:e.commandId,reason:n.reason,lastHealthyMutationAgeMs:n.reason===`recent_healthy_mutation`?n.lastHealthyMutationAgeMs:void 0,sessionReady:t.state===`ready`}})}async function B(e,t,n){let r=u(await e.text());if(!l(r))throw await w({error:p(r,n?.logPath),logSince:n});s(t,`ready`);let i=g(r);return V(i),i}function V(e){let t=e.gestureFallback;typeof t==`string`&&t.length!==0&&r({level:`debug`,phase:`ios_runner_gesture_fallback`,data:{fallback:t,message:typeof e.gestureFallbackMessage==`string`?e.gestureFallbackMessage:void 0,hint:typeof e.gestureFallbackHint==`string`?e.gestureFallbackHint:void 0}})}function H(e){if(e.runnerFatal===!0)return typeof e.runnerFatalReason==`string`&&e.runnerFatalReason.trim().length>0?e.runnerFatalReason:`runner_reported_fatal_response`}function U(e,t){let n=m(t);if(y(t))return{action:`skip`,reason:`preflight_exempt_command`};if(e.state!==`ready`)return n?{action:`skip`,reason:`read_only_startup_command`}:{action:`run`,reason:`startup`};if(f(t))return{action:`skip`,reason:`readiness_probe_command`};if(!b(t))return{action:`run`,reason:`conservative_command`};let r=e.lastHealthyMutation;if(!r)return{action:`run`,reason:`no_recent_healthy_mutation`};if(t.appBundleId!==r.appBundleId)return{action:`run`,reason:`app_activation_uncertain`};let i=Date.now()-r.atMs;return i>5e3?{action:`run`,reason:`healthy_mutation_stale`,lastHealthyMutationAgeMs:i}:{action:`skip`,reason:`recent_healthy_mutation`,lastHealthyMutationAgeMs:i}}function W(e){return G(e,{runnerReadinessPreflightFailed:!0})}function G(t,n){let r=t instanceof e?t:new e(`COMMAND_FAILED`,t instanceof Error?t.message:String(t),void 0,t);return new e(r.code,r.message,{...r.details??{},...n},r.cause??t)}function K(e){let t=e.launchDeadline;return t?Math.max(0,Math.floor(t.remainingMs())):o}export{M as executeRunnerExchange,K as readRunnerStartupTimeoutMs};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{P as e}from"./sdk-contracts.js";import{D as t,G as n,O as r,R as i,S as a,_ as ee,f as o,m as te,n as s,s as c,u as l,v as u,w as ne}from"./host.js";import"./runner-toolchain-probe.js";import{i as re,n as d,r as f,v as p}from"./runner-cache-metadata.js";import{r as ie}from"./runner-device-set.js";import m from"node:crypto";import h from"node:fs";import ae from"node:os";import g from"node:path";const _=new Set;function v(e){return g.join(e,d)}function oe(e,t){h.mkdirSync(e,{recursive:!0}),h.writeFileSync(v(e),`${JSON.stringify(t,null,2)}\n`)}async function se(e,t){if(e.cache===`external`){T(`preserve`,`external_bad_artifact`,{derived:e.derived,xctestrunPath:e.xctestrunPath,reason:t});return}_.add(e.derived),await n({acquire:()=>y(e.derived),task:async()=>{T(`clean`,`bad_artifact`,{derived:e.derived,xctestrunPath:e.xctestrunPath,reason:t}),w(e.derived),S(e.derived)}})}async function y(e,t=6e5){return await s({lockDirPath:ce(e),owner:{pid:process.pid,startTime:r(process.pid),acquiredAtMs:Date.now()},timeoutMs:t,pollMs:100,description:`iOS runner cache lock`})}function ce(e){return g.join(g.dirname(e),`${g.basename(e)}.lock`)}function le(e,t){!pe()&&!t&&!_.has(e)||(T(`clean`,t?`forced_rebuild`:`forced_clean`,{derived:e}),w(e),S(e),_.delete(e))}async function b(e,t,n,r){let{buildRunnerCacheArtifactManifest:i}=await import(`./runner-artifact-manifest.js`),a=i(e,n,r);return oe(e,a.ok?{...t,artifacts:a.artifacts}:t),a.ok?null:(T(`preserve`,`uncertifiable_products`,{derived:e,xctestrunPath:n,...a.refusal?{refusal:a.refusal}:{}}),a.refusal)}function x(t,n){if(t)throw new e(`COMMAND_FAILED`,`The Apple runner products cannot be certified for cache reuse`,{reason:`runner_cache_uncertifiable`,refusalReason:t.reason,refusingPath:t.path??n,...t.reason===`root_unusable`?{}:{resolvesTo:t.target},derived:n,hint:`Inspect ${t.path??n} under ${n}. A symlinked or unreadable product tree must be replaced; run pnpm build:xcuitest with a clean AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH.`})}function S(e){try{if(!h.existsSync(e))return;if(g.basename(e)!==`derived`){h.rmSync(e,{recursive:!0,force:!0});return}for(let t of h.readdirSync(e,{withFileTypes:!0}))ue(t.name)&&h.rmSync(g.join(e,t.name),{recursive:!0,force:!0})}catch{}}const C=new Set([d,`Build`,`BuildCache.noindex`,`Index.noindex`,`Logs`,`ModuleCache.noindex`,`SDKStatCaches.noindex`,`SourcePackages`,`TextBasedInstallAPI`,`info.plist`]);function ue(e){return C.has(e)}function de(e){try{let t=JSON.parse(h.readFileSync(v(e),`utf8`));return!t||typeof t!=`object`||Array.isArray(t)?null:t}catch{return null}}function fe(e,t){let n=de(e);return n?p(f(n))===p(f(t))?{ok:!0,metadata:n}:{ok:!1,reason:`cache_metadata_mismatch`,differences:re(t,n)}:{ok:!1,reason:`cache_metadata_missing`}}function pe(){return ee(process.env.AGENT_DEVICE_IOS_CLEAN_DERIVED)}function w(t,n=process.env){if(n.AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH?.trim()&&!me(t))throw new e(`COMMAND_FAILED`,`Refusing to clean AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH automatically`,{derivedPath:t,hint:`Unset AGENT_DEVICE_IOS_CLEAN_DERIVED, or move AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH under a subdirectory of ${g.join(o(),`.tmp`)}.`})}function me(e){let t=g.resolve(o(),`.tmp`),n=g.relative(t,g.resolve(e));return n!==``&&!n.startsWith(`..`)&&!g.isAbsolute(n)}async function he(e){let t=fe(e.derived,e.expectedCacheMetadata);if(!t.ok)return t.reason===`cache_metadata_mismatch`?{reason:t.reason,xctestrunPath:null,productPaths:[],metadataDifferences:t.differences}:{reason:t.reason,xctestrunPath:null,productPaths:[]};let{validateRunnerCacheArtifactManifest:n}=await import(`./runner-artifact-manifest.js`),r=n(e.derived,t.metadata);return r.ok?{reason:`reuse_ready`,xctestrunPath:r.xctestrunPath,productPaths:r.productPaths}:r.mismatch?{reason:`artifact_content_mismatch`,xctestrunPath:null,productPaths:[],mismatch:r.mismatch}:{reason:`artifact_manifest_missing`,xctestrunPath:null,productPaths:[]}}function ge(e,t){T(`rebuild`,e.reason,{derived:t,...e.reason===`cache_metadata_mismatch`?{metadataDifferences:e.metadataDifferences}:{},...e.reason===`artifact_content_mismatch`?{mismatch:e.mismatch}:{}})}function T(e,t,n){l({level:e===`rebuild`||e===`preserve`?`warn`:`info`,phase:`runner_xctestrun_cache`,data:{action:e,reason:t,...n}})}const E=process.pid;let D;function O(){return D??={value:r(process.pid)},D.value}function k(){return Re(E,O())}function A(e){let t=q(e.runnerLogPath);return{schemaVersion:1,deviceId:e.device.id,ownerToken:k(),ownerPid:E,ownerStartTime:O(),ownerStateDir:R(),sessionId:e.sessionId,runnerPid:e.runnerPid??null,runnerStartTime:e.runnerPid?r(e.runnerPid):null,port:e.port,xctestrunPath:e.xctestrunPath,cacheKey:e.cacheKey,jsonPath:e.jsonPath,...t?{runnerLogPath:t}:{},...J(ie(e.device)),createdAtMs:Date.now(),deviceClaimProtocol:1}}async function j(e,t){return await n({acquire:()=>s({lockDirPath:`${H(e)}.lock`,owner:{pid:E,startTime:O(),acquiredAtMs:Date.now()},timeoutMs:3e4,pollMs:100,description:`iOS runner lease for ${e}`}),task:t})}function M(e){try{return G(JSON.parse(h.readFileSync(H(e),`utf8`)),e)}catch{return null}}function N(e){if(!e)return{type:`empty`};if(e.ownerToken===k())return{type:`owned`,lease:e};let t=c({owner:{pid:e.ownerPid,startTime:e.ownerStartTime},...e.ownerStateDir?{stateDir:e.ownerStateDir}:{}});return t!==`live`&&t!==`unknown`?{type:`stale`,lease:e,staleReason:t}:{type:`busy`,lease:e}}async function P(t,n,r){let i=t.id,a=N(M(i));if(a.type===`empty`){await n.cleanupRunnerXcodebuildProcesses({deviceId:i});return}if(a.type===`busy`){if(F(a.lease)){await Z(a.lease,`same-state-dir`,n);return}if(I(a.lease,t)){await Z(a.lease,`device-claim-takeover`,n);return}if(L(a.lease,r)){await Z(a.lease,`logical-lease-takeover`,n);return}throw new e(`COMMAND_FAILED`,r?`iOS runner for ${i} is busy after device lease admission`:`iOS runner for ${i} is already owned by another agent-device daemon`,{reason:`IOS_RUNNER_OWNED_BY_OTHER_DAEMON`,deviceId:i,logicalLeaseContext:r,ownerPid:a.lease.ownerPid,ownerStartTime:a.lease.ownerStartTime,ownerStateDir:a.lease.ownerStateDir,ownerToken:a.lease.ownerToken,sessionId:a.lease.sessionId,hint:ve(a.lease,r)})}await Z(a.lease,a.type,n)}function F(e){let t=R();return!t||!e.ownerStateDir?!1:g.resolve(t)===g.resolve(e.ownerStateDir)}function I(e,t){return e.deviceClaimProtocol===1&&e.deviceId===t.id&&te(t)}function L(e,t){return!t||t.leaseProvider!==`proxy`||!t.leaseId||!t.clientId?!1:_e(t.deviceKey,e.deviceId)}function _e(e,t){if(!e)return!1;if(e===t)return!0;let[,,n]=e.split(`:`,3);return n===t}function R(){return a()||process.env.AGENT_DEVICE_STATE_DIR?.trim()||void 0}function ve(e,t){let n=ye(e),r=be(e);return t?[r,n,`The device is busy because another active device lease owns it, or the runner is owned by another daemon/process after lease admission.`,`Retry after the owning session closes or after the five-minute inactivity lease expires.`].join(` `):[r,n,`If the runner is still active, wait for it to finish. Do not run prepare ios-runner from another daemon/client to recover this.`].join(` `)}function ye(e){let t=`Runner owner: PID ${e.ownerPid}`;return e.ownerStateDir?`${t} with AGENT_DEVICE_STATE_DIR=${e.ownerStateDir}`:`${t}.`}function be(e){return e.ownerStateDir?`If it is stuck, stop the owning agent-device daemon for ${xe(`AGENT_DEVICE_STATE_DIR`,e.ownerStateDir)} and retry.`:`If it is stuck, stop the owning agent-device daemon and retry.`}function xe(e,t){return`${e}=${i(t)}`}function z(e){let t=N(M(e));switch(t.type){case`empty`:return{type:`absent`};case`owned`:return{type:`refused`,reason:`lease_owned_by_this_daemon`,lease:t.lease};case`busy`:return{type:`refused`,reason:`lease_owner_live`,lease:t.lease};case`stale`:return t.staleReason===`owner-state-dir-gone`?{type:`refused`,reason:`lease_owner_state_dir_gone`,lease:t.lease}:{type:`adoptable`,lease:t.lease}}}function Se(e){let t=z(e);return t.type===`adoptable`?t.lease:null}function B(e){return{...e,ownerToken:`detached-${e.ownerToken}`}}async function Ce(e,t){let n=N(M(e));n.type===`owned`&&await Z(n.lease,`owned`,t)}async function we(e,t){if(!Number.isInteger(e.pid)||e.pid<=0)return;let n=Oe(e);await Promise.all(n.map(async e=>{await Z(e,`owned`,t)}))}function Te(e){return M(e)?.ownerToken??null}function V(e){e&&De({deviceId:e.deviceId,ownerToken:e.ownerToken,sessionId:e.sessionId})}function Ee(e){let t=H(e.deviceId);h.mkdirSync(g.dirname(t),{recursive:!0}),ne({destination:t,contents:JSON.stringify(e,null,2)})}function De(e){let t=M(e.deviceId);if(t&&!(e.ownerToken&&t.ownerToken!==e.ownerToken)&&!(e.sessionId&&t.sessionId!==e.sessionId))try{h.unlinkSync(H(e.deviceId))}catch{}}function H(e){return g.join(U(),`${ze(e)}.json`)}function U(){let e=process.env.AGENT_DEVICE_IOS_RUNNER_LEASE_DIR?.trim();return e?g.resolve(e):g.join(ae.homedir(),`.agent-device`,`apple-runner`,`leases`)}function Oe(e){return W({strict:!1}).filter(t=>t.ownerPid===e.pid&&(e.startTime===void 0||t.ownerStartTime===e.startTime))}function W(e){let t=e.strict?Ae:ke,n=U(),r=t(()=>h.readdirSync(n,{withFileTypes:!0}))??[],i=[];for(let e of r){if(!e.isFile()||!e.name.endsWith(`.json`))continue;let r=t(()=>h.readFileSync(g.join(n,e.name),`utf8`)),a=r===null?null:Ne(r);a&&i.push(a)}return i}function ke(e){try{return e()}catch{return null}}function Ae(e){try{return e()}catch(e){if(e.code===`ENOENT`)return null;throw e}}function je(){return W({strict:!0}).filter(e=>!Me(e)).map(({xctestrunPath:e,cacheKey:t})=>({xctestrunPath:e,cacheKey:t}))}function Me(e){let t=N(e);if(t.type!==`stale`||t.staleReason===`owner-state-dir-gone`)return!1;if(e.runnerPid===null)return!0;let n=c({owner:{pid:e.runnerPid,startTime:e.runnerStartTime??null}});return n===`owner-process-dead`||n===`owner-process-reused`}function Ne(e){try{let t=JSON.parse(e),n=K(t.deviceId);return n?G(t,n):null}catch{return null}}function G(e,t){if(!e||typeof e!=`object`||Array.isArray(e))return null;let n=e;if(n.schemaVersion!==1||n.deviceId!==t)return null;let r=Pe(n);return r?{schemaVersion:1,deviceId:t,...r,ownerStartTime:Y(n.ownerStartTime),ownerStateDir:Y(n.ownerStateDir)??void 0,runnerPid:X(n.runnerPid),runnerStartTime:Y(n.runnerStartTime),runnerLogPath:q(n.runnerLogPath),cacheKey:q(n.cacheKey),...J(n.simulatorSetPath),...n.deviceClaimProtocol===1?{deviceClaimProtocol:1}:{}}:null}function Pe(e){let t={ownerToken:K(e.ownerToken),ownerPid:X(e.ownerPid),sessionId:K(e.sessionId),port:X(e.port),xctestrunPath:K(e.xctestrunPath),jsonPath:K(e.jsonPath),createdAtMs:Fe(e.createdAtMs)};return Object.values(t).some(e=>e===null)?null:t}function K(e){return typeof e==`string`&&e.length>0?e:null}function q(e){return K(e)??void 0}function J(e){let t=K(e);return t?{simulatorSetPath:t}:{}}function Y(e){return typeof e==`string`?e:null}function X(e){return typeof e==`number`&&Number.isInteger(e)&&e>0?e:null}function Fe(e){return typeof e==`number`&&Number.isFinite(e)?e:null}async function Z(e,t,n){l({level:t===`owned`?`debug`:`warn`,phase:`ios_runner_lease_cleanup`,data:{deviceId:e.deviceId,ownerPid:e.ownerPid,ownerStateDir:e.ownerStateDir,ownerToken:e.ownerToken,runnerPid:e.runnerPid,sessionId:e.sessionId,reason:t}}),await n.cleanupRunnerProcessTree(Q(e),`SIGTERM`),await n.cleanupRunnerXcodebuildProcesses({deviceId:e.deviceId,xctestrunPath:e.xctestrunPath}),await n.cleanupRunnerProcessTree(Q(e),`SIGKILL`),n.cleanupTempFile(e.xctestrunPath),n.cleanupTempFile(e.jsonPath),V(e)}function Ie(e,t){return u(t)&&$(e,t)}function Q(e){let t=e.runnerPid??void 0;if(!(!t||!u(t))){if($(e,t))return t;l({level:`warn`,phase:`ios_runner_lease_recycled_pid_skipped`,data:{deviceId:e.deviceId,runnerPid:t,runnerStartTime:e.runnerStartTime??null,sessionId:e.sessionId}})}}function $(e,n){return e.runnerStartTime?r(n)===e.runnerStartTime:Le(t(n))}function Le(e){return!!e&&e.includes(`xcodebuild`)&&e.includes(`AgentDeviceRunner`)}function Re(e,t){let n=m.createHash(`sha256`);return n.update(String(e)),n.update(`\0`),n.update(t??`unknown-start`),`owner-${e}-${n.digest(`hex`).slice(0,8)}`}function ze(e){return e.replaceAll(/[^A-Za-z0-9._-]/g,`-`)||`unknown-device`}export{se as C,b as E,he as S,v as T,w as _,Te as a,T as b,P as c,V as d,k as f,y as g,Ee as h,we as i,z as l,j as m,A as n,Ie as o,$ as p,Ce as r,je as s,B as t,Se as u,S as v,x as w,ge as x,le as y};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{l as e,n as t}from"./apple-runner-platform.js";import{_ as n,
|
|
1
|
+
import{l as e,n as t}from"./apple-runner-platform.js";import{_ as n,a as r,c as i,g as a,h as o,o as s,s as c,u as l}from"./runner-cache-metadata.js";import{a as u,c as d,d as f,f as p,i as m,l as h,n as g,o as _,p as v,r as y,s as b,u as x}from"./runner-client.js";import{E as S,p as C,u as w,w as T}from"./runner-lease.js";import{O as E,h as D,k as O}from"./runner-disposal.js";async function k(e,t,n,r){return await d(e,{command:`querySelector`,selectorKey:t.key,selectorValue:t.value,appBundleId:n},r)}async function A(e){let{cleanupRunnerLeasesForOwner:t}=await import(`./runner-client.js`).then(e=>e.t),{runnerLeaseCleanupAdapter:n}=await import(`./runner-disposal.js`).then(e=>e.s);await t(e,n)}export{E as applyXctestRunnerAppIconFromDerivedPath,A as cleanupRunnerLeasesForOwner,h as detachIosRunnerSessionsForShutdown,D as findRunnerXctestrun,g as hasLiveIosRunnerSession,t as isRunnerXcuitestScriptPlatform,y as notifyIosRunnerAppRelaunched,m as prepareIosRunner,u as prewarmAppleRunnerCache,_ as prewarmIosRunnerSession,k as queryAppleRunnerSelector,x as readRunnerSessionLiveness,w as readStaleRunnerLease,f as releaseIosRunnerOnClose,b as releaseSpeculativeIosRunnerSessionFor,T as requireCertifiedRunnerCacheArtifacts,r as requireRunnerBuildSettingsMatchBuildLog,O as resolveExistingRunnerProductPaths,s as resolveExpectedRunnerCacheMetadata,c as resolveRunnerAppBundleId,i as resolveRunnerArchBuildSettings,l as resolveRunnerBundleBuildSettings,o as resolveRunnerPerformanceBuildSettings,a as resolveRunnerSandboxBuildArgs,e as resolveRunnerScriptDevice,n as resolveRunnerSigningBuildSettings,d as runAppleRunnerCommand,p as stopAllIosRunnerSessions,v as stopIosRunnerSession,C as verifyLeaseRunnerPidIdentity,S as writeRunnerCacheMetadataForArtifacts};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{I as e,K as t,P as n,V as r,z as i}from"./sdk-contracts.js";import{n as a}from"./entities.js";import{t as o}from"./parser.js";import{A as s,L as c,M as l,V as u,a as d,i as f,j as p,o as m,t as h}from"./host.js";import{o as g}from"./runner-cache-metadata.js";import{d as _,i as v,m as y,r as ee,s as te,t as ne,v as re}from"./runner-error-classification.js";import b from"node:fs";import ie from"node:os";import x from"node:path";import S from"node:net";import C from"node:http";async function ae(){return await new Promise((e,t)=>{let r=S.createServer();r.listen(0,`127.0.0.1`,()=>{let i=r.address();if(typeof i==`object`&&i?.port){let t=i.port;r.close(()=>e(t))}else r.close(()=>t(new n(`COMMAND_FAILED`,`Failed to allocate port`)))}),r.on(`error`,t)})}function oe(e,t,n,r){t&&E(t,e),n&&E(n,e),r&&process.stderr.write(e)}const w=new Map,T=new Map;function E(e,t){let n=(w.get(e)??Promise.resolve()).then(()=>D(e,t),()=>D(e,t)).then(()=>{T.delete(e)},t=>{T.set(e,t)}).finally(()=>{w.get(e)===n&&w.delete(e)});w.set(e,n)}async function D(e,t){await b.promises.mkdir(x.dirname(e),{recursive:!0}),await b.promises.appendFile(e,t)}async function se(e,t={}){let n=AbortSignal.any([t.signal??new AbortController().signal,AbortSignal.timeout(t.timeoutMs??2e3)]);if(n.aborted)throw n.reason;let r=w.get(e);if(r){let e=()=>{};try{await Promise.race([r,new Promise((t,r)=>{e=()=>r(n.reason),n.addEventListener(`abort`,e,{once:!0})})])}finally{n.removeEventListener(`abort`,e)}}let i=T.get(e);if(i!==void 0)throw i}function ce(e){try{b.existsSync(e)&&b.unlinkSync(e)}catch{}}function le(e,t){if(e)return e;let n=t.replaceAll(/[^A-Za-z0-9._-]/g,`_`);return x.join(ie.tmpdir(),`agent-device`,`apple-runner`,`logs`,`${n}.log`)}function ue(e,t){let n=0;try{n=b.fstatSync(t).size}catch{}return{logPath:e,startOffset:n}}function de(e){let t=e.pollMs??50,n=Buffer.alloc(65536),r=e.file.startOffset,i=null,a=null,o=!1,s=()=>{if(!o)try{i??=b.openSync(e.file.logPath,`r`);let t=b.fstatSync(i).size;for(t<r&&(r=0);r<t;){let a=Math.min(n.length,t-r),o=b.readSync(i,n,0,a,r);if(o<=0)break;r+=o,e.onOutput(n.toString(`utf8`,0,o)),t=b.fstatSync(i).size}}catch{l()}},c=()=>{o||(a=setTimeout(()=>{s(),c()},t),a.unref?.())};function l(){if(!o&&(o=!0,a&&clearTimeout(a),a=null,i!==null)){try{b.closeSync(i)}catch{}i=null}}return c(),{drain:()=>{s(),l()},stop:l}}function fe(e,t){if(!e)return``;let n=null;try{n=b.openSync(e.logPath,`r`);let r=b.fstatSync(n).size,i=Math.max(e.startOffset,r-t),a=r-i;if(a<=0)return``;let o=Buffer.alloc(a),s=b.readSync(n,o,0,a,i);return o.toString(`utf8`,0,Math.max(s,0))}catch{return``}finally{if(n!==null)try{b.closeSync(n)}catch{}}}const O=new Map;function k(e,t){let n,r=!1;return{markUsbmuxUnattached:()=>{r=!0},resolveRoute:async(i,a=!1)=>{if(e.kind!==`device`)return j(e,t,null,!1);let o=p(e);if(o.backend===`xctest`||!r)return pe(e,t);if(!a){let r=me(e.id);if(r)return j(e,t,r,!0);if(n!==void 0)return j(e,t,n,!1)}let{tunnelIp:s}=await o.resolveTunnel(e,i);return n=s,s&&he(e.id,s),j(e,t,s,!1)}}}function A(e){O.delete(e)}function pe(e,t){return{kind:`usbmux`,endpoints:[`usbmux://${e.id}:${t}/command`],cachedTunnelIp:!1}}function j(e,t,n,r){let i=[`http://127.0.0.1:${t}/command`];return e.kind===`device`&&n&&i.unshift(`http://[${n}]:${t}/command`),{kind:`network`,endpoints:i,cachedTunnelIp:r}}function me(e){let t=O.get(e);return t?t.expiresAt<=Date.now()?(O.delete(e),null):t.ip:null}function he(e,t){O.set(e,{ip:t,expiresAt:Date.now()+3e4})}function M(e){return u(e).simulatorSetPath}function ge(e,t){let n=u(e),r=u(t);return n.udid===r.udid&&n.simulatorSetPath===r.simulatorSetPath}function _e(e,t){let n=M(e);return n===void 0?[`-destination`,t]:[`-destination`,t,`-DVTSimulatorSetLocation=${n}`]}function N(e){let t=M(e);if(t===void 0)return{};let n=g(e);return n===void 0?{simulatorSetPath:t}:{simulatorSetPath:t,xcodeVersion:n}}function P(e,t,n){return`${e}: xcodebuild found no simulator ${t.id} in simulator set ${n.simulatorSetPath}${n.xcodeVersion===void 0?``:` with Xcode ${n.xcodeVersion}`}`}const F=`Connect the device by cable, trust this Mac, keep it unlocked, and retry.`;async function ve(e,t,n,r,i){let a=h.fromTimeoutMs(r);return await be(e,t,await ye(e,t,a.remainingMs(),i),n,a.remainingMs(),i)}async function ye(e,t,r,i){let a=await I(e,r,i);try{await L(a,1,z(`ListDevices`));let e=xe((await R(a,r,i)).payload.toString(`utf8`),t);if(e!==void 0)return e;throw new n(`DEVICE_NOT_FOUND`,`iOS device is not available through usbmux`,{deviceId:t,backend:`xctest`,usbmuxDeviceAttached:!1,hint:F})}finally{a.destroy()}}async function be(e,t,n,r,i,a){let o=await I(e,i,a);try{await L(o,2,z(`Connect`,{DeviceID:n,PortNumber:Te(r)}));let e=Ce((await R(o,i,a)).payload.toString(`utf8`),`Number`);if(e!==0)throw we({result:e,udid:t,deviceId:n,port:r});return o}catch(e){throw o.destroy(),e}}async function I(t,r,i){if(H(r,`connect to usbmuxd`),i?.aborted)throw e();return await new Promise((a,o)=>{let s=S.createConnection(t),c=!1,l=setTimeout(()=>{p(new n(`COMMAND_FAILED`,`Timed out connecting to usbmuxd`,{backend:`xctest`,socketPath:t,timeoutMs:r}))},r),u=()=>p(),d=e=>p(e),f=()=>p(e()),p=e=>{c||(c=!0,clearTimeout(l),s.off(`connect`,u),s.off(`error`,d),i?.removeEventListener(`abort`,f),e?(s.destroy(),o(e)):a(s))};s.once(`connect`,u),s.once(`error`,d),i?.addEventListener(`abort`,f,{once:!0})})}async function L(e,t,n){let r=Buffer.from(n,`utf8`),i=Buffer.alloc(16+r.length);i.writeUInt32LE(i.length,0),i.writeUInt32LE(1,4),i.writeUInt32LE(8,8),i.writeUInt32LE(t,12),r.copy(i,16),!e.write(i)&&await new Promise((t,n)=>{e.once(`drain`,t),e.once(`error`,n)})}async function R(t,r,i){if(H(r,`read usbmuxd response`),i?.aborted)throw e();return await new Promise((a,o)=>{let s=Buffer.alloc(0),c=!1,l=setTimeout(()=>m(new n(`COMMAND_FAILED`,`Timed out reading usbmuxd response`,{backend:`xctest`,timeoutMs:r})),r),u=e=>{if(s=Buffer.concat([s,e]),s.length<16)return;let t=s.readUInt32LE(0);if(t<16||t>4194304){m(new n(`COMMAND_FAILED`,`Invalid usbmuxd response length`));return}s.length<t||m(void 0,{payload:s.subarray(16,t)})},d=e=>m(e),f=()=>m(new n(`COMMAND_FAILED`,`usbmuxd closed the connection unexpectedly`)),p=()=>m(e()),m=(e,n)=>{c||(c=!0,clearTimeout(l),t.off(`data`,u),t.off(`error`,d),t.off(`close`,f),i?.removeEventListener(`abort`,p),t.pause(),e?o(e):a(n))};t.on(`data`,u),t.once(`error`,d),t.once(`close`,f),i?.addEventListener(`abort`,p,{once:!0}),t.resume()})}function z(e,t={}){return`<?xml version="1.0" encoding="UTF-8"?><plist version="1.0"><dict>${[[`BundleID`,`com.callstack.agent-device`],[`ClientVersionString`,`agent-device`],[`MessageType`,e],[`ProgName`,`agent-device`],[`kLibUSBMuxVersion`,3],...Object.entries(t)].map(([e,t])=>typeof t==`number`?`<key>${a(e)}</key><integer>${t}</integer>`:`<key>${a(e)}</key><string>${a(t)}</string>`).join(``)}</dict></plist>`}function xe(e,t){let n;for(let r of V(o(e))){let e=Se(r);if(e?.udid===t){if(B(B(r,`Properties`),`ConnectionType`)?.text===`USB`)return e.id;n??=e.id}}return n}function Se(e){if(e.name!==`dict`)return;let t=B(e,`Properties`);if(t?.name!==`dict`)return;let n=B(t,`SerialNumber`)?.text,r=Number(B(e,`DeviceID`)?.text);if(!(!n||!Number.isSafeInteger(r)||r<=0))return{udid:n,id:r}}function Ce(e,t){for(let n of V(o(e))){if(n.name!==`dict`)continue;let e=B(n,t);if(e?.name!==`integer`)continue;let r=Number(e.text);if(Number.isSafeInteger(r))return r}}function B(e,t){for(let n=0;n<e.children.length-1;n+=1){let r=e.children[n];if(r?.name===`key`&&r.text===t)return e.children[n+1]}}function*V(e){for(let t of e)yield t,yield*V(t.children)}function we(e){let{result:t,udid:r,deviceId:i,port:a}=e;return t===2?new n(`DEVICE_NOT_FOUND`,`iOS device is no longer available through usbmux`,{deviceId:r,backend:`xctest`,usbmuxDeviceAttached:!1,usbmuxResult:t,hint:F}):t===3?new n(`COMMAND_FAILED`,`XCTest runner is not listening on the device port`,{backend:`xctest`,deviceId:i,port:a,usbmuxResult:t,hint:`The device is reachable but nothing is bound to the runner port yet; this resolves once the runner finishes starting.`}):new n(`COMMAND_FAILED`,`Failed to connect to XCTest runner through usbmux`,{backend:`xctest`,deviceId:i,port:a,usbmuxResult:t,hint:`Keep the device connected by cable and unlocked, then retry.`})}function Te(e){return(e&255)<<8|e>>>8&255}function H(e,t){if(!(e>0))throw new n(`COMMAND_FAILED`,`No time remaining to ${t}`,{backend:`xctest`,timeoutMs:e})}function Ee(e){return{postCommand:async(t,r,a,o,s)=>{let c=h.fromTimeoutMs(o),l=await ve(e,t,r,c.remainingMs(),s).catch(e=>{throw e instanceof n?i(e,`no`):e});try{return await De(l,a,c.remainingMs(),s)}catch(e){throw l.destroy(),e}}}}const U=Ee(`/var/run/usbmuxd`);async function De(t,r,i,a){if(Ae(i),a?.aborted)throw e();let o=Buffer.from(JSON.stringify(r),`utf8`),s=AbortSignal.timeout(i),c=a?AbortSignal.any([a,s]):s,l=new C.Agent;l.createConnection=(e,n)=>(n?.(null,t),t);try{let e=await Oe(l,t,o,c);return new Response((await ke(e)).toString(`utf8`),{status:e.statusCode??500})}catch(t){throw a?.aborted?e():s.aborted?new n(`COMMAND_FAILED`,`Timed out waiting for XCTest runner over usbmux`,{backend:`xctest`,timeoutMs:i}):t}finally{l.destroy(),t.destroy()}}async function Oe(e,t,n,r){return await new Promise((i,a)=>{let o=C.request({method:`POST`,host:`127.0.0.1`,path:`/command`,headers:{"Content-Type":`application/json`,"Content-Length":n.length,Connection:`close`},agent:e,signal:r},i);o.once(`error`,a),t.resume(),o.end(n)})}async function ke(e){let t=[],r=0;for await(let i of e){let e=Buffer.isBuffer(i)?i:Buffer.from(i);if(r+=e.length,r>67108864)throw new n(`COMMAND_FAILED`,`XCTest runner response exceeded size limit`);t.push(e)}return Buffer.concat(t)}function Ae(e){if(!(e>0))throw new n(`COMMAND_FAILED`,`No time remaining to send XCTest runner command`,{backend:`xctest`,timeoutMs:e})}const W=45e3;async function je(t,r,i,a=W,o){if(o?.aborted)throw e();let s=h.fromTimeoutMs(a),c=k(t,r),l=await c.resolveRoute(s.remainingMs());if(l.kind===`usbmux`)try{return await Me(t,r,i,s,o)}catch(e){if(!G(t,e))throw e;c.markUsbmuxUnattached(),l=await c.resolveRoute(s.remainingMs())}let u=s.remainingMs();if(u<=0)throw new n(`COMMAND_FAILED`,`Runner command deadline exceeded`,{timeoutMs:a});let d=l.endpoints[0];if(!d)throw new n(`COMMAND_FAILED`,`Runner command endpoint not available`,{port:r,endpoints:l.endpoints});return await K(d,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(i)},u,o)}async function Me(e,t,r,i,a){let o=i.remainingMs();if(o<=0)throw new n(`COMMAND_FAILED`,`Runner command deadline exceeded`,{port:t,timeoutMs:o});return await U.postCommand(e.id,t,r,o,a)}function G(e,t){return _(t)?p(e).backend!==`xctest`:!1}async function K(e,t,r,i){let a=AbortSignal.timeout(r),o=i?AbortSignal.any([i,a]):a;try{return await fetch(e,{...t,signal:o})}catch(e){throw e===a.reason?new n(`COMMAND_FAILED`,`Runner command deadline exceeded`,{timeoutMs:r},e):e}}const q=45e3,J=2e4;async function Ne(n,r,i,a,o=q,s,c){let u=h.fromTimeoutMs(o),{resolveRoute:d,markUsbmuxUnattached:f}=k(n,r),p=await d(u.remainingMs()),m=null,g=!1,v=Math.max(1,Math.ceil(o/250));try{return await l(async({deadline:e})=>{let t=await Pe({device:n,port:r,command:i,timeoutMs:o,logPath:a,session:s,route:p,resolveRoute:d,markUsbmuxUnattached:f,signal:c,attemptDeadline:e,setRoute:e=>{p=e},setLastError:e=>{m=e,te(e)||(g=!0)}});if(t)return t;throw ze({port:r,endpoints:p.endpoints,lastError:m,signal:c})},{maxAttempts:v,baseDelayMs:300,maxDelayMs:2e3,jitter:.2,shouldRetry:re},{deadline:u,phase:`ios_runner_connect`,signal:c,retryWakeSignal:n.kind===`simulator`?s?.startupRetryWake:void 0})}catch(n){if(c?.aborted||t(n))throw e();if(_(n))throw n;m||=n}if(c?.aborted)throw e();if(n.kind===`simulator`){let e=u.remainingMs();if(e<=0)throw Y(Ue({port:r,endpoints:p.endpoints,logPath:a,lastError:m}),g);let t=await Z(n,r,i,e,c).catch(e=>{throw Y(e,g)});return new Response(t.body,{status:t.status})}throw s?.child.exitCode!==null&&s?.child.exitCode!==void 0?Y(await We({session:s,port:r,logPath:a}),g):Y(Ue({port:r,endpoints:p.endpoints,logPath:a,lastError:m,deviceStates:s?.startupDeviceStates}),g)}function Y(e,t){return e instanceof n?t?i(e,`unknown`):r(e,`no`):e}async function Pe(e){await Fe(e);let t=await Ie(e);return t.response?t.response:await Le(e)||await Re(e,t.usedCachedTunnelIp)}async function Fe(e){if(e.attemptDeadline?.isExpired())throw new n(`COMMAND_FAILED`,`Runner connection deadline exceeded`,{port:e.port,timeoutMs:e.timeoutMs});if(e.session?.child.exitCode!==null&&e.session?.child.exitCode!==void 0)throw await We({session:e.session,port:e.port,logPath:e.logPath})}async function Ie(e){let t=e.route,n=!1;e.device.kind===`device`&&(t=await e.resolveRoute(e.attemptDeadline?.remainingMs()),n=t.cachedTunnelIp,e.setRoute(t));let r=async t=>{let n=t.cachedTunnelIp?t.endpoints[0]:null;return await X(e.device,t,{command:e.command,port:e.port,timeoutMs:e.timeoutMs,signal:e.signal,attemptDeadline:e.attemptDeadline,onUsbmuxUnattached:e.markUsbmuxUnattached,onError:(t,r)=>{e.setLastError(r),e.device.kind===`device`&&t===n&&A(e.device.id)}})},i=await r(t);if(i||t.kind!==`usbmux`)return{response:i,usedCachedTunnelIp:n};let a=await e.resolveRoute(e.attemptDeadline?.remainingMs());return a.kind===`usbmux`?{response:null,usedCachedTunnelIp:n}:(e.setRoute(a),{response:await r(a),usedCachedTunnelIp:a.cachedTunnelIp})}async function Le(e){return e.device.kind!==`simulator`||e.session?.state!==`ready`?null:await Ve(e.device,e.port,e.command,{signal:e.signal,attemptDeadline:e.attemptDeadline,onError:e.setLastError})}async function Re(e,t){if(e.device.kind!==`device`||!t)return null;A(e.device.id);let n=await e.resolveRoute(e.attemptDeadline?.remainingMs(),!0);return e.setRoute(n),await X(e.device,n,{command:e.command,port:e.port,timeoutMs:e.timeoutMs,signal:e.signal,attemptDeadline:e.attemptDeadline,onError:(t,n)=>{e.setLastError(n)}})}function ze(t){if(t.signal?.aborted)throw e();return new n(`COMMAND_FAILED`,`Runner endpoint probe failed`,{port:t.port,endpoints:t.endpoints,lastError:t.lastError?String(t.lastError):void 0,...y(`runner_endpoint_probe_exhausted`)})}async function X(r,a,o){if(a.kind===`network`)return await Be(a.endpoints,o);let s=a.endpoints[0];try{let e=o.attemptDeadline?.remainingMs()??o.timeoutMs;if(e<=0)throw i(new n(`COMMAND_FAILED`,`Runner connection deadline exceeded`,{port:o.port,timeoutMs:o.timeoutMs}),`no`);return await U.postCommand(r.id,o.port,o.command,Math.min(J,e),o.signal)}catch(n){if(o.signal?.aborted||t(n))throw e();if(_(n)){if(!G(r,n))throw n;return o.onUsbmuxUnattached?.(),null}return o.onError(s,n),null}}async function Be(r,a){let{command:o,port:s,timeoutMs:c,signal:l,attemptDeadline:u,onError:d}=a;for(let a of r)try{let e=u?.remainingMs()??c;if(e<=0)throw i(new n(`COMMAND_FAILED`,`Runner connection deadline exceeded`,{port:s,timeoutMs:c}),`no`);return await K(a,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(o)},Math.min(J,e),l)}catch(n){if(l?.aborted||t(n))throw e();d(a,n)}return null}async function Ve(n,r,i,a){let{signal:o,attemptDeadline:s,onError:c}=a,l=s?.remainingMs()??45e3;if(l<=0)return null;try{let e=await Z(n,r,i,l,o);return new Response(e.body,{status:e.status})}catch(n){if(o?.aborted||t(n))throw e();return c(n),null}}async function Z(e,t,n,r,i){let a=JSON.stringify(n),o=d(e,[`spawn`,e.id,`/usr/bin/curl`,`-s`,`-X`,`POST`,`-H`,`Content-Type: application/json`,`--data`,a,`http://127.0.0.1:${t}/command`]);return{status:200,body:s(await c(o,{allowFailure:!0,timeoutMs:r,signal:i}),`Runner did not accept connection (simctl spawn)`,e=>{let n=m({message:`Runner did not accept connection (simctl spawn)`,stdout:e.stdout,stderr:e.stderr,context:{platform:`ios`,phase:`connect`}});return{port:t,reason:n,hint:f(n),...y(`runner_connect_refused`),dispatched:e.exitCode===7?`no`:`unknown`}}).stdout}}function He(e,t,n,r){let i=`${e}\n${t}\n${n}`.toLowerCase();if(i.includes(`device is busy`)&&i.includes(`connecting`))return`Target iOS device is still connecting. Keep it unlocked, wait for device trust/connection to settle, then retry.`;let a=r??`IOS_RUNNER_CONNECT_TIMEOUT`;return a===`IOS_RUNNER_DEVICE_NOT_PROVISIONED`?f(a):`${f(a)} ${ne}`}function Ue(e){let{port:t,endpoints:r,logPath:i,lastError:a,deviceStates:o}=e,s=`Runner did not accept connection`,c=new n(`COMMAND_FAILED`,s,{port:t,endpoints:r,logPath:i,lastError:a?String(a):void 0,reason:m({error:a,message:s,context:{platform:`ios`,phase:`connect`}}),hint:f(`IOS_RUNNER_CONNECT_TIMEOUT`),...y(`runner_connect_refused`)});return v(c,o)}async function We(e){let{session:t,port:r,logPath:i}=e,a=await t.testPromise,o=`Runner did not accept connection (xcodebuild exited early)`,s=t.readLogTail?.(65536)??``,c=m({message:o,stdout:s,stderr:s,context:{platform:`ios`,phase:`connect`}}),l=N(t.device),u=ee(new n(`COMMAND_FAILED`,o,{stderr:s,...l})),d=u.reason===`simulator_set_destination_not_found`,f=new n(`COMMAND_FAILED`,d?P(o,t.device,l):o,{port:r,logPath:t.runnerLogPath??i,xcodebuild:{exitCode:a.exitCode,stderr:s},reason:d?u.reason:c,hint:d?u.hint:He(o,s,s,c),...l,...y(`xcodebuild_exited_early`)});return v(f,t.startupDeviceStates)}const Ge={starting:[`ready`,`draining`,`stopped`],ready:[`draining`,`stopped`],draining:[`stopped`],stopped:[]};function Ke(e,t){Ge[e.state].includes(t)&&(e.state=t)}function qe(e){return e.state===`starting`||e.state===`ready`}function Q(e){return e?.runnerMainThreadBusy===!0}var Je=class{charges=[];get hasOutstandingCharges(){return this.charges.length>0}get outstandingChargeCount(){return this.charges.length}get hasAbandonedCharges(){return this.charges.some(e=>e.abandoned)}charge(e){this.charges.push({commandId:$(e),abandoned:!1})}markAbandoned(e){let t=this.findChargeIndex(e);t!==-1&&(this.charges[t].abandoned=!0)}settleAnswered(e){let t=this.findChargeIndex(e);if(t===-1)return;let n=this.charges[t];if(this.charges.splice(t,1),n.abandoned)return;let r=this.charges.findIndex((e,n)=>n<t&&e.abandoned);r!==-1&&this.charges.splice(r,1)}settleTerminalEvidence(e){let t=$(e);if(t===``)return!1;let n=this.charges.filter(e=>e.commandId!==t||!e.abandoned);return n.length!==this.charges.length&&(this.charges=n,!0)}findChargeIndex(e){let t=$(e);if(t===``)return-1;for(let e=this.charges.length-1;e>=0;--e)if(this.charges[e].commandId===t)return e;return-1}};function $(e){return e?.trim()??``}function Ye(e){return e.state===`ready`?e.commandCharges.hasOutstandingCharges?{detach:!1,reason:`command_in_flight`}:Q(e)?{detach:!1,reason:`main_thread_occupied`}:{detach:!0}:{detach:!1,reason:`runner_never_served_a_command`}}function Xe(e){return e.processRunning?e.state:`gone`}function Ze(e,t){return`${e}:${t}:${Date.now()}`}function Qe(e){return typeof e==`number`&&Number.isFinite(e)&&e>0?Math.floor(e):void 0}export{fe as C,oe as S,de as T,_e as _,Q as a,se as b,Xe as c,W as d,je as f,P as g,M as h,qe as i,q as l,N as m,Ke as n,Qe as o,ge as p,Ze as r,Ye as s,Je as t,Ne as u,ce as v,le as w,ae as x,ue as y};
|
|
1
|
+
import{I as e,K as t,P as n,V as r,z as i}from"./sdk-contracts.js";import{n as a}from"./entities.js";import{t as o}from"./parser.js";import{A as s,L as c,M as l,a as u,i as d,j as f,o as p,t as m}from"./host.js";import{d as h,i as g,m as _,r as v,s as ee,t as te,v as ne}from"./runner-error-classification.js";import{i as re,n as ie}from"./runner-device-set.js";import y from"node:fs";import ae from"node:os";import b from"node:path";import x from"node:net";import S from"node:http";async function oe(){return await new Promise((e,t)=>{let r=x.createServer();r.listen(0,`127.0.0.1`,()=>{let i=r.address();if(typeof i==`object`&&i?.port){let t=i.port;r.close(()=>e(t))}else r.close(()=>t(new n(`COMMAND_FAILED`,`Failed to allocate port`)))}),r.on(`error`,t)})}function se(e,t,n,r){t&&T(t,e),n&&T(n,e),r&&process.stderr.write(e)}const C=new Map,w=new Map;function T(e,t){let n=(C.get(e)??Promise.resolve()).then(()=>E(e,t),()=>E(e,t)).then(()=>{w.delete(e)},t=>{w.set(e,t)}).finally(()=>{C.get(e)===n&&C.delete(e)});C.set(e,n)}async function E(e,t){await y.promises.mkdir(b.dirname(e),{recursive:!0}),await y.promises.appendFile(e,t)}async function ce(e,t={}){let n=AbortSignal.any([t.signal??new AbortController().signal,AbortSignal.timeout(t.timeoutMs??2e3)]);if(n.aborted)throw n.reason;let r=C.get(e);if(r){let e=()=>{};try{await Promise.race([r,new Promise((t,r)=>{e=()=>r(n.reason),n.addEventListener(`abort`,e,{once:!0})})])}finally{n.removeEventListener(`abort`,e)}}let i=w.get(e);if(i!==void 0)throw i}function le(e){try{y.existsSync(e)&&y.unlinkSync(e)}catch{}}function D(e,t){if(e)return e;let n=t.replaceAll(/[^A-Za-z0-9._-]/g,`_`);return b.join(ae.tmpdir(),`agent-device`,`apple-runner`,`logs`,`${n}.log`)}function ue(e,t){let n=0;try{n=y.fstatSync(t).size}catch{}return{logPath:e,startOffset:n}}function de(e){let t=e.pollMs??50,n=Buffer.alloc(65536),r=e.file.startOffset,i=null,a=null,o=!1,s=()=>{if(!o)try{i??=y.openSync(e.file.logPath,`r`);let t=y.fstatSync(i).size;for(t<r&&(r=0);r<t;){let a=Math.min(n.length,t-r),o=y.readSync(i,n,0,a,r);if(o<=0)break;r+=o,e.onOutput(n.toString(`utf8`,0,o)),t=y.fstatSync(i).size}}catch{l()}},c=()=>{o||(a=setTimeout(()=>{s(),c()},t),a.unref?.())};function l(){if(!o&&(o=!0,a&&clearTimeout(a),a=null,i!==null)){try{y.closeSync(i)}catch{}i=null}}return c(),{drain:()=>{s(),l()},stop:l}}function fe(e,t){if(!e)return``;let n=null;try{n=y.openSync(e.logPath,`r`);let r=y.fstatSync(n).size,i=Math.max(e.startOffset,r-t),a=r-i;if(a<=0)return``;let o=Buffer.alloc(a),s=y.readSync(n,o,0,a,i);return o.toString(`utf8`,0,Math.max(s,0))}catch{return``}finally{if(n!==null)try{y.closeSync(n)}catch{}}}const O=new Map;function k(e,t){let n,r=!1;return{markUsbmuxUnattached:()=>{r=!0},resolveRoute:async(i,a=!1)=>{if(e.kind!==`device`)return j(e,t,null,!1);let o=f(e);if(o.backend===`xctest`||!r)return pe(e,t);if(!a){let r=me(e.id);if(r)return j(e,t,r,!0);if(n!==void 0)return j(e,t,n,!1)}let{tunnelIp:s}=await o.resolveTunnel(e,i);return n=s,s&&he(e.id,s),j(e,t,s,!1)}}}function A(e){O.delete(e)}function pe(e,t){return{kind:`usbmux`,endpoints:[`usbmux://${e.id}:${t}/command`],cachedTunnelIp:!1}}function j(e,t,n,r){let i=[`http://127.0.0.1:${t}/command`];return e.kind===`device`&&n&&i.unshift(`http://[${n}]:${t}/command`),{kind:`network`,endpoints:i,cachedTunnelIp:r}}function me(e){let t=O.get(e);return t?t.expiresAt<=Date.now()?(O.delete(e),null):t.ip:null}function he(e,t){O.set(e,{ip:t,expiresAt:Date.now()+3e4})}const M=`Connect the device by cable, trust this Mac, keep it unlocked, and retry.`;async function ge(e,t,n,r,i){let a=m.fromTimeoutMs(r);return await ve(e,t,await _e(e,t,a.remainingMs(),i),n,a.remainingMs(),i)}async function _e(e,t,r,i){let a=await N(e,r,i);try{await P(a,1,I(`ListDevices`));let e=ye((await F(a,r,i)).payload.toString(`utf8`),t);if(e!==void 0)return e;throw new n(`DEVICE_NOT_FOUND`,`iOS device is not available through usbmux`,{deviceId:t,backend:`xctest`,usbmuxDeviceAttached:!1,hint:M})}finally{a.destroy()}}async function ve(e,t,n,r,i,a){let o=await N(e,i,a);try{await P(o,2,I(`Connect`,{DeviceID:n,PortNumber:Ce(r)}));let e=xe((await F(o,i,a)).payload.toString(`utf8`),`Number`);if(e!==0)throw Se({result:e,udid:t,deviceId:n,port:r});return o}catch(e){throw o.destroy(),e}}async function N(t,r,i){if(z(r,`connect to usbmuxd`),i?.aborted)throw e();return await new Promise((a,o)=>{let s=x.createConnection(t),c=!1,l=setTimeout(()=>{p(new n(`COMMAND_FAILED`,`Timed out connecting to usbmuxd`,{backend:`xctest`,socketPath:t,timeoutMs:r}))},r),u=()=>p(),d=e=>p(e),f=()=>p(e()),p=e=>{c||(c=!0,clearTimeout(l),s.off(`connect`,u),s.off(`error`,d),i?.removeEventListener(`abort`,f),e?(s.destroy(),o(e)):a(s))};s.once(`connect`,u),s.once(`error`,d),i?.addEventListener(`abort`,f,{once:!0})})}async function P(e,t,n){let r=Buffer.from(n,`utf8`),i=Buffer.alloc(16+r.length);i.writeUInt32LE(i.length,0),i.writeUInt32LE(1,4),i.writeUInt32LE(8,8),i.writeUInt32LE(t,12),r.copy(i,16),!e.write(i)&&await new Promise((t,n)=>{e.once(`drain`,t),e.once(`error`,n)})}async function F(t,r,i){if(z(r,`read usbmuxd response`),i?.aborted)throw e();return await new Promise((a,o)=>{let s=Buffer.alloc(0),c=!1,l=setTimeout(()=>m(new n(`COMMAND_FAILED`,`Timed out reading usbmuxd response`,{backend:`xctest`,timeoutMs:r})),r),u=e=>{if(s=Buffer.concat([s,e]),s.length<16)return;let t=s.readUInt32LE(0);if(t<16||t>4194304){m(new n(`COMMAND_FAILED`,`Invalid usbmuxd response length`));return}s.length<t||m(void 0,{payload:s.subarray(16,t)})},d=e=>m(e),f=()=>m(new n(`COMMAND_FAILED`,`usbmuxd closed the connection unexpectedly`)),p=()=>m(e()),m=(e,n)=>{c||(c=!0,clearTimeout(l),t.off(`data`,u),t.off(`error`,d),t.off(`close`,f),i?.removeEventListener(`abort`,p),t.pause(),e?o(e):a(n))};t.on(`data`,u),t.once(`error`,d),t.once(`close`,f),i?.addEventListener(`abort`,p,{once:!0}),t.resume()})}function I(e,t={}){return`<?xml version="1.0" encoding="UTF-8"?><plist version="1.0"><dict>${[[`BundleID`,`com.callstack.agent-device`],[`ClientVersionString`,`agent-device`],[`MessageType`,e],[`ProgName`,`agent-device`],[`kLibUSBMuxVersion`,3],...Object.entries(t)].map(([e,t])=>typeof t==`number`?`<key>${a(e)}</key><integer>${t}</integer>`:`<key>${a(e)}</key><string>${a(t)}</string>`).join(``)}</dict></plist>`}function ye(e,t){let n;for(let r of R(o(e))){let e=be(r);if(e?.udid===t){if(L(L(r,`Properties`),`ConnectionType`)?.text===`USB`)return e.id;n??=e.id}}return n}function be(e){if(e.name!==`dict`)return;let t=L(e,`Properties`);if(t?.name!==`dict`)return;let n=L(t,`SerialNumber`)?.text,r=Number(L(e,`DeviceID`)?.text);if(!(!n||!Number.isSafeInteger(r)||r<=0))return{udid:n,id:r}}function xe(e,t){for(let n of R(o(e))){if(n.name!==`dict`)continue;let e=L(n,t);if(e?.name!==`integer`)continue;let r=Number(e.text);if(Number.isSafeInteger(r))return r}}function L(e,t){for(let n=0;n<e.children.length-1;n+=1){let r=e.children[n];if(r?.name===`key`&&r.text===t)return e.children[n+1]}}function*R(e){for(let t of e)yield t,yield*R(t.children)}function Se(e){let{result:t,udid:r,deviceId:i,port:a}=e;return t===2?new n(`DEVICE_NOT_FOUND`,`iOS device is no longer available through usbmux`,{deviceId:r,backend:`xctest`,usbmuxDeviceAttached:!1,usbmuxResult:t,hint:M}):t===3?new n(`COMMAND_FAILED`,`XCTest runner is not listening on the device port`,{backend:`xctest`,deviceId:i,port:a,usbmuxResult:t,hint:`The device is reachable but nothing is bound to the runner port yet; this resolves once the runner finishes starting.`}):new n(`COMMAND_FAILED`,`Failed to connect to XCTest runner through usbmux`,{backend:`xctest`,deviceId:i,port:a,usbmuxResult:t,hint:`Keep the device connected by cable and unlocked, then retry.`})}function Ce(e){return(e&255)<<8|e>>>8&255}function z(e,t){if(!(e>0))throw new n(`COMMAND_FAILED`,`No time remaining to ${t}`,{backend:`xctest`,timeoutMs:e})}function we(e){return{postCommand:async(t,r,a,o,s)=>{let c=m.fromTimeoutMs(o),l=await ge(e,t,r,c.remainingMs(),s).catch(e=>{throw e instanceof n?i(e,`no`):e});try{return await Te(l,a,c.remainingMs(),s)}catch(e){throw l.destroy(),e}}}}const B=we(`/var/run/usbmuxd`);async function Te(t,r,i,a){if(De(i),a?.aborted)throw e();let o=Buffer.from(JSON.stringify(r),`utf8`),s=AbortSignal.timeout(i),c=a?AbortSignal.any([a,s]):s,l=new S.Agent;l.createConnection=(e,n)=>(n?.(null,t),t);try{let e=await Ee(l,t,o,c);return new Response((await V(e)).toString(`utf8`),{status:e.statusCode??500})}catch(t){throw a?.aborted?e():s.aborted?new n(`COMMAND_FAILED`,`Timed out waiting for XCTest runner over usbmux`,{backend:`xctest`,timeoutMs:i}):t}finally{l.destroy(),t.destroy()}}async function Ee(e,t,n,r){return await new Promise((i,a)=>{let o=S.request({method:`POST`,host:`127.0.0.1`,path:`/command`,headers:{"Content-Type":`application/json`,"Content-Length":n.length,Connection:`close`},agent:e,signal:r},i);o.once(`error`,a),t.resume(),o.end(n)})}async function V(e){let t=[],r=0;for await(let i of e){let e=Buffer.isBuffer(i)?i:Buffer.from(i);if(r+=e.length,r>67108864)throw new n(`COMMAND_FAILED`,`XCTest runner response exceeded size limit`);t.push(e)}return Buffer.concat(t)}function De(e){if(!(e>0))throw new n(`COMMAND_FAILED`,`No time remaining to send XCTest runner command`,{backend:`xctest`,timeoutMs:e})}const H=45e3;async function Oe(t,r,i,a=H,o){if(o?.aborted)throw e();let s=m.fromTimeoutMs(a),c=k(t,r),l=await c.resolveRoute(s.remainingMs());if(l.kind===`usbmux`)try{return await ke(t,r,i,s,o)}catch(e){if(!U(t,e))throw e;c.markUsbmuxUnattached(),l=await c.resolveRoute(s.remainingMs())}let u=s.remainingMs();if(u<=0)throw new n(`COMMAND_FAILED`,`Runner command deadline exceeded`,{timeoutMs:a});let d=l.endpoints[0];if(!d)throw new n(`COMMAND_FAILED`,`Runner command endpoint not available`,{port:r,endpoints:l.endpoints});return await W(d,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(i)},u,o)}async function ke(e,t,r,i,a){let o=i.remainingMs();if(o<=0)throw new n(`COMMAND_FAILED`,`Runner command deadline exceeded`,{port:t,timeoutMs:o});return await B.postCommand(e.id,t,r,o,a)}function U(e,t){return h(t)?f(e).backend!==`xctest`:!1}async function W(e,t,r,i){let a=AbortSignal.timeout(r),o=i?AbortSignal.any([i,a]):a;try{return await fetch(e,{...t,signal:o})}catch(e){throw e===a.reason?new n(`COMMAND_FAILED`,`Runner command deadline exceeded`,{timeoutMs:r},e):e}}const G=45e3,K=2e4;async function Ae(n,r,i,a,o=G,s,c){let u=m.fromTimeoutMs(o),{resolveRoute:d,markUsbmuxUnattached:f}=k(n,r),p=await d(u.remainingMs()),g=null,_=!1,v=Math.max(1,Math.ceil(o/250));try{return await l(async({deadline:e})=>{let t=await je({device:n,port:r,command:i,timeoutMs:o,logPath:a,session:s,route:p,resolveRoute:d,markUsbmuxUnattached:f,signal:c,attemptDeadline:e,setRoute:e=>{p=e},setLastError:e=>{g=e,ee(e)||(_=!0)}});if(t)return t;throw Ie({port:r,endpoints:p.endpoints,lastError:g,signal:c})},{maxAttempts:v,baseDelayMs:300,maxDelayMs:2e3,jitter:.2,shouldRetry:ne},{deadline:u,phase:`ios_runner_connect`,signal:c,retryWakeSignal:n.kind===`simulator`?s?.startupRetryWake:void 0})}catch(n){if(c?.aborted||t(n))throw e();if(h(n))throw n;g||=n}if(c?.aborted)throw e();if(n.kind===`simulator`){let e=u.remainingMs();if(e<=0)throw q(X({port:r,endpoints:p.endpoints,logPath:a,lastError:g}),_);let t=await Y(n,r,i,e,c).catch(e=>{throw q(e,_)});return new Response(t.body,{status:t.status})}throw s?.child.exitCode!==null&&s?.child.exitCode!==void 0?q(await Z({session:s,port:r,logPath:a}),_):q(X({port:r,endpoints:p.endpoints,logPath:a,lastError:g,deviceStates:s?.startupDeviceStates}),_)}function q(e,t){return e instanceof n?t?i(e,`unknown`):r(e,`no`):e}async function je(e){await Me(e);let t=await Ne(e);return t.response?t.response:await Pe(e)||await Fe(e,t.usedCachedTunnelIp)}async function Me(e){if(e.attemptDeadline?.isExpired())throw new n(`COMMAND_FAILED`,`Runner connection deadline exceeded`,{port:e.port,timeoutMs:e.timeoutMs});if(e.session?.child.exitCode!==null&&e.session?.child.exitCode!==void 0)throw await Z({session:e.session,port:e.port,logPath:e.logPath})}async function Ne(e){let t=e.route,n=!1;e.device.kind===`device`&&(t=await e.resolveRoute(e.attemptDeadline?.remainingMs()),n=t.cachedTunnelIp,e.setRoute(t));let r=async t=>{let n=t.cachedTunnelIp?t.endpoints[0]:null;return await J(e.device,t,{command:e.command,port:e.port,timeoutMs:e.timeoutMs,signal:e.signal,attemptDeadline:e.attemptDeadline,onUsbmuxUnattached:e.markUsbmuxUnattached,onError:(t,r)=>{e.setLastError(r),e.device.kind===`device`&&t===n&&A(e.device.id)}})},i=await r(t);if(i||t.kind!==`usbmux`)return{response:i,usedCachedTunnelIp:n};let a=await e.resolveRoute(e.attemptDeadline?.remainingMs());return a.kind===`usbmux`?{response:null,usedCachedTunnelIp:n}:(e.setRoute(a),{response:await r(a),usedCachedTunnelIp:a.cachedTunnelIp})}async function Pe(e){return e.device.kind!==`simulator`||e.session?.state!==`ready`?null:await Re(e.device,e.port,e.command,{signal:e.signal,attemptDeadline:e.attemptDeadline,onError:e.setLastError})}async function Fe(e,t){if(e.device.kind!==`device`||!t)return null;A(e.device.id);let n=await e.resolveRoute(e.attemptDeadline?.remainingMs(),!0);return e.setRoute(n),await J(e.device,n,{command:e.command,port:e.port,timeoutMs:e.timeoutMs,signal:e.signal,attemptDeadline:e.attemptDeadline,onError:(t,n)=>{e.setLastError(n)}})}function Ie(t){if(t.signal?.aborted)throw e();return new n(`COMMAND_FAILED`,`Runner endpoint probe failed`,{port:t.port,endpoints:t.endpoints,lastError:t.lastError?String(t.lastError):void 0,..._(`runner_endpoint_probe_exhausted`)})}async function J(r,a,o){if(a.kind===`network`)return await Le(a.endpoints,o);let s=a.endpoints[0];try{let e=o.attemptDeadline?.remainingMs()??o.timeoutMs;if(e<=0)throw i(new n(`COMMAND_FAILED`,`Runner connection deadline exceeded`,{port:o.port,timeoutMs:o.timeoutMs}),`no`);return await B.postCommand(r.id,o.port,o.command,Math.min(K,e),o.signal)}catch(n){if(o.signal?.aborted||t(n))throw e();if(h(n)){if(!U(r,n))throw n;return o.onUsbmuxUnattached?.(),null}return o.onError(s,n),null}}async function Le(r,a){let{command:o,port:s,timeoutMs:c,signal:l,attemptDeadline:u,onError:d}=a;for(let a of r)try{let e=u?.remainingMs()??c;if(e<=0)throw i(new n(`COMMAND_FAILED`,`Runner connection deadline exceeded`,{port:s,timeoutMs:c}),`no`);return await W(a,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(o)},Math.min(K,e),l)}catch(n){if(l?.aborted||t(n))throw e();d(a,n)}return null}async function Re(n,r,i,a){let{signal:o,attemptDeadline:s,onError:c}=a,l=s?.remainingMs()??45e3;if(l<=0)return null;try{let e=await Y(n,r,i,l,o);return new Response(e.body,{status:e.status})}catch(n){if(o?.aborted||t(n))throw e();return c(n),null}}async function Y(e,t,n,r,i){let a=JSON.stringify(n),o=u(e,[`spawn`,e.id,`/usr/bin/curl`,`-s`,`-X`,`POST`,`-H`,`Content-Type: application/json`,`--data`,a,`http://127.0.0.1:${t}/command`]);return{status:200,body:s(await c(o,{allowFailure:!0,timeoutMs:r,signal:i}),`Runner did not accept connection (simctl spawn)`,e=>{let n=p({message:`Runner did not accept connection (simctl spawn)`,stdout:e.stdout,stderr:e.stderr,context:{platform:`ios`,phase:`connect`}});return{port:t,reason:n,hint:d(n),..._(`runner_connect_refused`),dispatched:e.exitCode===7?`no`:`unknown`}}).stdout}}function ze(e,t,n,r){let i=`${e}\n${t}\n${n}`.toLowerCase();if(i.includes(`device is busy`)&&i.includes(`connecting`))return`Target iOS device is still connecting. Keep it unlocked, wait for device trust/connection to settle, then retry.`;let a=r??`IOS_RUNNER_CONNECT_TIMEOUT`;return a===`IOS_RUNNER_DEVICE_NOT_PROVISIONED`?d(a):`${d(a)} ${te}`}function X(e){let{port:t,endpoints:r,logPath:i,lastError:a,deviceStates:o}=e,s=`Runner did not accept connection`,c=new n(`COMMAND_FAILED`,s,{port:t,endpoints:r,logPath:i,lastError:a?String(a):void 0,reason:p({error:a,message:s,context:{platform:`ios`,phase:`connect`}}),hint:d(`IOS_RUNNER_CONNECT_TIMEOUT`),..._(`runner_connect_refused`)});return g(c,o)}async function Z(e){let{session:t,port:r,logPath:i}=e,a=await t.testPromise,o=`Runner did not accept connection (xcodebuild exited early)`,s=t.readLogTail?.(65536)??``,c=p({message:o,stdout:s,stderr:s,context:{platform:`ios`,phase:`connect`}}),l=ie(t.device),u=v(new n(`COMMAND_FAILED`,o,{stderr:s,...l})),d=u.reason===`simulator_set_destination_not_found`,f=new n(`COMMAND_FAILED`,d?re(o,t.device,l):o,{port:r,logPath:t.runnerLogPath??i,xcodebuild:{exitCode:a.exitCode,stderr:s},reason:d?u.reason:c,hint:d?u.hint:ze(o,s,s,c),...l,..._(`xcodebuild_exited_early`)});return g(f,t.startupDeviceStates)}const Be={starting:[`ready`,`draining`,`stopped`],ready:[`draining`,`stopped`],draining:[`stopped`],stopped:[]};function Ve(e,t){Be[e.state].includes(t)&&(e.state=t)}function He(e){return e.state===`starting`||e.state===`ready`}function Q(e){return e?.runnerMainThreadBusy===!0}var Ue=class{charges=[];get hasOutstandingCharges(){return this.charges.length>0}get outstandingChargeCount(){return this.charges.length}get hasAbandonedCharges(){return this.charges.some(e=>e.abandoned)}charge(e){this.charges.push({commandId:$(e),abandoned:!1})}markAbandoned(e){let t=this.findChargeIndex(e);t!==-1&&(this.charges[t].abandoned=!0)}settleAnswered(e){let t=this.findChargeIndex(e);if(t===-1)return;let n=this.charges[t];if(this.charges.splice(t,1),n.abandoned)return;let r=this.charges.findIndex((e,n)=>n<t&&e.abandoned);r!==-1&&this.charges.splice(r,1)}settleTerminalEvidence(e){let t=$(e);if(t===``)return!1;let n=this.charges.filter(e=>e.commandId!==t||!e.abandoned);return n.length!==this.charges.length&&(this.charges=n,!0)}findChargeIndex(e){let t=$(e);if(t===``)return-1;for(let e=this.charges.length-1;e>=0;--e)if(this.charges[e].commandId===t)return e;return-1}};function $(e){return e?.trim()??``}function We(e){return e.state===`ready`?e.commandCharges.hasOutstandingCharges?{detach:!1,reason:`command_in_flight`}:Q(e)?{detach:!1,reason:`main_thread_occupied`}:{detach:!0}:{detach:!1,reason:`runner_never_served_a_command`}}function Ge(e){return e.processRunning?e.state:`gone`}function Ke(e,t){return`${e}:${t}:${Date.now()}`}function qe(e){return typeof e==`number`&&Number.isFinite(e)&&e>0?Math.floor(e):void 0}export{se as _,Q as a,de as b,Ge as c,H as d,Oe as f,oe as g,ce as h,He as i,G as l,ue as m,Ve as n,qe as o,le as p,Ke as r,We as s,Ue as t,Ae as u,fe as v,D as y};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{I as e,K as t,P as n}from"./sdk-contracts.js";import{u as r}from"./host.js";import{i}from"./runner-
|
|
1
|
+
import{I as e,K as t,P as n}from"./sdk-contracts.js";import{u as r}from"./host.js";import{r as i}from"./runner-toolchain-probe.js";import{o as a}from"./runner-session-types.js";import{N as o,k as s}from"./runner-error-classification.js";import{S as c,f as l,l as u,u as d,v as f}from"./runner-disposal.js";function p(e){let t=a(e.startupTimeoutMs),n=t??6e5,r=new AbortController,s=setTimeout(()=>{r.abort(m(n,t!==void 0))},n);s.unref?.();let c=o(e),l=c?AbortSignal.any([c,r.signal]):r.signal;return{phase:i(n,l),timeoutMs:n,explicit:t!==void 0,exhausted:r.signal,close:()=>clearTimeout(s)}}function m(e,t){return new n(`COMMAND_FAILED`,`Apple runner start exceeded its ${t?`startup timeout`:`default start budget`} of ${e}ms`,{reason:`runner_start_budget_exhausted`,timeoutMs:e,retriable:!0,hint:t?"Raise the startup timeout, or run `prepare ios-runner` first so the runner is built before it is needed.":"Run `prepare ios-runner --timeout <ms>` so the cold build has a budget of your choosing; the session runner.log names the step that stalled."})}async function h(t,n,r){return r?await new Promise((i,a)=>{let o=r.aborted?`already-spent`:d(n,r),p=()=>{if(a(e(void 0,r.reason)),t.catch(_),s(r.reason)){o===`interested`&&c(n,r),f(n);return}l(n,r)&&u(n.deviceId)};r.aborted?p():r.addEventListener(`abort`,p,{once:!0}),t.then(i,a).finally(()=>{r.removeEventListener(`abort`,p),o===`interested`&&c(n,r)})}):await t}function g(e,t){let n=t.signal?void 0:o(t);if(!n||d(e,n)!==`interested`)return()=>{};let r=()=>{l(e,n)&&u(e.deviceId)};return n.addEventListener(`abort`,r,{once:!0}),()=>{n.removeEventListener(`abort`,r),c(e,n)}}function _(e){if(t(e))return;let i=e instanceof n?e:void 0;r({level:`warn`,phase:`ios_runner_detached_start_failed`,data:{code:i?.code,reason:i?.details?.reason,error:e instanceof Error?e.message:String(e)}})}export{p as openRunnerStartBudget,h as raceRunnerStartAgainstCaller,g as reserveRunnerStartOwnerInterest};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{I as e,K as t,P as n}from"./sdk-contracts.js";import{I as r,c as i,g as a,l as o,t as s}from"./host.js";import{c,t as l,u}from"./apple-runner-platform.js";function d(e,t){return{deadline:e!==void 0&&Number.isFinite(e)?s.fromTimeoutMs(Math.max(0,e)):void 0,signal:t}}function f(e,t){let n=e?.deadline;if(!n)return;let r=Math.floor(n.remainingMs());if(r<=0)throw p(t);return r}function p(e){return new n(`COMMAND_FAILED`,`The Apple runner budget ran out before this step began`,{phase:e,reason:`runner_phase_budget_exhausted`,retriable:!0})}function m(e){return e instanceof n&&e.details?.reason===`runner_phase_budget_exhausted`}function h(t){let n=t?.deadline,r=s.fromTimeoutMs(Math.min(45e3,n?n.remainingMs():1/0));return{attemptTimeoutMs:()=>Math.min(l,Math.floor(r.remainingMs())),throwIfCanceled:()=>{if(t?.signal?.aborted)throw e({phase:`apple_toolchain_probe`})}}}let g;function _(){return g??=o({ttlMs:6e5,scheduleExpiry:!0}),g}function v(e,t){let n=h(t);n.throwIfCanceled();let r=y(e),i=_().get(r);if(i)return _().set(r,i),i;let a=x(e,n);if(!a.ok)throw S(a.failures);return _().set(r,a.value),a.value}function y(e){return`${i()??``}\0${e}`}function b(e){return _().get(y(u(c(e),e.kind)))?.xcodeVersion}function x(e,t){let n=E(C(`xcodebuild`,[`-version`],t)),r=C(`xcrun`,[`--sdk`,e,`--show-sdk-version`],t),i=C(`xcrun`,[`--sdk`,e,`--show-sdk-build-version`],t);return!n.ok||!r.ok||!i.ok?{ok:!1,failures:[n,r,i].flatMap(e=>e.ok?[]:[e.failure])}:{ok:!0,value:{xcodeVersion:n.value.version,xcodeBuildVersion:n.value.buildVersion,sdkName:e,sdkVersion:r.value,sdkBuildVersion:i.value}}}function S(e){return new n(`COMMAND_FAILED`,`Could not read the Xcode toolchain versions the Apple runner cache is keyed on (${e.map(e=>`${e.probe}: ${e.detail}`).join(`; `)})`,{reason:`apple_toolchain_probe_unavailable`,retriable:!0,probes:e,hint:"The Apple runner cache is keyed on the toolchain version, so a cache decision cannot be made without it. Retry once the host is less loaded, or check `xcode-select -p` and `xcodebuild -version`."})}function C(e,n,r){let i=[e,...n].join(` `),a;try{a=w(e,n,r)}catch(e){if(r.throwIfCanceled(),t(e)||m(e))throw e;return D(i,`probe_error`,e instanceof Error?e.message:`${e}`)}if(a.exitCode!==0)return D(i,`nonzero_exit`,`exit ${a.exitCode}${a.stderr.trim()?`: ${a.stderr.trim()}`:``}`);let o=a.stdout.trim();return o?{ok:!0,value:o}:D(i,`empty_output`,`no output`)}function w(e,t,n){try{return T(e,t,n)}catch(r){if(!a(r))throw r;return T(e,t,n)}}function T(e,t,n){n.throwIfCanceled();let i=n.attemptTimeoutMs();if(i<=0)throw p(`apple_toolchain_probe`);return r(e,t,{allowFailure:!0,timeoutMs:i,maxBuffer:131072})}function E(e){if(!e.ok)return e;let t=e.value.match(/^Xcode\s+(.+)$/m)?.[1]?.trim(),n=e.value.match(/^Build version\s+(.+)$/m)?.[1]?.trim();return!t||!n?D(`xcodebuild -version`,`unparsable_output`,`unrecognized output: ${e.value.replaceAll(`
|
|
2
|
+
`,` `)}`):{ok:!0,value:{version:t,buildVersion:n}}}function D(e,t,n){return{ok:!1,failure:{probe:e,reason:t,detail:n.length>200?`${n.slice(0,200)}…`:n}}}export{f as i,v as n,d as r,b as t};
|
package/dist/src/runner.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime.js";import{B as t,P as n,rt as r,z as i}from"./sdk-contracts.js";import{
|
|
1
|
+
import{r as e}from"./rolldown-runtime.js";import{B as t,P as n,rt as r,z as i}from"./sdk-contracts.js";import{j as a}from"./sdk-device.js";import{r as o}from"./touch-runtime.js";import{t as s}from"./runner-cache-metadata.js";import{AsyncLocalStorage as c}from"node:async_hooks";const l=new c;function u(e,t){return{runCommand:e,...t}}function d(e,t,n={}){let r=f(e,n);return m(r?r.provider:t)}function f(e,t={}){let n=l.getStore();return n&&n.deviceId===e.id&&(n.requestId?n.requestId===t.requestId:!t.requestId)?n:void 0}async function p(e,t,n){if(!e)return await n();let r={provider:m(e),deviceId:t.deviceId,requestId:t.requestId};return await l.run(r,n)}function m(e){return typeof e==`function`?{runCommand:e,hasLiveSession:()=>!0}:e}const h=[`tap`,`doubleTap`,`longPress`];function g(e){return typeof e==`string`&&h.includes(e)}function _(e,t){return i(new n(`INVALID_ARGS`,e,{...t,reason:`runner_sequence_invalid`}),`no`)}function v(e,t,n){return _(n,{stepIndex:e,kind:typeof t==`string`?t:void 0})}function y(e){if(!Array.isArray(e)||e.length===0)throw _(`sequence requires at least one step`,{stepCount:Array.isArray(e)?e.length:0});if(e.length>20)throw _(`sequence accepts at most 20 steps, received ${e.length}`,{stepCount:e.length,maxSteps:20});e.forEach((e,t)=>b(e,t))}function b(e,t){if(!g(e.kind))throw v(t,e.kind,`sequence step ${t} has unsupported kind "${String(e.kind)}"; allowed: ${h.join(`, `)}`);if(!Number.isFinite(e.x)||!Number.isFinite(e.y))throw v(t,e.kind,`sequence step ${t} (${e.kind}) requires finite x and y`);e.durationMs!==void 0&&x(e.durationMs,0,1e4,t,e.kind,`durationMs`),e.pauseMs!==void 0&&x(e.pauseMs,0,1e4,t,e.kind,`pauseMs`)}function x(e,t,n,r,i,a){if(!Number.isFinite(e)||e<t||e>n)throw v(r,i,`sequence step ${r} (${i}) ${a} must be between ${t} and ${n}`)}function S(e,t){return y(e),{command:`sequence`,steps:e,appBundleId:t}}async function C(e,n,r,i,a){let o=w(T(e,n,r),20).map(e=>S(e,i)),s,c,l=0,u=[],d=0;for(let e of o){let n;try{n=await a(e)}catch(e){throw t(e,l)}s??=n,c=n;let r;try{r=O(n)}catch(e){throw t(D(e,d),l+E(e))}l+=r.completedSteps,u.push(...r.results),d+=e.steps?.length??0}return{...s??{},completedSteps:l,sequenceResults:u,...c?.gestureEndUptimeMs===void 0?{}:{gestureEndUptimeMs:c.gestureEndUptimeMs},timingMode:`runner-sequence`}}function w(e,t,n=2e4){let r=[],i=[],a=0;for(let o of e){let e=(o.durationMs??0)+(o.pauseMs??0)+250;i.length>0&&(i.length>=t||a+e>n)&&(r.push(i),i=[],a=0),i.push(o),a+=e}return i.length>0&&r.push(i),r}function T(e,t,n){let r=n.doubleTap?`doubleTap`:n.holdMs>0?`longPress`:`tap`,i=r===`tap`&&a(e);return Array.from({length:n.count},(e,a)=>{let[s,c]=o(a,n.jitterPx);return{kind:r,x:t.x+s,y:t.y+c,...i?{synthesized:!0}:{},...n.holdMs>0?{durationMs:n.holdMs}:{},...a<n.count-1&&n.intervalMs>0?{pauseMs:n.intervalMs}:{}}})}function E(e){let t=e instanceof n?e.details?.completedSteps:void 0;return typeof t==`number`?t:0}function D(e,t){if(t===0||!(e instanceof n)||!e.details)return e;let r=e.details.failedStepIndex;if(typeof r!=`number`)return e;let i=e.details.completedSteps;return new n(e.code,e.message,{...e.details,failedStepIndex:r+t,chunkStepIndex:r,...typeof i==`number`?{completedSteps:t+i}:{}},e.cause)}function O(e){let t=A(e.sequenceResults),n=typeof e.completedSteps==`number`&&Number.isFinite(e.completedSteps)?e.completedSteps:t.filter(e=>e.ok).length,r=t.findIndex(e=>!e.ok),i=typeof e.failedStepIndex==`number`&&Number.isFinite(e.failedStepIndex)?e.failedStepIndex:r>=0?r:void 0;if(i!==void 0)throw k(t,n,i);return{results:t,completedSteps:n,failedStepIndex:i}}function k(e,t,i){let a=e[i],o=a?.kind??`step`,s=a?.errorMessage??`sequence step ${i} (${o}) failed`;return new n(r(a?.errorCode),s,{failedStepIndex:i,failedStepKind:o,completedSteps:t,sequenceResults:e,hint:`Run snapshot -i to inspect the current UI, then continue from the observed state.`})}function A(e){return Array.isArray(e)?e.map(e=>{let t=e??{};return{ok:t.ok===!0,kind:typeof t.kind==`string`?t.kind:`unknown`,errorCode:typeof t.errorCode==`string`?t.errorCode:void 0,errorMessage:typeof t.errorMessage==`string`?t.errorMessage:void 0,gestureStartUptimeMs:typeof t.gestureStartUptimeMs==`number`?t.gestureStartUptimeMs:void 0,gestureEndUptimeMs:typeof t.gestureEndUptimeMs==`number`?t.gestureEndUptimeMs:void 0}}):[]}var j=e({IOS_RUNNER_CONTAINER_BUNDLE_IDS:()=>s,withAppleRunnerProvider:()=>p});export{u as a,C as i,S as n,d as o,O as r,p as s,j as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{P as e}from"./sdk-contracts.js";import{E as t}from"./sdk-device.js";import{nn as n}from"./sdk-batch.js";const r={support:`supported`},i={support:`unsupported`},a={lease:r,inventory:{support:`partial`,note:`Inventory exposes only the leased cloud device, not the provider catalog.`},install:{support:`partial`,note:`Requires provider-specific upload or a path visible to the remote Appium server.`},snapshot:{support:`partial`,note:`Uses Appium page source XML, not agent-device native snapshot backends.`},screenshot:r,tap:r,doubleTap:r,longPress:r,swipe:r,scroll:{support:`partial`,note:`Implemented as viewport-relative W3C pointer gestures.`},fill:r,type:r,keyboard:{support:`partial`,note:"Enter presses Android keycode 66 through `mobile: pressKey` and types a newline into the focused iOS field; dismiss uses the Appium hide-keyboard route, and Android status uses the Appium keyboard probe."},back:r,home:{support:`partial`,note:`Uses provider/Appium mobile pressButton support where available.`},orientation:{support:`partial`,note:`Uses the WebDriver rotation/orientation endpoints; four-way rotation collapses to portrait/landscape on drivers that only accept the two-way endpoint. Rotates the current display, so an activity that does not pin its orientation may need rotating again once it is foreground.`},appSwitcher:{support:`partial`,note:`Uses provider/Appium mobile pressButton support where available.`},tvRemote:i,"clipboard.read":{support:`partial`,note:`Uses provider/Appium clipboard extension support where available.`},"clipboard.write":{support:`partial`,note:`Uses provider/Appium clipboard extension support where available.`},settings:i,alert:i,pinch:i,rotateGesture:i,transformGesture:i,logs:i,record:i,artifacts:i,portReverse:i,nativeSnapshotBackend:{support:`unsupported`,note:`Cloud WebDriver cannot upload or run agent-device native runner/helper backends.`}};function o(e){return{provider:e.provider,platform:e.platform,snapshotBackend:e.platform===`ios`?`xctest`:`android`,snapshotSource:`appium-page-source`,operations:l(a,e.overrides)}}function s(e,t){return e.operations[t].support!==`unsupported`}function c(e,t){let n=e.operations[t],r=n.note?` ${n.note}`:``;return`${e.provider} WebDriver runtime does not support ${t}.${r}`}function l(e,t){let n={...e};for(let[r,i]of Object.entries(t??{}))n[r]=typeof i==`string`?{...e[r],support:i}:{...e[r],...i};return n}function u(e,t,n={}){return{platformName:e===`ios`?`iOS`:`Android`,"appium:deviceName":t,...n}}function d(e,t){let n=e?.bundleId??t?.appIdentifierHint,r=e?.packageName??t?.packageNameHint;return{bundleId:n,packageName:r,appName:e?.appName,launchTarget:p(e?.launchTarget,n,r)}}function f(e){return e===`ios`?`xctest`:`android`}function p(...e){return e.find(e=>e!==void 0)}const m=n(`owner-capability-missing`,`The WebDriver provider session is no longer active for this device.`);function h(e){let t=async(t,n,r,i,a)=>{let o=e.findSessionForDevice(t);if(!o)return;let s=await _(e,o,t,n,r.uploadPath,i,a);return await o.client.installApp(s?.appReference??r.appPath,a),d(s,i)},n=async(e,n,r,i,a)=>await t(e,n,{appPath:r,uploadPath:r},i,a);return Object.freeze({fact:t=>g(e.findSessionForDevice(t)),installApp:n,installInstallablePath:async(e,t,r,i)=>await n(e,``,t,r,i),deployApp:async(e,t,r)=>v(await n(e,t.app,t.appPath,{relaunch:t.replaceExisting,appIdentifierHint:t.app,packageNameHint:t.app},r),t.app),deployMaterializedApp:async(e,n,r)=>v(await t(e,``,{appPath:n.artifact.installablePath,uploadPath:n.artifact.uploadPath??n.artifact.installablePath},{appIdentifierHint:n.artifact.bundleId,packageNameHint:n.artifact.packageName},r))})}function g(e){return e?s(e.capabilities,`install`)?Object.freeze({available:!0}):n(`owner-capability-missing`,c(e.capabilities,`install`)):m}async function _(n,r,i,a,o,l,u){if(!s(r.capabilities,`install`))throw new e(`UNSUPPORTED_OPERATION`,c(r.capabilities,`install`),{provider:n.provider,deviceId:i.id,platform:t(i)});let d=r.prepared.uploadApp??n.uploadApp;if(d)return await d({provider:n.provider,lease:r.lease,device:i,app:a,appPath:o,options:l,signal:u})}function v(t,n){if(!t)throw new e(`UNSUPPORTED_OPERATION`,`The WebDriver provider session no longer supports app deployment.`);return{...t.bundleId?{bundleId:t.bundleId}:{},...t.packageName?{packageName:t.packageName}:{},...t.appName?{appName:t.appName}:{},...t.launchTarget??n?{launchTarget:t.launchTarget??n}:{}}}export{s as a,u as i,m as n,o,f as r,c as s,h as t};
|