agent-device 0.16.14 → 0.17.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.
Files changed (46) hide show
  1. package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.16.14.apk → agent-device-android-multitouch-helper-0.17.0.apk} +0 -0
  2. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.17.0.apk.sha256 +1 -0
  3. package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.16.14.manifest.json → agent-device-android-multitouch-helper-0.17.0.manifest.json} +4 -4
  4. package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.16.14.apk → agent-device-android-snapshot-helper-0.17.0.apk} +0 -0
  5. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.17.0.apk.sha256 +1 -0
  6. package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.16.14.manifest.json → agent-device-android-snapshot-helper-0.17.0.manifest.json} +6 -6
  7. package/dist/src/1352.js +1 -1
  8. package/dist/src/221.js +4 -4
  9. package/dist/src/2415.js +29 -29
  10. package/dist/src/2805.js +1 -1
  11. package/dist/src/6232.js +1 -1
  12. package/dist/src/7599.js +4 -3
  13. package/dist/src/8020.js +1 -0
  14. package/dist/src/8699.js +1 -1
  15. package/dist/src/940.js +1 -1
  16. package/dist/src/9533.js +1 -1
  17. package/dist/src/android-snapshot-helper.d.ts +1 -0
  18. package/dist/src/apple.js +1 -1
  19. package/dist/src/args.js +14 -9
  20. package/dist/src/cli.js +9 -9
  21. package/dist/src/command-metadata.js +1 -1
  22. package/dist/src/contracts.d.ts +1 -0
  23. package/dist/src/find.js +1 -1
  24. package/dist/src/finders.d.ts +1 -0
  25. package/dist/src/generic.js +9 -9
  26. package/dist/src/index.d.ts +19 -1
  27. package/dist/src/selectors.d.ts +1 -0
  28. package/dist/src/session.js +11 -11
  29. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.h +4 -0
  30. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.m +71 -0
  31. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Alert.swift +41 -7
  32. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +154 -11
  33. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +11 -0
  34. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Exceptions.swift +12 -4
  35. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +26 -0
  36. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +8 -0
  37. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +7 -1
  38. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +571 -56
  39. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Transport.swift +21 -0
  40. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TvRemote.swift +11 -0
  41. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +13 -2
  42. package/ios-runner/README.md +13 -0
  43. package/package.json +1 -1
  44. package/server.json +2 -2
  45. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.16.14.apk.sha256 +0 -1
  46. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.16.14.apk.sha256 +0 -1
