agent-device 0.17.9 → 0.18.0
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 +4 -0
- package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.17.9.apk → agent-device-android-multitouch-helper-0.18.0.apk} +0 -0
- package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.18.0.apk.sha256 +1 -0
- package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.17.9.manifest.json → agent-device-android-multitouch-helper-0.18.0.manifest.json} +4 -4
- package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.17.9.apk → agent-device-android-snapshot-helper-0.18.0.apk} +0 -0
- package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.18.0.apk.sha256 +1 -0
- package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.17.9.manifest.json → agent-device-android-snapshot-helper-0.18.0.manifest.json} +6 -6
- package/dist/src/1848.js +4 -0
- package/dist/src/2577.js +1 -1
- package/dist/src/2948.js +20 -20
- package/dist/src/4291.js +1 -1
- package/dist/src/4723.js +1 -1
- package/dist/src/5341.js +1 -0
- package/dist/src/5643.js +1 -0
- package/dist/src/6918.js +1 -1
- package/dist/src/8275.js +2 -2
- package/dist/src/8936.js +1 -0
- package/dist/src/9414.js +1 -0
- package/dist/src/9581.js +4 -4
- package/dist/src/9722.js +32 -37
- package/dist/src/9919.js +5 -5
- package/dist/src/apple.js +1 -1
- package/dist/src/apps.js +10 -10
- package/dist/src/batch.d.ts +20 -3
- package/dist/src/batch.js +1 -1
- package/dist/src/cli-help.js +111 -35
- package/dist/src/cli.js +22 -25
- package/dist/src/contracts.d.ts +14 -0
- package/dist/src/device-ready.js +2 -0
- package/dist/src/find.js +1 -1
- package/dist/src/index.d.ts +67 -16
- package/dist/src/interaction.js +1 -1
- package/dist/src/internal/bin.js +1 -1
- package/dist/src/lease.js +1 -1
- package/dist/src/metro.js +1 -1
- package/dist/src/react-native.js +1 -1
- package/dist/src/record-trace-recording.js +3 -3
- package/dist/src/remote-config.d.ts +17 -11
- package/dist/src/selector-runtime.js +1 -1
- package/dist/src/session.js +11 -8
- package/dist/src/simulator.js +2 -0
- package/dist/src/snapshot.js +1 -1
- package/package.json +1 -1
- package/server.json +2 -2
- package/skills/agent-device/SKILL.md +1 -0
- package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.17.9.apk.sha256 +0 -1
- package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.17.9.apk.sha256 +0 -1
- package/dist/src/2133.js +0 -1
- package/dist/src/5628.js +0 -1
- package/dist/src/8358.js +0 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
import{setSessionSnapshot as e,createDaemonRuntimeSessionStore as t,captureSnapshot as r,dispatchCommand as n,runIosRunnerCommand as s,errorResponse as o,isCommandSupportedOnDevice as i,ensureDeviceReady as a,stopIosRunnerSession as l,resolveRunnerAppBundleId as c,getActiveAndroidSnapshotFreshness as u,resolveTargetDevice as d,context_contextFromFlags as f}from"./9722.js";import{closeIosApp as p}from"./apps.js";import{emitDiagnostic as m}from"./432.js";import{asAppError as g,normalizeError as h,AppError as y}from"./733.js";import{evaluateIsPredicate as w,isSupportedPredicate as S,localCommandPolicy as v,createAgentDevice as _}from"./2577.js";import{getAndroidAppState as I}from"./3340.js";import{splitIsSelectorArgs as x,normalizeType as k,prefersValueForReadableText as P,findNodeByLabel as N,extractNodeReadText as A}from"./9836.js";import{resolveRectCenter as R,isSparseSnapshotQualityVerdict as b,parseWaitPositionals as q}from"./2948.js";import{buildSnapshotPresentationKey as D,snapshotPresentationOptionsFromFlags as E}from"./4291.js";import{isApplePlatform as C}from"./5910.js";import{parseFindArgs as M,tryParseSelectorChain as O}from"./587.js";async function $(e,t,r){let n=e.get(t),s=n?.device??await d(r??{});return n||await a(s),{session:n,device:s}}async function F(e,t,r){let n=!e&&"ios"===t.platform;try{return await r()}finally{n&&(await l(t.id),await L(t))}}async function L(e){let t=c();await p(e,t).catch(r=>{m({level:"debug",phase:"ios_sessionless_runner_host_close_failed",data:{deviceId:e.id,bundleId:t,error:r instanceof Error?r.message:String(r)}})})}function K(e,t,r,n){t&&e.recordAction(t,{command:r.command,positionals:r.positionals??[],flags:r.flags??{},result:n})}function U(e){let{session:t,sessionName:r,device:n,snapshot:s,appBundleId:o}=e;return t?{...t,snapshot:s,lastComparisonSafeSnapshot:s?.comparisonSafe===!0?s:t.lastComparisonSafeSnapshot}:{name:r,device:n,createdAt:Date.now(),appBundleId:o,snapshot:s,...s?.comparisonSafe===!0?{lastComparisonSafeSnapshot:s}:{},actions:[]}}function T(e,t={}){return{artifacts:function(e,t={}){let r=!0===t.plural?"do":"does";return{resolveInput:async()=>{throw new y("UNSUPPORTED_OPERATION",`${e} ${r} not resolve input artifacts`)},reserveOutput:async()=>{throw new y("UNSUPPORTED_OPERATION",`${e} ${r} not reserve output artifacts`)},createTempFile:async()=>{throw new y("UNSUPPORTED_OPERATION",`${e} ${r} not create temporary files`)}}}(e,t),policy:v()}}let G=[["snapshotDepth","--depth"],["snapshotScope","--scope"],["snapshotRaw","--raw"]];function V(e,t){let r=function(e){if(!e)return[];let t=[];for(let[r,n]of G)void 0!==e[r]&&t.push(n);return t}(t);return 0===r.length?null:o("INVALID_ARGS",`${e} @ref does not support ${r.join(", ")}.`)}async function B(e,t){let r=await X(e);if(r)throw new y("COMMAND_FAILED",`press ${t} left ${e.appBundleId} and foregrounded ${r.foregroundPackage}. The tap likely escaped the app.`,r)}async function X(e){var t;if("android"!==e.device.platform||!e.appBundleId)return null;let r=await I(e.device),n=r.package?.trim();return n&&n!==e.appBundleId&&("com.android.settings"===(t=n)||"com.android.systemui"===t||"com.google.android.permissioncontroller"===t||t.includes("launcher"))?{expectedPackage:e.appBundleId,foregroundPackage:n,activity:r.activity,hint:"com.google.android.permissioncontroller"===n?"Dismiss or allow the permission prompt, then retry the smoke assertion.":"Use screenshot as visual truth, then take a fresh snapshot -i before retrying."}:null}function H(e){return"COMMAND_FAILED"===e.code&&"string"==typeof e.details?.expectedPackage&&"string"==typeof e.details?.foregroundPackage}function j(e,t){let r=Array.isArray(e.selectorChain)?e.selectorChain:void 0,n=J(e),s=n?.kind==="ref"?Y(n.ref):void 0,o=n?.kind==="selector"?n.selector:void 0,i={...s?{ref:s}:{},...o?{selector:o}:{},...r?{selectorChain:r}:{}};if("attrs"===t)return i;let a="string"==typeof e.text?e.text:"";return{...i,text:a,refLabel:function(e){let t=e.trim();if(!(!t||t.length>80||/[\r\n]/.test(t)))return t}(a)}}function z(e){let t=J(e);return{...t?.kind==="ref"?{ref:Y(t.ref)}:{},...t?.kind==="selector"?{selector:t.selector}:{},..."string"==typeof e.text?{text:e.text}:{},...e.node&&"object"==typeof e.node?{node:e.node}:{}}}function Q(e){let{selectorChain:t,...r}=e;return r}function W(e,t,r,n){let s=e.get(t);s&&e.recordAction(s,{command:r.command,positionals:r.positionals??[],flags:r.flags??{},result:n})}function J(e){let t=e.target;return t&&"object"==typeof t?"ref"===t.kind&&"string"==typeof t.ref?{kind:"ref",ref:t.ref}:"selector"===t.kind&&"string"==typeof t.selector?{kind:"selector",selector:t.selector}:void 0:void 0}function Y(e){return e.startsWith("@")?e.slice(1):e}let Z=["application","window","tabbar","scrollbar","image"],ee=new Set(["tab bar"]);async function et(e,t){var r;if(t.ok||(r=t.error.message,!/^wait timed out for (?:selector|text): /i.test(r)))return t;let n=await er(e).catch(()=>null);return n?o(t.error.code,`${t.error.message}. Current surface: ${n.summary}.`,{...t.error.details??{},currentSurface:n.details}):t}async function er(e){let t=[...(await r({device:e.device,session:e.session,flags:{...e.req.flags,snapshotInteractiveOnly:!0},logPath:e.logPath??""})).snapshot.nodes].sort(es),n=en(t,6,{includeIdentifiers:!0});if(0===n.length)return null;let s=en(t.filter(e=>!ea(e)),4,{includeIdentifiers:!1}),o=en(t.filter(el),4,{includeIdentifiers:!0});return{summary:(s.length>0?s:n.slice(0,4)).join(", "),details:{labels:n,...o.length>0?{buttons:o}:{}}}}function en(e,t,r){let n=new Set,s=[];for(let o of e){let e=ei(o,r);if(!(!e||n.has(e))&&(n.add(e),s.push(e),s.length>=t))break}return s}function es(e,t){var r,n;return eo(e)-eo(t)||(r=e,n=t,r.rect&&n.rect?r.rect.y-n.rect.y||r.rect.x-n.rect.x:r.rect?-1:n.rect?1:(r.depth??0)-(n.depth??0)||r.index-n.index)}function eo(e){let t=!!ei(e,{includeIdentifiers:!1});return 2*!!ea(e)+ +!t}function ei(e,t){let r=(t.includeIdentifiers?[e.label,e.value,e.identifier]:[e.label,e.value]).map(e=>"string"==typeof e?e.trim():"").find(e=>e.length>0);return r?r.replace(/\s+/g," ").slice(0,80):""}function ea(e){let t=k(`${e.type??""} ${e.role??""} ${e.subrole??""}`),r=`${e.label??""} ${e.value??""}`.trim().toLowerCase();return Z.some(e=>t.includes(e))||ee.has(r)||r.endsWith(".fill")}function el(e){return k(`${e.type??""} ${e.role??""} ${e.subrole??""}`).includes("button")}function ec(e){var t;let{session:r,selectorExpression:n}=e;if(!r||"ios"!==r.device.platform||r.postGestureStabilization)return null;let s=O(n);if(!s||1!==s.selectors.length)return null;let o=s.selectors[0];if(!o||1!==o.terms.length)return null;let i=o.terms[0];return i&&"string"==typeof i.value&&("id"===(t=i.key)||"label"===t||"text"===t||"value"===t)?{key:i.key,value:i.value,raw:o.raw}:null}function eu(e,t={}){let r=g(e);if("ELEMENT_NOT_FOUND"===r.code)return!0===t.allowElementNotFound;if("COMMAND_FAILED"!==r.code)return!1;let n=r.message.toLowerCase();return n.includes("fetch failed")||n.includes("timed out")||n.includes("timeout")||n.includes("runner did not accept connection")||n.includes("invalid runner response")}async function ed(e){let{device:t,node:r,flags:s,appBundleId:o,traceOutPath:i,surface:a,contextFromFlags:l}=e,c=A(r),u=R(r.rect);if(!u||"ios"===t.platform&&c&&!P(r.type??""))return c;try{let e=await n(t,"read",[String(u.x),String(u.y)],void 0,{...l(s,o,i),surface:a}),d=e&&"object"==typeof e?e:void 0,f="string"==typeof d?.text?d.text:"";if(f.trim())return f;return m({level:"warn",phase:"interaction_read_fallback",data:{reason:"empty_backend_text",nodeRef:r.ref,surface:a,platform:t.platform}}),c}catch(e){return m({level:"warn",phase:"interaction_read_fallback",data:{reason:"backend_read_failed",nodeRef:r.ref,surface:a,platform:t.platform,error:e instanceof Error?e.message:String(e)}}),c}}function ef(t){let r,n,{session:s,sessionStore:o,sessionName:i}=t,a=0;return{capture:async l=>{var c,d;let f=Date.now(),p=(c=l,d=t.req.flags?.out,JSON.stringify({presentationKey:D(E(ew(c))),includeRects:!0===c.includeRects,outPath:c.outPath??d??null})),m=function(e){let{timestamp:t,lastSnapshotAt:r,lastSnapshotResult:n,lastSnapshotCacheKey:s,session:o,request:i,cacheKey:a}=e;if(!(i.cache?.forceFresh===!0||!n||s!==a||t-r>=750||u(o))&&!ey(o,i))return n}({timestamp:f,lastSnapshotAt:a,lastSnapshotResult:r,lastSnapshotCacheKey:n,session:s,request:l,cacheKey:p});if(m)return m;let g=function(e){var t,r;let{session:n,timestamp:s,request:o}=e,i=n?.snapshot;if(i&&(t=n,r=o,!(r.cache?.forceFresh===!0||r.cache?.useSessionSnapshot!==!0||u(t)||ey(t,r)))&&s-i.createdAt<750&&i.presentationKey===function(e){return D(E(ew(e)))}(o))return i}({session:s,timestamp:f,request:l});if(g)return a=g.createdAt,r={snapshot:g},n=p,r;let h=await ep({params:t,request:l}),y={snapshot:h};return function(t){let{session:r,sessionStore:n,sessionName:s,snapshot:o}=t;!r||b(o.snapshotQuality)||(e(r,o),n.set(s,r))}({session:s,sessionStore:o,sessionName:i,snapshot:h}),a=f,r=y,n=p,y}}}async function ep(e){var t;let{params:r,request:n}=e,s=await eh(r,n,n.snapshotScope);return n.recovery?.legacyIosSparse&&!(t=s).snapshotQuality&&"xctest"===t.backend&&1===t.nodes.length&&t.nodes[0]?.type==="Application"?await em({runtimeParams:r,request:n,policy:n.recovery.legacyIosSparse}):n.recovery?.sparseVerdictQueryScope?.shouldScope&&b(s.snapshotQuality)?await eg({runtimeParams:r,request:n,policy:n.recovery.sparseVerdictQueryScope,snapshot:s}):s}async function em(e){let{runtimeParams:t,request:r,policy:n}=e;try{return await eh(t,r,n.scope,!1)}catch(e){if(!n.shouldScope)throw e;return await eh(t,r,n.query,!1)}}async function eg(e){let{runtimeParams:t,request:r,policy:n,snapshot:s}=e;try{return await eh(t,r,n.query,!1)}catch{return s}}async function eh(e,t,n,s=t.flags?.snapshotInteractiveOnly){return(await r({device:e.device,session:e.session,flags:{...t.flags,snapshotInteractiveOnly:s},outPath:t.outPath??e.req.flags?.out,logPath:e.logPath??"",snapshotScope:n,includeRects:t.includeRects})).snapshot}function ey(e,t){return t.cache?.bypassForPostGestureStabilization===!0&&!!e?.postGestureStabilization}function ew(e){return void 0===e.snapshotScope?e.flags:{...e.flags,snapshotScope:e.snapshotScope}}function eS(r){return _({backend:function(e){let{req:t,session:r,device:n,logPath:s,sessionName:o,sessionStore:i}=e,a=ef({device:n,session:r,sessionStore:i,sessionName:o,req:t,logPath:s});return{platform:n.platform,captureSnapshot:async(e,r)=>{var s;let o,i={...t.flags,...(s=r,o={},s?.interactiveOnly!==void 0&&(o.snapshotInteractiveOnly=s.interactiveOnly),s?.scope!==void 0&&(o.snapshotScope=s.scope),s?.depth!==void 0&&(o.snapshotDepth=s.depth),s?.raw!==void 0&&(o.snapshotRaw=s.raw),o)},l=r?.includeRects===!0,c=r?.scope??t.flags?.snapshotScope,u="wait"===t.command||"find"===t.command||l&&"web"===n.platform;return await a.capture({flags:i,snapshotScope:c,includeRects:l,cache:{forceFresh:u,useSessionSnapshot:!0,bypassForPostGestureStabilization:!0}})},readText:async(o,i)=>({text:await ed({device:n,node:i,flags:t.flags,appBundleId:r?.appBundleId,traceOutPath:r?.trace?.outPath,surface:r?.surface,contextFromFlags:e.contextFromFlags??((e,t,r)=>f(s??"",e,t,r))})}),findText:async(t,r)=>({found:await e_(e,r)})}}(r),...T("selector commands",{plural:!0}),sessions:t({sessionName:r.sessionName,getSession:()=>r.session,recordOptions:{includeSnapshot:!0},setRecord:t=>{r.session&&t.snapshot&&(e(r.session,t.snapshot),r.sessionStore.set(r.sessionName,r.session))}})})}async function ev(e,t){let r=e.sessionStore.get(e.sessionName);if(!r&&t.requireSession)return{ok:!1,response:o("SESSION_NOT_FOUND","No active session. Run open first.")};let n=r?.device??await d(e.req.flags??{});return(r||await a(n),i(t.capability,n))?{ok:!0,runtime:eS({...e,session:r,device:n})}:{ok:!1,response:o("UNSUPPORTED_OPERATION",`${t.capability} is not supported on this device`)}}async function e_(e,t){let r=await eI(e,t);if(null!==r)return r;let n=await ex(e,t);return null!==n?n:await ek(e,t)}async function eI(e,t){return"macos"===e.device.platform&&e.session?.surface&&"app"!==e.session.surface?await ek(e,t):null}async function ex(e,t){var r,n,o;let i,a,l=C((r=e).device.platform)&&r.session?.appBundleId?{device:r.device,appBundleId:r.session.appBundleId,traceLogPath:r.session.trace?.outPath}:null;if(!l)return null;let c=await s(l.device,{command:"findText",text:t,appBundleId:l.appBundleId},(n=e,o=l,i=n.req.flags??{},a=n.req.meta??{},{verbose:i.verbose,logPath:n.logPath,traceLogPath:o.traceLogPath,requestId:a.requestId,iosXctestrunFile:i.iosXctestrunFile,iosXctestDerivedDataPath:i.iosXctestDerivedDataPath,iosXctestEnvDir:i.iosXctestEnvDir}));return c?.found===!0}async function ek(e,t){return!!N((await eP(e)).nodes,t)}async function eP(e){let t=ef({device:e.device,session:e.session,sessionStore:e.sessionStore,sessionName:e.sessionName,req:e.req,logPath:e.logPath}),{snapshot:r}=await t.capture({flags:{...e.req.flags,snapshotInteractiveOnly:!1},cache:{forceFresh:!0,bypassForPostGestureStabilization:!0}});return r}async function eN(e){var t;let{req:r}=e;if("find"!==r.command)return null;let n=r.positionals??[];if(0===n.length)return o("INVALID_ARGS","find requires a locator or text");let s=M(n);if(!s.query)return o("INVALID_ARGS","find requires a value");if(r.flags?.findFirst&&r.flags?.findLast)return o("INVALID_ARGS","find accepts only one of --first or --last");let i=s.action;if("exists"!==(t=i)&&"wait"!==t&&"get_text"!==t&&"get_attrs"!==t)return null;let a=await ev(e,{requireSession:!1,capability:"find"});return a.ok?await eF(async()=>{let t=await a.runtime.selectors.find({session:e.sessionName,requestId:r.meta?.requestId,locator:s.locator,query:s.query,action:i,timeoutMs:s.timeoutMs});return W(e.sessionStore,e.sessionName,r,function(e,t){if("exists"===t)return{found:!0};if("wait"===t)return{found:!0,waitedMs:e.waitedMs};let r="string"==typeof e.ref?e.ref:void 0;return"get_attrs"===t?{ref:r,action:"get attrs"}:{ref:r,action:"get text",text:"string"==typeof e.text?e.text:""}}(t,i)),"found"===t.kind?{found:!0,..."number"==typeof t.waitedMs?{waitedMs:t.waitedMs}:{}}:{..."string"==typeof t.ref?{ref:t.ref}:{},..."string"==typeof t.text?{text:t.text}:{},...t.node&&"object"==typeof t.node?{node:t.node}:{}}}):a.response}async function eA(e){let{req:t}=e;if("get"!==t.command)return null;let r=t.positionals?.[0];if("text"!==r&&"attrs"!==r)return o("INVALID_ARGS","get only supports text or attrs");let n=function(e){let t=e.positionals?.[1]??"";if(t.startsWith("@"))return{ok:!0,target:{kind:"ref",ref:t,fallbackLabel:e.positionals.length>2?e.positionals.slice(2).join(" ").trim():""}};let r=e.positionals?.slice(1).join(" ").trim()??"";return r?{ok:!0,target:{kind:"selector",selector:r}}:{ok:!1,response:o("INVALID_ARGS","get requires @ref or selector expression")}}(t);if(!n.ok)return n.response;if("ref"===n.target.kind){let e=V("get",t.flags);if(e)return e}if("selector"===n.target.kind){let t=await eq(e,r,n.target.selector);if(t)return t}let s=await ev(e,{requireSession:!0,capability:"get"});return s.ok?await eF(async()=>{let o=await s.runtime.selectors.get({session:e.sessionName,requestId:t.meta?.requestId,property:r,target:n.target});return W(e.sessionStore,e.sessionName,t,j(o,r)),z(o)}):s.response}async function eR(e){let{req:t}=e;if("is"!==t.command)return null;let r=(t.positionals?.[0]??"").toLowerCase();if(!S(r))return o("INVALID_ARGS","is requires predicate: visible|hidden|exists|editable|selected|text");let{split:n}=x(t.positionals??[]);if(!n)return o("INVALID_ARGS","is requires a selector expression");let s=n.rest.join(" ").trim();if("text"===r&&!s)return o("INVALID_ARGS","is text requires expected text value");if("text"!==r&&n.rest.length>0)return o("INVALID_ARGS",`is ${r} does not accept trailing values`);let i=await eD(e,r,n.selectorExpression,s);if(i)return i;let a=await ev(e,{requireSession:!0,capability:"is"});if(!a.ok)return a.response;let l=await eF(async()=>{let o=await a.runtime.selectors.is({session:e.sessionName,requestId:t.meta?.requestId,predicate:r,selector:n.selectorExpression,expectedText:s});return W(e.sessionStore,e.sessionName,t,o),Q(o)});return await eL(e,l,`is ${r}`)}async function eb(e){let{req:t,sessionName:r,sessionStore:n}=e,s=q(t.positionals??[]);if(!s)return o("INVALID_ARGS","wait requires a duration or text");let{session:a,device:l}=await $(n,r,t.flags);if("sleep"!==s.kind&&!i("wait",l))return o("UNSUPPORTED_OPERATION","wait is not supported on this device");if("selector"===s.kind){let t=await eE({...e,session:a,device:l,selectorExpression:s.selectorExpression,timeoutMs:s.timeoutMs});if(t)return t}let c=async()=>{let o=eS({...e,session:a,device:l}),i=await eF(async()=>{let e=await o.selectors.wait({session:r,requestId:t.meta?.requestId,target:function(e,t){if("sleep"===e.kind)return{kind:"sleep",durationMs:e.durationMs};if("selector"===e.kind)return{kind:"selector",selector:e.selectorExpression,timeoutMs:e.timeoutMs};if("ref"===e.kind){if(!t?.snapshot)throw new y("INVALID_ARGS","Ref wait requires an existing snapshot in session.");return{kind:"ref",ref:e.rawRef,timeoutMs:e.timeoutMs}}if(!e.text)throw new y("INVALID_ARGS","wait requires text");return{kind:"text",text:e.text,timeoutMs:e.timeoutMs}}(s,a)});return W(n,r,t,e),{waitedMs:e.waitedMs,..."string"==typeof e.text?{text:e.text}:{},..."string"==typeof e.selector?{selector:e.selector}:{}}}),c=await et({req:t,logPath:e.logPath,session:a,device:l},i);return await eL(e,c,"wait")};return"sleep"===s.kind?await c():await F(a,l,c)}async function eq(e,t,r){let n=e.sessionStore.get(e.sessionName),s=ec({session:n,selectorExpression:r});if(!n||!s||"text"===t&&"id"!==s.key)return null;let o=await eO(e,n,s);if(e$(o))return o.response;if(!o)return null;let i=function(e,t,r){if(!r.found||!r.node)return null;let n={target:{kind:"selector",selector:t},node:r.node,selectorChain:[t]};return"attrs"===e?{kind:"attrs",...n}:"string"!=typeof r.text?null:{kind:"text",...n,text:r.text}}(t,s.raw,o);return i?(W(e.sessionStore,e.sessionName,e.req,j(i,t)),{ok:!0,data:z(i)}):null}async function eD(e,t,r,n){var s,o,i,a,l;let c;if("hidden"===t)return null;let u=await eC(e,r);if(e$(u))return u.response;if(!u?.result.found||!u.result.node)return null;let d="exists"===t?{predicate:t,pass:!0,selector:u.selector.raw,matches:1,selectorChain:[u.selector.raw]}:(s=t,o=n,i=u.selector.raw,a=u.session,c=w({predicate:s,node:l=u.result.node,nodes:[l],expectedText:o,platform:a.device.platform}),{predicate:s,pass:c.pass,selector:i,..."text"===s?{text:c.actualText}:{},selectorChain:[i]});return d?(W(e.sessionStore,e.sessionName,e.req,d),{ok:!0,data:Q(d)}):null}async function eE(e){let t=ec({session:e.session,selectorExpression:e.selectorExpression});if(!e.session||!t)return null;let r=Date.now(),n=await eO(e,e.session,t);if(e$(n))return n.response;if(!n?.found)return null;let s={kind:"selector",selector:t.raw,waitedMs:Date.now()-r,selectorChain:[t.raw]};return W(e.sessionStore,e.sessionName,e.req,s),await et({req:e.req,logPath:e.logPath,session:e.session,device:e.device},{ok:!0,data:s})}async function eC(e,t){let r=e.sessionStore.get(e.sessionName),n=ec({session:r,selectorExpression:t});if(!r||!n)return null;let s=await eO(e,r,n);return e$(s)?s:s?{session:r,selector:n,result:s}:null}async function eM(e,t,r){let n=await s(t.device,{command:"querySelector",selectorKey:r.key,selectorValue:r.value,appBundleId:t.appBundleId},{verbose:!!e.req.flags?.verbose,logPath:e.logPath,traceLogPath:t.trace?.outPath,requestId:e.req.meta?.requestId,iosXctestrunFile:e.req.flags?.iosXctestrunFile,iosXctestDerivedDataPath:e.req.flags?.iosXctestDerivedDataPath,iosXctestEnvDir:e.req.flags?.iosXctestEnvDir}),o=!0===n.found,i=function(e){let t=e.nodes;if(!Array.isArray(t))return;let r=t[0];if(r&&"object"==typeof r)return r}(n);return{found:o,..."string"==typeof n.text?{text:n.text}:{},...i?{node:i}:{}}}async function eO(e,t,r){try{return await eM(e,t,r)}catch(e){if(eu(e,{allowElementNotFound:!0}))return null;return{kind:"error",response:{ok:!1,error:h(e)}}}}function e$(e){return null!==e&&"kind"in e&&"error"===e.kind}async function eF(e){try{return{ok:!0,data:await e()}}catch(t){let e=g(t);return o(e.code,e.message,e.details)}}async function eL(e,t,r){var n;let s;if(t.ok)return t;let i=e.sessionStore.get(e.sessionName);if(!i)return t;try{s=await X(i)}catch{return t}return s?o(t.error.code,`${r} failed because ${"com.google.android.permissioncontroller"===(n=s).foregroundPackage?`Android permission dialog is blocking ${n.expectedPackage}`:`${n.foregroundPackage} is foreground instead of ${n.expectedPackage}`}.`,{...t.error.details??{},...s,blockedBy:"android_foreground_surface",originalMessage:t.error.message}):t}export{B as assertAndroidPressStayedInApp,U as buildSnapshotSession,T as createDaemonRuntimePolicy,ef as createSelectorCaptureRuntime,eN as dispatchFindReadOnlyViaRuntime,eA as dispatchGetViaRuntime,eR as dispatchIsViaRuntime,eb as dispatchWaitViaRuntime,H as isAndroidEscapeError,eu as isDirectIosSelectorFallbackError,ec as readSimpleIosSelectorTarget,ed as readTextForNode,K as recordIfSession,V as refSnapshotFlagGuardResponse,$ as resolveSessionDevice,F as withSessionlessRunnerCleanup};
|
|
1
|
+
import{setSessionSnapshot as e,createDaemonRuntimeSessionStore as t,captureSnapshot as r,dispatchCommand as n,runIosRunnerCommand as s,isCommandSupportedOnDevice as o,errorResponse as i,stopIosRunnerSession as a,resolveRunnerAppBundleId as l,getActiveAndroidSnapshotFreshness as c,resolveTargetDevice as u,context_contextFromFlags as d}from"./9722.js";import{closeIosApp as f}from"./apps.js";import{emitDiagnostic as p}from"./432.js";import{ensureDeviceReady as m}from"./device-ready.js";import{asAppError as g,normalizeError as h,AppError as y}from"./733.js";import{evaluateIsPredicate as w,isSupportedPredicate as S,localCommandPolicy as _,createAgentDevice as v}from"./2577.js";import{getAndroidAppState as I}from"./3340.js";import{splitIsSelectorArgs as x,normalizeType as k,prefersValueForReadableText as P,findNodeByLabel as N,extractNodeReadText as A}from"./9836.js";import{resolveRectCenter as R,isSparseSnapshotQualityVerdict as b,parseWaitPositionals as q}from"./2948.js";import{buildSnapshotPresentationKey as D,snapshotPresentationOptionsFromFlags as E}from"./4291.js";import{isApplePlatform as C}from"./5910.js";import{parseFindArgs as M,tryParseSelectorChain as O}from"./587.js";async function $(e,t,r){let n=e.get(t),s=n?.device??await u(r??{});return n||await m(s),{session:n,device:s}}async function F(e,t,r){let n=!e&&"ios"===t.platform;try{return await r()}finally{n&&(await a(t.id),await K(t))}}async function K(e){let t=l();await f(e,t).catch(r=>{p({level:"debug",phase:"ios_sessionless_runner_host_close_failed",data:{deviceId:e.id,bundleId:t,error:r instanceof Error?r.message:String(r)}})})}function L(e,t,r,n){t&&e.recordAction(t,{command:r.command,positionals:r.positionals??[],flags:r.flags??{},result:n})}function U(e){let{session:t,sessionName:r,device:n,snapshot:s,appBundleId:o}=e;return t?{...t,snapshot:s,lastComparisonSafeSnapshot:s?.comparisonSafe===!0?s:t.lastComparisonSafeSnapshot}:{name:r,device:n,createdAt:Date.now(),appBundleId:o,snapshot:s,...s?.comparisonSafe===!0?{lastComparisonSafeSnapshot:s}:{},actions:[]}}function T(e,t={}){return{artifacts:function(e,t={}){let r=!0===t.plural?"do":"does";return{resolveInput:async()=>{throw new y("UNSUPPORTED_OPERATION",`${e} ${r} not resolve input artifacts`)},reserveOutput:async()=>{throw new y("UNSUPPORTED_OPERATION",`${e} ${r} not reserve output artifacts`)},createTempFile:async()=>{throw new y("UNSUPPORTED_OPERATION",`${e} ${r} not create temporary files`)}}}(e,t),policy:_()}}let G=[["snapshotDepth","--depth"],["snapshotScope","--scope"],["snapshotRaw","--raw"]];function V(e,t){let r=function(e){if(!e)return[];let t=[];for(let[r,n]of G)void 0!==e[r]&&t.push(n);return t}(t);return 0===r.length?null:i("INVALID_ARGS",`${e} @ref does not support ${r.join(", ")}.`)}async function B(e,t){let r=await H(e);if(r)throw new y("COMMAND_FAILED",`press ${t} left ${e.appBundleId} and foregrounded ${r.foregroundPackage}. The tap likely escaped the app.`,r)}async function H(e){var t;if("android"!==e.device.platform||!e.appBundleId)return null;let r=await I(e.device),n=r.package?.trim();return n&&n!==e.appBundleId&&("com.android.settings"===(t=n)||"com.android.systemui"===t||"com.google.android.permissioncontroller"===t||t.includes("launcher"))?{expectedPackage:e.appBundleId,foregroundPackage:n,activity:r.activity,hint:"com.google.android.permissioncontroller"===n?"Dismiss or allow the permission prompt, then retry the smoke assertion.":"Use screenshot as visual truth, then take a fresh snapshot -i before retrying."}:null}function X(e){return"COMMAND_FAILED"===e.code&&"string"==typeof e.details?.expectedPackage&&"string"==typeof e.details?.foregroundPackage}function j(e,t){let r=Array.isArray(e.selectorChain)?e.selectorChain:void 0,n=J(e),s=n?.kind==="ref"?Y(n.ref):void 0,o=n?.kind==="selector"?n.selector:void 0,i={...s?{ref:s}:{},...o?{selector:o}:{},...r?{selectorChain:r}:{}};if("attrs"===t)return i;let a="string"==typeof e.text?e.text:"";return{...i,text:a,refLabel:function(e){let t=e.trim();if(!(!t||t.length>80||/[\r\n]/.test(t)))return t}(a)}}function z(e){let t=J(e);return{...t?.kind==="ref"?{ref:Y(t.ref)}:{},...t?.kind==="selector"?{selector:t.selector}:{},..."string"==typeof e.text?{text:e.text}:{},...e.node&&"object"==typeof e.node?{node:e.node}:{}}}function Q(e){let{selectorChain:t,...r}=e;return r}function W(e,t,r,n){let s=e.get(t);s&&e.recordAction(s,{command:r.command,positionals:r.positionals??[],flags:r.flags??{},result:n})}function J(e){let t=e.target;return t&&"object"==typeof t?"ref"===t.kind&&"string"==typeof t.ref?{kind:"ref",ref:t.ref}:"selector"===t.kind&&"string"==typeof t.selector?{kind:"selector",selector:t.selector}:void 0:void 0}function Y(e){return e.startsWith("@")?e.slice(1):e}let Z=["application","window","tabbar","scrollbar","image"],ee=new Set(["tab bar"]);async function et(e,t){var r;if(t.ok||(r=t.error.message,!/^wait timed out for (?:selector|text): /i.test(r)))return t;let n=await er(e).catch(()=>null);return n?i(t.error.code,`${t.error.message}. Current surface: ${n.summary}.`,{...t.error.details??{},currentSurface:n.details}):t}async function er(e){let t=[...(await r({device:e.device,session:e.session,flags:{...e.req.flags,snapshotInteractiveOnly:!0},logPath:e.logPath??""})).snapshot.nodes].sort(es),n=en(t,6,{includeIdentifiers:!0});if(0===n.length)return null;let s=en(t.filter(e=>!ea(e)),4,{includeIdentifiers:!1}),o=en(t.filter(el),4,{includeIdentifiers:!0});return{summary:(s.length>0?s:n.slice(0,4)).join(", "),details:{labels:n,...o.length>0?{buttons:o}:{}}}}function en(e,t,r){let n=new Set,s=[];for(let o of e){let e=ei(o,r);if(!(!e||n.has(e))&&(n.add(e),s.push(e),s.length>=t))break}return s}function es(e,t){var r,n;return eo(e)-eo(t)||(r=e,n=t,r.rect&&n.rect?r.rect.y-n.rect.y||r.rect.x-n.rect.x:r.rect?-1:n.rect?1:(r.depth??0)-(n.depth??0)||r.index-n.index)}function eo(e){let t=!!ei(e,{includeIdentifiers:!1});return 2*!!ea(e)+ +!t}function ei(e,t){let r=(t.includeIdentifiers?[e.label,e.value,e.identifier]:[e.label,e.value]).map(e=>"string"==typeof e?e.trim():"").find(e=>e.length>0);return r?r.replace(/\s+/g," ").slice(0,80):""}function ea(e){let t=k(`${e.type??""} ${e.role??""} ${e.subrole??""}`),r=`${e.label??""} ${e.value??""}`.trim().toLowerCase();return Z.some(e=>t.includes(e))||ee.has(r)||r.endsWith(".fill")}function el(e){return k(`${e.type??""} ${e.role??""} ${e.subrole??""}`).includes("button")}function ec(e){var t;let{session:r,selectorExpression:n}=e;if(!r||"ios"!==r.device.platform||r.postGestureStabilization)return null;let s=O(n);if(!s||1!==s.selectors.length)return null;let o=s.selectors[0];if(!o||1!==o.terms.length)return null;let i=o.terms[0];return i&&"string"==typeof i.value&&("id"===(t=i.key)||"label"===t||"text"===t||"value"===t)?{key:i.key,value:i.value,raw:o.raw}:null}function eu(e,t={}){let r=g(e);if("ELEMENT_NOT_FOUND"===r.code)return!0===t.allowElementNotFound;if("COMMAND_FAILED"!==r.code)return!1;let n=r.message.toLowerCase();return n.includes("fetch failed")||n.includes("timed out")||n.includes("timeout")||n.includes("runner did not accept connection")||n.includes("invalid runner response")}async function ed(e){let{device:t,node:r,flags:s,appBundleId:o,traceOutPath:i,surface:a,contextFromFlags:l}=e,c=A(r),u=R(r.rect);if(!u||"ios"===t.platform&&c&&!P(r.type??""))return c;try{let e=await n(t,"read",[String(u.x),String(u.y)],void 0,{...l(s,o,i),surface:a}),d=e&&"object"==typeof e?e:void 0,f="string"==typeof d?.text?d.text:"";if(f.trim())return f;return p({level:"warn",phase:"interaction_read_fallback",data:{reason:"empty_backend_text",nodeRef:r.ref,surface:a,platform:t.platform}}),c}catch(e){return p({level:"warn",phase:"interaction_read_fallback",data:{reason:"backend_read_failed",nodeRef:r.ref,surface:a,platform:t.platform,error:e instanceof Error?e.message:String(e)}}),c}}function ef(t){let r,n,{session:s,sessionStore:o,sessionName:i}=t,a=0;return{capture:async l=>{var u,d;let f=Date.now(),p=(u=l,d=t.req.flags?.out,JSON.stringify({presentationKey:D(E(ew(u))),includeRects:!0===u.includeRects,outPath:u.outPath??d??null})),m=function(e){let{timestamp:t,lastSnapshotAt:r,lastSnapshotResult:n,lastSnapshotCacheKey:s,session:o,request:i,cacheKey:a}=e;if(!(i.cache?.forceFresh===!0||!n||s!==a||t-r>=750||c(o))&&!ey(o,i))return n}({timestamp:f,lastSnapshotAt:a,lastSnapshotResult:r,lastSnapshotCacheKey:n,session:s,request:l,cacheKey:p});if(m)return m;let g=function(e){var t,r;let{session:n,timestamp:s,request:o}=e,i=n?.snapshot;if(i&&(t=n,r=o,!(r.cache?.forceFresh===!0||r.cache?.useSessionSnapshot!==!0||c(t)||ey(t,r)))&&s-i.createdAt<750&&i.presentationKey===function(e){return D(E(ew(e)))}(o))return i}({session:s,timestamp:f,request:l});if(g)return a=g.createdAt,r={snapshot:g},n=p,r;let h=await ep({params:t,request:l}),y={snapshot:h};return function(t){let{session:r,sessionStore:n,sessionName:s,snapshot:o}=t;!r||b(o.snapshotQuality)||(e(r,o),n.set(s,r))}({session:s,sessionStore:o,sessionName:i,snapshot:h}),a=f,r=y,n=p,y}}}async function ep(e){var t;let{params:r,request:n}=e,s=await eh(r,n,n.snapshotScope);return n.recovery?.legacyIosSparse&&!(t=s).snapshotQuality&&"xctest"===t.backend&&1===t.nodes.length&&t.nodes[0]?.type==="Application"?await em({runtimeParams:r,request:n,policy:n.recovery.legacyIosSparse}):n.recovery?.sparseVerdictQueryScope?.shouldScope&&b(s.snapshotQuality)?await eg({runtimeParams:r,request:n,policy:n.recovery.sparseVerdictQueryScope,snapshot:s}):s}async function em(e){let{runtimeParams:t,request:r,policy:n}=e;try{return await eh(t,r,n.scope,!1)}catch(e){if(!n.shouldScope)throw e;return await eh(t,r,n.query,!1)}}async function eg(e){let{runtimeParams:t,request:r,policy:n,snapshot:s}=e;try{return await eh(t,r,n.query,!1)}catch{return s}}async function eh(e,t,n,s=t.flags?.snapshotInteractiveOnly){return(await r({device:e.device,session:e.session,flags:{...t.flags,snapshotInteractiveOnly:s},outPath:t.outPath??e.req.flags?.out,logPath:e.logPath??"",snapshotScope:n,includeRects:t.includeRects})).snapshot}function ey(e,t){return t.cache?.bypassForPostGestureStabilization===!0&&!!e?.postGestureStabilization}function ew(e){return void 0===e.snapshotScope?e.flags:{...e.flags,snapshotScope:e.snapshotScope}}function eS(r){return v({backend:function(e){let{req:t,session:r,device:n,logPath:s,sessionName:o,sessionStore:i}=e,a=ef({device:n,session:r,sessionStore:i,sessionName:o,req:t,logPath:s});return{platform:n.platform,captureSnapshot:async(e,r)=>{var s;let o,i={...t.flags,...(s=r,o={},s?.interactiveOnly!==void 0&&(o.snapshotInteractiveOnly=s.interactiveOnly),s?.scope!==void 0&&(o.snapshotScope=s.scope),s?.depth!==void 0&&(o.snapshotDepth=s.depth),s?.raw!==void 0&&(o.snapshotRaw=s.raw),o)},l=r?.includeRects===!0,c=r?.scope??t.flags?.snapshotScope,u="wait"===t.command||"find"===t.command||l&&"web"===n.platform;return await a.capture({flags:i,snapshotScope:c,includeRects:l,cache:{forceFresh:u,useSessionSnapshot:!0,bypassForPostGestureStabilization:!0}})},readText:async(o,i)=>({text:await ed({device:n,node:i,flags:t.flags,appBundleId:r?.appBundleId,traceOutPath:r?.trace?.outPath,surface:r?.surface,contextFromFlags:e.contextFromFlags??((e,t,r)=>d(s??"",e,t,r))})}),findText:async(t,r)=>({found:await ev(e,r)})}}(r),...T("selector commands",{plural:!0}),sessions:t({sessionName:r.sessionName,getSession:()=>r.session,recordOptions:{includeSnapshot:!0},setRecord:t=>{r.session&&t.snapshot&&(e(r.session,t.snapshot),r.sessionStore.set(r.sessionName,r.session))}})})}async function e_(e,t){let r=e.sessionStore.get(e.sessionName);if(!r&&t.requireSession)return{ok:!1,response:i("SESSION_NOT_FOUND","No active session. Run open first.")};let n=r?.device??await u(e.req.flags??{});return(r||await m(n),o(t.capability,n))?{ok:!0,runtime:eS({...e,session:r,device:n})}:{ok:!1,response:i("UNSUPPORTED_OPERATION",`${t.capability} is not supported on this device`)}}async function ev(e,t){let r=await eI(e,t);if(null!==r)return r;let n=await ex(e,t);return null!==n?n:await ek(e,t)}async function eI(e,t){return"macos"===e.device.platform&&e.session?.surface&&"app"!==e.session.surface?await ek(e,t):null}async function ex(e,t){var r,n,o;let i,a,l=C((r=e).device.platform)&&r.session?.appBundleId?{device:r.device,appBundleId:r.session.appBundleId,traceLogPath:r.session.trace?.outPath}:null;if(!l)return null;let c=await s(l.device,{command:"findText",text:t,appBundleId:l.appBundleId},(n=e,o=l,i=n.req.flags??{},a=n.req.meta??{},{verbose:i.verbose,logPath:n.logPath,traceLogPath:o.traceLogPath,requestId:a.requestId,iosXctestrunFile:i.iosXctestrunFile,iosXctestDerivedDataPath:i.iosXctestDerivedDataPath,iosXctestEnvDir:i.iosXctestEnvDir}));return c?.found===!0}async function ek(e,t){return!!N((await eP(e)).nodes,t)}async function eP(e){let t=ef({device:e.device,session:e.session,sessionStore:e.sessionStore,sessionName:e.sessionName,req:e.req,logPath:e.logPath}),{snapshot:r}=await t.capture({flags:{...e.req.flags,snapshotInteractiveOnly:!1},cache:{forceFresh:!0,bypassForPostGestureStabilization:!0}});return r}async function eN(e){var t;let{req:r}=e;if("find"!==r.command)return null;let n=r.positionals??[];if(0===n.length)return i("INVALID_ARGS","find requires a locator or text");let s=M(n);if(!s.query)return i("INVALID_ARGS","find requires a value");if(r.flags?.findFirst&&r.flags?.findLast)return i("INVALID_ARGS","find accepts only one of --first or --last");let o=s.action;if("exists"!==(t=o)&&"wait"!==t&&"get_text"!==t&&"get_attrs"!==t)return null;let a=await e_(e,{requireSession:!1,capability:"find"});return a.ok?await eF(async()=>{let t=await a.runtime.selectors.find({session:e.sessionName,requestId:r.meta?.requestId,locator:s.locator,query:s.query,action:o,timeoutMs:s.timeoutMs});return W(e.sessionStore,e.sessionName,r,function(e,t){if("exists"===t)return{found:!0};if("wait"===t)return{found:!0,waitedMs:e.waitedMs};let r="string"==typeof e.ref?e.ref:void 0;return"get_attrs"===t?{ref:r,action:"get attrs"}:{ref:r,action:"get text",text:"string"==typeof e.text?e.text:""}}(t,o)),"found"===t.kind?{found:!0,..."number"==typeof t.waitedMs?{waitedMs:t.waitedMs}:{}}:{..."string"==typeof t.ref?{ref:t.ref}:{},..."string"==typeof t.text?{text:t.text}:{},...t.node&&"object"==typeof t.node?{node:t.node}:{}}}):a.response}async function eA(e){let{req:t}=e;if("get"!==t.command)return null;let r=t.positionals?.[0];if("text"!==r&&"attrs"!==r)return i("INVALID_ARGS","get only supports text or attrs");let n=function(e){let t=e.positionals?.[1]??"";if(t.startsWith("@"))return{ok:!0,target:{kind:"ref",ref:t,fallbackLabel:e.positionals.length>2?e.positionals.slice(2).join(" ").trim():""}};let r=e.positionals?.slice(1).join(" ").trim()??"";return r?{ok:!0,target:{kind:"selector",selector:r}}:{ok:!1,response:i("INVALID_ARGS","get requires @ref or selector expression")}}(t);if(!n.ok)return n.response;if("ref"===n.target.kind){let e=V("get",t.flags);if(e)return e}if("selector"===n.target.kind){let t=await eq(e,r,n.target.selector);if(t)return t}let s=await e_(e,{requireSession:!0,capability:"get"});return s.ok?await eF(async()=>{let o=await s.runtime.selectors.get({session:e.sessionName,requestId:t.meta?.requestId,property:r,target:n.target});return W(e.sessionStore,e.sessionName,t,j(o,r)),z(o)}):s.response}async function eR(e){let{req:t}=e;if("is"!==t.command)return null;let r=(t.positionals?.[0]??"").toLowerCase();if(!S(r))return i("INVALID_ARGS","is requires predicate: visible|hidden|exists|editable|selected|text");let{split:n}=x(t.positionals??[]);if(!n)return i("INVALID_ARGS","is requires a selector expression");let s=n.rest.join(" ").trim();if("text"===r&&!s)return i("INVALID_ARGS","is text requires expected text value");if("text"!==r&&n.rest.length>0)return i("INVALID_ARGS",`is ${r} does not accept trailing values`);let o=await eD(e,r,n.selectorExpression,s);if(o)return o;let a=await e_(e,{requireSession:!0,capability:"is"});if(!a.ok)return a.response;let l=await eF(async()=>{let o=await a.runtime.selectors.is({session:e.sessionName,requestId:t.meta?.requestId,predicate:r,selector:n.selectorExpression,expectedText:s});return W(e.sessionStore,e.sessionName,t,o),Q(o)});return await eK(e,l,`is ${r}`)}async function eb(e){let{req:t,sessionName:r,sessionStore:n}=e,s=q(t.positionals??[]);if(!s)return i("INVALID_ARGS","wait requires a duration or text");let{session:a,device:l}=await $(n,r,t.flags);if("sleep"!==s.kind&&!o("wait",l))return i("UNSUPPORTED_OPERATION","wait is not supported on this device");if("selector"===s.kind){let t=await eE({...e,session:a,device:l,selectorExpression:s.selectorExpression,timeoutMs:s.timeoutMs});if(t)return t}let c=async()=>{let o=eS({...e,session:a,device:l}),i=await eF(async()=>{let e=await o.selectors.wait({session:r,requestId:t.meta?.requestId,target:function(e,t){if("sleep"===e.kind)return{kind:"sleep",durationMs:e.durationMs};if("selector"===e.kind)return{kind:"selector",selector:e.selectorExpression,timeoutMs:e.timeoutMs};if("ref"===e.kind){if(!t?.snapshot)throw new y("INVALID_ARGS","Ref wait requires an existing snapshot in session.");return{kind:"ref",ref:e.rawRef,timeoutMs:e.timeoutMs}}if(!e.text)throw new y("INVALID_ARGS","wait requires text");return{kind:"text",text:e.text,timeoutMs:e.timeoutMs}}(s,a)});return W(n,r,t,e),{waitedMs:e.waitedMs,..."string"==typeof e.text?{text:e.text}:{},..."string"==typeof e.selector?{selector:e.selector}:{}}}),c=await et({req:t,logPath:e.logPath,session:a,device:l},i);return await eK(e,c,"wait")};return"sleep"===s.kind?await c():await F(a,l,c)}async function eq(e,t,r){let n=e.sessionStore.get(e.sessionName),s=ec({session:n,selectorExpression:r});if(!n||!s||"text"===t&&"id"!==s.key)return null;let o=await eO(e,n,s);if(e$(o))return o.response;if(!o)return null;let i=function(e,t,r){if(!r.found||!r.node)return null;let n={target:{kind:"selector",selector:t},node:r.node,selectorChain:[t]};return"attrs"===e?{kind:"attrs",...n}:"string"!=typeof r.text?null:{kind:"text",...n,text:r.text}}(t,s.raw,o);return i?(W(e.sessionStore,e.sessionName,e.req,j(i,t)),{ok:!0,data:z(i)}):null}async function eD(e,t,r,n){var s,o,i,a,l;let c;if("hidden"===t)return null;let u=await eC(e,r);if(e$(u))return u.response;if(!u?.result.found||!u.result.node)return null;let d="exists"===t?{predicate:t,pass:!0,selector:u.selector.raw,matches:1,selectorChain:[u.selector.raw]}:(s=t,o=n,i=u.selector.raw,a=u.session,c=w({predicate:s,node:l=u.result.node,nodes:[l],expectedText:o,platform:a.device.platform}),{predicate:s,pass:c.pass,selector:i,..."text"===s?{text:c.actualText}:{},selectorChain:[i]});return d?(W(e.sessionStore,e.sessionName,e.req,d),{ok:!0,data:Q(d)}):null}async function eE(e){let t=ec({session:e.session,selectorExpression:e.selectorExpression});if(!e.session||!t)return null;let r=Date.now(),n=await eO(e,e.session,t);if(e$(n))return n.response;if(!n?.found)return null;let s={kind:"selector",selector:t.raw,waitedMs:Date.now()-r,selectorChain:[t.raw]};return W(e.sessionStore,e.sessionName,e.req,s),await et({req:e.req,logPath:e.logPath,session:e.session,device:e.device},{ok:!0,data:s})}async function eC(e,t){let r=e.sessionStore.get(e.sessionName),n=ec({session:r,selectorExpression:t});if(!r||!n)return null;let s=await eO(e,r,n);return e$(s)?s:s?{session:r,selector:n,result:s}:null}async function eM(e,t,r){let n=await s(t.device,{command:"querySelector",selectorKey:r.key,selectorValue:r.value,appBundleId:t.appBundleId},{verbose:!!e.req.flags?.verbose,logPath:e.logPath,traceLogPath:t.trace?.outPath,requestId:e.req.meta?.requestId,iosXctestrunFile:e.req.flags?.iosXctestrunFile,iosXctestDerivedDataPath:e.req.flags?.iosXctestDerivedDataPath,iosXctestEnvDir:e.req.flags?.iosXctestEnvDir}),o=!0===n.found,i=function(e){let t=e.nodes;if(!Array.isArray(t))return;let r=t[0];if(r&&"object"==typeof r)return r}(n);return{found:o,..."string"==typeof n.text?{text:n.text}:{},...i?{node:i}:{}}}async function eO(e,t,r){try{return await eM(e,t,r)}catch(e){if(eu(e,{allowElementNotFound:!0}))return null;return{kind:"error",response:{ok:!1,error:h(e)}}}}function e$(e){return null!==e&&"kind"in e&&"error"===e.kind}async function eF(e){try{return{ok:!0,data:await e()}}catch(t){let e=g(t);return i(e.code,e.message,e.details)}}async function eK(e,t,r){var n;let s;if(t.ok)return t;let o=e.sessionStore.get(e.sessionName);if(!o)return t;try{s=await H(o)}catch{return t}return s?i(t.error.code,`${r} failed because ${"com.google.android.permissioncontroller"===(n=s).foregroundPackage?`Android permission dialog is blocking ${n.expectedPackage}`:`${n.foregroundPackage} is foreground instead of ${n.expectedPackage}`}.`,{...t.error.details??{},...s,blockedBy:"android_foreground_surface",originalMessage:t.error.message}):t}export{B as assertAndroidPressStayedInApp,U as buildSnapshotSession,T as createDaemonRuntimePolicy,ef as createSelectorCaptureRuntime,eN as dispatchFindReadOnlyViaRuntime,eA as dispatchGetViaRuntime,eR as dispatchIsViaRuntime,eb as dispatchWaitViaRuntime,X as isAndroidEscapeError,eu as isDirectIosSelectorFallbackError,ec as readSimpleIosSelectorTarget,ed as readTextForNode,L as recordIfSession,V as refSnapshotFlagGuardResponse,$ as resolveSessionDevice,F as withSessionlessRunnerCleanup};
|