agent-device 0.18.1 → 0.18.2
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/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.18.1.apk → agent-device-android-multitouch-helper-0.18.2.apk} +0 -0
- package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.18.2.apk.sha256 +1 -0
- package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.18.1.manifest.json → agent-device-android-multitouch-helper-0.18.2.manifest.json} +4 -4
- package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.18.1.apk → agent-device-android-snapshot-helper-0.18.2.apk} +0 -0
- package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.18.2.apk.sha256 +1 -0
- package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.18.1.manifest.json → agent-device-android-snapshot-helper-0.18.2.manifest.json} +6 -6
- package/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +2 -1
- package/dist/src/1986.js +1 -1
- package/dist/src/2948.js +16 -16
- package/dist/src/3340.js +8 -8
- package/dist/src/4428.js +3 -3
- package/dist/src/495.js +5 -5
- package/dist/src/6849.js +1 -1
- package/dist/src/7871.js +1 -1
- package/dist/src/8184.js +1 -1
- package/dist/src/8414.js +2 -2
- package/dist/src/8875.js +4 -1
- package/dist/src/9624.js +1 -1
- package/dist/src/9722.js +36 -36
- package/dist/src/android.js +1 -1
- package/dist/src/apps.js +9 -9
- package/dist/src/audio-probe.js +1 -1
- package/dist/src/batch.d.ts +1 -1
- package/dist/src/cli-help.js +9 -7
- package/dist/src/cli.js +23 -23
- package/dist/src/contracts.d.ts +1 -1
- package/dist/src/devices.js +1 -1
- package/dist/src/devices~1.js +1 -1
- package/dist/src/index.d.ts +42 -15
- package/dist/src/input-actions.js +1 -1
- package/dist/src/interaction.js +1 -1
- package/dist/src/interactor.js +1 -1
- package/dist/src/internal/bin.js +1 -1
- package/dist/src/linux.js +1 -1
- package/dist/src/record-trace-recording.js +3 -3
- package/dist/src/remote-config.d.ts +1 -1
- package/dist/src/selector-runtime.js +1 -1
- package/dist/src/selectors.d.ts +8 -4
- package/dist/src/session.js +11 -11
- package/dist/src/simulator.js +2 -2
- package/dist/src/snapshot.js +2 -2
- package/dist/src/web.js +1 -1
- package/package.json +1 -1
- package/server.json +2 -2
- package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.18.1.apk.sha256 +0 -1
- package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.18.1.apk.sha256 +0 -1
- package/dist/src/432.js +0 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
import{setSessionSnapshot as e,createDaemonRuntimeSessionStore as t,context_contextFromFlags as r,captureSnapshot as n,dispatchCommand as s,requireCommandSupported as o,stopIosRunnerSession as i,errorResponse as a,resolveRunnerAppBundleId as l,getActiveAndroidSnapshotFreshness as c,noActiveSessionError as u,resolveTargetDevice as f,runAppleRunnerCommand as d}from"./9722.js";import{closeIosApp as p}from"./apps.js";import{emitDiagnostic as m}from"./432.js";import{ensureDeviceReady as g,buildAppleRunnerRequestOptions as h}from"./8414.js";import{asAppError as y,normalizeError as w,AppError as S}from"./485.js";import{evaluateIsPredicate as _,isSupportedPredicate as v,localCommandPolicy as x,createAgentDevice as k}from"./7871.js";import{getAndroidAppState as I}from"./3340.js";import{splitIsSelectorArgs as A,normalizeType as P,prefersValueForReadableText as N,findNodeByLabel as R,extractNodeReadText as b}from"./893.js";import{resolveRectCenter as q,isSparseSnapshotQualityVerdict as C,parseWaitPositionals as M}from"./2948.js";import{buildSnapshotPresentationKey as E,snapshotPresentationOptionsFromFlags as D,isApplePlatform as $}from"./6849.js";import{parseFindArgs as L,tryParseSelectorChain as O}from"./587.js";async function K(e,t,r){let n=e.get(t),s=n?.device??await f(r??{});return n||await g(s),{session:n,device:s}}async function F(e,t,r){let n=!e&&"ios"===t.platform;try{return await r()}finally{n&&(await i(t.id),await G(t))}}async function G(e){let t=l();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 V(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 S("UNSUPPORTED_OPERATION",`${e} ${r} not resolve input artifacts`)},reserveOutput:async()=>{throw new S("UNSUPPORTED_OPERATION",`${e} ${r} not reserve output artifacts`)},createTempFile:async()=>{throw new S("UNSUPPORTED_OPERATION",`${e} ${r} not create temporary files`)}}}(e,t),policy:x()}}let B=[["snapshotDepth","--depth"],["snapshotScope","--scope"],["snapshotRaw","--raw"]];function H(e,t){let r=function(e){if(!e)return[];let t=[];for(let[r,n]of B)void 0!==e[r]&&t.push(n);return t}(t);return 0===r.length?null:a("INVALID_ARGS",`${e} @ref does not support ${r.join(", ")}.`)}async function j(e,t){let r=await z(e);if(r)throw new S("COMMAND_FAILED",`press ${t} left ${e.appBundleId} and foregrounded ${r.foregroundPackage}. The tap likely escaped the app.`,r)}async function z(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 Q(e){return"COMMAND_FAILED"===e.code&&"string"==typeof e.details?.expectedPackage&&"string"==typeof e.details?.foregroundPackage}function W(e,t){let r=Array.isArray(e.selectorChain)?e.selectorChain:void 0,n=Z(e),s=n?.kind==="ref"?ee(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 J(e){let t=Z(e);return{...t?.kind==="ref"?{ref:ee(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 X(e){let{selectorChain:t,...r}=e;return r}function Y(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 Z(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 ee(e){return e.startsWith("@")?e.slice(1):e}let et=["application","window","tabbar","scrollbar","image"],er=new Set(["tab bar"]);async function en(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 es(e).catch(()=>null);return n?a(t.error.code,`${t.error.message}. Current surface: ${n.summary}.`,{...t.error.details??{},currentSurface:n.details}):t}async function es(e){let t=[...(await n({device:e.device,session:e.session,flags:{...e.req.flags,snapshotInteractiveOnly:!0},logPath:e.logPath??""})).snapshot.nodes].sort(ei),r=eo(t,6,{includeIdentifiers:!0});if(0===r.length)return null;let s=eo(t.filter(e=>!ec(e)),4,{includeIdentifiers:!1}),o=eo(t.filter(eu),4,{includeIdentifiers:!0});return{summary:(s.length>0?s:r.slice(0,4)).join(", "),details:{labels:r,...o.length>0?{buttons:o}:{}}}}function eo(e,t,r){let n=new Set,s=[];for(let o of e){let e=el(o,r);if(!(!e||n.has(e))&&(n.add(e),s.push(e),s.length>=t))break}return s}function ei(e,t){var r,n;return ea(e)-ea(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 ea(e){let t=!!el(e,{includeIdentifiers:!1});return 2*!!ec(e)+ +!t}function el(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 ec(e){let t=P(`${e.type??""} ${e.role??""} ${e.subrole??""}`),r=`${e.label??""} ${e.value??""}`.trim().toLowerCase();return et.some(e=>t.includes(e))||er.has(r)||r.endsWith(".fill")}function eu(e){return P(`${e.type??""} ${e.role??""} ${e.subrole??""}`).includes("button")}function ef(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 ed(e,t={}){let r=y(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 ep(e){let{device:t,node:r,flags:n,appBundleId:o,traceOutPath:i,surface:a,contextFromFlags:l}=e,c=b(r),u=q(r.rect);if(!u||"ios"===t.platform&&c&&!N(r.type??""))return c;try{let e=await s(t,"read",[String(u.x),String(u.y)],void 0,{...l(n,o,i),surface:a}),f=e&&"object"==typeof e?e:void 0,d="string"==typeof f?.text?f.text:"";if(d.trim())return d;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 em(t){let r,n,{session:s,sessionStore:o,sessionName:i}=t,a=0;return{capture:async l=>{var u,f;let d=Date.now(),p=(u=l,f=t.req.flags?.out,JSON.stringify({presentationKey:E(D(e_(u))),includeRects:!0===u.includeRects,outPath:u.outPath??f??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))&&!eS(o,i))return n}({timestamp:d,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)||eS(t,r)))&&s-i.createdAt<750&&i.presentationKey===function(e){return E(D(e_(e)))}(o))return i}({session:s,timestamp:d,request:l});if(g)return a=g.createdAt,r={snapshot:g},n=p,r;let h=await eg({params:t,request:l}),y={snapshot:h};return function(t){let{session:r,sessionStore:n,sessionName:s,snapshot:o}=t;!r||C(o.snapshotQuality)||(e(r,o),n.set(s,r))}({session:s,sessionStore:o,sessionName:i,snapshot:h}),a=d,r=y,n=p,y}}}async function eg(e){var t;let{params:r,request:n}=e,s=await ew(r,n,n.snapshotScope);return n.recovery?.legacyIosSparse&&!(t=s).snapshotQuality&&"xctest"===t.backend&&1===t.nodes.length&&t.nodes[0]?.type==="Application"?await eh({runtimeParams:r,request:n,policy:n.recovery.legacyIosSparse}):n.recovery?.sparseVerdictQueryScope?.shouldScope&&C(s.snapshotQuality)?await ey({runtimeParams:r,request:n,policy:n.recovery.sparseVerdictQueryScope,snapshot:s}):s}async function eh(e){let{runtimeParams:t,request:r,policy:n}=e;try{return await ew(t,r,n.scope,!1)}catch(e){if(!n.shouldScope)throw e;return await ew(t,r,n.query,!1)}}async function ey(e){let{runtimeParams:t,request:r,policy:n,snapshot:s}=e;try{return await ew(t,r,n.query,!1)}catch{return s}}async function ew(e,t,r,s=t.flags?.snapshotInteractiveOnly){return(await n({device:e.device,session:e.session,flags:{...t.flags,snapshotInteractiveOnly:s},outPath:t.outPath??e.req.flags?.out,logPath:e.logPath??"",snapshotScope:r,includeRects:t.includeRects})).snapshot}function eS(e,t){return t.cache?.bypassForPostGestureStabilization===!0&&!!e?.postGestureStabilization}function e_(e){return void 0===e.snapshotScope?e.flags:{...e.flags,snapshotScope:e.snapshotScope}}function ev(n){return k({backend:function(e){let{req:t,session:n,device:s,logPath:o,sessionName:i,sessionStore:a}=e,l=em({device:s,session:n,sessionStore:a,sessionName:i,req:t,logPath:o});return{platform:s.platform,captureSnapshot:async(e,r)=>{var n;let o,i={...t.flags,...(n=r,o={},n?.interactiveOnly!==void 0&&(o.snapshotInteractiveOnly=n.interactiveOnly),n?.scope!==void 0&&(o.snapshotScope=n.scope),n?.depth!==void 0&&(o.snapshotDepth=n.depth),n?.raw!==void 0&&(o.snapshotRaw=n.raw),o)},a=r?.includeRects===!0,c=r?.scope??t.flags?.snapshotScope,u="wait"===t.command||"find"===t.command||a&&"web"===s.platform;return await l.capture({flags:i,snapshotScope:c,includeRects:a,cache:{forceFresh:u,useSessionSnapshot:!0,bypassForPostGestureStabilization:!0}})},readText:async(i,a)=>({text:await ep({device:s,node:a,flags:t.flags,appBundleId:n?.appBundleId,traceOutPath:n?.trace?.outPath,surface:n?.surface,contextFromFlags:e.contextFromFlags??((e,t,n)=>r(o??"",e,t,n))})}),findText:async(t,r)=>({found:await ek(e,r)})}}(n),...T("selector commands",{plural:!0}),sessions:t({sessionName:n.sessionName,getSession:()=>n.session,recordOptions:{includeSnapshot:!0},setRecord:t=>{n.session&&t.snapshot&&(e(n.session,t.snapshot),n.sessionStore.set(n.sessionName,n.session))}})})}async function ex(e,t){let r=e.sessionStore.get(e.sessionName);if(!r&&t.requireSession)return{ok:!1,response:u()};let n=r?.device??await f(e.req.flags??{});r||await g(n);let s=o(t.capability,n);return s?{ok:!1,response:s}:{ok:!0,runtime:ev({...e,session:r,device:n})}}async function ek(e,t){let r=await eI(e,t);if(null!==r)return r;let n=await eA(e,t);return null!==n?n:await eP(e,t)}async function eI(e,t){return"macos"===e.device.platform&&e.session?.surface&&"app"!==e.session.surface?await eP(e,t):null}async function eA(e,t){var r,n,s;let o=$((r=e).device.platform)&&r.session?.appBundleId?{device:r.device,appBundleId:r.session.appBundleId,traceLogPath:r.session.trace?.outPath}:null;if(!o)return null;let i=await d(o.device,{command:"findText",text:t,appBundleId:o.appBundleId},(n=e,s=o,h({req:n.req,logPath:n.logPath,traceLogPath:s.traceLogPath})));return i?.found===!0}async function eP(e,t){return!!R((await eN(e)).nodes,t)}async function eN(e){let t=em({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 eR(e){var t;let{req:r}=e;if("find"!==r.command)return null;let n=r.positionals??[];if(0===n.length)return a("INVALID_ARGS","find requires a locator or text");let s=L(n);if(!s.query)return a("INVALID_ARGS","find requires a value");if(r.flags?.findFirst&&r.flags?.findLast)return a("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 i=await ex(e,{requireSession:!1,capability:"find"});return i.ok?await eF(async()=>{let t=await i.runtime.selectors.find({session:e.sessionName,requestId:r.meta?.requestId,locator:s.locator,query:s.query,action:o,timeoutMs:s.timeoutMs});return Y(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}:{}}}):i.response}async function eb(e){let{req:t}=e;if("get"!==t.command)return null;let r=t.positionals?.[0];if("text"!==r&&"attrs"!==r)return a("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:a("INVALID_ARGS","get requires @ref or selector expression")}}(t);if(!n.ok)return n.response;if("ref"===n.target.kind){let e=H("get",t.flags);if(e)return e}if("selector"===n.target.kind){let t=await eM(e,r,n.target.selector);if(t)return t}let s=await ex(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 Y(e.sessionStore,e.sessionName,t,W(o,r)),J(o)}):s.response}async function eq(e){let{req:t}=e;if("is"!==t.command)return null;let r=(t.positionals?.[0]??"").toLowerCase();if(!v(r))return a("INVALID_ARGS","is requires predicate: visible|hidden|exists|editable|selected|text");let{split:n}=A(t.positionals??[]);if(!n)return a("INVALID_ARGS","is requires a selector expression");let s=n.rest.join(" ").trim();if("text"===r&&!s)return a("INVALID_ARGS","is text requires expected text value");if("text"!==r&&n.rest.length>0)return a("INVALID_ARGS",`is ${r} does not accept trailing values`);let o=await eE(e,r,n.selectorExpression,s);if(o)return o;let i=await ex(e,{requireSession:!0,capability:"is"});if(!i.ok)return i.response;let l=await eF(async()=>{let o=await i.runtime.selectors.is({session:e.sessionName,requestId:t.meta?.requestId,predicate:r,selector:n.selectorExpression,expectedText:s});return Y(e.sessionStore,e.sessionName,t,o),X(o)});return await eG(e,l,`is ${r}`)}async function eC(e){let{req:t,sessionName:r,sessionStore:n}=e,s=M(t.positionals??[]);if(!s)return a("INVALID_ARGS","wait requires a duration or text");let{session:i,device:l}=await K(n,r,t.flags);if("sleep"!==s.kind){let e=o("wait",l);if(e)return e}if("selector"===s.kind){let t=await eD({...e,session:i,device:l,selectorExpression:s.selectorExpression,timeoutMs:s.timeoutMs});if(t)return t}let c=async()=>{let o=ev({...e,session:i,device:l}),a=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 S("INVALID_ARGS","Ref wait requires an existing snapshot in session.");return{kind:"ref",ref:e.rawRef,timeoutMs:e.timeoutMs}}if(!e.text)throw new S("INVALID_ARGS","wait requires text");return{kind:"text",text:e.text,timeoutMs:e.timeoutMs}}(s,i)});return Y(n,r,t,e),{waitedMs:e.waitedMs,..."string"==typeof e.text?{text:e.text}:{},..."string"==typeof e.selector?{selector:e.selector}:{}}}),c=await en({req:t,logPath:e.logPath,session:i,device:l},a);return await eG(e,c,"wait")};return"sleep"===s.kind?await c():await F(i,l,c)}async function eM(e,t,r){let n=e.sessionStore.get(e.sessionName),s=ef({session:n,selectorExpression:r});if(!n||!s||"text"===t&&"id"!==s.key)return null;let o=await eO(e,n,s);if(eK(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?(Y(e.sessionStore,e.sessionName,e.req,W(i,t)),{ok:!0,data:J(i)}):null}async function eE(e,t,r,n){var s,o,i,a,l;let c;if("hidden"===t)return null;let u=await e$(e,r);if(eK(u))return u.response;if(!u?.result.found||!u.result.node)return null;let f="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=_({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 f?(Y(e.sessionStore,e.sessionName,e.req,f),{ok:!0,data:X(f)}):null}async function eD(e){let t=ef({session:e.session,selectorExpression:e.selectorExpression});if(!e.session||!t)return null;let r=Date.now(),n=await eO(e,e.session,t);if(eK(n))return n.response;if(!n?.found)return null;let s={kind:"selector",selector:t.raw,waitedMs:Date.now()-r,selectorChain:[t.raw]};return Y(e.sessionStore,e.sessionName,e.req,s),await en({req:e.req,logPath:e.logPath,session:e.session,device:e.device},{ok:!0,data:s})}async function e$(e,t){let r=e.sessionStore.get(e.sessionName),n=ef({session:r,selectorExpression:t});if(!r||!n)return null;let s=await eO(e,r,n);return eK(s)?s:s?{session:r,selector:n,result:s}:null}async function eL(e,t,r){let n=await d(t.device,{command:"querySelector",selectorKey:r.key,selectorValue:r.value,appBundleId:t.appBundleId},h({req:e.req,logPath:e.logPath,traceLogPath:t.trace?.outPath})),s=!0===n.found,o=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:s,..."string"==typeof n.text?{text:n.text}:{},...o?{node:o}:{}}}async function eO(e,t,r){try{return await eL(e,t,r)}catch(e){if(ed(e,{allowElementNotFound:!0}))return null;return{kind:"error",response:{ok:!1,error:w(e)}}}}function eK(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=y(t);return a(e.code,e.message,e.details)}}async function eG(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 z(o)}catch{return t}return s?a(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{j as assertAndroidPressStayedInApp,U as buildSnapshotSession,T as createDaemonRuntimePolicy,em as createSelectorCaptureRuntime,eR as dispatchFindReadOnlyViaRuntime,eb as dispatchGetViaRuntime,eq as dispatchIsViaRuntime,eC as dispatchWaitViaRuntime,Q as isAndroidEscapeError,ed as isDirectIosSelectorFallbackError,ef as readSimpleIosSelectorTarget,ep as readTextForNode,V as recordIfSession,H as refSnapshotFlagGuardResponse,K as resolveSessionDevice,F as withSessionlessRunnerCleanup};
|
|
1
|
+
import{snapshotPresentationOptionsFromFlags as e,isMacOs as t,isApplePlatform as r,publicPlatformString as n,isIosFamily as s,buildSnapshotPresentationKey as o}from"./6849.js";import{setSessionSnapshot as i,createDaemonRuntimeSessionStore as a,context_contextFromFlags as l,captureSnapshot as c,dispatchCommand as u,requireCommandSupported as d,stopIosRunnerSession as f,errorResponse as p,resolveRunnerAppBundleId as m,getActiveAndroidSnapshotFreshness as g,noActiveSessionError as h,resolveTargetDevice as y,runAppleRunnerCommand as w}from"./9722.js";import{closeIosApp as S}from"./apps.js";import{emitDiagnostic as _}from"./8875.js";import{ensureDeviceReady as v,buildAppleRunnerRequestOptions as x}from"./8414.js";import{asAppError as k,normalizeError as I,AppError as A}from"./485.js";import{evaluateIsPredicate as P,isSupportedPredicate as N,localCommandPolicy as R,createAgentDevice as b}from"./7871.js";import{getAndroidAppState as q}from"./3340.js";import{splitIsSelectorArgs as C,normalizeType as M,prefersValueForReadableText as E,findNodeByLabel as D,extractNodeReadText as $}from"./893.js";import{resolveRectCenter as L,isSparseSnapshotQualityVerdict as O,parseWaitPositionals as K}from"./2948.js";import{parseFindArgs as F,tryParseSelectorChain as G}from"./587.js";async function V(e,t,r){let n=e.get(t),s=n?.device??await y(r??{});return n||await v(s),{session:n,device:s}}async function U(e,t,r){let n=!e&&s(t);try{return await r()}finally{n&&(await f(t.id),await T(t))}}async function T(e){let t=m();await S(e,t).catch(r=>{_({level:"debug",phase:"ios_sessionless_runner_host_close_failed",data:{deviceId:e.id,bundleId:t,error:r instanceof Error?r.message:String(r)}})})}function B(e,t,r,n){t&&e.recordAction(t,{command:r.command,positionals:r.positionals??[],flags:r.flags??{},result:n})}function H(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 j(e,t={}){return{artifacts:function(e,t={}){let r=!0===t.plural?"do":"does";return{resolveInput:async()=>{throw new A("UNSUPPORTED_OPERATION",`${e} ${r} not resolve input artifacts`)},reserveOutput:async()=>{throw new A("UNSUPPORTED_OPERATION",`${e} ${r} not reserve output artifacts`)},createTempFile:async()=>{throw new A("UNSUPPORTED_OPERATION",`${e} ${r} not create temporary files`)}}}(e,t),policy:R()}}let z=[["snapshotDepth","--depth"],["snapshotScope","--scope"],["snapshotRaw","--raw"]];function Q(e,t){let r=function(e){if(!e)return[];let t=[];for(let[r,n]of z)void 0!==e[r]&&t.push(n);return t}(t);return 0===r.length?null:p("INVALID_ARGS",`${e} @ref does not support ${r.join(", ")}.`)}async function W(e,t){let r=await J(e);if(r)throw new A("COMMAND_FAILED",`press ${t} left ${e.appBundleId} and foregrounded ${r.foregroundPackage}. The tap likely escaped the app.`,r)}async function J(e){var t;if("android"!==e.device.platform||!e.appBundleId)return null;let r=await q(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 Y(e,t){let r=Array.isArray(e.selectorChain)?e.selectorChain:void 0,n=er(e),s=n?.kind==="ref"?en(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=er(e);return{...t?.kind==="ref"?{ref:en(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 ee(e){let{selectorChain:t,...r}=e;return r}function et(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 er(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 en(e){return e.startsWith("@")?e.slice(1):e}let es=["application","window","tabbar","scrollbar","image"],eo=new Set(["tab bar"]);async function ei(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 ea(e).catch(()=>null);return n?p(t.error.code,`${t.error.message}. Current surface: ${n.summary}.`,{...t.error.details??{},currentSurface:n.details}):t}async function ea(e){let t=[...(await c({device:e.device,session:e.session,flags:{...e.req.flags,snapshotInteractiveOnly:!0},logPath:e.logPath??""})).snapshot.nodes].sort(ec),r=el(t,6,{includeIdentifiers:!0});if(0===r.length)return null;let n=el(t.filter(e=>!ef(e)),4,{includeIdentifiers:!1}),s=el(t.filter(ep),4,{includeIdentifiers:!0});return{summary:(n.length>0?n:r.slice(0,4)).join(", "),details:{labels:r,...s.length>0?{buttons:s}:{}}}}function el(e,t,r){let n=new Set,s=[];for(let o of e){let e=ed(o,r);if(!(!e||n.has(e))&&(n.add(e),s.push(e),s.length>=t))break}return s}function ec(e,t){var r,n;return eu(e)-eu(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 eu(e){let t=!!ed(e,{includeIdentifiers:!1});return 2*!!ef(e)+ +!t}function ed(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 ef(e){let t=M(`${e.type??""} ${e.role??""} ${e.subrole??""}`),r=`${e.label??""} ${e.value??""}`.trim().toLowerCase();return es.some(e=>t.includes(e))||eo.has(r)||r.endsWith(".fill")}function ep(e){return M(`${e.type??""} ${e.role??""} ${e.subrole??""}`).includes("button")}function em(e){var t;let{session:r,selectorExpression:n}=e;if(!r||!s(r.device)||r.postGestureStabilization)return null;let o=G(n);if(!o||1!==o.selectors.length)return null;let i=o.selectors[0];if(!i||1!==i.terms.length)return null;let a=i.terms[0];return a&&"string"==typeof a.value&&("id"===(t=a.key)||"label"===t||"text"===t||"value"===t)?{key:a.key,value:a.value,raw:i.raw}:null}function eg(e,t={}){let r=k(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 eh(e){let{device:t,node:r,flags:n,appBundleId:o,traceOutPath:i,surface:a,contextFromFlags:l}=e,c=$(r),d=L(r.rect);if(!d||s(t)&&c&&!E(r.type??""))return c;try{let e=await u(t,"read",[String(d.x),String(d.y)],void 0,{...l(n,o,i),surface:a}),s=e&&"object"==typeof e?e:void 0,f="string"==typeof s?.text?s.text:"";if(f.trim())return f;return _({level:"warn",phase:"interaction_read_fallback",data:{reason:"empty_backend_text",nodeRef:r.ref,surface:a,platform:t.platform}}),c}catch(e){return _({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 ey(t){let r,n,{session:s,sessionStore:a,sessionName:l}=t,c=0;return{capture:async u=>{var d,f;let p=Date.now(),m=(d=u,f=t.req.flags?.out,JSON.stringify({presentationKey:o(e(ek(d))),includeRects:!0===d.includeRects,outPath:d.outPath??f??null})),h=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||g(o))&&!ex(o,i))return n}({timestamp:p,lastSnapshotAt:c,lastSnapshotResult:r,lastSnapshotCacheKey:n,session:s,request:u,cacheKey:m});if(h)return h;let y=function(t){var r,n;let{session:s,timestamp:i,request:a}=t,l=s?.snapshot;if(l&&(r=s,n=a,!(n.cache?.forceFresh===!0||n.cache?.useSessionSnapshot!==!0||g(r)||ex(r,n)))&&i-l.createdAt<750&&l.presentationKey===function(t){return o(e(ek(t)))}(a))return l}({session:s,timestamp:p,request:u});if(y)return c=y.createdAt,r={snapshot:y},n=m,r;let w=await ew({params:t,request:u}),S={snapshot:w};return function(e){let{session:t,sessionStore:r,sessionName:n,snapshot:s}=e;!t||O(s.snapshotQuality)||(i(t,s),r.set(n,t))}({session:s,sessionStore:a,sessionName:l,snapshot:w}),c=p,r=S,n=m,S}}}async function ew(e){var t;let{params:r,request:n}=e,s=await ev(r,n,n.snapshotScope);return n.recovery?.legacyIosSparse&&!(t=s).snapshotQuality&&"xctest"===t.backend&&1===t.nodes.length&&t.nodes[0]?.type==="Application"?await eS({runtimeParams:r,request:n,policy:n.recovery.legacyIosSparse}):n.recovery?.sparseVerdictQueryScope?.shouldScope&&O(s.snapshotQuality)?await e_({runtimeParams:r,request:n,policy:n.recovery.sparseVerdictQueryScope,snapshot:s}):s}async function eS(e){let{runtimeParams:t,request:r,policy:n}=e;try{return await ev(t,r,n.scope,!1)}catch(e){if(!n.shouldScope)throw e;return await ev(t,r,n.query,!1)}}async function e_(e){let{runtimeParams:t,request:r,policy:n,snapshot:s}=e;try{return await ev(t,r,n.query,!1)}catch{return s}}async function ev(e,t,r,n=t.flags?.snapshotInteractiveOnly){return(await c({device:e.device,session:e.session,flags:{...t.flags,snapshotInteractiveOnly:n},outPath:t.outPath??e.req.flags?.out,logPath:e.logPath??"",snapshotScope:r,includeRects:t.includeRects})).snapshot}function ex(e,t){return t.cache?.bypassForPostGestureStabilization===!0&&!!e?.postGestureStabilization}function ek(e){return void 0===e.snapshotScope?e.flags:{...e.flags,snapshotScope:e.snapshotScope}}function eI(e){return b({backend:function(e){let{req:t,session:r,device:s,logPath:o,sessionName:i,sessionStore:a}=e,c=ey({device:s,session:r,sessionStore:a,sessionName:i,req:t,logPath:o});return{platform:n(s),captureSnapshot:async(e,r)=>{var n;let o,i={...t.flags,...(n=r,o={},n?.interactiveOnly!==void 0&&(o.snapshotInteractiveOnly=n.interactiveOnly),n?.scope!==void 0&&(o.snapshotScope=n.scope),n?.depth!==void 0&&(o.snapshotDepth=n.depth),n?.raw!==void 0&&(o.snapshotRaw=n.raw),o)},a=r?.includeRects===!0,l=r?.scope??t.flags?.snapshotScope,u="wait"===t.command||"find"===t.command||a&&"web"===s.platform;return await c.capture({flags:i,snapshotScope:l,includeRects:a,cache:{forceFresh:u,useSessionSnapshot:!0,bypassForPostGestureStabilization:!0}})},readText:async(n,i)=>({text:await eh({device:s,node:i,flags:t.flags,appBundleId:r?.appBundleId,traceOutPath:r?.trace?.outPath,surface:r?.surface,contextFromFlags:e.contextFromFlags??((e,t,r)=>l(o??"",e,t,r))})}),findText:async(t,r)=>({found:await eP(e,r)})}}(e),...j("selector commands",{plural:!0}),sessions:a({sessionName:e.sessionName,getSession:()=>e.session,recordOptions:{includeSnapshot:!0},setRecord:t=>{e.session&&t.snapshot&&(i(e.session,t.snapshot),e.sessionStore.set(e.sessionName,e.session))}})})}async function eA(e,t){let r=e.sessionStore.get(e.sessionName);if(!r&&t.requireSession)return{ok:!1,response:h()};let n=r?.device??await y(e.req.flags??{});r||await v(n);let s=d(t.capability,n);return s?{ok:!1,response:s}:{ok:!0,runtime:eI({...e,session:r,device:n})}}async function eP(e,t){let r=await eN(e,t);if(null!==r)return r;let n=await eR(e,t);return null!==n?n:await eb(e,t)}async function eN(e,r){return t(e.device)&&e.session?.surface&&"app"!==e.session.surface?await eb(e,r):null}async function eR(e,t){var n,s,o;let i=r((n=e).device.platform)&&n.session?.appBundleId?{device:n.device,appBundleId:n.session.appBundleId,traceLogPath:n.session.trace?.outPath}:null;if(!i)return null;let a=await w(i.device,{command:"findText",text:t,appBundleId:i.appBundleId},(s=e,o=i,x({req:s.req,logPath:s.logPath,traceLogPath:o.traceLogPath})));return a?.found===!0}async function eb(e,t){return!!D((await eq(e)).nodes,t)}async function eq(e){let t=ey({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 eC(e){var t;let{req:r}=e;if("find"!==r.command)return null;let n=r.positionals??[];if(0===n.length)return p("INVALID_ARGS","find requires a locator or text");let s=F(n);if(!s.query)return p("INVALID_ARGS","find requires a value");if(r.flags?.findFirst&&r.flags?.findLast)return p("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 i=await eA(e,{requireSession:!1,capability:"find"});return i.ok?await eU(async()=>{let t=await i.runtime.selectors.find({session:e.sessionName,requestId:r.meta?.requestId,locator:s.locator,query:s.query,action:o,timeoutMs:s.timeoutMs});return et(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}:{}}}):i.response}async function eM(e){let{req:t}=e;if("get"!==t.command)return null;let r=t.positionals?.[0];if("text"!==r&&"attrs"!==r)return p("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:p("INVALID_ARGS","get requires @ref or selector expression")}}(t);if(!n.ok)return n.response;if("ref"===n.target.kind){let e=Q("get",t.flags);if(e)return e}if("selector"===n.target.kind){let t=await e$(e,r,n.target.selector);if(t)return t}let s=await eA(e,{requireSession:!0,capability:"get"});return s.ok?await eU(async()=>{let o=await s.runtime.selectors.get({session:e.sessionName,requestId:t.meta?.requestId,property:r,target:n.target});return et(e.sessionStore,e.sessionName,t,Y(o,r)),Z(o)}):s.response}async function eE(e){let{req:t}=e;if("is"!==t.command)return null;let r=(t.positionals?.[0]??"").toLowerCase();if(!N(r))return p("INVALID_ARGS","is requires predicate: visible|hidden|exists|editable|selected|text");let{split:n}=C(t.positionals??[]);if(!n)return p("INVALID_ARGS","is requires a selector expression");let s=n.rest.join(" ").trim();if("text"===r&&!s)return p("INVALID_ARGS","is text requires expected text value");if("text"!==r&&n.rest.length>0)return p("INVALID_ARGS",`is ${r} does not accept trailing values`);let o=await eL(e,r,n.selectorExpression,s);if(o)return o;let i=await eA(e,{requireSession:!0,capability:"is"});if(!i.ok)return i.response;let a=await eU(async()=>{let o=await i.runtime.selectors.is({session:e.sessionName,requestId:t.meta?.requestId,predicate:r,selector:n.selectorExpression,expectedText:s});return et(e.sessionStore,e.sessionName,t,o),ee(o)});return await eT(e,a,`is ${r}`)}async function eD(e){let{req:t,sessionName:r,sessionStore:n}=e,s=K(t.positionals??[]);if(!s)return p("INVALID_ARGS","wait requires a duration or text");let{session:o,device:i}=await V(n,r,t.flags);if("sleep"!==s.kind){let e=d("wait",i);if(e)return e}if("selector"===s.kind){let t=await eO({...e,session:o,device:i,selectorExpression:s.selectorExpression,timeoutMs:s.timeoutMs});if(t)return t}let a=async()=>{let a=eI({...e,session:o,device:i}),l=await eU(async()=>{let e=await a.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 A("INVALID_ARGS","Ref wait requires an existing snapshot in session.");return{kind:"ref",ref:e.rawRef,timeoutMs:e.timeoutMs}}if(!e.text)throw new A("INVALID_ARGS","wait requires text");return{kind:"text",text:e.text,timeoutMs:e.timeoutMs}}(s,o)});return et(n,r,t,e),{waitedMs:e.waitedMs,..."string"==typeof e.text?{text:e.text}:{},..."string"==typeof e.selector?{selector:e.selector}:{}}}),c=await ei({req:t,logPath:e.logPath,session:o,device:i},l);return await eT(e,c,"wait")};return"sleep"===s.kind?await a():await U(o,i,a)}async function e$(e,t,r){let n=e.sessionStore.get(e.sessionName),s=em({session:n,selectorExpression:r});if(!n||!s||"text"===t&&"id"!==s.key)return null;let o=await eG(e,n,s);if(eV(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?(et(e.sessionStore,e.sessionName,e.req,Y(i,t)),{ok:!0,data:Z(i)}):null}async function eL(e,t,r,n){var s,o,i,a,l;let c;if("hidden"===t)return null;let u=await eK(e,r);if(eV(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=P({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?(et(e.sessionStore,e.sessionName,e.req,d),{ok:!0,data:ee(d)}):null}async function eO(e){let t=em({session:e.session,selectorExpression:e.selectorExpression});if(!e.session||!t)return null;let r=Date.now(),n=await eG(e,e.session,t);if(eV(n))return n.response;if(!n?.found)return null;let s={kind:"selector",selector:t.raw,waitedMs:Date.now()-r,selectorChain:[t.raw]};return et(e.sessionStore,e.sessionName,e.req,s),await ei({req:e.req,logPath:e.logPath,session:e.session,device:e.device},{ok:!0,data:s})}async function eK(e,t){let r=e.sessionStore.get(e.sessionName),n=em({session:r,selectorExpression:t});if(!r||!n)return null;let s=await eG(e,r,n);return eV(s)?s:s?{session:r,selector:n,result:s}:null}async function eF(e,t,r){let n=await w(t.device,{command:"querySelector",selectorKey:r.key,selectorValue:r.value,appBundleId:t.appBundleId},x({req:e.req,logPath:e.logPath,traceLogPath:t.trace?.outPath})),s=!0===n.found,o=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:s,..."string"==typeof n.text?{text:n.text}:{},...o?{node:o}:{}}}async function eG(e,t,r){try{return await eF(e,t,r)}catch(e){if(eg(e,{allowElementNotFound:!0}))return null;return{kind:"error",response:{ok:!1,error:I(e)}}}}function eV(e){return null!==e&&"kind"in e&&"error"===e.kind}async function eU(e){try{return{ok:!0,data:await e()}}catch(t){let e=k(t);return p(e.code,e.message,e.details)}}async function eT(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 J(o)}catch{return t}return s?p(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{W as assertAndroidPressStayedInApp,H as buildSnapshotSession,j as createDaemonRuntimePolicy,ey as createSelectorCaptureRuntime,eC as dispatchFindReadOnlyViaRuntime,eM as dispatchGetViaRuntime,eE as dispatchIsViaRuntime,eD as dispatchWaitViaRuntime,X as isAndroidEscapeError,eg as isDirectIosSelectorFallbackError,em as readSimpleIosSelectorTarget,eh as readTextForNode,B as recordIfSession,Q as refSnapshotFlagGuardResponse,V as resolveSessionDevice,U as withSessionlessRunnerCleanup};
|
package/dist/src/selectors.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare function findSelectorChainMatch(nodes: SnapshotState['nodes'], chain: SelectorChain, options: {
|
|
2
|
-
platform: Platform;
|
|
2
|
+
platform: Platform | PublicPlatform;
|
|
3
3
|
requireRect?: boolean;
|
|
4
4
|
}): {
|
|
5
5
|
selectorIndex: number;
|
|
@@ -12,7 +12,7 @@ export declare function formatSelectorFailure(chain: SelectorChain, diagnostics:
|
|
|
12
12
|
unique?: boolean;
|
|
13
13
|
}): string;
|
|
14
14
|
|
|
15
|
-
export declare function isNodeEditable(node: SnapshotNode, platform: Platform): boolean;
|
|
15
|
+
export declare function isNodeEditable(node: SnapshotNode, platform: Platform | PublicPlatform): boolean;
|
|
16
16
|
|
|
17
17
|
export declare function isNodeVisible(node: SnapshotNode): boolean;
|
|
18
18
|
|
|
@@ -22,7 +22,11 @@ export declare function parseSelectorChain(expression: string): SelectorChain;
|
|
|
22
22
|
|
|
23
23
|
declare type Platform = (typeof PLATFORMS)[number];
|
|
24
24
|
|
|
25
|
-
declare const PLATFORMS: readonly ['
|
|
25
|
+
declare const PLATFORMS: readonly ['apple', 'android', 'linux', 'web'];
|
|
26
|
+
|
|
27
|
+
declare const PUBLIC_PLATFORMS: readonly ['ios', 'macos', 'android', 'linux', 'web'];
|
|
28
|
+
|
|
29
|
+
declare type PublicPlatform = (typeof PUBLIC_PLATFORMS)[number];
|
|
26
30
|
|
|
27
31
|
declare type RawSnapshotNode = {
|
|
28
32
|
index: number;
|
|
@@ -59,7 +63,7 @@ declare type Rect = {
|
|
|
59
63
|
};
|
|
60
64
|
|
|
61
65
|
export declare function resolveSelectorChain(nodes: SnapshotState['nodes'], chain: SelectorChain, options: {
|
|
62
|
-
platform: Platform;
|
|
66
|
+
platform: Platform | PublicPlatform;
|
|
63
67
|
requireRect?: boolean;
|
|
64
68
|
requireUnique?: boolean;
|
|
65
69
|
disambiguateAmbiguous?: boolean;
|