package/dist/src/find.js CHANGED
@@ -1 +1 @@
1
- import{context_contextFromFlags as t,setSessionSnapshot as e,captureSnapshot as r,dispatchCommand as n,errorResponse as o,ensureDeviceReady as a,getActiveAndroidSnapshotFreshness as i,resolveTargetDevice as s,stripInternalInteractionFlags as l}from"./2415.js";import{findBestMatchesByLocator as c,parseFindArgs as f}from"./7556.js";import{dispatchFindReadOnlyViaRuntime as u,readTextForNode as d}from"./selector-runtime.js";import{centerOfRect as p}from"./4057.js";import{resolveActionableTouchResolution as _,resolveActionableTouchNode as g}from"./9533.js";import{sleep as m}from"./4829.js";import{extractNodeText as h}from"./940.js";async function A(t){var n,d;let{req:m,sessionName:A,logPath:R,sessionStore:K,invoke:F}=t,P=m.command;if("find"!==P)return null;let E=m.positionals??[];if(0===E.length)return o("INVALID_ARGS","find requires a locator or text");let{locator:U,query:v,action:L,value:H,timeoutMs:O}=f(E);if(!v)return o("INVALID_ARGS","find requires a value");if(m.flags?.findFirst&&m.flags?.findLast)return o("INVALID_ARGS","find accepts only one of --first or --last");let b=await u({req:m,sessionName:A,logPath:R,sessionStore:K});if(b)return b;let $=K.get(A),q="exists"===(n=L)||"wait"===n||"get_text"===n||"get_attrs"===n;if(!$&&!q)return o("SESSION_NOT_FOUND","No active session. Run open first.");let G=$?.device??await s(m.flags??{});$||await a(G);let B="click"===(d=L)||"focus"===d||"fill"===d||"type"===d,V="role"===U||B?void 0:v,T=0,j=null,z=async()=>{let t=Date.now();if(j&&t-T<750&&!i($))return{nodes:j};let{snapshot:n}=await r({device:G,session:$,flags:{...m.flags,snapshotInteractiveOnly:B,snapshotCompact:B},outPath:m.flags?.out,logPath:R,snapshotScope:V}),o=n.nodes;return T=t,j=o,$&&(e($,n),K.set(A,$)),{nodes:o,truncated:n.truncated,backend:n.backend}},J={req:m,sessionName:A,logPath:R,sessionStore:K,invoke:F,session:$,device:G,command:P,locator:U,query:v,publicFlags:{...l(m.flags)??{}}};if("wait"===L)return S(J,z,U,v,O);let{nodes:Q}=await z(),W=function(t){let{nodes:e,locator:r,query:n,requiresRect:a,flags:i}=t,s=c(e,r,n,{requireRect:a});if(a&&(s.matches=function(t,e){var r,n;let o=e[0]?.rect;if(!o)return t;let a=t.filter(t=>{if(!t.rect)return!1;let e=p(t.rect);return e.x>=o.x&&e.x<=o.x+o.width&&e.y>=o.y&&e.y<=o.y+o.height});return r=a.length>0?a:t,n=e,r.length<2?r:r.map((t,e)=>{var r,o;let a;return{node:t,index:e,score:(r=t,"semantic-target"===(a=_(o=n,r)).reason&&a.node.rect||"same-rect-descendant"===a.reason&&a.node.rect?4:"hittable-ancestor"===a.reason&&a.node.rect&&!y(a.node,o[0])?2:r.hittable&&r.rect&&!y(r,o[0])?3:+!!r.rect)}}).sort((t,e)=>e.score!==t.score?e.score-t.score:w(t.node)-w(e.node)||t.index-e.index).map(t=>t.node)}(s.matches,e)),a&&s.matches.length>1)if(i?.findFirst)s.matches=[s.matches[0]];else{if(!i?.findLast){var l,f,u;let t;return{ok:!1,response:(l=s.matches,f=r,u=n,t=l.slice(0,8).map(t=>{let e=h(t)||t.label||t.identifier||t.type||"";return`@${t.ref}${e?`(${e})`:""}`}),o("AMBIGUOUS_MATCH",`find matched ${l.length} elements for ${f} "${u}". Use a more specific locator or selector.`,{locator:f,query:u,matches:l.length,candidates:t}))}}s.matches=[s.matches[s.matches.length-1]]}let d=s.matches[0]??null;return d?{ok:!0,node:d}:{ok:!1,response:o("COMMAND_FAILED","find did not match any element")}}({nodes:Q,locator:U,query:v,requiresRect:B,flags:m.flags});if(!W.ok)return W.response;let X=W.node,Y=B?g(Q,X):X,Z=`@${Y.ref}`,tt={node:X,resolvedNode:Y,ref:Z,nodes:Q,actionFlags:{...m.flags??{},noRecord:!0}},te={exists:()=>k(J),get_text:()=>C(J,tt),get_attrs:()=>x(J,tt),click:()=>N(J,tt),fill:()=>I(J,tt,H),focus:()=>M(J,tt),type:()=>D(J,tt,H)}[L];return te?te():null}function w(t){return t.rect?t.rect.width*t.rect.height:1/0}function y(t,e){if(!e?.rect||!t.rect)return!1;let r=t.type?.toLowerCase()??"";return(!!r.includes("application")||!!r.includes("window"))&&t.rect.x===e.rect.x&&t.rect.y===e.rect.y&&t.rect.width===e.rect.width&&t.rect.height===e.rect.height}async function S(t,e,r,n,a){let{req:i,sessionStore:s,session:l,command:f,publicFlags:u}=t,d=a??1e4,p=Date.now();for(;Date.now()-p<d;){let{nodes:t}=await e();if(c(t,r,n,{requireRect:!1}).matches[0])return l&&s.recordAction(l,{command:f,positionals:i.positionals??[],flags:u,result:{found:!0,waitedMs:Date.now()-p}}),{ok:!0,data:{found:!0,waitedMs:Date.now()-p}};await m(300)}return o("COMMAND_FAILED","find wait timed out")}async function k(t){let{req:e,sessionStore:r,session:n,command:o,publicFlags:a}=t;return n&&r.recordAction(n,{command:o,positionals:e.positionals??[],flags:a,result:{found:!0}}),{ok:!0,data:{found:!0}}}async function C(e,r){let{req:n,sessionStore:o,session:a,command:i,device:s,logPath:l,publicFlags:c}=e,f=await d({device:s,node:r.node,flags:n.flags,appBundleId:a?.appBundleId,traceOutPath:a?.trace?.outPath,surface:a?.surface,contextFromFlags:(e,r,n)=>t(l,e,r,n)});return a&&o.recordAction(a,{command:i,positionals:n.positionals??[],flags:c,result:{ref:r.ref,action:"get text",text:f}}),{ok:!0,data:{ref:r.ref,text:f,node:r.node}}}async function x(t,e){let{req:r,sessionStore:n,session:o,command:a,publicFlags:i}=t;return o&&n.recordAction(o,{command:a,positionals:r.positionals??[],flags:i,result:{ref:e.ref,action:"get attrs"}}),{ok:!0,data:{ref:e.ref,node:e.node}}}async function N(t,e){let{req:r,sessionName:n,sessionStore:o,session:a,invoke:i,command:s,locator:l,query:c,publicFlags:f}=t,u=await i({token:r.token,session:n,command:"click",positionals:[e.ref],flags:e.actionFlags});if(!u.ok)return u;let d=e.resolvedNode.rect?p(e.resolvedNode.rect):e.node.rect?p(e.node.rect):null,_={ref:e.ref,locator:l,query:c};return d&&(_.x=d.x,_.y=d.y),a&&o.recordAction(a,{command:s,positionals:r.positionals??[],flags:f,result:{ref:e.ref,action:"click",locator:l,query:c}}),{ok:!0,data:_}}async function I(t,e,r){let{req:n,sessionName:a,sessionStore:i,session:s,invoke:l,command:c,publicFlags:f}=t;if(!r)return o("INVALID_ARGS","find fill requires text");let u=await l({token:n.token,session:a,command:"fill",positionals:[e.ref,r],flags:e.actionFlags});return u.ok&&s&&i.recordAction(s,{command:c,positionals:n.positionals??[],flags:f,result:{ref:e.ref,action:"fill"}}),u}async function M(t,e){let r=await R(t,e);return r.ok&&K(t,e,"focus"),r}async function D(e,r,a){let{req:i,device:s,logPath:l,session:c}=e;if(!a)return o("INVALID_ARGS","find type requires text");let f=await R(e,r);if(!f.ok)return f;let u=await n(s,"type",[a],i.flags?.out,{...t(l,i.flags,c?.appBundleId,c?.trace?.outPath)});return K(e,r,"type"),{ok:!0,data:u??{ref:r.ref}}}async function R(e,r){let{req:a,device:i,logPath:s,session:l}=e,c=r.node.rect?p(r.node.rect):null;return c?{ok:!0,data:await n(i,"focus",[String(c.x),String(c.y)],a.flags?.out,{...t(s,a.flags,l?.appBundleId,l?.trace?.outPath)})??{ref:r.ref}}:o("COMMAND_FAILED","matched element has no bounds")}function K(t,e,r){let{req:n,sessionStore:o,session:a,command:i,publicFlags:s}=t;a&&o.recordAction(a,{command:i,positionals:n.positionals??[],flags:s,result:{ref:e.ref,action:r}})}export{parseFindArgs}from"./7556.js";export{A as handleFindCommands};
1
+ import{context_contextFromFlags as e,setSessionSnapshot as t,captureSnapshot as r,dispatchCommand as n,errorResponse as o,ensureDeviceReady as a,getActiveAndroidSnapshotFreshness as i,resolveTargetDevice as s,stripInternalInteractionFlags as l}from"./2415.js";import{findBestMatchesByLocator as c,parseFindArgs as f}from"./7556.js";import{dispatchFindReadOnlyViaRuntime as d,readTextForNode as u}from"./selector-runtime.js";import{centerOfRect as p}from"./4057.js";import{resolveActionableTouchResolution as _,resolveActionableTouchNode as g,isSnapshotNodeInteractionBlocked as h}from"./9533.js";import{sleep as m}from"./4829.js";import{extractNodeText as A}from"./940.js";async function y(e){var n,u;let{req:h,sessionName:m,logPath:y,sessionStore:R,invoke:K}=e,F=h.command;if("find"!==F)return null;let E=h.positionals??[];if(0===E.length)return o("INVALID_ARGS","find requires a locator or text");let{locator:P,query:U,action:b,value:L,timeoutMs:O}=f(E);if(!U)return o("INVALID_ARGS","find requires a value");if(h.flags?.findFirst&&h.flags?.findLast)return o("INVALID_ARGS","find accepts only one of --first or --last");let H=await d({req:h,sessionName:m,logPath:y,sessionStore:R});if(H)return H;let $=R.get(m),B="exists"===(n=b)||"wait"===n||"get_text"===n||"get_attrs"===n;if(!$&&!B)return o("SESSION_NOT_FOUND","No active session. Run open first.");let q=$?.device??await s(h.flags??{});$||await a(q);let G="click"===(u=b)||"focus"===u||"fill"===u||"type"===u,V="role"===P||G?void 0:U,T=0,j=null,z=async()=>{let e=Date.now();if(j&&e-T<750&&!i($))return{nodes:j};let{snapshot:n}=await r({device:q,session:$,flags:{...h.flags,snapshotInteractiveOnly:G,snapshotCompact:G},outPath:h.flags?.out,logPath:y,snapshotScope:V}),o=n.nodes;return T=e,j=o,$&&(t($,n),R.set(m,$)),{nodes:o,truncated:n.truncated,backend:n.backend}},J={req:h,sessionName:m,logPath:y,sessionStore:R,invoke:K,session:$,device:q,command:F,locator:P,query:U,publicFlags:{...l(h.flags)??{}}};if("wait"===b)return k(J,z,P,U,O);let{nodes:Q}=await z(),W=function(e){let{nodes:t,locator:r,query:n,requiresRect:a,flags:i}=e,s=c(t,r,n,{requireRect:a});if(a&&(s.matches=function(e,t){var r,n;let o=t[0]?.rect;if(!o)return e;let a=e.filter(e=>{if(!e.rect)return!1;let t=p(e.rect);return t.x>=o.x&&t.x<=o.x+o.width&&t.y>=o.y&&t.y<=o.y+o.height});return r=a.length>0?a:e,n=t,r.length<2?r:r.map((e,t)=>{var r,o;let a;return{node:e,index:t,score:(r=e,"covered"===(a=_(o=n,r)).reason?0:"semantic-target"===a.reason&&a.node.rect||"same-rect-descendant"===a.reason&&a.node.rect?4:"hittable-ancestor"===a.reason&&a.node.rect&&!S(a.node,o[0])?2:r.hittable&&r.rect&&!S(r,o[0])?3:+!!r.rect)}}).sort((e,t)=>t.score!==e.score?t.score-e.score:w(e.node)-w(t.node)||e.index-t.index).map(e=>e.node)}(s.matches,t)),a&&s.matches.length>1)if(i?.findFirst)s.matches=[s.matches[0]];else{if(!i?.findLast){var l,f,d;let e;return{ok:!1,response:(l=s.matches,f=r,d=n,e=l.slice(0,8).map(e=>{let t=A(e)||e.label||e.identifier||e.type||"";return`@${e.ref}${t?`(${t})`:""}`}),o("AMBIGUOUS_MATCH",`find matched ${l.length} elements for ${f} "${d}". Use a more specific locator or selector.`,{locator:f,query:d,matches:l.length,candidates:e}))}}s.matches=[s.matches[s.matches.length-1]]}let u=s.matches[0]??null;return u?{ok:!0,node:u}:{ok:!1,response:o("COMMAND_FAILED","find did not match any element")}}({nodes:Q,locator:P,query:U,requiresRect:G,flags:h.flags});if(!W.ok)return W.response;let X=W.node,Y=G?g(Q,X):X,Z=`@${Y.ref}`,ee={node:X,resolvedNode:Y,ref:Z,nodes:Q,actionFlags:{...h.flags??{},noRecord:!0}},et={exists:()=>N(J),get_text:()=>C(J,ee),get_attrs:()=>x(J,ee),click:()=>I(J,ee),fill:()=>M(J,ee,L),focus:()=>v(J,ee),type:()=>D(J,ee,L)}[b];return et?et():null}function w(e){return e.rect?e.rect.width*e.rect.height:1/0}function S(e,t){if(!t?.rect||!e.rect)return!1;let r=e.type?.toLowerCase()??"";return(!!r.includes("application")||!!r.includes("window"))&&e.rect.x===t.rect.x&&e.rect.y===t.rect.y&&e.rect.width===t.rect.width&&e.rect.height===t.rect.height}async function k(e,t,r,n,a){let{req:i,sessionStore:s,session:l,command:f,publicFlags:d}=e,u=a??1e4,p=Date.now();for(;Date.now()-p<u;){let{nodes:e}=await t();if(c(e,r,n,{requireRect:!1}).matches[0])return l&&s.recordAction(l,{command:f,positionals:i.positionals??[],flags:d,result:{found:!0,waitedMs:Date.now()-p}}),{ok:!0,data:{found:!0,waitedMs:Date.now()-p}};await m(300)}return o("COMMAND_FAILED","find wait timed out")}async function N(e){let{req:t,sessionStore:r,session:n,command:o,publicFlags:a}=e;return n&&r.recordAction(n,{command:o,positionals:t.positionals??[],flags:a,result:{found:!0}}),{ok:!0,data:{found:!0}}}async function C(t,r){let{req:n,sessionStore:o,session:a,command:i,device:s,logPath:l,publicFlags:c}=t,f=await u({device:s,node:r.node,flags:n.flags,appBundleId:a?.appBundleId,traceOutPath:a?.trace?.outPath,surface:a?.surface,contextFromFlags:(t,r,n)=>e(l,t,r,n)});return a&&o.recordAction(a,{command:i,positionals:n.positionals??[],flags:c,result:{ref:r.ref,action:"get text",text:f}}),{ok:!0,data:{ref:r.ref,text:f,node:r.node}}}async function x(e,t){let{req:r,sessionStore:n,session:o,command:a,publicFlags:i}=e;return o&&n.recordAction(o,{command:a,positionals:r.positionals??[],flags:i,result:{ref:t.ref,action:"get attrs"}}),{ok:!0,data:{ref:t.ref,node:t.node}}}async function I(e,t){let{req:r,sessionName:n,sessionStore:o,session:a,invoke:i,command:s,locator:l,query:c,publicFlags:f}=e,d=await i({token:r.token,session:n,command:"click",positionals:[t.ref],flags:t.actionFlags});if(!d.ok)return d;let u=t.resolvedNode.rect?p(t.resolvedNode.rect):t.node.rect?p(t.node.rect):null,_={ref:t.ref,locator:l,query:c};return u&&(_.x=u.x,_.y=u.y),a&&o.recordAction(a,{command:s,positionals:r.positionals??[],flags:f,result:{ref:t.ref,action:"click",locator:l,query:c}}),{ok:!0,data:_}}async function M(e,t,r){let{req:n,sessionName:a,sessionStore:i,session:s,invoke:l,command:c,publicFlags:f}=e;if(!r)return o("INVALID_ARGS","find fill requires text");let d=await l({token:n.token,session:a,command:"fill",positionals:[t.ref,r],flags:t.actionFlags});return d.ok&&s&&i.recordAction(s,{command:c,positionals:n.positionals??[],flags:f,result:{ref:t.ref,action:"fill"}}),d}async function v(e,t){let r=await R(e,t);return r.ok&&K(e,t,"focus"),r}async function D(t,r,a){let{req:i,device:s,logPath:l,session:c}=t;if(!a)return o("INVALID_ARGS","find type requires text");let f=await R(t,r);if(!f.ok)return f;let d=await n(s,"type",[a],i.flags?.out,{...e(l,i.flags,c?.appBundleId,c?.trace?.outPath)});return K(t,r,"type"),{ok:!0,data:d??{ref:r.ref}}}async function R(t,r){var a;let i,{req:s,device:l,logPath:c,session:f}=t,d=(i=[(a=r).resolvedNode,a.node].find(h))?o("COMMAND_FAILED",`Matched element ${a.ref} is covered by another visible element and cannot be focused safely`,{ref:`@${i.ref}`,interactionBlocked:i.interactionBlocked,hint:"Use a different visible target, scroll it clear of the overlay, or inspect with snapshot/screenshot before retrying."}):null;if(d)return d;let u=r.resolvedNode.rect?p(r.resolvedNode.rect):null;return u?{ok:!0,data:await n(l,"focus",[String(u.x),String(u.y)],s.flags?.out,{...e(c,s.flags,f?.appBundleId,f?.trace?.outPath)})??{ref:r.ref}}:o("COMMAND_FAILED","matched element has no bounds")}function K(e,t,r){let{req:n,sessionStore:o,session:a,command:i,publicFlags:s}=e;a&&o.recordAction(a,{command:i,positionals:n.positionals??[],flags:s,result:{ref:t.ref,action:r}})}export{parseFindArgs}from"./7556.js";export{y as handleFindCommands};
@@ -65,6 +65,7 @@ declare type RawSnapshotNode = {
65
65
  surface?: string;
66
66
  hiddenContentAbove?: boolean;
67
67
  hiddenContentBelow?: boolean;
68
+ interactionBlocked?: 'covered';
68
69
  presentationHints?: string[];
69
70
  };
70
71
 
@@ -1,13 +1,13 @@
1
- import t from"node:fs";import e from"node:path";import{AppError as r}from"./9152.js";import{runCliCommandWithOutput as s,printJson as i,writeCommandOutput as n}from"./cli.js";import{formatDurationSeconds as o}from"./9238.js";import{readCommandMessage as a}from"./1998.js";function u(t){var r,s;let i,n,o=t.attempts>1?` after ${t.attempts} attempts`:"",a=y(t);for(let u of(process.stdout.write(`FAIL ${(i=h(r=t),n=e.basename(r.file),i&&i.length>0?`${JSON.stringify(i)} in ${n}`:n)}${o}${a}
1
+ import t from"node:fs";import e from"node:path";import{AppError as r}from"./9152.js";import{runCliCommandWithOutput as s,printJson as i,writeCommandOutput as n}from"./cli.js";import{formatDurationSeconds as o}from"./9238.js";import{readCommandMessage as a}from"./1998.js";function u(t){var r,s;let i,n,o,a=t.attempts>1?` after ${t.attempts} attempts`:"",u=y(t);for(let d of(process.stdout.write(`FAIL ${(i=g(r=t),n=e.basename(r.file),o=i&&i.length>0?`${JSON.stringify(i)} in ${n}`:n,`${o}${M(r)}`)}${a}${u}
2
2
  `),process.stdout.write(` ${t.error?.message??"Unknown test failure"}
3
- `),s=t,[s.error?.hint?`hint: ${s.error.hint}`:"",s.artifactsDir?`artifacts: ${s.artifactsDir}`:"",s.error?.logPath?`log: ${s.error.logPath}`:"",s.error?.diagnosticId?`diagnostic: ${s.error.diagnosticId}`:""].filter(Boolean)))process.stdout.write(` ${u}
4
- `);for(let e of l(t))process.stdout.write(` ${e}
5
- `)}function l(r){var s,i,n;if("skipped"===r.status)return[];let a=(s=r).artifactsDir?e.join(s.artifactsDir,`attempt-${s.attempts}`,"replay-timing.ndjson"):void 0;if(!a)return[];let u=function(e){try{return t.readFileSync(e,"utf8").split(/\r?\n/).filter(t=>t.trim().length>0).flatMap(t=>{try{let e=JSON.parse(t);return m(e)?[e]:[]}catch{return[]}})}catch{return[]}}(a);if(0===u.length)return[];let l=[],$=[];for(let t of u){if("replay_action_start"===(i=t).type&&f(i)&&p(i,"line")&&d(i,"command")&&(void 0===i.positionals||Array.isArray(i.positionals))){l.push(t);continue}"replay_action_stop"===(n=t).type&&f(n)&&p(n,"line")&&d(n,"command")&&(void 0===n.ok||"boolean"==typeof n.ok)&&p(n,"durationMs")&&d(n,"errorCode")&&(void 0===n.resultTiming||m(n.resultTiming))&&$.push({stop:t,start:function(t,e){let r=e.command,s=t.findIndex(t=>t.step===e.step&&(void 0===r||void 0===t.command||t.command===r));if(!(s<0))return t.splice(s,1)[0]}(l,t)})}return 0===$.length?[]:[r.attempts>1?`steps (attempt ${r.attempts}):`:"steps:",...$.map(({stop:t,start:e})=>{var r,s,i,n,a,u;let l,f,p;return r=t,s=e,l=!1===r.ok?"[FAIL] ":!0===r.ok?"":"[info] ",` ${l}${i=s,n=r,[function(t){if(!t)return"unknown";if(!t.startsWith("__maestro"))return t;let e=t.slice(9);return e.length>0?e[0].toLowerCase()+e.slice(1):t}(i?.command??n.command),...(i?.positionals??[]).map(c)].join(" ")}${a=r,u=s,(p=["number"==typeof(f=u?.line??a.line)?`line ${f}`:"","number"==typeof a.durationMs?o(a.durationMs):"",a.errorCode??"",a.resultTiming?`timing ${JSON.stringify(a.resultTiming)}`:""].filter(Boolean)).length>0?` (${p.join(", ")})`:""}`})]}function f(t){return"number"==typeof t.step}function p(t,e){return void 0===t[e]||"number"==typeof t[e]}function d(t,e){return void 0===t[e]||"string"==typeof t[e]}function c(t){return"string"==typeof t?JSON.stringify(t):"number"==typeof t||"boolean"==typeof t?String(t):JSON.stringify(t)}function m(t){return!!t&&"object"==typeof t&&!Array.isArray(t)}function $(t){return"passed"===t.status&&t.attempts>1}function g(t){let r=h(t);return r&&r.length>0?JSON.stringify(r):e.basename(t.file)}function h(t){let e=t.title?.trim();return e&&e.length>0?e:void 0}function y(t){if("passed"===t.status&&t.attempts>1)return v(t);if("failed"===t.status&&t.attempts>1&&t.durationMs>0)return` (total ${o(t.durationMs)})`;let e="passed"===t.status&&"number"==typeof t.finalAttemptDurationMs?t.finalAttemptDurationMs:t.durationMs;return e>0?` (${o(e)})`:""}function v(t){let e=["number"==typeof t.finalAttemptDurationMs?`passed attempt ${o(t.finalAttemptDurationMs)}`:"",t.durationMs>0?`total ${o(t.durationMs)}`:""].filter(Boolean);return e.length>0?` (${e.join(", ")})`:""}function M(t,e,r={}){r.includeMessage&&t.push(`errorMessage: ${e.message}`),e.hint&&t.push(`hint: ${e.hint}`),e.diagnosticId&&t.push(`diagnosticId: ${e.diagnosticId}`),e.logPath&&t.push(`logPath: ${e.logPath}`),!1!==r.includeDetails&&S(t,e,r.detailsIndent)}function S(t,e,r){let s=e.details?JSON.stringify(e.details,null,r):void 0;s&&t.push(`details: ${s}`)}function _(t,e){e&&t.push(e)}function A(t){return(Math.max(0,t)/1e3).toFixed(3)}function w(t){return t.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;").replaceAll("'","&apos;")}async function D({command:f,positionals:p,flags:d,client:c}){var m,k,b,j,C;"test"===f&&(({json:d.json}).json||process.stderr.write("Running replay suite...\n"));let{result:N,cliOutput:P}=await s({client:c,command:f,positionals:p,flags:d});if(P){m=d,k=P,!m.json&&k.stderr&&process.stderr.write(k.stderr),n(m,m.json?k.jsonData??k.data:k.data,()=>k.text)}else{let s=(b=f,j=d,C=N,"test"===b?function(s){let{suite:n,json:a,verbose:f,reportJunit:p}=s;return(p&&function(s,i){let n=e.dirname(s);try{t.mkdirSync(n,{recursive:!0}),t.writeFileSync(s,function(t){let r=['<?xml version="1.0" encoding="UTF-8"?>',"<testsuites>",` <testsuite name="agent-device replay suite" tests="${t.total}" failures="${t.failed}" skipped="${t.skipped}" time="${A(t.durationMs)}">`];for(let s of t.tests)r.push(...function(t){let r=w(h(t)??e.basename(t.file)),s=w("."===e.dirname(t.file)?t.file:e.dirname(t.file)),i=w(t.file),n=A(t.durationMs),o=[` <testcase classname="${s}" name="${r}" file="${i}" time="${n}">`];"failed"===t.status?o.push(` <failure message="${w(t.error.message)}">${w(function(t){let e=[t.error.message];return M(e,t.error,{includeDetails:!1}),t.artifactsDir&&e.push(`artifactsDir: ${t.artifactsDir}`),S(e,t.error,2),e.join("\n")}(t))}</failure>`):"skipped"===t.status&&o.push(` <skipped message="${w(t.message)}" />`);let a=function(t){let e=[`status: ${t.status}`,`durationMs: ${t.durationMs}`];return function(t,e){var r,s;_(t,"attempts"in e?`attempts: ${e.attempts}`:void 0),_(t,"session"in e?`session: ${e.session}`:void 0),_(t,"replayed"in e?`replayed: ${e.replayed}`:void 0),_(t,"healed"in e?`healed: ${e.healed}`:void 0),_(t,"artifactsDir"in e&&e.artifactsDir?`artifactsDir: ${e.artifactsDir}`:void 0),"failed"===e.status&&(r=t,s=e,r.push(`errorCode: ${s.error.code}`),M(r,s.error,{includeMessage:!0})),_(t,$(e)?"flaky: true":void 0)}(e,t),e.join("\n")}(t);return a&&o.push(` <system-out>${w(a)}</system-out>`),o.push(" </testcase>"),o}(s));return r.push(" </testsuite>"),r.push("</testsuites>"),`${r.join("\n")}
6
- `}(i),"utf8")}catch(e){let t=e instanceof Error?e.message:String(e);throw new r("COMMAND_FAILED",`Failed to write JUnit report to ${s}: ${t}`)}}(p,n),a)?(i({success:!0,data:n}),+(n.failed>0)):function(t,e={}){let r=t.tests.filter($);if(e.verbose)for(let e of t.tests)!function(t){var e;if("failed"===t.status)return u(t);let r=y(t);for(let s of(process.stdout.write(`${"passed"===(e=t).status?"PASS":"skipped"===e.status?"SKIP":"INFO"} ${g(t)}${r}
3
+ `),s=t,[s.error?.hint?`hint: ${s.error.hint}`:"",s.artifactsDir?`artifacts: ${s.artifactsDir}`:"",s.error?.logPath?`log: ${s.error.logPath}`:"",s.error?.diagnosticId?`diagnostic: ${s.error.diagnosticId}`:""].filter(Boolean)))process.stdout.write(` ${d}
4
+ `);for(let e of d(t))process.stdout.write(` ${e}
5
+ `)}function d(r){var s,i,n;if("skipped"===r.status)return[];let a=(s=r).artifactsDir?e.join(s.artifactsDir,`attempt-${s.attempts}`,"replay-timing.ndjson"):void 0;if(!a)return[];let u=function(e){try{return t.readFileSync(e,"utf8").split(/\r?\n/).filter(t=>t.trim().length>0).flatMap(t=>{try{let e=JSON.parse(t);return m(e)?[e]:[]}catch{return[]}})}catch{return[]}}(a);if(0===u.length)return[];let d=[],$=[];for(let t of u){if("replay_action_start"===(i=t).type&&l(i)&&f(i,"line")&&p(i,"command")&&(void 0===i.positionals||Array.isArray(i.positionals))){d.push(t);continue}"replay_action_stop"===(n=t).type&&l(n)&&f(n,"line")&&p(n,"command")&&(void 0===n.ok||"boolean"==typeof n.ok)&&f(n,"durationMs")&&p(n,"errorCode")&&(void 0===n.resultTiming||m(n.resultTiming))&&$.push({stop:t,start:function(t,e){let r=e.command,s=t.findIndex(t=>t.step===e.step&&(void 0===r||void 0===t.command||t.command===r));if(!(s<0))return t.splice(s,1)[0]}(d,t)})}return 0===$.length?[]:[r.attempts>1?`steps (attempt ${r.attempts}):`:"steps:",...$.map(({stop:t,start:e})=>{var r,s,i,n,a,u;let d,l,f;return r=t,s=e,d=!1===r.ok?"[FAIL] ":!0===r.ok?"":"[info] ",` ${d}${i=s,n=r,[function(t){if(!t)return"unknown";if(!t.startsWith("__maestro"))return t;let e=t.slice(9);return e.length>0?e[0].toLowerCase()+e.slice(1):t}(i?.command??n.command),...(i?.positionals??[]).map(c)].join(" ")}${a=r,u=s,(f=["number"==typeof(l=u?.line??a.line)?`line ${l}`:"","number"==typeof a.durationMs?o(a.durationMs):"",a.errorCode??"",a.resultTiming?`timing ${JSON.stringify(a.resultTiming)}`:""].filter(Boolean)).length>0?` (${f.join(", ")})`:""}`})]}function l(t){return"number"==typeof t.step}function f(t,e){return void 0===t[e]||"number"==typeof t[e]}function p(t,e){return void 0===t[e]||"string"==typeof t[e]}function c(t){return"string"==typeof t?JSON.stringify(t):"number"==typeof t||"boolean"==typeof t?String(t):JSON.stringify(t)}function m(t){return!!t&&"object"==typeof t&&!Array.isArray(t)}function $(t){return"passed"===t.status&&t.attempts>1}function h(t){let r=g(t),s=r&&r.length>0?JSON.stringify(r):e.basename(t.file);return`${s}${M(t)}`}function g(t){let e=t.title?.trim();return e&&e.length>0?e:void 0}function y(t){if("passed"===t.status&&t.attempts>1)return v(t);if("failed"===t.status&&t.attempts>1&&t.durationMs>0)return` (total ${o(t.durationMs)})`;let e="passed"===t.status&&"number"==typeof t.finalAttemptDurationMs?t.finalAttemptDurationMs:t.durationMs;return e>0?` (${o(e)})`:""}function v(t){let e=["number"==typeof t.finalAttemptDurationMs?`passed attempt ${o(t.finalAttemptDurationMs)}`:"",t.durationMs>0?`total ${o(t.durationMs)}`:""].filter(Boolean);return e.length>0?` (${e.join(", ")})`:""}function M(t){if(!("shardIndex"in t)||"number"!=typeof t.shardIndex)return"";let e="number"==typeof t.shardCount?t.shardCount:"?",r="string"==typeof t.deviceId?` ${t.deviceId}`:"";return` [shard ${t.shardIndex+1}/${e}${r}]`}function S(t,e,r={}){r.includeMessage&&t.push(`errorMessage: ${e.message}`),e.hint&&t.push(`hint: ${e.hint}`),e.diagnosticId&&t.push(`diagnosticId: ${e.diagnosticId}`),e.logPath&&t.push(`logPath: ${e.logPath}`),!1!==r.includeDetails&&_(t,e,r.detailsIndent)}function _(t,e,r){let s=e.details?JSON.stringify(e.details,null,r):void 0;s&&t.push(`details: ${s}`)}function A(t,e){e&&t.push(e)}function I(t){return(Math.max(0,t)/1e3).toFixed(3)}function b(t){return t.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;").replaceAll("'","&apos;")}async function w({command:l,positionals:f,flags:p,client:c}){var m,C,D,k,j;"test"===l&&(({json:p.json}).json||process.stderr.write("Running replay suite...\n"));let{result:x,cliOutput:N}=await s({client:c,command:l,positionals:f,flags:p});if(N){m=p,C=N,!m.json&&C.stderr&&process.stderr.write(C.stderr),n(m,m.json?C.jsonData??C.data:C.data,()=>C.text)}else{let s=(D=l,k=p,j=x,"test"===D?function(s){let{suite:n,json:a,verbose:l,reportJunit:f}=s;return(f&&function(s,i){let n=e.dirname(s);try{t.mkdirSync(n,{recursive:!0}),t.writeFileSync(s,function(t){let r=['<?xml version="1.0" encoding="UTF-8"?>',"<testsuites>",` <testsuite name="agent-device replay suite" tests="${t.total}" failures="${t.failed}" skipped="${t.skipped}" time="${I(t.durationMs)}">`];for(let s of t.tests)r.push(...function(t){let r=b(`${g(t)??e.basename(t.file)}${M(t)}`),s=b(`${"."===e.dirname(t.file)?t.file:e.dirname(t.file)}${M(t)}`),i=b(t.file),n=I(t.durationMs),o=[` <testcase classname="${s}" name="${r}" file="${i}" time="${n}">`];"failed"===t.status?o.push(` <failure message="${b(t.error.message)}">${b(function(t){let e=[t.error.message];return S(e,t.error,{includeDetails:!1}),t.artifactsDir&&e.push(`artifactsDir: ${t.artifactsDir}`),_(e,t.error,2),e.join("\n")}(t))}</failure>`):"skipped"===t.status&&o.push(` <skipped message="${b(t.message)}" />`);let a=function(t){let e=[`status: ${t.status}`,`durationMs: ${t.durationMs}`];return function(t,e){var r,s,i,n;A(t,"attempts"in e?`attempts: ${e.attempts}`:void 0),A(t,"session"in e?`session: ${e.session}`:void 0),A(t,"replayed"in e?`replayed: ${e.replayed}`:void 0),A(t,"healed"in e?`healed: ${e.healed}`:void 0),A(t,"artifactsDir"in e&&e.artifactsDir?`artifactsDir: ${e.artifactsDir}`:void 0),r=t,s=e,"shardIndex"in s&&"number"==typeof s.shardIndex&&(r.push(`shardIndex: ${s.shardIndex}`),A(r,"number"==typeof s.shardCount?`shardCount: ${s.shardCount}`:void 0),A(r,"string"==typeof s.deviceId?`deviceId: ${s.deviceId}`:void 0)),"failed"===e.status&&(i=t,n=e,i.push(`errorCode: ${n.error.code}`),S(i,n.error,{includeMessage:!0})),A(t,$(e)?"flaky: true":void 0)}(e,t),e.join("\n")}(t);return a&&o.push(` <system-out>${b(a)}</system-out>`),o.push(" </testcase>"),o}(s));return r.push(" </testsuite>"),r.push("</testsuites>"),`${r.join("\n")}
6
+ `}(i),"utf8")}catch(e){let t=e instanceof Error?e.message:String(e);throw new r("COMMAND_FAILED",`Failed to write JUnit report to ${s}: ${t}`)}}(f,n),a)?(i({success:!0,data:n}),+(n.failed>0)):function(t,e={}){let r=t.tests.filter($);if(e.verbose)for(let e of t.tests)!function(t){var e;if("failed"===t.status)return u(t);let r=y(t);for(let s of(process.stdout.write(`${"passed"===(e=t).status?"PASS":"skipped"===e.status?"SKIP":"INFO"} ${h(t)}${r}
7
7
  `),"skipped"===t.status&&process.stdout.write(` ${t.message??"skipped"}
8
- `),l(t)))process.stdout.write(` ${s}
9
- `)}(e);else for(let e of t.tests){var s;"failed"===(s=e).status?u(s):"passed"===s.status&&process.stdout.write(`PASS ${g(s)}${y(s)}
8
+ `),d(t)))process.stdout.write(` ${s}
9
+ `)}(e);else for(let e of t.tests){var s;"failed"===(s=e).status?u(s):"passed"===s.status&&process.stdout.write(`PASS ${h(s)}${y(s)}
10
10
  `)}let i="number"==typeof t.durationMs?t.durationMs:void 0,n=r.length>0?`, ${r.length} flaky`:"",a=void 0!==i?` in ${o(i)}`:"";return process.stdout.write(`Test summary: ${t.passed} passed, ${t.failed} failed${n}${a}
11
- `),function(t){if(0!==t.length)for(let e of(process.stdout.write("Flaky tests:\n"),t))for(let t of(process.stdout.write(` PASS ${g(e)} after ${e.attempts} attempts${v(e)}
11
+ `),function(t){if(0!==t.length)for(let e of(process.stdout.write("Flaky tests:\n"),t))for(let t of(process.stdout.write(` PASS ${h(e)} after ${e.attempts} attempts${v(e)}
12
12
  `),e.attemptFailures??[])){let e="number"==typeof t.durationMs?` (${o(t.durationMs)})`:"";process.stdout.write(` attempt ${t.attempt} failed${e}: ${t.message}
13
- `)}}(r),+(t.failed>0)}(n,{verbose:f})}({suite:C,verbose:j.verbose,json:j.json,reportJunit:j.reportJunit}):(n(j,C,()=>a(C)),0));0!==s&&process.exit(s)}return!0}export{D as runGenericClientBackedCommand};
13
+ `)}}(r),+(t.failed>0)}(n,{verbose:l})}({suite:j,verbose:k.verbose,json:k.json,reportJunit:k.reportJunit}):(n(k,j,()=>a(j)),0));0!==s&&process.exit(s)}return!0}export{w as runGenericClientBackedCommand};
@@ -157,6 +157,8 @@ export declare type AgentDeviceSelectionOptions = {
157
157
  export declare type AgentDeviceSession = {
158
158
  name: string;
159
159
  createdAt: number;
160
+ sessionStateDir?: string;
161
+ runnerLogPath?: string;
160
162
  device: AgentDeviceSessionDevice;
161
163
  identifiers: AgentDeviceIdentifiers;
162
164
  };
@@ -314,6 +316,8 @@ export declare type AppOpenOptions = AgentDeviceRequestOverrides & AgentDeviceSe
314
316
  export declare type AppOpenResult = {
315
317
  session: string;
316
318
  sessionStateDir?: string;
319
+ runnerLogPath?: string;
320
+ requestLogPath?: string;
317
321
  appName?: string;
318
322
  appBundleId?: string;
319
323
  appId?: string;
@@ -829,7 +833,18 @@ declare type PanOptions = ClientCommandBaseOptions & {
829
833
  durationMs?: number;
830
834
  };
831
835
 
832
- export declare type PerfOptions = ClientCommandBaseOptions;
836
+ declare const PERF_ACTION_VALUES: readonly ["sample"];
837
+
838
+ declare const PERF_AREA_VALUES: readonly ["metrics", "frames"];
839
+
840
+ declare type PerfAction = (typeof PERF_ACTION_VALUES)[number];
841
+
842
+ declare type PerfArea = (typeof PERF_AREA_VALUES)[number];
843
+
844
+ export declare type PerfOptions = ClientCommandBaseOptions & {
845
+ area?: PerfArea;
846
+ action?: PerfAction;
847
+ };
833
848
 
834
849
  export declare type PermissionTarget = 'camera' | 'microphone' | 'photos' | 'contacts' | 'contacts-limited' | 'notifications' | 'calendar' | 'location' | 'location-always' | 'media-library' | 'motion' | 'reminders' | 'siri' | 'accessibility' | 'screen-recording' | 'input-monitoring';
835
850
 
@@ -902,6 +917,7 @@ declare type RawSnapshotNode = {
902
917
  surface?: string;
903
918
  hiddenContentAbove?: boolean;
904
919
  hiddenContentBelow?: boolean;
920
+ interactionBlocked?: 'covered';
905
921
  presentationHints?: string[];
906
922
  };
907
923
 
@@ -971,6 +987,8 @@ export declare type ReplayTestOptions = AgentDeviceRequestOverrides & AgentDevic
971
987
  retries?: number;
972
988
  artifactsDir?: string;
973
989
  reportJunit?: string;
990
+ shardAll?: number;
991
+ shardSplit?: number;
974
992
  };
975
993
 
976
994
  export declare type ReservedOutputFile = {
@@ -47,6 +47,7 @@ declare type RawSnapshotNode = {
47
47
  surface?: string;
48
48
  hiddenContentAbove?: boolean;
49
49
  hiddenContentBelow?: boolean;
50
+ interactionBlocked?: 'covered';
50
51
  presentationHints?: string[];
51
52
  };
52
53