momentic 2.27.2 → 2.28.1

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/bin/cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="e7177dc2-f0a2-521c-9f12-ce6944a8112e")}catch(e){}}();
3
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="5eac6469-788b-5be3-9906-4739217289e9")}catch(e){}}();
4
4
  var nL=Object.defineProperty;var dt=(r,e)=>()=>(r&&(e=r(r=0)),e);var oL=(r,e)=>{for(var t in e)nL(r,t,{get:e[t],enumerable:!0})};var Mw,Iw=dt(()=>{"use strict";Mw=typeof globalThis=="object"?globalThis:global});var Pw=dt(()=>{"use strict";Iw()});var Ow=dt(()=>{"use strict";Pw()});var Zn,qg=dt(()=>{"use strict";Zn="1.9.0"});function ZH(r){var e=new Set([r]),t=new Set,n=r.match(Lw);if(!n)return function(){return!1};var o={major:+n[1],minor:+n[2],patch:+n[3],prerelease:n[4]};if(o.prerelease!=null)return function(c){return c===r};function i(s){return t.add(s),!1}function a(s){return e.add(s),!0}return function(c){if(e.has(c))return!0;if(t.has(c))return!1;var l=c.match(Lw);if(!l)return i(c);var u={major:+l[1],minor:+l[2],patch:+l[3],prerelease:l[4]};return u.prerelease!=null||o.major!==u.major?i(c):o.major===0?o.minor===u.minor&&o.patch<=u.patch?a(c):i(c):o.minor<=u.minor?a(c):i(c)}}var Lw,Nw,Dw=dt(()=>{"use strict";qg();Lw=/^(\d+)\.(\d+)\.(\d+)(-(.+))?$/;Nw=ZH(Zn)});function Ya(r,e,t,n){var o;n===void 0&&(n=!1);var i=Ol[Pl]=(o=Ol[Pl])!==null&&o!==void 0?o:{version:Zn};if(!n&&i[r]){var a=new Error("@opentelemetry/api: Attempted duplicate registration of API: "+r);return t.error(a.stack||a.message),!1}if(i.version!==Zn){var a=new Error("@opentelemetry/api: Registration of version v"+i.version+" for "+r+" does not match previously registered API v"+Zn);return t.error(a.stack||a.message),!1}return i[r]=e,t.debug("@opentelemetry/api: Registered a global for "+r+" v"+Zn+"."),!0}function eo(r){var e,t,n=(e=Ol[Pl])===null||e===void 0?void 0:e.version;if(!(!n||!Nw(n)))return(t=Ol[Pl])===null||t===void 0?void 0:t[r]}function Xa(r,e){e.debug("@opentelemetry/api: Unregistering a global for "+r+" v"+Zn+".");var t=Ol[Pl];t&&delete t[r]}var ez,Pl,Ol,Ll=dt(()=>{"use strict";Ow();qg();Dw();ez=Zn.split(".")[0],Pl=Symbol.for("opentelemetry.js.api."+ez),Ol=Mw});function Nl(r,e,t){var n=eo("diag");if(n)return t.unshift(e),n[r].apply(n,rz([],tz(t),!1))}var tz,rz,kw,Fw=dt(()=>{"use strict";Ll();tz=function(r,e){var t=typeof Symbol=="function"&&r[Symbol.iterator];if(!t)return r;var n=t.call(r),o,i=[],a;try{for(;(e===void 0||e-- >0)&&!(o=n.next()).done;)i.push(o.value)}catch(s){a={error:s}}finally{try{o&&!o.done&&(t=n.return)&&t.call(n)}finally{if(a)throw a.error}}return i},rz=function(r,e,t){if(t||arguments.length===2)for(var n=0,o=e.length,i;n<o;n++)(i||!(n in e))&&(i||(i=Array.prototype.slice.call(e,0,n)),i[n]=e[n]);return r.concat(i||Array.prototype.slice.call(e))},kw=function(){function r(e){this._namespace=e.namespace||"DiagComponentLogger"}return r.prototype.debug=function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];return Nl("debug",this._namespace,e)},r.prototype.error=function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];return Nl("error",this._namespace,e)},r.prototype.info=function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];return Nl("info",this._namespace,e)},r.prototype.warn=function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];return Nl("warn",this._namespace,e)},r.prototype.verbose=function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];return Nl("verbose",this._namespace,e)},r}()});var ot,Td=dt(()=>{"use strict";(function(r){r[r.NONE=0]="NONE",r[r.ERROR=30]="ERROR",r[r.WARN=50]="WARN",r[r.INFO=60]="INFO",r[r.DEBUG=70]="DEBUG",r[r.VERBOSE=80]="VERBOSE",r[r.ALL=9999]="ALL"})(ot||(ot={}))});function Uw(r,e){r<ot.NONE?r=ot.NONE:r>ot.ALL&&(r=ot.ALL),e=e||{};function t(n,o){var i=e[n];return typeof i=="function"&&r>=o?i.bind(e):function(){}}return{error:t("error",ot.ERROR),warn:t("warn",ot.WARN),info:t("info",ot.INFO),debug:t("debug",ot.DEBUG),verbose:t("verbose",ot.VERBOSE)}}var Bw=dt(()=>{"use strict";Td()});var nz,oz,iz,Cn,Dl=dt(()=>{"use strict";Fw();Bw();Td();Ll();nz=function(r,e){var t=typeof Symbol=="function"&&r[Symbol.iterator];if(!t)return r;var n=t.call(r),o,i=[],a;try{for(;(e===void 0||e-- >0)&&!(o=n.next()).done;)i.push(o.value)}catch(s){a={error:s}}finally{try{o&&!o.done&&(t=n.return)&&t.call(n)}finally{if(a)throw a.error}}return i},oz=function(r,e,t){if(t||arguments.length===2)for(var n=0,o=e.length,i;n<o;n++)(i||!(n in e))&&(i||(i=Array.prototype.slice.call(e,0,n)),i[n]=e[n]);return r.concat(i||Array.prototype.slice.call(e))},iz="diag",Cn=function(){function r(){function e(o){return function(){for(var i=[],a=0;a<arguments.length;a++)i[a]=arguments[a];var s=eo("diag");if(s)return s[o].apply(s,oz([],nz(i),!1))}}var t=this,n=function(o,i){var a,s,c;if(i===void 0&&(i={logLevel:ot.INFO}),o===t){var l=new Error("Cannot use diag as the logger for itself. Please use a DiagLogger implementation like ConsoleDiagLogger or a custom implementation");return t.error((a=l.stack)!==null&&a!==void 0?a:l.message),!1}typeof i=="number"&&(i={logLevel:i});var u=eo("diag"),d=Uw((s=i.logLevel)!==null&&s!==void 0?s:ot.INFO,o);if(u&&!i.suppressOverrideMessage){var p=(c=new Error().stack)!==null&&c!==void 0?c:"<failed to generate stacktrace>";u.warn("Current logger will be overwritten from "+p),d.warn("Current logger will overwrite one already registered from "+p)}return Ya("diag",d,t,!0)};t.setLogger=n,t.disable=function(){Xa(iz,t)},t.createComponentLogger=function(o){return new kw(o)},t.verbose=e("verbose"),t.debug=e("debug"),t.info=e("info"),t.warn=e("warn"),t.error=e("error")}return r.instance=function(){return this._instance||(this._instance=new r),this._instance},r}()});var Hw,zw=dt(()=>{"use strict";Hw=Symbol("BaggageEntryMetadata")});function Kg(r){return typeof r!="string"&&(az.error("Cannot create baggage metadata from unknown type: "+typeof r),r=""),{__TYPE__:Hw,toString:function(){return r}}}var az,Gw=dt(()=>{"use strict";Dl();zw();az=Cn.instance()});function Yg(r){return Symbol.for(r)}var sz,Xg,Jg=dt(()=>{"use strict";sz=function(){function r(e){var t=this;t._currentContext=e?new Map(e):new Map,t.getValue=function(n){return t._currentContext.get(n)},t.setValue=function(n,o){var i=new r(t._currentContext);return i._currentContext.set(n,o),i},t.deleteValue=function(n){var o=new r(t._currentContext);return o._currentContext.delete(n),o}}return r}(),Xg=new sz});function ef(){return Zg}var Di,lz,vd,cz,uz,dz,pz,Qg,mz,hz,gz,Zg,fz,Sz,yz,Ez,bz,Tz,vz,tf=dt(()=>{"use strict";Di=function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(n,o){n.__proto__=o}||function(n,o){for(var i in o)Object.prototype.hasOwnProperty.call(o,i)&&(n[i]=o[i])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function n(){this.constructor=e}e.prototype=t===null?Object.create(t):(n.prototype=t.prototype,new n)}}(),lz=function(){function r(){}return r.prototype.createGauge=function(e,t){return Sz},r.prototype.createHistogram=function(e,t){return yz},r.prototype.createCounter=function(e,t){return fz},r.prototype.createUpDownCounter=function(e,t){return Ez},r.prototype.createObservableGauge=function(e,t){return Tz},r.prototype.createObservableCounter=function(e,t){return bz},r.prototype.createObservableUpDownCounter=function(e,t){return vz},r.prototype.addBatchObservableCallback=function(e,t){},r.prototype.removeBatchObservableCallback=function(e){},r}(),vd=function(){function r(){}return r}(),cz=function(r){Di(e,r);function e(){return r!==null&&r.apply(this,arguments)||this}return e.prototype.add=function(t,n){},e}(vd),uz=function(r){Di(e,r);function e(){return r!==null&&r.apply(this,arguments)||this}return e.prototype.add=function(t,n){},e}(vd),dz=function(r){Di(e,r);function e(){return r!==null&&r.apply(this,arguments)||this}return e.prototype.record=function(t,n){},e}(vd),pz=function(r){Di(e,r);function e(){return r!==null&&r.apply(this,arguments)||this}return e.prototype.record=function(t,n){},e}(vd),Qg=function(){function r(){}return r.prototype.addCallback=function(e){},r.prototype.removeCallback=function(e){},r}(),mz=function(r){Di(e,r);function e(){return r!==null&&r.apply(this,arguments)||this}return e}(Qg),hz=function(r){Di(e,r);function e(){return r!==null&&r.apply(this,arguments)||this}return e}(Qg),gz=function(r){Di(e,r);function e(){return r!==null&&r.apply(this,arguments)||this}return e}(Qg),Zg=new lz,fz=new cz,Sz=new dz,yz=new pz,Ez=new uz,bz=new mz,Tz=new hz,vz=new gz});var Rr,jw=dt(()=>{"use strict";(function(r){r[r.INT=0]="INT",r[r.DOUBLE=1]="DOUBLE"})(Rr||(Rr={}))});var Rz,Az,Vw,$w=dt(()=>{"use strict";Jg();Rz=function(r,e){var t=typeof Symbol=="function"&&r[Symbol.iterator];if(!t)return r;var n=t.call(r),o,i=[],a;try{for(;(e===void 0||e-- >0)&&!(o=n.next()).done;)i.push(o.value)}catch(s){a={error:s}}finally{try{o&&!o.done&&(t=n.return)&&t.call(n)}finally{if(a)throw a.error}}return i},Az=function(r,e,t){if(t||arguments.length===2)for(var n=0,o=e.length,i;n<o;n++)(i||!(n in e))&&(i||(i=Array.prototype.slice.call(e,0,n)),i[n]=e[n]);return r.concat(i||Array.prototype.slice.call(e))},Vw=function(){function r(){}return r.prototype.active=function(){return Xg},r.prototype.with=function(e,t,n){for(var o=[],i=3;i<arguments.length;i++)o[i-3]=arguments[i];return t.call.apply(t,Az([n],Rz(o),!1))},r.prototype.bind=function(e,t){return t},r.prototype.enable=function(){return this},r.prototype.disable=function(){return this},r}()});var wz,Cz,rf,xz,Ww,qw=dt(()=>{"use strict";$w();Ll();Dl();wz=function(r,e){var t=typeof Symbol=="function"&&r[Symbol.iterator];if(!t)return r;var n=t.call(r),o,i=[],a;try{for(;(e===void 0||e-- >0)&&!(o=n.next()).done;)i.push(o.value)}catch(s){a={error:s}}finally{try{o&&!o.done&&(t=n.return)&&t.call(n)}finally{if(a)throw a.error}}return i},Cz=function(r,e,t){if(t||arguments.length===2)for(var n=0,o=e.length,i;n<o;n++)(i||!(n in e))&&(i||(i=Array.prototype.slice.call(e,0,n)),i[n]=e[n]);return r.concat(i||Array.prototype.slice.call(e))},rf="context",xz=new Vw,Ww=function(){function r(){}return r.getInstance=function(){return this._instance||(this._instance=new r),this._instance},r.prototype.setGlobalContextManager=function(e){return Ya(rf,e,Cn.instance())},r.prototype.active=function(){return this._getContextManager().active()},r.prototype.with=function(e,t,n){for(var o,i=[],a=3;a<arguments.length;a++)i[a-3]=arguments[a];return(o=this._getContextManager()).with.apply(o,Cz([e,t,n],wz(i),!1))},r.prototype.bind=function(e,t){return this._getContextManager().bind(e,t)},r.prototype._getContextManager=function(){return eo(rf)||xz},r.prototype.disable=function(){this._getContextManager().disable(),Xa(rf,Cn.instance())},r}()});var Ja,Kw=dt(()=>{"use strict";qw();Ja=Ww.getInstance()});var W,Yw=dt(()=>{"use strict";Dl();W=Cn.instance()});var _z,Xw,Jw=dt(()=>{"use strict";tf();_z=function(){function r(){}return r.prototype.getMeter=function(e,t,n){return Zg},r}(),Xw=new _z});var nf,Qw,Zw=dt(()=>{"use strict";Jw();Ll();Dl();nf="metrics",Qw=function(){function r(){}return r.getInstance=function(){return this._instance||(this._instance=new r),this._instance},r.prototype.setGlobalMeterProvider=function(e){return Ya(nf,e,Cn.instance())},r.prototype.getMeterProvider=function(){return eo(nf)||Xw},r.prototype.getMeter=function(e,t,n){return this.getMeterProvider().getMeter(e,t,n)},r.prototype.disable=function(){Xa(nf,Cn.instance())},r}()});var Rd,eC=dt(()=>{"use strict";Zw();Rd=Qw.getInstance()});var Ke=dt(()=>{"use strict";Gw();Jg();Td();tf();jw();Kw();Yw();eC()});var Is=(r,e)=>{},mm=!1;try{let r=await import("@sentry/node");Is=r.captureException,r.init({dsn:"https://89e980855f7b9c6e56fc6c7e7143888b@o4506426201800704.ingest.us.sentry.io/4508343221354497",environment:"production",release:process.env.SENTRY_RELEASE_NAME,tracesSampleRate:0}),mm=!0}catch{}import{Command as a2,Option as cr}from"@commander-js/extra-typings";import{execSync as s2}from"child_process";import{existsSync as fF,statSync as SF}from"fs";import{z as hm}from"zod";var E2=hm.object({input:hm.string(),agentConfigVersion:hm.string().optional()});import{z as _t}from"zod";var v2=_t.object({srcs:_t.array(_t.string()),urls:_t.array(_t.string()),desiredSrc:_t.string().optional(),desiredUrl:_t.string().optional()}),xy=_t.object({srcRegex:_t.string().optional(),urlRegex:_t.string().optional()}),_y=_t.object({x:_t.number(),y:_t.number(),correlation:_t.number()}),R2=_t.object({searchImageBase64String:_t.string(),pageImageBase64String:_t.string(),id:_t.string().uuid(),timeoutMs:_t.number().max(1e4).min(0).optional()});import{z as L}from"zod";import*as D from"zod";import{extendZodWithOpenApi as iL}from"zod-openapi";iL(D);var co=(s=>(s.AI="AI",s.AI_HEALED="AI_HEALED",s.CLICK_TO_FIND="CLICK_TO_FIND",s.XY_PERCENT="XY_PERCENT",s.RECORDING="RECORDING",s.USER_CSS_SELECTOR="USER_CSS_SELECTOR",s.HEURISTIC_HEALED="HEURISTIC_HEALED",s))(co||{}),aL=D.object({mPathSelectorTokens:D.string().array(),frameSrcRegex:D.string().optional(),frameUrlRegex:D.string().optional(),indices:D.number().array()}),gm=D.object({result:D.number(),traceId:D.string()}).array(),Rc=D.object({type:D.literal("GCS_TRACES"),traces:gm}),lo=(o=>(o.Precise="precise",o.Narrow="narrow",o.Unspecific="broad",o.Irrelevant="irrelevant",o))(lo||{}),My=D.object({attributes:D.record(D.string(),D.string()).optional(),text:D.string().optional(),position:D.object({x1:D.number(),y1:D.number(),x2:D.number(),y2:D.number(),tolerance:D.nativeEnum(lo)}).optional(),shape:D.object({width:D.number(),height:D.number(),tolerance:D.nativeEnum(lo)}).optional(),boundingBox:D.object({x:D.number(),y:D.number(),width:D.number(),height:D.number()}).optional()}),sL=D.object({selectors:D.string().array(),requirements:My.optional()}),uo=D.object({id:D.number().int(),dataMomenticId:D.number().int().optional(),selector:D.string().optional(),hybridSelector:D.object({textContent:D.string().nullish(),attributes:D.record(D.string(),D.string().optional()),tagName:D.string(),expandShadowRoot:D.boolean().optional(),classNames:D.string().array(),nthChild:D.number()}).array().optional(),generatedSelectors:D.string().array().optional(),requirements:My.optional(),additionalElements:sL.array().optional(),role:D.string().optional(),name:D.string().optional(),numChildren:D.number().optional(),content:D.string().optional(),pathFromRoot:D.string().optional(),serializedHtml:D.string().optional().describe("pruned html including 1 neighbor and 1 layer of children. value for text inputs pruned."),nodeOnlySerializedHtml:D.string().optional().describe("outerHtml of the element without any children. value for text inputs pruned."),screenshotUrl:D.string().url().optional(),boundingBox:D.object({x:D.number().optional(),y:D.number().optional(),width:D.number(),height:D.number()}).describe("css pixel bounding box").optional(),frameCache:aL.optional(),inputDescription:D.string().optional().describe("the description that generated this cache"),targetSource:D.nativeEnum(co).optional(),targetUpdateTime:D.string().optional(),targetUpdateLoggerTags:D.record(D.string(),D.string()).optional(),cacheResolutionUpdateSource:D.string().optional(),cacheResolutionUpdateTime:D.string().optional(),cacheResolutionUpdateLoggerTags:D.record(D.string(),D.string()).optional(),memory:Rc.optional()}).openapi({ref:"ElementTargetCache"});function Ac(r){return!!(r.serializedHtml||r.screenshotUrl||r.generatedSelectors||r.hybridSelector)}var lL=D.object({type:D.literal("description"),elementDescriptor:D.string().describe("Description of the element.")}).openapi({ref:"DescriptionTarget"}),cL=D.object({x:D.number(),y:D.number()}),uL=D.object({type:D.literal("coordinates"),pixels:cL}).openapi({ref:"CoordinatesTarget"});function po(r){return r.type==="description"}function mn(r){return r.type==="coordinates"}var Vt=D.discriminatedUnion("type",[lL,uL]).openapi({ref:"ElementTarget"});function fm(r){if(!r)return!1;switch(r.type){case"description":return!!r.elementDescriptor}return!0}function $t(r){if(!r)return"";switch(r.type){case"description":return r.elementDescriptor;case"coordinates":return`x: ${r.pixels.x}, y: ${r.pixels.y}`}}function wc(r){return Rc.safeParse(r).success}import{v4 as Le}from"uuid";import*as R from"zod";import{extendZodWithOpenApi as TL}from"zod-openapi";import{z as Se}from"zod";import{extendZodWithOpenApi as dL}from"zod-openapi";import{z as Os}from"zod";import Iy from"zod";var Ps=Iy.object({updatedAt:Iy.coerce.date().optional()});var Sm=Os.object({result:Os.boolean(),traceId:Os.string()}).array(),ym=Os.object({type:Os.literal("GCS_TRACES"),traces:Sm}),Em=Ps.extend({memory:ym.optional()});dL(Se);var Py=Se.object({thoughts:Se.string(),result:Se.boolean(),relevantElements:Se.array(Se.number()).optional(),updatedMemory:Sm.optional()}),Yr=(o=>(o.CONTAINS="CONTAINS",o.STARTS_WITH="STARTS_WITH",o.EQUALS="EQUALS",o.EXISTS="EXISTS",o))(Yr||{});var pL=Se.object({type:Se.literal("ELEMENT_NAME"),negated:Se.boolean().optional(),operation:Se.nativeEnum(Yr),value:Se.string()}).openapi({ref:"ElementNameAssertion"}),mL=Se.object({type:Se.literal("ELEMENT_STYLE"),negated:Se.boolean().optional(),operation:Se.nativeEnum(Yr),property:Se.string(),value:Se.string()}).openapi({ref:"ElementStyleAssertion"}),hL=Se.object({type:Se.literal("ELEMENT_CONTENT"),negated:Se.boolean().optional(),operation:Se.nativeEnum(Yr),value:Se.string()}).openapi({ref:"ElementContentAssertion"}),gL=Se.object({type:Se.literal("ELEMENT_ATTRIBUTE"),negated:Se.boolean().optional(),operation:Se.nativeEnum(Yr),attr:Se.string(),value:Se.string()}).openapi({ref:"ElementAttributeValueAssertion"}),Gn=(i=>(i.EXISTS="EXISTS",i.VISIBLE="VISIBLE",i.ENABLED="ENABLED",i.EDITABLE="EDITABLE",i.FOCUSED="FOCUSED",i))(Gn||{});var fL=Se.object({type:Se.literal("ELEMENT_EXISTENCE"),negated:Se.boolean().optional(),condition:Se.nativeEnum(Gn).describe("Treated as the element exists AND is also ...")}).openapi({ref:"ElementExistenceAssertion"}),Cc=Se.discriminatedUnion("type",[hL,gL,fL,pL,mL]).openapi({ref:"ManualElementAssertion"});var SL=Se.object({type:Se.literal("CONTENT"),negated:Se.boolean().optional(),value:Se.string()}).openapi({ref:"PageContentAssertion"}),Oy=Se.discriminatedUnion("type",[SL]).openapi({ref:"ManualPageAssertion"});import er from"zod";var bm=er.discriminatedUnion("type",[er.object({type:er.literal("SUBSTRING"),url:er.string()}),er.object({type:er.literal("GLOB"),glob:er.string()}),er.object({type:er.literal("REGEX"),regex:er.string()}),er.object({type:er.literal("DOMAIN"),domain:er.string()})]),Ls=er.object({urlMatcher:bm,method:er.string().optional()});import{z as pe}from"zod";var yL=pe.object({type:pe.literal("json"),content:pe.string().describe("The JSON content to send in the request body")}),EL=pe.object({type:pe.literal("form-urlencoded"),content:pe.record(pe.string(),pe.string()).describe("The form fields to send in the request body")}),bL=pe.discriminatedUnion("type",[yL,EL]),ri=pe.object({url:pe.string(),method:pe.union([pe.literal("GET"),pe.literal("POST"),pe.literal("PUT"),pe.literal("DELETE"),pe.literal("PATCH")]),headers:pe.record(pe.string(),pe.string()).optional(),params:pe.record(pe.string(),pe.string()).optional(),body:bL.optional(),timeout:pe.number().int().optional().describe("Max seconds to wait for the request to complete")}),Ly=pe.object({url:pe.string(),headers:pe.record(pe.string(),pe.string()).optional(),query:pe.string(),variables:pe.string().optional(),timeout:pe.number().int().optional().describe("Max seconds to wait for the request to complete")}),xc=pe.object({code:pe.string(),fragment:pe.boolean().optional().describe("Agents should not touch this unless explicitly told to"),environment:pe.union([pe.literal("NODE"),pe.literal("BROWSER")]).optional().describe("default NODE, Agents default to using node unless it is necessary to use browser"),timeout:pe.number().int().max(60).optional().describe("Max seconds for the code to complete")});var Xe=(K=>(K.AI_EXTRACT="AI_EXTRACT",K.AI_ASSERTION="AI_ASSERTION",K.AUTH_LOAD="AUTH_LOAD",K.AUTH_SAVE="AUTH_SAVE",K.BLUR="BLUR",K.CAPTCHA="CAPTCHA",K.CLICK="CLICK",K.COOKIE="COOKIE",K.COPY="COPY",K.DIALOG="DIALOG",K.DRAG="DRAG",K.ELEMENT_CHECK="ELEMENT_CHECK",K.FILE_UPLOAD="FILE_UPLOAD",K.FOCUS="FOCUS",K.GO_BACK="GO_BACK",K.GO_FORWARD="GO_FORWARD",K.HOVER="HOVER",K.JAVASCRIPT="JAVASCRIPT",K.LOCAL_STORAGE="LOCAL_STORAGE",K.MOUSE_DRAG="MOUSE_DRAG",K.NAVIGATE="NAVIGATE",K.NEW_TAB="NEW_TAB",K.PAGE_CHECK="PAGE_CHECK",K.PASTE="PASTE",K.PRESS="PRESS",K.KEY_DOWN="KEY_DOWN",K.KEY_UP="KEY_UP",K.REFRESH="REFRESH",K.REQUEST="REQUEST",K.GRAPHQL_REQUEST="GRAPHQL_REQUEST",K.SCROLL_DOWN="SCROLL_DOWN",K.SCROLL_UP="SCROLL_UP",K.SCROLL_LEFT="SCROLL_LEFT",K.SCROLL_RIGHT="SCROLL_RIGHT",K.SELECT_OPTION="SELECT_OPTION",K.SWITCH_TAB="TAB",K.TYPE="TYPE",K.VISUAL_DIFF="VISUAL_DIFF",K.WAIT="WAIT",K.WAIT_FOR_URL="WAIT_FOR_URL",K.REGISTER_REQUEST_LISTENER="REGISTER_REQUEST_LISTENER",K.AWAIT_LISTENER="AWAIT_LISTENER",K.RECORD_REQUESTS="RECORD_REQUESTS",K.GET_RECORDED_REQUESTS="GET_RECORDED_REQUESTS",K.SET_HEADER="SET_HEADER",K.MOCK_ROUTE="MOCK_ROUTE",K.REMOVE_ROUTE_MOCK="REMOVE_ROUTE_MOCK",K.OFFLINE_MODE="OFFLINE_MODE",K.SUCCESS="SUCCESS",K))(Xe||{});TL(R);var re=R.object({thoughts:R.string().optional(),id:R.string().uuid().describe("unique identifier to this step, used for step cache")}),xr=R.object({useSelector:R.boolean().optional(),force:R.boolean().optional(),disableCache:R.boolean().optional().describe("disable element caching for this step"),iframeUrl:R.string().optional().describe("url or url regex for the iframe")}).openapi({ref:"CommonTargetingOptions"}),Sr=Ps.extend({target:uo}).optional().openapi({ref:"SingleTargetCache"});function Ny(r){return Sr.safeParse(r).success}var Mc=R.object({loadTimeout:R.number().int().max(60).optional().describe("Max seconds for the page to load")}),Dy=re.merge(Mc).merge(R.object({type:R.literal("NAVIGATE"),url:R.string()})).openapi({ref:"NavigateCommand"}),Ic=xr.merge(R.object({cache:Sr})),oi=re.merge(Ic.merge(R.object({target:Vt.optional(),type:R.literal("SCROLL_UP"),deltaY:R.number().optional()}))).openapi({ref:"ScrollUpCommand"}),ii=re.merge(Ic.merge(R.object({target:Vt.optional(),type:R.literal("SCROLL_DOWN"),deltaY:R.number().optional()}))).openapi({ref:"ScrollDownCommand"}),ea=re.merge(Ic.merge(R.object({target:Vt.optional(),type:R.literal("SCROLL_LEFT"),deltaX:R.number().optional()}))).openapi({ref:"ScrollLeftCommand"}),ta=re.merge(Ic.merge(R.object({target:Vt.optional(),type:R.literal("SCROLL_RIGHT"),deltaX:R.number().optional()}))).openapi({ref:"ScrollRightCommand"}),tY=R.discriminatedUnion("type",[oi,ii,ea,ta]).openapi({ref:"AllScrollCommands"}),vL=re.merge(R.object({type:R.literal("DIALOG"),action:R.union([R.literal("ACCEPT"),R.literal("DISMISS")])})).openapi({ref:"DialogCommand"}),ky=re.merge(R.object({type:R.literal("WAIT"),delay:R.number()})).openapi({ref:"WaitCommand"}),RL=R.object({caseInsensitive:R.boolean().optional().describe("Whether to ignore case when matching the URL"),negated:R.boolean().optional().describe("Wait for the URL to NOT match the provided matcher instead."),timeout:R.number().int().optional().describe("Max seconds to wait for the URL to match")}),Fy=re.extend({type:R.literal("WAIT_FOR_URL"),matcher:bm}).merge(RL).openapi({ref:"WaitUrlCommand"}),Uy=re.merge(Mc).merge(R.object({type:R.literal("REFRESH")})).openapi({ref:"RefreshCommand"}),By=re.merge(R.object({type:R.literal("GO_BACK")})).openapi({ref:"GoBackCommand"}),Hy=re.merge(R.object({type:R.literal("GO_FORWARD")})).openapi({ref:"GoForwardCommand"}),AL=re.extend({type:R.literal("AUTH_SAVE")}).openapi({ref:"AuthSaveCommand"}),wL=re.extend({type:R.literal("AUTH_LOAD"),storageState:R.string().describe("JSON string auth state. Leave blank or set to the empty string to clear all existing authentication.")}).openapi({ref:"AuthLoadCommand"}),Tm=re.merge(xr).extend({type:R.literal("CAPTCHA")}).openapi({ref:"CaptchaCommand"}),zy=re.extend({type:R.literal("COPY"),value:R.string()}).openapi({ref:"CopyCommand"}),Gy=re.extend({type:R.literal("PASTE")}).openapi({ref:"PasteCommand"}),jy=re.merge(xc).extend({type:R.literal("JAVASCRIPT")}).openapi({ref:"JavaScriptCommand"}),ra=re.merge(xr).extend({type:R.literal("CLICK"),target:Vt,doubleClick:R.boolean().optional(),rightClick:R.boolean().optional(),waitForDownload:R.boolean().optional().describe("Wait for the click to trigger a file download and for the file download to complete."),delayMs:R.number().optional(),downloadTimeoutMs:R.number().optional(),cache:Sr,relativePosition:R.object({x:R.number(),y:R.number()}).optional()}).openapi({ref:"ClickCommand"}),vm=Ps.extend({fromTarget:uo.optional(),toTarget:uo.optional()}),na=re.merge(xr).merge(R.object({type:R.literal("DRAG"),fromTarget:Vt,toTarget:Vt,steps:R.number().optional(),hoverSeconds:R.number().optional().describe("Seconds to hover the object before dropping"),cache:vm.optional()})).openapi({ref:"DragCommand"}),oa=re.merge(xr).merge(R.object({type:R.literal("MOUSE_DRAG"),target:Vt.optional(),deltaX:R.string().describe("pixels to move horizontally, can be template"),deltaY:R.string().describe("pixels to move vertically, can be template"),steps:R.number().optional(),cache:Sr})).openapi({ref:"MouseDragCommand"}),ia=re.merge(xr).merge(R.object({type:R.literal("HOVER"),target:Vt,cache:Sr})).openapi({ref:"HoverCommand"}),Ns=re.merge(xr).merge(R.object({type:R.literal("FOCUS"),target:Vt,cache:Sr})).openapi({ref:"FocusCommand"}),Ds=re.merge(xr).extend({type:R.literal("BLUR"),target:Vt.optional(),cache:Sr}).openapi({ref:"BlurCommand"}),CL=R.object({type:R.literal("URL"),url:R.string()}).describe("Accessible link to the file, either public http or local file://").openapi({ref:"UrlSource"}),xL=R.object({type:R.literal("USER_FILE"),name:R.string()}).describe("Accessible link to the file, references the google cloud file").openapi({ref:"UploadedFileSource"}),_L=re.extend({type:R.literal("FILE_UPLOAD"),fileSource:R.discriminatedUnion("type",[CL,xL]),filename:R.string().optional()}).openapi({ref:"FileUploadCommand"}),Rm=R.discriminatedUnion("type",[R.object({type:R.literal("VALUE"),value:R.string()}),R.object({type:R.literal("LABEL"),label:R.string()}),R.object({type:R.literal("INDEX"),index:R.coerce.string()})]),aa=re.merge(xr).extend({type:R.literal("SELECT_OPTION"),target:Vt,cache:Sr,choice:Rm.describe("new field for selecting options, optional for backcompat")}).openapi({ref:"SelectOptionCommand"}),Am=R.union([R.literal("MULTIMODAL"),R.literal("VISION_ONLY")]),ks=re.merge(R.object({type:R.literal("AI_ASSERTION"),assertion:R.string(),disableCache:R.boolean().optional(),iframeUrl:R.string().optional(),contextChoice:Am.optional(),timeout:R.number().int().optional().describe("Max seconds to wait for assertion to be true"),cache:Em.optional()})).openapi({ref:"AIAssertionCommand"}),hn=5,sa=600,la=re.merge(xr).extend({type:R.literal("ELEMENT_CHECK"),target:Vt,assertion:Cc,cache:Sr.or(Em).optional(),timeout:R.number().int().min(0).max(sa).optional().describe("max seconds to wait for the assertion to be true")}).openapi({ref:"ElementAssertionCommand"}),Vy=re.extend({type:R.literal("PAGE_CHECK"),assertion:Oy,iframeUrl:R.string().optional().describe("url or url regex for the iframe"),timeout:R.number().int().min(0).max(sa).optional().describe("max seconds to wait for the assertion to be true")}).openapi({ref:"PageAssertionCommand"}),$y=re.merge(R.object({type:R.literal("AI_EXTRACT"),goal:R.string(),schema:R.string().optional(),envKey:R.string().optional(),disableCache:R.boolean().optional(),iframeUrl:R.string().optional()})).openapi({ref:"AIExtractCommand"}),ML=R.object({clearContent:R.boolean().optional(),forceClearContent:R.boolean().optional(),delay:R.number().min(0).max(1e3).optional().describe("Delay between each press in milliseconds."),force:R.boolean().optional(),pressEnter:R.boolean().optional(),relativePosition:R.object({x:R.number(),y:R.number()}).optional()}),Wy=25,ca=re.merge(xr).merge(ML).extend({type:R.literal("TYPE"),target:Vt.optional(),value:R.string(),cache:Sr}).openapi({ref:"TypeCommand"}),qy=re.merge(R.object({type:R.literal("PRESS"),value:R.string(),repeat:R.number().optional(),convertMeta:R.boolean().optional(),delayMs:R.number().optional()})).openapi({ref:"PressCommand"}),Ky=re.merge(R.object({type:R.literal("KEY_DOWN"),value:R.string(),convertMeta:R.boolean().optional()})).openapi({ref:"KeyDownCommand"}),Yy=re.merge(R.object({type:R.literal("KEY_UP"),value:R.string(),convertMeta:R.boolean().optional()})).openapi({ref:"KeyUpCommand"}),IL=R.object({type:R.literal("SUBSTRING"),substring:R.string()}),PL=R.object({type:R.literal("REGEX"),pattern:R.string()}),OL=R.object({type:R.literal("INDEX"),index:R.coerce.string()}),LL=R.discriminatedUnion("type",[IL,PL,OL]),NL=re.merge(Mc).merge(R.object({type:R.literal("TAB"),action:LL})).openapi({ref:"TabCommand"}),Xy=re.merge(Mc).merge(R.object({type:R.literal("NEW_TAB"),url:R.string()})).openapi({ref:"NewTabCommand"}),DL=re.merge(R.object({type:R.literal("COOKIE"),value:R.string()})).openapi({ref:"CookieCommand"}),Jy=re.merge(R.object({type:R.literal("LOCAL_STORAGE"),key:R.string(),value:R.string()})).openapi({ref:"LocalStorageCommand"}),Qy=re.extend({type:R.literal("REQUEST")}).merge(ri).openapi({ref:"RequestCommand"}),Zy=re.extend({type:R.literal("GRAPHQL_REQUEST")}).merge(Ly).openapi({ref:"GraphQLRequestCommand"}),eE=re.merge(R.object({type:R.literal("SUCCESS"),condition:ks.optional()})).openapi({ref:"SuccessCommand"}),tE=re.merge(R.object({type:R.literal("FAILURE")})).openapi({ref:"FailureCommand"}),kL=R.object({data:R.string().describe("location at which to find a jpg"),width:R.number(),height:R.number()}),Fs=re.merge(xr).merge(R.object({type:R.literal("VISUAL_DIFF"),threshold:R.number().optional().describe("default 0.1"),target:Vt.optional(),screenshot:kL.optional(),cache:Sr})).openapi({ref:"VisualDiffCommand"}),FL=re.merge(R.object({type:R.literal("REGISTER_REQUEST_LISTENER"),requestMatcher:Ls,key:R.string()})).openapi({ref:"RegisterRequestListenerCommand"}),UL=re.merge(R.object({type:R.literal("AWAIT_LISTENER"),key:R.string(),timeout:R.number().optional().describe("timeout")})).openapi({ref:"WaitForListenerCommand"}),BL=re.merge(R.object({type:R.literal("RECORD_REQUESTS"),requestMatcher:Ls,key:R.string()})).openapi({ref:"RecordRequestsCommand"}),HL=re.merge(R.object({type:R.literal("GET_RECORDED_REQUESTS"),key:R.string()})).openapi({ref:"GetRecordedRequestsCommand"}),zL=re.merge(R.object({type:R.literal("SET_HEADER"),name:R.string(),value:R.string(),requestMatcher:Ls.optional()})).openapi({ref:"SetHeaderCommand"}),GL=re.merge(R.object({type:R.literal("MOCK_ROUTE"),requestMatcher:Ls,responseGenerator:R.string().describe("JavaScript code to generate a response"),fetchOriginalResponse:R.boolean().optional().describe("Whether to fetch the real response and pass it to the response generator. If enabled, the original response will be available as `response` in the code."),key:R.string().optional().describe("Key to reference this mock. This only needs to be set if you plan to remove the mock later in the test.")}).openapi({ref:"MockRouteCommandOptions"})),jL=re.merge(R.object({type:R.literal("REMOVE_ROUTE_MOCK"),key:R.string().optional().describe("Key of the mock to remove. If not set, all route mocks will be removed.")}).openapi({ref:"RemoveRouteMockCommandOptions"})),VL=re.merge(R.object({type:R.literal("OFFLINE_MODE"),enable:R.boolean()})).openapi({ref:"OfflineModeCommand"}),$L=["CLICK","TYPE","PRESS","KEY_DOWN","KEY_UP","SELECT_OPTION","NAVIGATE","SCROLL_DOWN","SCROLL_UP","AI_ASSERTION","GO_BACK","HOVER","WAIT"],rY=[...$L,"DRAG"],WL=R.discriminatedUnion("type",[ra,ca,qy,Ky,Yy,aa,Dy,ii,oi,ks,By,ia,ky]),qL=R.discriminatedUnion("type",[...WL.options,na]),KL=R.discriminatedUnion("type",[...qL.options]),rE=R.discriminatedUnion("type",[...KL.options,eE]),wm=R.discriminatedUnion("type",[eE,ra,ca,qy,Ky,Yy,aa,Dy,ii,oi,ks,By,ia,ky,jy,la,Vy,Xy,Fy,$y,zy,Hy,Jy,na,oa,Gy,Uy,Qy,Zy]),YL=R.discriminatedUnion("type",[$y,wL,AL,Tm,DL,zy,vL,la,_L,Hy,jy,Jy,oa,Xy,Vy,Gy,Uy,Qy,Zy,ea,ta,NL,Fs,Ns,Ds,Fy,FL,UL,BL,HL,zL,GL,jL,VL]),ua=R.discriminatedUnion("type",[...rE.options,...YL.options]).openapi({ref:"Command"}),Pc=R.discriminatedUnion("type",[...rE.options,tE]),nY=R.discriminatedUnion("type",[...wm.options,tE]);function jn(r){let e;switch(r){case"PASTE":case"AUTH_SAVE":case"VISUAL_DIFF":case"SUCCESS":case"SCROLL_DOWN":case"SCROLL_UP":case"SCROLL_LEFT":case"SCROLL_RIGHT":case"CAPTCHA":case"GO_BACK":case"GO_FORWARD":case"REFRESH":e={id:Le(),type:r};break;case"AUTH_LOAD":{e={id:Le(),type:r,storageState:""};break}case"AI_EXTRACT":e={id:Le(),type:r,goal:""};break;case"DIALOG":e={id:Le(),type:r,action:"DISMISS"};break;case"DRAG":e={id:Le(),type:r,fromTarget:{type:"description",elementDescriptor:""},toTarget:{type:"description",elementDescriptor:""}};break;case"MOUSE_DRAG":e={id:Le(),type:r,deltaX:"0",deltaY:"0",steps:1};break;case"WAIT_FOR_URL":e={id:Le(),type:r,matcher:{type:"SUBSTRING",url:""}};break;case"WAIT":e={id:Le(),type:r,delay:1};break;case"BLUR":e={id:Le(),type:r};break;case"HOVER":case"FOCUS":case"CLICK":e={id:Le(),type:r,target:{type:"description",elementDescriptor:""}};break;case"COOKIE":case"PRESS":case"COPY":case"TYPE":e={id:Le(),type:r,value:"",clearContent:!0};break;case"KEY_DOWN":case"KEY_UP":e={id:Le(),type:r,value:""};break;case"SELECT_OPTION":e={id:Le(),type:r,target:{type:"description",elementDescriptor:""},choice:{type:"VALUE",value:""}};break;case"NAVIGATE":case"NEW_TAB":return{id:Le(),type:r,url:""};case"TAB":e={id:Le(),type:r,action:{type:"SUBSTRING",substring:""}};break;case"REQUEST":e={id:Le(),type:r,url:"",method:"GET"};break;case"GRAPHQL_REQUEST":e={id:Le(),type:r,url:"",query:""};break;case"LOCAL_STORAGE":e={id:Le(),type:r,key:"",value:""};break;case"JAVASCRIPT":e={id:Le(),type:r,code:""};break;case"AI_ASSERTION":e={id:Le(),type:r,assertion:""};break;case"FILE_UPLOAD":{e={id:Le(),type:r,fileSource:{type:"URL",url:""}};break}case"ELEMENT_CHECK":{e={id:Le(),type:r,target:{type:"description",elementDescriptor:""},assertion:{type:"ELEMENT_EXISTENCE",condition:"EXISTS"}};break}case"PAGE_CHECK":{e={id:Le(),type:r,assertion:{type:"CONTENT",value:""}};break}case"REGISTER_REQUEST_LISTENER":{e={id:Le(),type:r,requestMatcher:{urlMatcher:{type:"REGEX",regex:""}},key:""};break}case"AWAIT_LISTENER":{e={id:Le(),type:r,key:""};break}case"RECORD_REQUESTS":{e={id:Le(),type:r,requestMatcher:{urlMatcher:{type:"REGEX",regex:""}},key:""};break}case"GET_RECORDED_REQUESTS":{e={id:Le(),type:r,key:""};break}case"SET_HEADER":{e={id:Le(),type:r,name:"",value:""};break}case"MOCK_ROUTE":{e={id:Le(),type:r,requestMatcher:{urlMatcher:{type:"REGEX",regex:""}},responseGenerator:""};break}case"REMOVE_ROUTE_MOCK":{e={id:Le(),type:r};break}case"OFFLINE_MODE":{e={id:Le(),type:r,enable:!0};break}default:return(n=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(r)}return e}function nE(r){switch(r.type){case"BLUR":case"CLICK":case"DRAG":case"FOCUS":case"HOVER":case"MOUSE_DRAG":case"PRESS":case"KEY_DOWN":case"KEY_UP":case"SCROLL_DOWN":case"SCROLL_UP":case"SCROLL_LEFT":case"SCROLL_RIGHT":case"TYPE":return!0;case"AUTH_LOAD":case"AUTH_SAVE":case"AWAIT_LISTENER":case"SUCCESS":case"AI_ASSERTION":case"AI_EXTRACT":case"CAPTCHA":case"COOKIE":case"COPY":case"DIALOG":case"ELEMENT_CHECK":case"FILE_UPLOAD":case"GET_RECORDED_REQUESTS":case"GO_BACK":case"GO_FORWARD":case"GRAPHQL_REQUEST":case"JAVASCRIPT":case"LOCAL_STORAGE":case"NAVIGATE":case"NEW_TAB":case"PASTE":case"PAGE_CHECK":case"RECORD_REQUESTS":case"REGISTER_REQUEST_LISTENER":case"REFRESH":case"REQUEST":case"SELECT_OPTION":case"SET_HEADER":case"TAB":case"VISUAL_DIFF":case"WAIT":case"WAIT_FOR_URL":case"OFFLINE_MODE":case"MOCK_ROUTE":case"REMOVE_ROUTE_MOCK":return!1;default:return(t=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(r)}}import{z as XL}from"zod";var lY=XL.discriminatedUnion("type",[Ds,Tm,ra,na,Ns,ia,oa,oi,ii,ea,ta,aa,ca,Fs,la]);function oE(r){return["AI_ASSERTION","ELEMENT_CHECK","PAGE_CHECK"].includes(r)}import{z as JL}from"zod";import{z as mo}from"zod";function Us(r){return mo.object({key:mo.string(),testId:mo.string().optional(),moduleId:mo.string().optional(),organizationId:mo.string(),value:r})}function Bs(r){return Us(r).extend({uniqueKey:mo.string()})}function Oc(r){return mo.record(mo.string(),Bs(r))}var tr={type:!0,cache:!0},Vn=JL.discriminatedUnion("type",[ks.pick(tr),Ds.pick(tr),ra.pick(tr),na.pick(tr),la.pick(tr),Ns.pick(tr),ia.pick(tr),oa.pick(tr),oi.pick(tr),ii.pick(tr),ea.pick(tr),ta.pick(tr),aa.pick(tr),ca.pick(tr),Fs.pick(tr)]),Lc=Object.values(Xe).filter(r=>Vn.options.some(e=>e.shape.type.safeParse(r).success));ua.options.forEach(r=>{if("target"in r.shape&&!Lc.includes(r.shape.type.value))throw new Error(`Command ${r.shape.type.value} has a target but no cache`)});function Nc(r){return Lc.includes(r.type)}var iE=Us(Vn),aE=Bs(Vn),fY=Oc(Vn);import{v4 as Ve}from"uuid";import{z as w}from"zod";var lE=Symbol("Let zodToJsonSchema decide on which parser to use");var sE={name:void 0,$refStrategy:"root",basePath:["#"],effectStrategy:"input",pipeStrategy:"all",dateStrategy:"format:date-time",mapStrategy:"entries",removeAdditionalStrategy:"passthrough",allowedAdditionalProperties:!0,rejectedAdditionalProperties:!1,definitionPath:"definitions",target:"jsonSchema7",strictUnions:!1,definitions:{},errorMessages:!1,markdownDescription:!1,patternStrategy:"escape",applyRegexFlags:!1,emailStrategy:"format:email",base64Strategy:"contentEncoding:base64",nameStrategy:"ref",openAiAnyTypeName:"OpenAiAnyType"},cE=r=>typeof r=="string"?{...sE,name:r}:{...sE,...r};var uE=r=>{let e=cE(r),t=e.name!==void 0?[...e.basePath,e.definitionPath,e.name]:e.basePath;return{...e,flags:{hasReferencedOpenAiAnyType:!1},currentPath:t,propertyPath:void 0,seen:new Map(Object.entries(e.definitions).map(([n,o])=>[o._def,{def:o._def,path:[...e.basePath,e.definitionPath,n],jsonSchema:void 0}]))}};function Cm(r,e,t,n){n?.errorMessages&&t&&(r.errorMessage={...r.errorMessage,[e]:t})}function Ae(r,e,t,n,o){r[e]=t,Cm(r,e,n,o)}var Dc=(r,e)=>{let t=0;for(;t<r.length&&t<e.length&&r[t]===e[t];t++);return[(r.length-t).toString(),...e.slice(t)].join("/")};import{ZodFirstPartyTypeKind as ve}from"zod";function at(r){if(r.target!=="openAi")return{};let e=[...r.basePath,r.definitionPath,r.openAiAnyTypeName];return r.flags.hasReferencedOpenAiAnyType=!0,{$ref:r.$refStrategy==="relative"?Dc(e,r.currentPath):e.join("/")}}import{ZodFirstPartyTypeKind as QL}from"zod";function dE(r,e){let t={type:"array"};return r.type?._def&&r.type?._def?.typeName!==QL.ZodAny&&(t.items=ne(r.type._def,{...e,currentPath:[...e.currentPath,"items"]})),r.minLength&&Ae(t,"minItems",r.minLength.value,r.minLength.message,e),r.maxLength&&Ae(t,"maxItems",r.maxLength.value,r.maxLength.message,e),r.exactLength&&(Ae(t,"minItems",r.exactLength.value,r.exactLength.message,e),Ae(t,"maxItems",r.exactLength.value,r.exactLength.message,e)),t}function pE(r,e){let t={type:"integer",format:"int64"};if(!r.checks)return t;for(let n of r.checks)switch(n.kind){case"min":e.target==="jsonSchema7"?n.inclusive?Ae(t,"minimum",n.value,n.message,e):Ae(t,"exclusiveMinimum",n.value,n.message,e):(n.inclusive||(t.exclusiveMinimum=!0),Ae(t,"minimum",n.value,n.message,e));break;case"max":e.target==="jsonSchema7"?n.inclusive?Ae(t,"maximum",n.value,n.message,e):Ae(t,"exclusiveMaximum",n.value,n.message,e):(n.inclusive||(t.exclusiveMaximum=!0),Ae(t,"maximum",n.value,n.message,e));break;case"multipleOf":Ae(t,"multipleOf",n.value,n.message,e);break}return t}function mE(){return{type:"boolean"}}function kc(r,e){return ne(r.type._def,e)}var hE=(r,e)=>ne(r.innerType._def,e);function xm(r,e,t){let n=t??e.dateStrategy;if(Array.isArray(n))return{anyOf:n.map((o,i)=>xm(r,e,o))};switch(n){case"string":case"format:date-time":return{type:"string",format:"date-time"};case"format:date":return{type:"string",format:"date"};case"integer":return ZL(r,e)}}var ZL=(r,e)=>{let t={type:"integer",format:"unix-time"};if(e.target==="openApi3")return t;for(let n of r.checks)switch(n.kind){case"min":Ae(t,"minimum",n.value,n.message,e);break;case"max":Ae(t,"maximum",n.value,n.message,e);break}return t};function gE(r,e){return{...ne(r.innerType._def,e),default:r.defaultValue()}}function fE(r,e){return e.effectStrategy==="input"?ne(r.schema._def,e):at(e)}function SE(r){return{type:"string",enum:Array.from(r.values)}}var eN=r=>"type"in r&&r.type==="string"?!1:"allOf"in r;function yE(r,e){let t=[ne(r.left._def,{...e,currentPath:[...e.currentPath,"allOf","0"]}),ne(r.right._def,{...e,currentPath:[...e.currentPath,"allOf","1"]})].filter(i=>!!i),n=e.target==="jsonSchema2019-09"?{unevaluatedProperties:!1}:void 0,o=[];return t.forEach(i=>{if(eN(i))o.push(...i.allOf),i.unevaluatedProperties===void 0&&(n=void 0);else{let a=i;if("additionalProperties"in i&&i.additionalProperties===!1){let{additionalProperties:s,...c}=i;a=c}else n=void 0;o.push(a)}}),o.length?{allOf:o,...n}:void 0}function EE(r,e){let t=typeof r.value;return t!=="bigint"&&t!=="number"&&t!=="boolean"&&t!=="string"?{type:Array.isArray(r.value)?"array":"object"}:e.target==="openApi3"?{type:t==="bigint"?"integer":t,enum:[r.value]}:{type:t==="bigint"?"integer":t,const:r.value}}import{ZodFirstPartyTypeKind as Hs}from"zod";var _m,Xr={cuid:/^[cC][^\s-]{8,}$/,cuid2:/^[0-9a-z]+$/,ulid:/^[0-9A-HJKMNP-TV-Z]{26}$/,email:/^(?!\.)(?!.*\.\.)([a-zA-Z0-9_'+\-\.]*)[a-zA-Z0-9_+-]@([a-zA-Z0-9][a-zA-Z0-9\-]*\.)+[a-zA-Z]{2,}$/,emoji:()=>(_m===void 0&&(_m=RegExp("^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$","u")),_m),uuid:/^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/,ipv4:/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/,ipv4Cidr:/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/(3[0-2]|[12]?[0-9])$/,ipv6:/^(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))$/,ipv6Cidr:/^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/,base64:/^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/,base64url:/^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z-_]{3}(=)?))?$/,nanoid:/^[a-zA-Z0-9_-]{21}$/,jwt:/^[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_]*$/};function Fc(r,e){let t={type:"string"};if(r.checks)for(let n of r.checks)switch(n.kind){case"min":Ae(t,"minLength",typeof t.minLength=="number"?Math.max(t.minLength,n.value):n.value,n.message,e);break;case"max":Ae(t,"maxLength",typeof t.maxLength=="number"?Math.min(t.maxLength,n.value):n.value,n.message,e);break;case"email":switch(e.emailStrategy){case"format:email":Jr(t,"email",n.message,e);break;case"format:idn-email":Jr(t,"idn-email",n.message,e);break;case"pattern:zod":rr(t,Xr.email,n.message,e);break}break;case"url":Jr(t,"uri",n.message,e);break;case"uuid":Jr(t,"uuid",n.message,e);break;case"regex":rr(t,n.regex,n.message,e);break;case"cuid":rr(t,Xr.cuid,n.message,e);break;case"cuid2":rr(t,Xr.cuid2,n.message,e);break;case"startsWith":rr(t,RegExp(`^${Mm(n.value,e)}`),n.message,e);break;case"endsWith":rr(t,RegExp(`${Mm(n.value,e)}$`),n.message,e);break;case"datetime":Jr(t,"date-time",n.message,e);break;case"date":Jr(t,"date",n.message,e);break;case"time":Jr(t,"time",n.message,e);break;case"duration":Jr(t,"duration",n.message,e);break;case"length":Ae(t,"minLength",typeof t.minLength=="number"?Math.max(t.minLength,n.value):n.value,n.message,e),Ae(t,"maxLength",typeof t.maxLength=="number"?Math.min(t.maxLength,n.value):n.value,n.message,e);break;case"includes":{rr(t,RegExp(Mm(n.value,e)),n.message,e);break}case"ip":{n.version!=="v6"&&Jr(t,"ipv4",n.message,e),n.version!=="v4"&&Jr(t,"ipv6",n.message,e);break}case"base64url":rr(t,Xr.base64url,n.message,e);break;case"jwt":rr(t,Xr.jwt,n.message,e);break;case"cidr":{n.version!=="v6"&&rr(t,Xr.ipv4Cidr,n.message,e),n.version!=="v4"&&rr(t,Xr.ipv6Cidr,n.message,e);break}case"emoji":rr(t,Xr.emoji(),n.message,e);break;case"ulid":{rr(t,Xr.ulid,n.message,e);break}case"base64":{switch(e.base64Strategy){case"format:binary":{Jr(t,"binary",n.message,e);break}case"contentEncoding:base64":{Ae(t,"contentEncoding","base64",n.message,e);break}case"pattern:zod":{rr(t,Xr.base64,n.message,e);break}}break}case"nanoid":rr(t,Xr.nanoid,n.message,e);case"toLowerCase":case"toUpperCase":case"trim":break;default:}return t}function Mm(r,e){return e.patternStrategy==="escape"?rN(r):r}var tN=new Set("ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvxyz0123456789");function rN(r){let e="";for(let t=0;t<r.length;t++)tN.has(r[t])||(e+="\\"),e+=r[t];return e}function Jr(r,e,t,n){r.format||r.anyOf?.some(o=>o.format)?(r.anyOf||(r.anyOf=[]),r.format&&(r.anyOf.push({format:r.format,...r.errorMessage&&n.errorMessages&&{errorMessage:{format:r.errorMessage.format}}}),delete r.format,r.errorMessage&&(delete r.errorMessage.format,Object.keys(r.errorMessage).length===0&&delete r.errorMessage)),r.anyOf.push({format:e,...t&&n.errorMessages&&{errorMessage:{format:t}}})):Ae(r,"format",e,t,n)}function rr(r,e,t,n){r.pattern||r.allOf?.some(o=>o.pattern)?(r.allOf||(r.allOf=[]),r.pattern&&(r.allOf.push({pattern:r.pattern,...r.errorMessage&&n.errorMessages&&{errorMessage:{pattern:r.errorMessage.pattern}}}),delete r.pattern,r.errorMessage&&(delete r.errorMessage.pattern,Object.keys(r.errorMessage).length===0&&delete r.errorMessage)),r.allOf.push({pattern:bE(e,n),...t&&n.errorMessages&&{errorMessage:{pattern:t}}})):Ae(r,"pattern",bE(e,n),t,n)}function bE(r,e){if(!e.applyRegexFlags||!r.flags)return r.source;let t={i:r.flags.includes("i"),m:r.flags.includes("m"),s:r.flags.includes("s")},n=t.i?r.source.toLowerCase():r.source,o="",i=!1,a=!1,s=!1;for(let c=0;c<n.length;c++){if(i){o+=n[c],i=!1;continue}if(t.i){if(a){if(n[c].match(/[a-z]/)){s?(o+=n[c],o+=`${n[c-2]}-${n[c]}`.toUpperCase(),s=!1):n[c+1]==="-"&&n[c+2]?.match(/[a-z]/)?(o+=n[c],s=!0):o+=`${n[c]}${n[c].toUpperCase()}`;continue}}else if(n[c].match(/[a-z]/)){o+=`[${n[c]}${n[c].toUpperCase()}]`;continue}}if(t.m){if(n[c]==="^"){o+=`(^|(?<=[\r
5
5
  ]))`;continue}else if(n[c]==="$"){o+=`($|(?=[\r
6
6
  ]))`;continue}}if(t.s&&n[c]==="."){o+=a?`${n[c]}\r
@@ -28,8 +28,8 @@ ${this.decisions.map(e=>e.toString()).join(`
28
28
  `);process.stderr.write(`${o}
29
29
  `),globalThis.console=e}}var bt=" ".repeat(6);function oR(r,e="",t=!1){let n=process.stdout?.columns||process.stderr?.columns||80,o=Math.max(n-e.length,20),i=r.split(`
30
30
  `),a=[];for(let s of i)if(t){let c=s;for(;c.length>o;){let u=c.slice(0,o+1).lastIndexOf(" "),d=u>-1?u:o;a.push(e+c.slice(0,d)),c=c.slice(d).trimStart()}a.push(e+c)}else{let c=s.split(" "),l="";for(let u of c){if(!l.length){l=u;continue}let d=`${l} ${u}`;d.length<=o?l=d:(a.push(e+l),l=u)}a.push(e+l)}return a.join(`
31
- `)}import wF from"fetch-retry";import CF from"os";import iR,{multistream as xF}from"pino";import _F from"pino-pretty";import MF from"pino-std-serializers";var _a=new Map,IF=!0,aR="Log throttle exceeded",PF=100,OF=5e3,LF=wF(global.fetch,{retries:2,retryOn:function(r,e,t){return!!(e!==null||t&&t.status>=500)},retryDelay:function(r){return Math.pow(2,r)*500}}),tg=class r{consoleLogger;hostname;bindingAttributes;disableConsoleLogs;minLevelValue=20;logsInCurrentWindow=0;droppedLogsInWindow=!1;lastWindowStart=Date.now();site="https://ingest.us.signoz.cloud:443/logs/json";flushIntervalMs;maxBatchSize;buffer=[];flushTimer;constructor({bindings:e,hostname:t,disableConsoleLogs:n,flushIntervalMs:o,maxBatchSize:i}){this.hostname=t??CF.hostname(),this.disableConsoleLogs=n,this.bindingAttributes={...e,env:"production"},this.flushIntervalMs=o??5e3,this.maxBatchSize=i??10;let a={base:this.bindingAttributes,errorKey:"err",level:"debug"};this.consoleLogger=IF?iR(a):iR(a,xF([{stream:_F({colorize:!0})}]))}child(e){return new r({bindings:{...this.bindingAttributes,...e},hostname:this.hostname,disableConsoleLogs:this.disableConsoleLogs,flushIntervalMs:this.flushIntervalMs,maxBatchSize:this.maxBatchSize})}async flush(){await this.flushBuffer(),this.disableConsoleLogs||this.consoleLogger.flush()}scheduleFlush(){this.flushTimer||(this.flushTimer=setTimeout(()=>{this.flushTimer=void 0,this.flushBuffer()},this.flushIntervalMs))}async flushBuffer(){if(this.buffer.length===0)return;let e=this.buffer;this.buffer=[];try{let t=await LF(this.site,{method:"POST",headers:{"Content-Type":"application/json","signoz-access-token":"CumAaTMUcwjt05OddAmefKgshbhfRmWxzxih"},body:Ti(e),signal:AbortSignal.timeout(5e3)});if(!t.ok)throw new Error(`Got error status (${t.statusText}) from SigNoz`)}catch{}}shouldAllowLog(e){if(e===aR)return!0;let t=Date.now();return t-this.lastWindowStart>OF&&(this.logsInCurrentWindow=0,this.droppedLogsInWindow&&this.log("error",void 0,aR),this.droppedLogsInWindow=!1,this.lastWindowStart=t),this.logsInCurrentWindow<PF?(this.logsInCurrentWindow++,!0):(this.droppedLogsInWindow=!0,!1)}log(e,t,n,...o){try{this.logHelper(e,t,n,...o)}catch(i){this.consoleLogger.warn(`Failed to log to Signoz: ${i}`)}}logHelper(e,t,n,...o){if(cl[e]<this.minLevelValue||!this.shouldAllowLog(n))return;typeof t=="string"&&!n&&(t={message:t}),typeof t=="object"&&t&&"err"in t&&t.err instanceof Error&&(t.err=MF.err(t.err));let i={...this.bindingAttributes,...t&&typeof t=="object"?t:{},...o.length>0?{args:o}:{}},a={host:this.hostname,env:this.bindingAttributes.env};this.disableConsoleLogs||this.consoleLogger[e](i,n,...o);let s={timestamp:Math.round(Date.now()*1e6),severity_text:e.toUpperCase(),resources:a,attributes:{},body:KT({message:n||"",...i})};this.buffer.push(s),this.buffer.length>=this.maxBatchSize?(this.flushTimer&&(clearTimeout(this.flushTimer),this.flushTimer=void 0),this.flushBuffer()):this.scheduleFlush()}setApp(e){let t=this.bindingAttributes.app;this.bindingAttributes.app=e,_a.set("app",this),_a.delete(t)}debug(e,t,...n){this.log("debug",e,t,...n)}info(e,t,...n){this.log("info",e,t,...n)}warn(e,t,...n){this.log("warn",e,t,...n)}error(e,t,...n){this.log("error",e,t,...n)}bindings(){return this.bindingAttributes}addBinding(e,t){this.bindingAttributes[e]=t}setMinLevel(e){typeof e=="number"?(this.minLevelValue=e,this.consoleLogger.level=YT[e]):(this.minLevelValue=cl[e],this.consoleLogger.level=e)}enableConsoleLogs(){this.disableConsoleLogs=!1}},Ma=({app:r,hostname:e,disableConsoleLogs:t})=>(_a.has(r)||_a.set(r,new tg({bindings:{app:r},hostname:e,disableConsoleLogs:t})),_a.get(r));async function lR(){await Promise.all([..._a.values()].map(r=>r.flush()))}import{hostname as NF}from"os";var X=Ma({app:"cli",hostname:NF(),disableConsoleLogs:!0}).child({cliVersion:"2.27.2"});var kF=5;async function Iu({getResults:r,checkDone:e,name:t,timeoutMs:n=18e5}){let o=Date.now(),i=0;for(;Date.now()-o<n;){let a;i>kF&&(E.error(`Failed to fetch ${t} status too many times.`),process.exit(1));try{a=await r(),i=0}catch(l){i++,X.warn({err:l},"Failed to fetch run status, retrying..."),E.warn({err:l},"Failed to fetch run status, retrying..."),await new Promise(u=>setTimeout(u,1500*i));continue}if(e(a))return a;let c=Math.max(1e4,Math.floor(n/100));await new Promise(l=>setTimeout(l,c))}E.error(`Timeout elapsed waiting for ${t} to complete (${Math.floor(n/1e3)}s).`),process.exit(1)}function Ia({results:r,startTime:e,entity:t,getDisplayLine:n,onFailed:o}){let i=r.filter(u=>u.status==="PASSED"&&u.quarantined),a=r.filter(u=>u.status==="PASSED"&&!u.quarantined),s=r.filter(u=>u.status==="FAILED"&&u.quarantined),c=r.filter(u=>u.status==="FAILED"&&!u.quarantined),l=r.filter(u=>u.status==="CANCELLED");return nR(()=>{if(c.forEach(u=>{E.log(""),o(u)}),c.length){E.log("");let u=c.length===1?"":"s";E.error(`${c.length} ${t}${u} failed:`),c.forEach(d=>{E.dimmed(n(d))})}if(l.length){E.log("");let u=l.length===1?"":"s";E.warn(`${l.length} ${t}${u} cancelled:`),l.forEach(d=>{E.dimmed(n(d))})}if(a.length){E.log("");let u=a.length===1?"":"s";E.success(`${a.length} ${t}${u} passed:`),a.forEach(d=>{E.dimmed(n(d))})}if(s.length){E.log("");let u=s.length===1?"":"s";E.warn(`${s.length} quarantined ${t}${u} failed:`),s.forEach(d=>{E.dimmed(n(d))})}if(i.length){E.log("");let u=i.length===1?"":"s";E.warn(`${i.length} quarantined ${t}${u} passed:`),i.forEach(d=>{E.dimmed(n(d))})}E.log(""),E.dimmed(`Total time: ${Math.round((Date.now()-e)/1e3)}s`)}),{quarantinedPassed:i.length,passed:a.length,quarantinedFailed:s.length,failed:c.length,cancelled:l.length}}var Pu=(r,e)=>{if(!r.failureDetails||!r.failureReason)return;let t=Bc[r.failureDetails?.classification?.reason||r.failureReason],n=r.failureDetails?.classification?.summary||da[r.failureReason],o=r.failureDetails.classification?.rootCause;if(E.error(e),o){E.log(`${bt}- Error type: ${Tn.dim(t)}`);let i="- Root cause analysis:",a=oR(`${i} ${o}`,`${bt} `,!1),s=a.indexOf(":");E.log(`${bt}${i} ${Tn.dim(a.slice(s+1))}`)}else E.log(`${bt}Reason: ${Tn.red(t)}`),E.log(`${bt}Description: ${Tn.red(n)}`)},ml=({status:r,testLogRef:e,getRunningTestsCount:t,getTotalTestsCount:n,additionalText:o})=>{r=r.toUpperCase();let i=r,a;r.includes("FAIL")?(i=Tn.bgRed.white("FAIL"),a=3):r.includes("PASS")?(i=Tn.bgGreen.white("PASS"),a=3):r.includes("START")?(i=Tn.bgBlue.white("START"),a=2):r.includes("CANCEL")?(i=Tn.bgRgb(191,68,11).white("CANCEL"),a=1):r.includes("RETRY")?(i=Tn.bgRgb(191,68,11).white("RETRY"),a=2):r.includes("RUN")||r.includes("PROG")?(i=Tn.bgMagenta.white("RUNNING"),a=0):(E.warn(`Unknown status tried to be logged in run test locally: ${r}`),a=0),DF||(i=`${i}`),E.log(`${i}${" ".repeat(a)} ${e} ${o?`${o} `:""}(${t()}/${n()})`)};import FF from"fs";import{tmpdir as UF}from"os";import BF from"path";import{registry as hl}from"playwright-core/lib/server";import cR from"proper-lockfile";var uR=BF.join(UF(),"momenticBrowserInstallation");var rg=["chrome","chromium","chrome-for-testing","ffmpeg"],HF={Chromium:"chromium","Google Chrome":"chrome","Chrome for Testing":"chrome-for-testing"},dR={chrome:"chrome",chromium:"chromium","chrome-for-testing":"chromium-headless-shell",ffmpeg:"ffmpeg"};function pR(r){let e=dR[HF[r]??""]??"",t=hl.findExecutable(e);return!t||t.installType==="none"?!1:ng(t)}function ng(r){let e=r.executablePath();return FF.existsSync(e)}function zF(r,e){let t=dR[r];if(!t)throw new Error(`Requested install of unknown browser type ${r}`);let n=hl.findExecutable(t);if(!n||n.installType==="none")throw new Error(`Requested install of unknown browser type ${r}`);if(!(!e&&ng(n)))return n}async function GF({browser:r,force:e}){let t=zF(r,e);if(!t){E.info(`Browser '${r}' is already installed, skipping...`);return}E.info(`Installing browser '${r}'...`);try{await hl.installDeps([t],!1),await hl.install([t],!1)}catch(n){if(n.message.includes("Lock file is already being held")){E.warn("Another process is installing Playwright browsers. Waiting for completion before proceeding..");let o=hl.findExecutable(r),i=5*60*1e3,a=Date.now();for(;Date.now()-a<i&&!ng(o);)E.info("Waiting for browser to finish installing..."),await new Promise(s=>setTimeout(s,5e3))}else throw n}}async function mR({rawBrowsers:r,force:e=!1,all:t=!1}){let n=t?rg:Array.from(new Set(r));try{await cR.lock(uR,{stale:1e3*60*5,update:1e3*60,realpath:!1,retries:{retries:30,factor:2,maxTimeout:15e3,minTimeout:500}})}catch(i){E.warn(`Failed to acquire lock to install browsers. Please ensure that any other process installing browsers completes within 5 minutes: ${i}. Continuing without installation...`);return}let o;try{for(let i of n)try{await GF({browser:i,force:e})}catch(a){o=a,E.error(`Failed to install the ${i} browser: ${a}`)}}finally{await cR.unlock(uR,{realpath:!1})}if(o)throw o}import jF from"blocked-at";import VF from"why-is-node-running";function hR(r){$F(r),WF()}function $F(r){jF((e,t)=>{console.warn(`Detected the NodeJS event loop was blocked for ${e.toFixed(0)}ms. This can cause the CLI to hang.`);let n=t.join(`
32
- `);console.warn(n),r.warn({stack:n,time:e},"NodeJS event loop blocked")},{threshold:1e3,trimFalsePositives:!0})}function WF(){process.on("SIGINT",()=>{if("_getActiveHandles"in process){let r=process._getActiveHandles();console.log("Active handles:",r.map(e=>e.constructor?.name))}VF(),setImmediate(()=>{setTimeout(()=>{process.exit(1)},2e3).unref()})})}import{randomUUID as l2}from"crypto";import FP from"body-parser";import Kq from"cors";import Yq from"dedent";import{Router as KU}from"express";import ar from"fs";import{globSync as YU}from"glob";import Ot from"path";import nd from"fs";import{z as tU}from"zod";var H="v1",og="cli",Ai="2.27.2";var wo=3.1783027;function qF(r){let e=0;for(let t=0;t<r.length;t++){let n=r.charCodeAt(t);!(n>=48&&n<=57)&&!(n>=65&&n<=90)&&!(n>=97&&n<=122)&&e++}return e}function Pe(r){return Math.ceil(ig(r)/wo)}function ig(r){let e=0;if(typeof r=="string"){let t=r;t=t.replaceAll(`
31
+ `)}import wF from"fetch-retry";import CF from"os";import iR,{multistream as xF}from"pino";import _F from"pino-pretty";import MF from"pino-std-serializers";var _a=new Map,IF=!0,aR="Log throttle exceeded",PF=100,OF=5e3,LF=wF(global.fetch,{retries:2,retryOn:function(r,e,t){return!!(e!==null||t&&t.status>=500)},retryDelay:function(r){return Math.pow(2,r)*500}}),tg=class r{consoleLogger;hostname;bindingAttributes;disableConsoleLogs;minLevelValue=20;logsInCurrentWindow=0;droppedLogsInWindow=!1;lastWindowStart=Date.now();site="https://ingest.us.signoz.cloud:443/logs/json";flushIntervalMs;maxBatchSize;buffer=[];flushTimer;constructor({bindings:e,hostname:t,disableConsoleLogs:n,flushIntervalMs:o,maxBatchSize:i}){this.hostname=t??CF.hostname(),this.disableConsoleLogs=n,this.bindingAttributes={...e,env:"production"},this.flushIntervalMs=o??5e3,this.maxBatchSize=i??10;let a={base:this.bindingAttributes,errorKey:"err",level:"debug"};this.consoleLogger=IF?iR(a):iR(a,xF([{stream:_F({colorize:!0})}]))}child(e){return new r({bindings:{...this.bindingAttributes,...e},hostname:this.hostname,disableConsoleLogs:this.disableConsoleLogs,flushIntervalMs:this.flushIntervalMs,maxBatchSize:this.maxBatchSize})}async flush(){await this.flushBuffer(),this.disableConsoleLogs||this.consoleLogger.flush()}scheduleFlush(){this.flushTimer||(this.flushTimer=setTimeout(()=>{this.flushTimer=void 0,this.flushBuffer()},this.flushIntervalMs))}async flushBuffer(){if(this.buffer.length===0)return;let e=this.buffer;this.buffer=[];try{let t=await LF(this.site,{method:"POST",headers:{"Content-Type":"application/json","signoz-access-token":"CumAaTMUcwjt05OddAmefKgshbhfRmWxzxih"},body:Ti(e),signal:AbortSignal.timeout(5e3)});if(!t.ok)throw new Error(`Got error status (${t.statusText}) from SigNoz`)}catch{}}shouldAllowLog(e){if(e===aR)return!0;let t=Date.now();return t-this.lastWindowStart>OF&&(this.logsInCurrentWindow=0,this.droppedLogsInWindow&&this.log("error",void 0,aR),this.droppedLogsInWindow=!1,this.lastWindowStart=t),this.logsInCurrentWindow<PF?(this.logsInCurrentWindow++,!0):(this.droppedLogsInWindow=!0,!1)}log(e,t,n,...o){try{this.logHelper(e,t,n,...o)}catch(i){this.consoleLogger.warn(`Failed to log to Signoz: ${i}`)}}logHelper(e,t,n,...o){if(cl[e]<this.minLevelValue||!this.shouldAllowLog(n))return;typeof t=="string"&&!n&&(t={message:t}),typeof t=="object"&&t&&"err"in t&&t.err instanceof Error&&(t.err=MF.err(t.err));let i={...this.bindingAttributes,...t&&typeof t=="object"?t:{},...o.length>0?{args:o}:{}},a={host:this.hostname,env:this.bindingAttributes.env};this.disableConsoleLogs||this.consoleLogger[e](i,n,...o);let s={timestamp:Math.round(Date.now()*1e6),severity_text:e.toUpperCase(),resources:a,attributes:{},body:KT({message:n||"",...i})};this.buffer.push(s),this.buffer.length>=this.maxBatchSize?(this.flushTimer&&(clearTimeout(this.flushTimer),this.flushTimer=void 0),this.flushBuffer()):this.scheduleFlush()}setApp(e){let t=this.bindingAttributes.app;this.bindingAttributes.app=e,_a.set("app",this),_a.delete(t)}debug(e,t,...n){this.log("debug",e,t,...n)}info(e,t,...n){this.log("info",e,t,...n)}warn(e,t,...n){this.log("warn",e,t,...n)}error(e,t,...n){this.log("error",e,t,...n)}bindings(){return this.bindingAttributes}addBinding(e,t){this.bindingAttributes[e]=t}setMinLevel(e){typeof e=="number"?(this.minLevelValue=e,this.consoleLogger.level=YT[e]):(this.minLevelValue=cl[e],this.consoleLogger.level=e)}enableConsoleLogs(){this.disableConsoleLogs=!1}},Ma=({app:r,hostname:e,disableConsoleLogs:t})=>(_a.has(r)||_a.set(r,new tg({bindings:{app:r},hostname:e,disableConsoleLogs:t})),_a.get(r));async function lR(){await Promise.all([..._a.values()].map(r=>r.flush()))}import{hostname as NF}from"os";var X=Ma({app:"cli",hostname:NF(),disableConsoleLogs:!0}).child({cliVersion:"2.28.1"});var kF=5;async function Iu({getResults:r,checkDone:e,name:t,timeoutMs:n=18e5}){let o=Date.now(),i=0;for(;Date.now()-o<n;){let a;i>kF&&(E.error(`Failed to fetch ${t} status too many times.`),process.exit(1));try{a=await r(),i=0}catch(l){i++,X.warn({err:l},"Failed to fetch run status, retrying..."),E.warn({err:l},"Failed to fetch run status, retrying..."),await new Promise(u=>setTimeout(u,1500*i));continue}if(e(a))return a;let c=Math.max(1e4,Math.floor(n/100));await new Promise(l=>setTimeout(l,c))}E.error(`Timeout elapsed waiting for ${t} to complete (${Math.floor(n/1e3)}s).`),process.exit(1)}function Ia({results:r,startTime:e,entity:t,getDisplayLine:n,onFailed:o}){let i=r.filter(u=>u.status==="PASSED"&&u.quarantined),a=r.filter(u=>u.status==="PASSED"&&!u.quarantined),s=r.filter(u=>u.status==="FAILED"&&u.quarantined),c=r.filter(u=>u.status==="FAILED"&&!u.quarantined),l=r.filter(u=>u.status==="CANCELLED");return nR(()=>{if(c.forEach(u=>{E.log(""),o(u)}),c.length){E.log("");let u=c.length===1?"":"s";E.error(`${c.length} ${t}${u} failed:`),c.forEach(d=>{E.dimmed(n(d))})}if(l.length){E.log("");let u=l.length===1?"":"s";E.warn(`${l.length} ${t}${u} cancelled:`),l.forEach(d=>{E.dimmed(n(d))})}if(a.length){E.log("");let u=a.length===1?"":"s";E.success(`${a.length} ${t}${u} passed:`),a.forEach(d=>{E.dimmed(n(d))})}if(s.length){E.log("");let u=s.length===1?"":"s";E.warn(`${s.length} quarantined ${t}${u} failed:`),s.forEach(d=>{E.dimmed(n(d))})}if(i.length){E.log("");let u=i.length===1?"":"s";E.warn(`${i.length} quarantined ${t}${u} passed:`),i.forEach(d=>{E.dimmed(n(d))})}E.log(""),E.dimmed(`Total time: ${Math.round((Date.now()-e)/1e3)}s`)}),{quarantinedPassed:i.length,passed:a.length,quarantinedFailed:s.length,failed:c.length,cancelled:l.length}}var Pu=(r,e)=>{if(!r.failureDetails||!r.failureReason)return;let t=Bc[r.failureDetails?.classification?.reason||r.failureReason],n=r.failureDetails?.classification?.summary||da[r.failureReason],o=r.failureDetails.classification?.rootCause;if(E.error(e),o){E.log(`${bt}- Error type: ${Tn.dim(t)}`);let i="- Root cause analysis:",a=oR(`${i} ${o}`,`${bt} `,!1),s=a.indexOf(":");E.log(`${bt}${i} ${Tn.dim(a.slice(s+1))}`)}else E.log(`${bt}Reason: ${Tn.red(t)}`),E.log(`${bt}Description: ${Tn.red(n)}`)},ml=({status:r,testLogRef:e,getRunningTestsCount:t,getTotalTestsCount:n,additionalText:o})=>{r=r.toUpperCase();let i=r,a;r.includes("FAIL")?(i=Tn.bgRed.white("FAIL"),a=3):r.includes("PASS")?(i=Tn.bgGreen.white("PASS"),a=3):r.includes("START")?(i=Tn.bgBlue.white("START"),a=2):r.includes("CANCEL")?(i=Tn.bgRgb(191,68,11).white("CANCEL"),a=1):r.includes("RETRY")?(i=Tn.bgRgb(191,68,11).white("RETRY"),a=2):r.includes("RUN")||r.includes("PROG")?(i=Tn.bgMagenta.white("RUNNING"),a=0):(E.warn(`Unknown status tried to be logged in run test locally: ${r}`),a=0),DF||(i=`${i}`),E.log(`${i}${" ".repeat(a)} ${e} ${o?`${o} `:""}(${t()}/${n()})`)};import FF from"fs";import{tmpdir as UF}from"os";import BF from"path";import{registry as hl}from"playwright-core/lib/server";import cR from"proper-lockfile";var uR=BF.join(UF(),"momenticBrowserInstallation");var rg=["chrome","chromium","chrome-for-testing","ffmpeg"],HF={Chromium:"chromium","Google Chrome":"chrome","Chrome for Testing":"chrome-for-testing"},dR={chrome:"chrome",chromium:"chromium","chrome-for-testing":"chromium-headless-shell",ffmpeg:"ffmpeg"};function pR(r){let e=dR[HF[r]??""]??"",t=hl.findExecutable(e);return!t||t.installType==="none"?!1:ng(t)}function ng(r){let e=r.executablePath();return FF.existsSync(e)}function zF(r,e){let t=dR[r];if(!t)throw new Error(`Requested install of unknown browser type ${r}`);let n=hl.findExecutable(t);if(!n||n.installType==="none")throw new Error(`Requested install of unknown browser type ${r}`);if(!(!e&&ng(n)))return n}async function GF({browser:r,force:e}){let t=zF(r,e);if(!t){E.info(`Browser '${r}' is already installed, skipping...`);return}E.info(`Installing browser '${r}'...`);try{await hl.installDeps([t],!1),await hl.install([t],!1)}catch(n){if(n.message.includes("Lock file is already being held")){E.warn("Another process is installing Playwright browsers. Waiting for completion before proceeding..");let o=hl.findExecutable(r),i=5*60*1e3,a=Date.now();for(;Date.now()-a<i&&!ng(o);)E.info("Waiting for browser to finish installing..."),await new Promise(s=>setTimeout(s,5e3))}else throw n}}async function mR({rawBrowsers:r,force:e=!1,all:t=!1}){let n=t?rg:Array.from(new Set(r));try{await cR.lock(uR,{stale:1e3*60*5,update:1e3*60,realpath:!1,retries:{retries:30,factor:2,maxTimeout:15e3,minTimeout:500}})}catch(i){E.warn(`Failed to acquire lock to install browsers. Please ensure that any other process installing browsers completes within 5 minutes: ${i}. Continuing without installation...`);return}let o;try{for(let i of n)try{await GF({browser:i,force:e})}catch(a){o=a,E.error(`Failed to install the ${i} browser: ${a}`)}}finally{await cR.unlock(uR,{realpath:!1})}if(o)throw o}import jF from"blocked-at";import VF from"why-is-node-running";function hR(r){$F(r),WF()}function $F(r){jF((e,t)=>{console.warn(`Detected the NodeJS event loop was blocked for ${e.toFixed(0)}ms. This can cause the CLI to hang.`);let n=t.join(`
32
+ `);console.warn(n),r.warn({stack:n,time:e},"NodeJS event loop blocked")},{threshold:1e3,trimFalsePositives:!0})}function WF(){process.on("SIGINT",()=>{if("_getActiveHandles"in process){let r=process._getActiveHandles();console.log("Active handles:",r.map(e=>e.constructor?.name))}VF(),setImmediate(()=>{setTimeout(()=>{process.exit(1)},2e3).unref()})})}import{randomUUID as l2}from"crypto";import FP from"body-parser";import Kq from"cors";import Yq from"dedent";import{Router as KU}from"express";import ar from"fs";import{globSync as YU}from"glob";import Ot from"path";import nd from"fs";import{z as tU}from"zod";var H="v1",og="cli",Ai="2.28.1";var wo=3.1783027;function qF(r){let e=0;for(let t=0;t<r.length;t++){let n=r.charCodeAt(t);!(n>=48&&n<=57)&&!(n>=65&&n<=90)&&!(n>=97&&n<=122)&&e++}return e}function Pe(r){return Math.ceil(ig(r)/wo)}function ig(r){let e=0;if(typeof r=="string"){let t=r;t=t.replaceAll(`
33
33
  `,""),t=t.replaceAll(" ","");let n=qF(t);return t.length-n+wo*n}if(typeof r>"u"||r===null)return 0;if(typeof r=="number")return String(r).length;if(Array.isArray(r))return r.forEach(t=>{e+=ig(t)}),e;if(typeof r=="object"){let t=r;return t.type==="image"||t.type==="media"&&"data"in t&&"mediaType"in t&&typeof t.mediaType=="string"&&t.mediaType.includes("jpeg")?1600:(Object.keys(t).forEach(n=>{e+=String(n).length,n==="image_url"?(t[n]??{}).detail==="high"?e+=1105*wo:e+=85*wo:n==="source"&&typeof t[n]=="object"&&t[n]?.type==="base64"?e+=1600*wo:e+=ig(t[n])}),e)}if(typeof r=="boolean")return r?4:5;throw new Error(`Unsupported type passed to token length calculator '${typeof r}': ${r}`)}var Co=class extends Error{constructor(e){super(e),this.name="TimeoutError"}};var gR=r=>{let e=r.reason===void 0?new DOMException("This operation was aborted.","AbortError"):r.reason;return e instanceof Error?e:new DOMException(e,"AbortError")};function j(r,e){let{milliseconds:t,fallback:n,message:o,customTimers:i={setTimeout,clearTimeout}}=e,a;if(typeof t!="number"||Math.sign(t)!==1)throw new TypeError(`Expected \`milliseconds\` to be a positive number, got \`${t}\``);return new Promise((s,c)=>{let l;if(e.signal){let{signal:p}=e;if(p.aborted)return c(gR(p));l=()=>c(gR(p)),p.addEventListener("abort",l,{once:!0})}let u=()=>{if(e.signal&&e.signal.removeEventListener("abort",l),n)try{s(n())}catch(p){c(p)}else{typeof r.cancel=="function"&&Promise.resolve().then(()=>r.cancel()).catch(()=>{});let p=o instanceof Error?o:new Co(o??`Promise timed out after ${t}ms`);c(p)}};t<1/0&&(a=i.setTimeout(u,t));let d=()=>{i.clearTimeout(a),e.signal&&e.signal.removeEventListener("abort",l)};Promise.resolve(r).then(p=>{d(),s(p)}).catch(p=>{d(),c(p)})})}var Ou=class{limit;windowMs;userActions;constructor(e,t){this.limit=e,this.windowMs=t,this.userActions=new Map}_cleanup(e,t="DEFAULT_USER"){let n=Date.now(),o=`${t}:${e}`;if(this.userActions.has(o)){let a=this.userActions.get(o)?.filter(s=>n-s<=this.windowMs)??[];a.length>0?this.userActions.set(o,a):this.userActions.delete(o)}}increment(e,t="DEFAULT_USER"){let n=Date.now(),o=`${t}:${e}`;this._cleanup(t,e),this.userActions.has(o)||this.userActions.set(o,[]);let i=this.userActions.get(o);return i.length>=this.limit?!0:(i.push(n),!1)}};var KF=9e4,YF=3,XF=1500,JF=15e3,tn=class extends Error{status;rawError;constructor(e,t,n,o={}){super(n,o),this.status=e,this.rawError=t}};async function QF(r){return r.text().then(e=>{try{return JSON.parse(e).error}catch{return e}})}var ag=class{baseUrl;logger;constructor(e){this.baseUrl=e.baseUrl,this.logger=e.logger}getHeaders(){let e={"Content-Type":"application/json"};return Ai&&(e[wu]=Ai),og&&(e[tv]=og),e}async sendRequest(e,t){let{retries:n=YF,requestTimeoutMs:o=KF,initialRetryDelayMs:i=XF,maxRetryDelayMs:a=JF,onFailedRequest:s}=t,c=n,l=n,u,d={path:e,baseUrl:this.baseUrl,method:t.method};for(;c>0;)try{return c--,await this.sendSingleRequestHelper(e,t,o)}catch(p){u=p;try{s?.(u)}catch{}if(p instanceof tn&&p.status>=400&&p.status<500)throw p;if(p instanceof Error&&p.name==="AbortError"&&(u=new Co),c===0)throw u;let m=l-c,h=Math.min(i*Math.pow(2,m-1),a);await new Promise(g=>setTimeout(g,h))}throw this.logger.warn({...d,err:u},"Got fatal error response from Momentic server"),u}async sendSingleRequestHelper(e,t,n){let o={path:e,baseUrl:this.baseUrl,method:t.method},i=new AbortController,a=setTimeout(()=>i.abort(),n),s=()=>i.abort();t.signal&&t.signal.addEventListener("abort",s,{once:!0});let c=Date.now(),l={...this.getHeaders(),...t.extraHeaders};try{let u=await fetch(`${this.baseUrl}${e}`,{method:t.method,body:t.body?JSON.stringify(t.body):void 0,headers:l,signal:i.signal});if(!u.ok){let p=await QF(u);throw new tn(u.status,p,`Request to ${t.method} ${e} failed with status ${u.status}: ${p}`)}let d;if(u.status===204)d={};else{let p=await u.text();try{d=JSON.parse(p)}catch{d=p}}return this.logger&&t.logResponse===!0&&d&&this.logger.debug({result:d,status:u.status,durationMs:Date.now()-c,...o},"Got response from Momentic server"),d}finally{clearTimeout(a),t.signal&&t.signal.removeEventListener("abort",s)}}},Bt=class extends ag{apiKey;mode;constructor(e){super(e),this.apiKey=e.apiKey,this.mode=e.mode}getHeaders(){return{...super.getHeaders(),Authorization:`Bearer ${this.apiKey}`,[ev]:this.mode??""}}};import{createAnthropic as ZF}from"@ai-sdk/anthropic";function eU(r){let{apiKey:e,sessionId:t,extraHeaders:n,loggerTags:o}=r,i={Authorization:`Bearer ${e}`,[wu]:Ai??"",...t&&{[nv]:t},...n||{}};return o&&(i[rv]=JSON.stringify(o)),i}var gl=r=>e=>{let t=eU(r);return ZF({baseURL:`${r.baseUrl}/v1/llm/anthropic/${e}`,headers:t,apiKey:r.apiKey})(e)};var qn=class extends Bt{agentConfig;constructor(e,t){let n={...lu,...e};super(t),this.agentConfig=n}getAgentConfig(){return this.agentConfig}async rankChunksWithAi(e,t){let n={...e,loggerTags:t.loggerTags},o=await this.sendRequest(`/${H}/web-agent/recommend-chunks-ai`,{method:"POST",body:n,signal:t.abortSignal});return Bb.parse(o)}async rankChunksWithRag(e,t){let n=await this.sendRequest(`/${H}/web-agent/recommend-chunks`,{method:"POST",body:{cliVersion:Ai,...e},signal:t.abortSignal});return Ub.parse(n)}async getScreenshotFromS3(e){let t=await this.sendRequest(`/${H}/s3/visual-diff-screenshot`,{method:"POST",body:{url:e}});return tU.string().parse(t)}async getElementLocation(e,t){let n={...e,disableCache:t.disableCache,loggerTags:t.loggerTags,useMemory:t.useMemory,agentConfigVersion:this.agentConfig?.locator},o=await this.sendRequest(`/${H}/web-agent/locate-element`,{method:"POST",body:n,signal:t.abortSignal});return sv.parse(o)}async getAssertionResult(e,t){let n={...e,disableCache:!!t.disableCache,useConsensus:!!t.useConsensus,attemptNumber:t.attemptNumber,loggerTags:t.loggerTags,useMemory:t.useMemory,agentConfigVersion:this.agentConfig?.assertion},o=await this.sendRequest(`/${H}/web-agent/assertion`,{method:"POST",body:n,signal:t.abortSignal});return jh.parse(o)}async getLintStepResult(e,t){let n={...e,disableCache:!!t.disableCache,loggerTags:t.loggerTags},o=await this.sendRequest(`/${H}/web-agent/lint/step`,{method:"POST",body:n,signal:t.abortSignal});return av.parse(o)}async getLintMcpCopilotMessageResult(e,t){let n={message:e.message,disableCache:!!t.disableCache,loggerTags:t.loggerTags},o=await this.sendRequest(`/${H}/web-agent/lint/mcp-copilot`,{method:"POST",body:n,signal:t.abortSignal});return iv.parse(o)}async getVisualAssertionResult(e,t){let n={...e,disableCache:!!t.disableCache,useConsensus:!!t.useConsensus,attemptNumber:t.attemptNumber,loggerTags:t.loggerTags,useMemory:t.useMemory,agentConfigVersion:this.agentConfig?.["visual-assertion"]},o=await this.sendRequest(`/${H}/web-agent/visual-assertion`,{method:"POST",body:n,signal:t.abortSignal});return jh.parse(o)}async getAiActionCommand(e,t){let n=await this.sendRequest(`/${H}/web-agent/next-command-dynamic`,{method:"POST",body:{...e,disableCache:t.disableCache,loggerTags:t.loggerTags},signal:t.abortSignal});return ov.parse(n)}async getMultiturnAiActionCommand(e,t){return await this.sendRequest(`/${H}/web-agent/ai-action/next-command`,{method:"POST",body:{...e,disableCache:t.disableCache,loggerTags:t.loggerTags},signal:t.abortSignal})}async getMultiturnAiActionEvaluation(e,t){let n=await this.sendRequest(`/${H}/web-agent/ai-action/evaluate`,{method:"POST",body:{...e,disableCache:t.disableCache,loggerTags:t.loggerTags},signal:t.abortSignal});return eh.parse(n)}async getReverseMappedDescription(e,t){let n=await this.sendRequest(`/${H}/web-agent/reverse-mapped-description`,{method:"POST",body:{...e,disableCache:t.disableCache,loggerTags:t.loggerTags},signal:t.abortSignal});return lv.parse(n)}async getTextExtraction(e,t){let n={...e,disableCache:t.disableCache,loggerTags:t.loggerTags,agentConfigVersion:this.agentConfig?.["text-extraction"]},o=await this.sendRequest(`/${H}/web-agent/text-extraction`,{method:"POST",body:n,signal:t.abortSignal});return Jm.parse(o)}async getPageSummary(e,t){let n={...e,disableCache:t.disableCache,loggerTags:t.loggerTags},o=await this.sendRequest(`/${H}/web-agent/page-summary`,{method:"POST",body:n,signal:t.abortSignal});return gb.parse(o)}async getSmartWaitingDecision(e,t){let n={...e,disableCache:t.disableCache,loggerTags:t.loggerTags},o=await this.sendRequest(`/${H}/web-agent/smart-waiting`,{method:"POST",body:n,signal:t.abortSignal});return fb.parse(o)}async getTestResultClassification(e,t){let n=await this.sendRequest(`/${H}/web-agent/result-classification`,{method:"POST",body:{...e,loggerTags:t.loggerTags},signal:t.abortSignal});return Im.parse(n)}async getExtractedKeywords(e,t){let n=await this.sendRequest(`/${H}/web-agent/extract-keywords`,{method:"POST",body:e,signal:t.abortSignal});return Jb.parse(n)}async getAutohealingProposal(e,t){let n=await this.sendRequest(`/${H}/web-agent/autoheal-section`,{method:"POST",body:{...e,loggerTags:t.loggerTags},signal:t.abortSignal});return db.parse(n)}async getFailureRecoveryProposal(e,t){let n=await this.sendRequest(`/${H}/web-agent/failure-recovery`,{method:"POST",body:{...e,loggerTags:t.loggerTags},signal:t.abortSignal});return mb.parse(n)}async getFailureRecoveryPlan(e,t){let n=await this.sendRequest(`/${H}/web-agent/failure-recovery-plan`,{method:"POST",body:{...e,loggerTags:t.loggerTags},signal:t.abortSignal});return pb.parse(n)}async getIframeRegex(e,t){let n=await this.sendRequest(`/${H}/web-agent/iframe-regex`,{method:"POST",body:e,signal:t.abortSignal});return xy.parse(n)}getVercelAnthropicModelFactory({loggerTags:e}){return gl({baseUrl:this.baseUrl,apiKey:this.apiKey,loggerTags:e})}};import{z as sg}from"zod";var Qe=class extends Bt{constructor(e){super({...e,mode:void 0})}getAppUrl(){return this.baseUrl==="http://localhost:8000"?"http://localhost:3000":this.baseUrl.replace(/\/\/api/,"//app")}async getAuthInfo(){let e=await this.sendRequest(`/${H}/auth/check`,{method:"GET",retries:10,requestTimeoutMs:5e3,onFailedRequest:t=>{E.warn(`API key check failed: ${t.message}`)}});return Tv.parse(e)}async bulkGetRunStatus(e){let t=await this.sendRequest(`/${H}/runs/status`,{method:"POST",body:e,retries:3,requestTimeoutMs:1e4});return Sv.parse(t)}async getTestYAMLExport(e){let t=await this.sendRequest(`/${H}/tests/export`,{method:"POST",body:e,retries:3,requestTimeoutMs:3e4});return uv.parse(t)}async updateStepCaches(e,t){await this.sendRequest(`/${H}/cache`,{method:"PATCH",body:e,extraHeaders:t,retries:3,requestTimeoutMs:1e4,initialRetryDelayMs:3e3})}async getStepCacheForTest(e,t){let n=await this.sendRequest(`/${H}/cache`,{method:"POST",body:e,extraHeaders:t,retries:10,requestTimeoutMs:3e4,initialRetryDelayMs:3e3});return pv.parse(n)}async updateMobileStepCaches(e,t){await this.sendRequest(`/${H}/mobile-cache`,{method:"PATCH",body:e,extraHeaders:t,retries:3,requestTimeoutMs:1e4,initialRetryDelayMs:3e3})}async getMobileStepCacheForTest(e,t){let n=await this.sendRequest(`/${H}/mobile-cache`,{method:"POST",body:e,extraHeaders:t,retries:10,requestTimeoutMs:3e4,initialRetryDelayMs:3e3});return mv.parse(n)}async queueTests(e){let t=await this.sendRequest(`/${H}/tests/queue`,{method:"POST",body:e,retries:3,requestTimeoutMs:1e4});return cv.parse(t)}async uploadScreenshot(e){let t=await this.sendRequest(`/${H}/screenshots`,{method:"POST",body:e,retries:3,requestTimeoutMs:5e3});return bv.parse(t)}async getAllEnvironments(){let e=await this.sendRequest(`/${H}/environments`,{method:"GET",retries:3,requestTimeoutMs:5e3});return vv.parse(e)}async acquireCacheLock(e,t){let n=await this.sendRequest(`/${H}/result-cache/lock`,{method:"POST",body:e,signal:t,retries:3,requestTimeoutMs:3e4});return Fv.parse(n)}async releaseCacheLock(e){await this.sendRequest(`/${H}/result-cache/lock`,{method:"DELETE",body:{key:e},retries:3,requestTimeoutMs:5e3})}async deleteCacheResult(e){await this.sendRequest(`/${H}/result-cache/entry`,{method:"DELETE",body:e,retries:3,requestTimeoutMs:5e3})}async setCacheResult(e){await this.sendRequest(`/${H}/result-cache/entry`,{method:"PATCH",body:e,retries:3,requestTimeoutMs:5e3})}async getCacheResult(e){try{return await this.sendRequest(`/${H}/result-cache/entry`,{method:"POST",body:e,retries:3,requestTimeoutMs:5e3})}catch(t){if(t instanceof Error&&t.message.includes("404"))return null;throw t}}async queueSuiteRuns(e){let t=await this.sendRequest(`/${H}/suites/queue`,{method:"POST",body:e,retries:3,requestTimeoutMs:5e3});return Rv.parse(t)}async bulkGetRunGroupStatus(e){let t={runGroupIds:e},n=await this.sendRequest(`/${H}/run-groups/status`,{method:"POST",body:t,retries:3,requestTimeoutMs:5e3});return Lb.array().parse(n)}async uploadProposedSteps(e,t){try{await this.sendRequest(`/${H}/test-fragments/`,{method:"POST",body:e,retries:3,requestTimeoutMs:1e4})}catch(n){t.error({err:n},"Failed to upload proposed steps")}}async reportBillableEvents(e,t){try{await this.sendRequest(`/${H}/billing/events`,{method:"POST",body:t,retries:10,requestTimeoutMs:1e4})}catch(n){e.error({err:n},"Failed to report billable event")}}async fetchTestFragment(e){let t=await this.sendRequest(`/${H}/test-fragments/${e}`,{method:"GET",retries:3,requestTimeoutMs:1e4});return Av.parse(t)}async patchTestFragment(e,t){await this.sendRequest(`/${H}/test-fragments/${e}`,{method:"PATCH",body:t,retries:3,requestTimeoutMs:1e4})}async getPastTestResults(e,t){let n=await this.sendRequest(`/${H}/results/tests/${e}`,{method:"POST",body:t,retries:3,requestTimeoutMs:1e4});return wv.parse(n)}async generateTestResultsUploadUrl(){let e=await this.sendRequest(`/${H}/results/uploads`,{method:"POST",retries:3,requestTimeoutMs:1e4});return Cv.parse(e)}async startProcessingResultsUpload(e,t){let n=await this.sendRequest(`/${H}/results/uploads/${e}/process`,{method:"POST",body:t,retries:3,requestTimeoutMs:1e4});return xv.parse(n)}async fetchIconKnowledgeBase(e){try{let t=await this.sendRequest(`/${H}/knowledge-base/icons`,{method:"GET",retries:3,requestTimeoutMs:5e3});return Gv.parse(t)}catch(t){return e.error({err:t},"Failed to fetch icon knowledge base"),null}}async saveNewIcons(e,t){try{await this.sendRequest(`/${H}/knowledge-base/icons`,{method:"POST",body:e,retries:3,requestTimeoutMs:5e3})}catch(n){t.error({err:n},"Failed to save new icons to icon knowledge base")}}async getMergeBaseCommitFromGithub(e,t,n,o){let i=new URLSearchParams;i.set("base",n),i.set("head",o);let a=await this.sendRequest(`/${H}/git/github/${e}/${t}/merge-base-commit?${i.toString()}`,{method:"GET",retries:3,requestTimeoutMs:1e4});return ul.parse(a)}async getCommitFromGithub(e,t,n){let o=await this.sendRequest(`/${H}/git/github/${e}/${t}/commits/${n}`,{method:"GET",retries:3,requestTimeoutMs:1e4});return ul.parse(o)}async getMergedBranchFromGithub(e,t,n,o){let i=encodeURIComponent(n),a=await this.sendRequest(`/${H}/git/github/${e}/${t}/${i}/${o}/merged-branch`,{method:"GET",retries:3,requestTimeoutMs:1e4});return qh.parse(a)}async getMergeBaseCommitFromGitlab(e,t,n){let o=new URLSearchParams;o.set("base",t),o.set("head",n);let i=encodeURIComponent(e),a=await this.sendRequest(`/${H}/git/gitlab/${i}/merge-base-commit?${o.toString()}`,{method:"GET",retries:3,requestTimeoutMs:5e3});return ul.parse(a)}async getCommitFromGitlab(e,t){let n=encodeURIComponent(e),o=await this.sendRequest(`/${H}/git/gitlab/${n}/commits/${t}`,{method:"GET",retries:3,requestTimeoutMs:1e4});return ul.parse(o)}async getMergedBranchFromGitlab(e,t,n){let o=encodeURIComponent(t),i=encodeURIComponent(e),a=await this.sendRequest(`/${H}/git/gitlab/${i}/${o}/${n}/merged-branch`,{method:"GET",retries:3,requestTimeoutMs:1e4});return qh.parse(a)}async getAgentConfig(){let e=await this.sendRequest(`/${H}/web-agent/agent-config`,{method:"GET",retries:3,requestTimeoutMs:5e3});return sg.record(sg.string(),sg.string()).parse(e)}async getQuarantinedTests(){let e=await this.sendRequest(`/${H}/quarantine`,{method:"GET"});return _v.parse(e)}async quarantineTest(e,t,n){await this.sendRequest(`/${H}/quarantine`,{method:"POST",body:{testId:e.id,testName:e.name,reason:t,...n??{}},retries:3,requestTimeoutMs:1e4})}async unquarantineTest(e,t,n){await this.sendRequest(`/${H}/quarantine/${e.id}`,{method:"DELETE",body:{testName:e.name,reason:t,...n??{}},retries:3,requestTimeoutMs:1e4})}async createAndroidEmulator(e){let t=await this.sendRequest(`/${H}/limbar/android`,{method:"POST",retries:3,body:e,requestTimeoutMs:9e4,initialRetryDelayMs:5e3,maxRetryDelayMs:15e3});return Mv.parse(t)}async extendAndroidEmulatorTtl(e){try{await this.sendRequest(`/${H}/limbar/android/${e}/keepalive`,{method:"POST",retries:3,requestTimeoutMs:15e3})}catch{}}async generateAndroidAssetUrls({channel:e,tag:t,md5:n}){let o={channel:e,tag:t,md5:n},i=await this.sendRequest(`/${H}/limbar/android/upload-url`,{method:"POST",retries:3,body:o,requestTimeoutMs:15e3,logResponse:!0});return Iv.parse(i)}async deleteAndroidEmulator(e){await this.sendRequest(`/${H}/limbar/android/${e}`,{method:"DELETE",retries:3,requestTimeoutMs:3e4})}async getAndroidAssets(){let e=await this.sendRequest(`/${H}/limbar/assets`,{method:"GET",retries:3,requestTimeoutMs:1e4});return Pv.parse(e)}async deleteAndroidAsset(e,t){await this.sendRequest(`/${H}/limbar/assets/${e}/${t}`,{method:"DELETE",retries:3,requestTimeoutMs:1e4})}};async function lg(r){let e=process.versions.node,t=parseInt(e.split(".")[0]);(isNaN(t)||t<18)&&(E.error(`Node.js version 20 or higher is required to run the CLI. Detected: ${process.versions.node}.`),process.exit(1)),E.debug(`Identified node version ${e}`);let n=await r.client.getAuthInfo();return E.debug("Got auth info from API"),n}var Lu=class{apiClient;constructor(e){this.apiClient=e}async reportBillableEvents(e,t){await this.apiClient.reportBillableEvents(e,t)}};var xo=class extends Bt{generator;constructor(e,t){super(e),this.generator=t}async runTemplateMatching(e,t={}){let n=await this.sendRequest(`/${H}/web-agent/template-matching`,{method:"POST",body:e,signal:t?.signal});return _y.parse(n)}async constructIframeRegex(e,t={}){return this.generator.getIframeRegex(e,{abortSignal:t.signal})}};var Pa=class{constructor(e,t){this.client=e;this.orgId=t}async acquireCacheLock(e,t){return this.client.acquireCacheLock(e,t)}async uploadScreenshot(e){return(await this.client.uploadScreenshot({screenshot:e.toString("base64")})).key}async releaseCacheLock(e){return this.client.releaseCacheLock(e)}async deleteCacheResult(e){return this.client.deleteCacheResult(e)}async setCacheResult(e){return this.client.setCacheResult(e)}async getCacheResult(e){return this.client.getCacheResult(e)}fetchIconKnowledgeBase(e){return this.client.fetchIconKnowledgeBase(e)}saveNewIcons(e,t){return this.client.saveNewIcons(e,t)}};import{Faker as rU,en as nU}from"@faker-js/faker";var Oa="v1",vn=class{httpClient;fakerInstance;type="API_CLIENT";sms={send:this.sendSms.bind(this),fetchLatest:this.fetchLatestSms.bind(this)};email={send:this.sendEmail.bind(this),fetchLatest:this.fetchLatestEmail.bind(this),fetchAll:this.fetchAllEmails.bind(this)};ai={generate:this.sendAiGenerate.bind(this)};constructor(e){this.httpClient=e.httpClient,e.fakerSeed&&(this.fakerInstance=new rU({locale:nU}),this.fakerInstance.seed(e.fakerSeed))}async sendAiGenerate(e){let t=typeof e=="string"?{input:e}:e;return this.httpClient.sendRequest(`/${Oa}/tools/ai/generate`,{method:"POST",body:t}).catch(n=>{throw n instanceof tn?new Error(n.rawError):new Error(`Failed to send AI generation: ${n.message}`)})}async sendSms(e){return this.httpClient.sendRequest(`/${Oa}/tools/sms/send`,{method:"POST",body:e}).then(()=>{}).catch(t=>{throw t instanceof tn?new Error(t.rawError):new Error(`Failed to send sms: ${t.message}`)})}async fetchLatestSms(e){return this.httpClient.sendRequest(`/${Oa}/tools/sms/fetchLatest`,{method:"POST",body:e}).catch(t=>{throw t instanceof tn?new Error(t.rawError):t})}async sendEmail(e){return this.httpClient.sendRequest(`/${Oa}/tools/email/send`,{method:"POST",body:e}).then(()=>{}).catch(t=>{throw t instanceof tn?new Error(t.rawError):new Error(`Failed to send email: ${t.message}`)})}async fetchAllEmails(e){return this.httpClient.sendRequest(`/${Oa}/tools/email/fetchAll`,{method:"POST",body:e}).catch(t=>{throw t instanceof tn?new Error(t.rawError):new Error(`Failed to fetch all emails: ${t.message}`)})}async fetchLatestEmail(e){return this.httpClient.sendRequest(`/${Oa}/tools/email/fetchLatest`,{method:"POST",body:e}).catch(t=>{throw t instanceof tn?new Error(t.rawError):new Error(`Failed to fetch latest emails: ${t.message}`)})}};function fR(r,e,t){return fetch(r,{method:"PUT",body:t,headers:{"Content-Type":e}})}var Nu=class{constructor(e){this.client=e}async uploadResultsArchive(e,t){let{uploadUrl:n,id:o}=await this.client.generateTestResultsUploadUrl(),i=await fR(n,"application/zip",t);if(!i.ok)throw new Error(`Failed to upload test results: ${await i.text()}`);let{runGroupId:a}=await this.client.startProcessingResultsUpload(o,{runGroupId:e});return a}};function mt(r,e,t=!1){return r.length<e?r:r.slice(0,e-3)+(t?"...TRUNCATED...":"[...]")}var Kn={EQUALS:"equals",CONTAINS:"contains",STARTS_WITH:"starts with",EXISTS:"exists"},Yn={EQUALS:"does not equal",CONTAINS:"does not contain",STARTS_WITH:"does not start with",EXISTS:"does not exist"},cg={EXISTS:"exists",VISIBLE:"is visible",ENABLED:"is enabled",EDITABLE:"is editable",FOCUSED:"is focused"},ug={EXISTS:"does not exist",VISIBLE:"is not visible",ENABLED:"is disabled",EDITABLE:"is not editable",FOCUSED:"is not focused"};function SR(r){switch(r.type){case"ELEMENT_CONTENT":return`content ${r.negated?Yn[r.operation]:Kn[r.operation]} '${r.value}'`;case"ELEMENT_ATTRIBUTE":{let t=r.negated?Yn[r.operation]:Kn[r.operation];return r.operation==="EXISTS"?`attribute '${r.attr}' ${t}`:`attribute '${r.attr}' ${t} '${r.value}'`}case"ELEMENT_NAME":{let t=r.negated?Yn[r.operation]:Kn[r.operation];return r.operation==="EXISTS"?`tag name ${t}`:`tag name ${t} '${r.value}'`}case"ELEMENT_STYLE":{let t=r.negated?Yn[r.operation]:Kn[r.operation];return r.operation==="EXISTS"?`style property '${r.property}' ${t}`:`style property '${r.property}' ${t} '${r.value}'`}case"ELEMENT_EXISTENCE":return r.negated?ug[r.condition]:cg[r.condition];default:return(t=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(r)}}var lce={CONTENT:"The page"};function iU(r){switch(r.type){case"VALUE":return`the option with value ${r.value}`;case"LABEL":return`the option with label ${r.label}`;case"INDEX":return`the option at index ${r.index}`;default:return(t=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(r)}}function ku(r){switch(r.type){case"SUBSTRING":return`match substring '${r.url}'`;case"REGEX":return`match regex '${r.regex}'`;case"GLOB":return`match glob '${r.glob}'`;case"DOMAIN":return`match domain '${r.domain}'`;default:return(t=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(r)}}function Du(r){let e="";return r.method&&(e=` with method ${r.method}`),`${ku(r.urlMatcher)}${e}`}function aU(r){return`${r.negated?Yn.CONTAINS:Kn.CONTAINS} '${r.value}'`}function sU(r){switch(r.type){case"CONTENT":return aU(r);default:return r.type,""}}function _o(r,e=!0){switch(r.type){case"SUCCESS":return r.condition?.assertion?`Check success condition: ${r.condition.assertion}`:"All commands completed";case"AI_EXTRACT":return`Extract data from page: ${r.goal}`;case"NAVIGATE":return`Go to URL: ${e?mt(r.url,30):r.url}`;case"DIALOG":return`Automatically ${r.action.toLowerCase()} the next dialog`;case"CAPTCHA":return"Solve captchas on the page";case"GO_BACK":return"Go back to the previous page";case"GO_FORWARD":return"Go forward to the next page";case"SCROLL_DOWN":return`Scroll down ${r.deltaY?`${r.deltaY}px`:"1 page height"}${r.target?` in the container of: ${$t(r.target)}`:""}`;case"SCROLL_UP":return`Scroll up ${r.deltaY?`${r.deltaY}px`:"1 page height"}${r.target?` in the container of: ${$t(r.target)}`:""}`;case"SCROLL_LEFT":return`Scroll left ${r.deltaX?`${r.deltaX}px`:"1 page width"}${r.target?` in the container of: ${$t(r.target)}`:""}`;case"SCROLL_RIGHT":return`Scroll right ${r.deltaX?`${r.deltaX}px`:"1 page width"}${r.target?` in the container of: ${$t(r.target)}`:""}`;case"WAIT":return`Wait for ${r.delay} seconds`;case"REFRESH":return"Refresh the page";case"CLICK":{if(r.target?.type==="coordinates")return`Click at coordinates: ${$t(r.target)}`;let n="";return r.target?.elementDescriptor.length?n=` on element: '${r.target.elementDescriptor}'`:r.cache?.target.nodeOnlySerializedHtml&&(n=` on element: '${r.cache?.target.nodeOnlySerializedHtml}'`),`Click${n}`}case"FOCUS":return`Focus ${$t(r.target)}`;case"BLUR":return`Focus ${$t(r.target)}`;case"DRAG":return`Drag ${$t(r.fromTarget)} onto ${$t(r.toTarget)}`;case"MOUSE_DRAG":return r.target?.type==="description"&&r.target.elementDescriptor?`Click and drag ${$t(r.target)} by ${r.deltaX}px horizontally, ${r.deltaY}px vertically`:`Click and drag mouse by ${r.deltaX}px horizontally, ${r.deltaY}px vertically`;case"TYPE":{let n="";return r.target?.type==="coordinates"?n=` in element at coordinates: ${$t(r.target)}`:r.target?.elementDescriptor.length?n=` in element: '${r.target.elementDescriptor}'`:r.cache?.target.nodeOnlySerializedHtml&&(n=` in element: '${r.cache?.target.nodeOnlySerializedHtml}'`),`Type '${r.value}'${n||""}`}case"HOVER":{let n="";return r.target.type==="coordinates"?n=` over coordinates: ${$t(r.target)}`:r.target.elementDescriptor.length>0?n=` over element: '${r.target.elementDescriptor}'`:r.cache?.target.nodeOnlySerializedHtml&&(n=` over element: '${r.cache?.target.nodeOnlySerializedHtml}'`),`Hover${n}`}case"PRESS":return`Press ${r.value}`;case"KEY_DOWN":return`Hold down ${r.value} on the keyboard`;case"KEY_UP":return`Release ${r.value} on the keyboard`;case"SELECT_OPTION":{let n="",o=iU(r.choice);return r.target.type==="coordinates"?n=` from element at coordinates: ${$t(r.target)}`:r.target.elementDescriptor.length>0?n=` from: '${r.target.elementDescriptor}'`:r.cache?.target.nodeOnlySerializedHtml&&(n=` from: '${r.cache?.target.nodeOnlySerializedHtml}'`),`Select option '${o}'${n}`}case"TAB":switch(r.action.type){case"SUBSTRING":return`Switch to tab with substring: ${r.action.substring}`;case"REGEX":return`Switch to tab matching regex: ${r.action.pattern}`;case"INDEX":return`Switch to tab at index: ${r.action.index}`;default:return(o=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(r.action)}return"Switch to unknown tab";case"NEW_TAB":return`Open new tab to: ${r.url}`;case"REQUEST":return`Send ${r.method} request to ${r.url}`;case"GRAPHQL_REQUEST":return`Send GraphQL request to ${r.url}`;case"COOKIE":return`Set cookie: ${r.value}`;case"LOCAL_STORAGE":return`Set local storage: ${r.key}: ${r.value}`;case"JAVASCRIPT":return`Run JavaScript: ${e?mt(r.code,30):r.code}`;case"AI_ASSERTION":return`Assertion: '${r.assertion}'`;case"VISUAL_DIFF":return`Visual diff against baseline ${r.target?`for element: ${$t(r.target)}`:"for entire page"}`;case"FILE_UPLOAD":return r.fileSource.type==="URL"?`Upload file: ${r.fileSource.url}`:`Upload file: ${r.fileSource.name}`;case"AUTH_LOAD":return"Load auth state";case"AUTH_SAVE":return"Save auth state";case"ELEMENT_CHECK":return`Check the element ${$t(r.target)} ${SR(r.assertion)}`;case"PAGE_CHECK":return`Check the page ${sU(r.assertion)}`;case"WAIT_FOR_URL":return`Wait for page URL to ${ku(r.matcher)}`;case"COPY":return"Copy to clipboard";case"PASTE":return"Paste clipboard contents";case"REGISTER_REQUEST_LISTENER":return r.requestMatcher?`Register a listener for network requests that ${Du(r.requestMatcher)}`:"Register a listener for network requests";case"AWAIT_LISTENER":return r.key?`Wait for the listener ${r.key} to resolve`:"Wait for a listener to resolve";case"RECORD_REQUESTS":return r.requestMatcher?`Start recording requests that match ${Du(r.requestMatcher)}`:"Start recording network requests";case"GET_RECORDED_REQUESTS":return r.key?`Get the requests that were recorded for ${r.key}`:"Get the requests that were recorded";case"SET_HEADER":return r.name?r.requestMatcher?`Set a ${r.name} header for requests that match ${Du(r.requestMatcher)}`:`Set a ${r.name} header for all requests`:"Set a header";case"MOCK_ROUTE":return r.requestMatcher?`Mock requests that ${Du(r.requestMatcher)}`:"Mock a network route";case"REMOVE_ROUTE_MOCK":return r.key?`Remove the mock with key ${r.key}`:"Remove all route mocks";case"OFFLINE_MODE":return r.enable?"Enable offline mode":"Disable offline mode";default:return(n=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(r)}}function lU(r){return typeof r=="object"&&r!==null}function Rn(r){if(Array.isArray(r))return r.map(Rn);if(lU(r)){let e={};return Object.entries(r).forEach(([t,n])=>{n!==void 0&&(e[t]=Rn(n))}),e}return r}function fl(r,e,t,n){let{negated:o,ignoreCase:i}=n,a=r.trim(),s=e.trim();i&&(a=a.toLowerCase(),s=s.toLowerCase());let c;switch(t){case"CONTAINS":{c=a.includes(s);break}case"EQUALS":{c=a===s;break}case"STARTS_WITH":{c=a.startsWith(s);break}case"EXISTS":{c=a.length>0;break}default:throw new Error(`Unrecognized content assertion type: ${t}`)}return o?!c:c}function yR(r){return r.type==="ELEMENT_EXISTENCE"&&r.negated&&(r.condition==="EXISTS"||r.condition==="VISIBLE")}function La(r){return r.type==="ELEMENT_EXISTENCE"?r.negated?cg[r.condition]:ug[r.condition]:r.negated?Kn[r.operation]:Yn[r.operation]}import{diff as uU}from"deep-object-diff";import{cloneDeep as Hu}from"lodash-es";function wi(r){let e={parentChain:[]};return Fu(r,e),e}function Fu(r,e){let{onPresetAction:t,onSimpleStepContainer:n,onConditional:o,earlyStop:i}=r;for(let a of r.steps)switch(a.type){case"PRESET_ACTION":if(t(a,e)&&i)return!0;break;case"CONDITIONAL":if(o?.(a,e)&&i)return!0;e.parentChain.push(a);for(let c of a.blocks)if(t(c.assertion,e)&&i||Fu({...r,steps:c.steps},e)&&i)return!0;if(Fu({...r,steps:a.elseSteps??[]},e)&&i)return!0;e.parentChain.pop();break;case"RESOLVED_MODULE":case"SECTION":case"AI_ACTION":if(n?.(a,e)&&i)return!0;if(a.steps){if(e.parentChain.push(a),Fu({...r,steps:a.steps},e)&&i)return!0;e.parentChain.pop()}break;case"AI_ACTION_DYNAMIC":{if(n?.(a,e)&&i)return!0;break}default:return(c=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(a)}}function ER(r,e,t,n){let o=Array.from(e),i=Array.from(n);for(let s=0;s<o.length;s++){if(o[s]!==n[s])return!1;i.shift()}return!!cU([r],t,i).result}function cU(r,e,t=[]){let n,o=[],i=(a,s)=>{let c=JSON.stringify(s.parentChain.map(u=>u.id)),l=t.length===0?!0:JSON.stringify(t)===c;return a.id===e&&l?(n=a,o=s.parentChain,!0):!1};return wi({steps:r,earlyStop:!0,onPresetAction:i,onConditional:i,onSimpleStepContainer:i}),{result:n,parentChain:o}}function bR(r,e){e(r);for(let t in r){let n=r[t];n&&(Array.isArray(n)?Bu(n,e):typeof n=="object"&&bR(n,e))}}function Bu(r,e){for(let t of r)t&&(Array.isArray(t)?Bu(t,e):typeof t=="object"&&bR(t,e))}function dg(r,e){if(r.length>e.length)return dg(e,r);for(let t=0;t<r.length;t++)if(r[t]!==e[t])return!1;return!0}function Uu(r){for(let e of r.results)switch(e.type){case"PRESET_ACTION":r.onPresetAction(e);break;case"AI_ACTION":case"AI_ACTION_DYNAMIC":case"MODULE":r.onSimpleStepContainer?.(e),Uu({...r,results:e.results});break;case"CONDITIONAL":r.onConditional?.(e),e.assertionResult&&r.onPresetAction(e.assertionResult),Uu({...r,results:e.results});break;default:throw new Error(`Unsupported result type: ${e.type}`)}}function Mo(r,e){return!r&&!e?!1:!r||!e?!0:Object.keys(uU(r,e)).length>0}function Na({steps:r,topLevel:e=!0,...t}){let{stepCacheEntries:n,logger:o,keyPrefix:i}=t,a=[],s=[],c=[],l=0,u=(p,m)=>{try{let h=Vn.parse(m.value);if(h.type!==p.type){o.warn({parsedCacheEntry:h,command:p},"Not using step cache due to type mismatch"),s.push(m.key);return}p.cache=h.cache,a.push(m.key),c.push(m.uniqueKey)}catch(h){s.push(m.key),o.error({err:h,cacheEntry:m},"Not using step cache due to parsing error")}},d=(p,m)=>{let h=dU(p.id,m),g=h.find(f=>!!n[f]);if(g)u(p,n[g]);else{if(p.type==="AI_ASSERTION")return;s.push(h[0])}};for(let p of r)switch(p.type){case"RESOLVED_MODULE":{l+=p.steps.length;let{cacheKeysHit:m,cacheKeysMissed:h,uniqueKeysHit:g}=Na({...t,steps:p.steps,keyPrefix:i?`${i}:${p.id}`:p.id,topLevel:!1});a.push(...m),s.push(...h),c.push(...g);break}case"SECTION":case"AI_ACTION":{if(l+=p.steps?.length??0,!p.steps?.length)break;let{cacheKeysHit:m,cacheKeysMissed:h,uniqueKeysHit:g}=Na({...t,steps:p.steps,topLevel:!1});a.push(...m),s.push(...h),c.push(...g);break}case"AI_ACTION_DYNAMIC":continue;case"PRESET_ACTION":{if(!Lc.includes(p.command.type)||(p.command.type==="TYPE"||p.command.type==="MOUSE_DRAG"||p.command.type==="VISUAL_DIFF"||p.command.type==="SCROLL_DOWN"||p.command.type==="SCROLL_UP"||p.command.type==="SCROLL_LEFT"||p.command.type==="SCROLL_RIGHT")&&!p.command.target||"cache"in p.command&&p.command.cache)continue;l++,d(p.command,i);break}case"CONDITIONAL":{for(let m of p.blocks){l++,d(m.assertion.command,i),l+=m.steps.length;let{cacheKeysHit:h,cacheKeysMissed:g,uniqueKeysHit:f}=Na({...t,steps:m.steps,topLevel:!1});a.push(...h),s.push(...g),c.push(...f)}if(p.elseSteps){l+=p.elseSteps.length;let{cacheKeysHit:m,cacheKeysMissed:h,uniqueKeysHit:g}=Na({...t,steps:p.elseSteps,topLevel:!1});a.push(...m),s.push(...h),c.push(...g)}break}default:return(h=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(p)}return e&&l&&s.length>0&&o.warn({totalSteps:l,cacheKeysMissed:s,cacheKeysHit:a,uniqueKeysHit:c,cacheEntriesKeys:Object.values(n).map(p=>p.uniqueKey)},"Step cache did not fully resolve"),{cacheKeysHit:a,cacheKeysMissed:s,uniqueKeysHit:c}}function TR(r,e){return e?`${e}:${r}`:r}function dU(r,e){let t=[],n=e?.split(":")??[];for(let o=n.length;o>=0;o--){let i=[...n.slice(o),r];t.push(i.join(":"))}return t.reverse(),t}function pg(r){let{moduleStepParents:e=[],moduleIdParents:t=[]}=r;if(e.length!==t.length)throw new Error(`Invalid cache entry parent length: ${JSON.stringify(e)}
34
34
  ${JSON.stringify(t)}`);let n=[];return n.push({key:TR(r.id,e.join(":")),organizationId:r.orgId,value:r.value,testId:r.testId}),n}function vR(r){let e=new Set;return Bu(r,t=>{if("type"in t&&t.type==="RESOLVED_MODULE"&&"moduleId"in t){let n=t.moduleId;typeof n=="string"&&!e.has(n)&&e.add(n)}}),e}function zu({cmd:r,newTarget:e,key:t,logger:n,updatedWithAI:o}){if(r.type==="DRAG")if(t!=="fromTarget"&&t!=="toTarget")n.error({cmd:r,newTarget:e,key:t},"Attempted to apply invalid cache to DRAG command");else{let i=r.cache?.updatedAt;r.cache={...r.cache,[t]:e,updatedAt:i&&!o?i:new Date}}else if(t==="target"&&Nc(r)){let i=r.cache?.updatedAt;r.cache={...r.cache,target:e,updatedAt:i&&!o?i:new Date}}else n.error({cmd:r,newTarget:e,key:t},"Invalid target cache application")}function yl(r,e,t){let n=r.cache&&"memory"in r.cache?r.cache.memory?.traces:void 0;Mo(n,e)&&(t.info({updatedTraces:e,oldCmd:r},"Wrote new memory to assertion command"),r.cache={...r.cache,memory:{type:"GCS_TRACES",traces:e},updatedAt:new Date})}function RR({steps:r}){let e={};return wi({steps:r,onPresetAction:(t,n)=>{let o=t.command;if(!("cache"in o)||!o.cache)return;let i=n.parentChain.filter(c=>c.type==="RESOLVED_MODULE").map(c=>c.id).join(":"),a=TR(o.id,i),s=Vn.parse(o);e[a]=s},onSimpleStepContainer:(t,n)=>{},onConditional:(t,n)=>{}}),e}function Sl(r){return{...r,serializedHtml:void 0,nodeOnlySerializedHtml:void 0,screenshotUrl:void 0,boundingBox:void 0,selector:void 0,hybridSelector:void 0,generatedSelectors:void 0,id:-1}}function pU(r,e){return Mo(r.memory,e.memory)?{...r,memory:e.memory,updatedAt:e.updatedAt}:r}function mg(r,e){return r?Mo(r.target.memory,e.target.memory)?{target:{...r.target,memory:e.target.memory},updatedAt:e.updatedAt}:r:{target:Sl(e.target),updatedAt:e.updatedAt}}function mU(r,e){let t=Hu(r);return t.fromTarget?Mo(r.fromTarget?.memory,e.fromTarget?.memory)&&(t.fromTarget={...t.fromTarget,memory:e.fromTarget?.memory},t.updatedAt=e.updatedAt):(t.fromTarget=e.fromTarget,t.fromTarget&&(t.fromTarget=Sl(t.fromTarget),t.updatedAt=e.updatedAt)),t.toTarget?Mo(r.toTarget?.memory,e.toTarget?.memory)&&(t.toTarget={...t.toTarget,memory:e.toTarget?.memory},t.updatedAt=e.updatedAt):(t.toTarget=e.toTarget,t.toTarget&&(t.toTarget=Sl(t.toTarget),t.updatedAt=e.updatedAt)),t}function AR({newEntries:r,originalCachesMap:e,logger:t}){let n=[];for(let o of r){let i=e[o.key];if(!i||!i.cache){n.push(o);continue}if(o.value.type!==i.type){n.push(o);continue}let a=o.value.cache;if(o.value={...i},!a){n.push(o);continue}if("memory"in a&&a.memory){let s=i.cache&&"memory"in i.cache?i.cache.memory:void 0;Mo(s,a.memory)&&(o.value.cache=pU(i.cache,a),n.push(o))}else if("target"in a&&a.target.memory){let s=i.cache&&"memory"in i.cache?i.cache.memory:void 0;if(Mo(s,a.target.memory)){let c=Sr.safeParse(o.value.cache);o.value.cache=mg(c.data,a),n.push(o)}}else if("fromTarget"in a||"toTarget"in a){let s=vm.optional().parse(o.value.cache);if(!s)continue;let c={from:s.fromTarget?.memory,to:s.toTarget?.memory},l={from:i.cache&&"fromTarget"in i.cache?i.cache.fromTarget?.memory:void 0,to:i.cache&&"toTarget"in i.cache?i.cache.toTarget?.memory:void 0};Mo(l,c)&&(o.value.cache=mU(s,a),n.push(o))}}return n}async function Gu({cacheStorage:r,logger:e,schemaVersion:t,stepLists:n,testId:o}){let i=Hu(n.steps),a=Hu(n.beforeSteps)??void 0,s=Hu(n.afterSteps)??void 0,c={steps:i,beforeSteps:a,afterSteps:s};try{await r.resolveStepCacheEntries({testId:o,stepLists:c,schemaVersion:t,logger:e})}catch(l){throw e.error({err:l},"Failed to resolve step cache entries"),new Error(`Failed to resolve step cache entries. Please ensure you are running using a supported version of Momentic. If you believe this is a Momentic issue, please contact Support with the following error: ${l}`)}return c}function wR(r){let e=[];for(let t of r){t.sort((a,s)=>a.timestamp-s.timestamp);let n=[],o,i=1;for(let a of t)o&&o.text===a.text&&o.type===a.type&&JSON.stringify(o.args??null)===JSON.stringify(a.args??null)?i++:(o&&(i>1?o.args&&o.args.length?o.args.push(`(repeated ${i} times)`):o.text+=` (repeated ${i} times)`:n.push(o)),o=a,i=1);o&&n.push(o),e.push(n)}return e}import{cloneDeep as Gde}from"lodash-es";import hg from"semver";function ju(r,e){if(r!=="0.0.1"&&r!==e[e.length-1].toVersion)throw new Error("Please bump latestSchemaVersion in types package after adding a migration");e.forEach((t,n)=>{if(!hg.valid(t.toVersion)||!hg.valid(t.fromVersion))throw new Error(`Migration '${t.name}' has invalid version`);if(!hg.gt(t.toVersion,t.fromVersion))throw new Error(`Migration '${t.name}' has toVersion <= fromVersion`);if(n===0)return;if(e[n-1].toVersion!==t.fromVersion)throw new Error(`Migration '${t.name}' at index ${n} is not contiguous with previous migration`)})}import hU from"diff-lines";import gU,{gte as fU}from"semver";function SU(r){return r.every(e=>e&&typeof e=="object"&&!Array.isArray(e))}async function gg({metadata:r,steps:e,logger:t,toVersion:n,migrations:o}){let i=e,{schemaVersion:a,id:s}=r,c=o.findIndex(d=>gU.gt(d.toVersion,a));if(c===-1)return{steps:i,newVersion:a};let l=a;for(let d=c;d<o.length;d++){if(n&&fU(l,n)){t.debug("Stopping migration early because toVersion was reached");break}let p=o[d],m={id:s,migration:p.name,toVersion:p.toVersion};try{i=await CR(i,p),l=p.toVersion}catch(h){throw t.error({err:h,...m},"Migration failed"),new Error(`Step migration ${p.name} failed: ${h}`)}}let u=hU(JSON.stringify(e,void 0,2),JSON.stringify(i,void 0,2),{n_surrounding:1});return u.trim()&&t.debug({diffs:u,id:s},"Migration diffs"),{newVersion:l,steps:i}}async function CR(r,e){let t=await e.execute(r);for(let n of t)for(let o of Object.keys(n)){if(!e.recursiveKeys.has(o))continue;let i=n[o];!i||!Array.isArray(i)||SU(i)&&(n[o]=await CR(i,e))}return t}var xR={name:"Migrate API request body types",fromVersion:"0.0.1",toVersion:"0.0.2",recursiveKeys:new Set(["results","steps","blocks","elseSteps"]),stopOnFailure:!1,execute:async r=>r.map(e=>{if(e.type!=="MOBILE_PRESET_STEP")return e;let t=e.command;if(!t||t.type!=="REQUEST")return e;let n=typeof t.body=="string"&&t.body.length>0?{type:"json",content:t.body}:void 0;return t.body=n,e})};var yU=[xR];ju(qm,yU);var _R={name:"Migrate to ai step v2",fromVersion:"1.0.4",toVersion:"1.0.5",recursiveKeys:new Set(["results","commands"]),stopOnFailure:!0,execute:async r=>(r=r.filter(e=>!(e.status!==void 0&&e.type==="AI_ACTION")),r=r.map(e=>(e.status===void 0||e.type==="PRESET_ACTION"&&(e.results=e.commands??e.results??[]),e)),r)};var MR={name:"Make sure ai step v2 has done command",fromVersion:"1.0.5",toVersion:"1.0.6",recursiveKeys:new Set(["results","commands"]),stopOnFailure:!0,execute:async r=>r.map(e=>{if(e.type!=="AI_ACTION"||e.status!==void 0||!e.commands||!e.commands.length)return e;let t=e.commands,n=t[t.length-1];return n&&n.type!=="SUCCESS"&&t.push({type:"SUCCESS"}),e})};var EU=["target","fromTarget","toTarget"];function IR(r){for(let e of EU){if(r[e]===void 0)continue;let t=r[e];t.elementDescriptor!==void 0?t.type="description":r[e]={type:"description",elementDescriptor:""}}}var PR={name:"Migrate element target to discriminated union",fromVersion:"1.0.6",toVersion:"1.0.7",recursiveKeys:new Set(["results","steps"]),stopOnFailure:!0,execute:async r=>r.map(e=>{switch(e.type){case"PRESET_ACTION":return IR(e.command),e;case"AI_ACTION":{let t=e.commands;for(let n of t??[])IR(n);return e}default:return e}})};import{v4 as bU}from"uuid";var OR={name:"Ensure module steps have ids",fromVersion:"1.0.7",toVersion:"1.0.8",recursiveKeys:new Set(["results","steps"]),stopOnFailure:!0,execute:async r=>r.map(e=>{switch(e.type){case"MODULE":return e.id||(e.id=bU()),e;default:return e}})};import{v4 as LR}from"uuid";var NR={name:"Ensure module steps have ids",fromVersion:"1.0.8",toVersion:"1.0.9",recursiveKeys:new Set(["results","steps"]),stopOnFailure:!0,execute:async r=>r.map(e=>{switch(e.type){case"PRESET_ACTION":{if(!e.command)return e;let t=e.command;return t.id=t.id??LR(),e}case"AI_ACTION":return e.commands&&(e.steps=e.commands.map(t=>({type:"PRESET_ACTION",command:{...t,id:t.id??LR()}})),delete e.commands),e;default:return e}})};var DR={name:"Migrate ai waits to checks",fromVersion:"1.0.9",toVersion:"1.0.10",recursiveKeys:new Set(["results","steps","blocks","elseSteps"]),stopOnFailure:!0,execute:async r=>r.map(e=>{switch(e.type){case"PRESET_ACTION":{if(!e.command)return e;let t=e.command;return typeof t.type!="string"||t.type!=="AI_WAIT"||(t.type="AI_ASSERTION",t.timeout||(t.timeout=10)),e}default:return e}})};import{v4 as TU}from"uuid";var kR={name:"Add ids to all steps",fromVersion:"1.0.10",toVersion:"1.0.11",recursiveKeys:new Set(["results","steps","blocks","elseSteps"]),stopOnFailure:!0,execute:async r=>r.map(e=>("id"in e&&typeof e.id=="string"||(e.id=TU()),e))};import{v4 as FR}from"uuid";var UR={name:"Add ids to all steps",fromVersion:"1.0.11",toVersion:"1.0.12",recursiveKeys:new Set(["results","steps","blocks","elseSteps"]),stopOnFailure:!0,execute:async r=>r.map(e=>{if("id"in e&&typeof e.id=="string")return e;if("condition"in e&&typeof e.condition=="object"&&e.condition){let t=e.condition;t.id||(t.id=FR())}return e.id=FR(),e})};var BR={name:"Move env key to steps",fromVersion:"1.0.12",toVersion:"1.0.13",recursiveKeys:new Set(["results","steps","blocks","elseSteps"]),stopOnFailure:!0,execute:async r=>r.map(e=>{if(e.type!=="PRESET_ACTION")return e;let t=e.command;return!t||typeof t.envKey!="string"||(e.envKey=t.envKey,delete t.envKey),e})};import{v4 as vU}from"uuid";var HR={name:"Redo last two migrations",fromVersion:"1.0.13",toVersion:"1.0.14",recursiveKeys:new Set(["results","steps","blocks","elseSteps"]),stopOnFailure:!0,execute:async r=>r.map(e=>{if((!("id"in e)||typeof e.id!="string")&&(e.id=vU()),e.type!=="PRESET_ACTION")return e;let t=e.command;return!t||typeof t.envKey!="string"||(e.envKey=t.envKey,delete t.envKey),e})};var zR={name:"Migrate select choice",fromVersion:"1.0.14",toVersion:"1.0.15",recursiveKeys:new Set(["results","steps","blocks","elseSteps"]),stopOnFailure:!0,execute:async r=>r.map(e=>{if(e.type!=="PRESET_ACTION")return e;let t=e.command;return!t||t.type!=="SELECT_OPTION"||e.option===void 0||(e.choice={type:"VALUE",value:t.option},e.option=void 0),e})};var GR={name:"Migrate select choice",fromVersion:"1.0.15",toVersion:"1.0.16",recursiveKeys:new Set(["results","steps","blocks","elseSteps"]),stopOnFailure:!0,execute:async r=>r.map(e=>{if(e.type!=="PRESET_ACTION")return e;let t=e.command;return t&&jR(t),e})};function jR(r){r&&Object.keys(r).forEach(e=>{if(typeof r[e]=="object"&&r[e]){jR(r[e]);return}if(typeof r[e]!="string")return;let t=r[e];e==="code"?r[e]=t.replace(/inputs\./g,"env."):t.includes("{{")&&t.includes("}}")&&(r[e]=t.replace(/inputs\./g,"env."))})}var VR={name:"Migrate switch tab choice",fromVersion:"1.0.16",toVersion:"1.0.17",recursiveKeys:new Set(["results","steps","blocks","elseSteps"]),stopOnFailure:!0,execute:async r=>r.map(e=>{if(e.type!=="PRESET_ACTION")return e;let t=e.command;return!t||t.type!=="TAB"||t.url===void 0||(t.action={type:"SUBSTRING",substring:t.url},t.url=void 0),e})};var $R={name:"Remove press keys sequentially",fromVersion:"1.0.17",toVersion:"1.0.18",recursiveKeys:new Set(["results","steps","blocks","elseSteps"]),stopOnFailure:!1,execute:async r=>r.map(e=>{if(e.type!=="PRESET_ACTION")return e;let t=e.command;return!t||t.type!=="TYPE"?e:t.pressKeysSequentially===void 0?(t.delay=0,e):(t.pressKeysSequentially&&(t.pressKeysSequentially=void 0,t.delay=50),e)})};var WR={name:"Migrate wait for URL to matcher",fromVersion:"1.0.18",toVersion:"1.0.19",recursiveKeys:new Set(["results","steps","blocks","elseSteps"]),stopOnFailure:!1,execute:async r=>r.map(e=>{if(e.type!=="PRESET_ACTION")return e;let t=e.command;return!t||t.type!=="WAIT_FOR_URL"||t.url===void 0||(t.matcher={type:"GLOB",glob:t.url},t.url=void 0),e})};var qR={name:"Migrate select choice round 2",fromVersion:"1.0.19",toVersion:"1.0.20",recursiveKeys:new Set(["results","steps","blocks","elseSteps"]),stopOnFailure:!0,execute:async r=>r.map(e=>{if(e.type!=="PRESET_ACTION")return e;let t=e.command;if(!t)return e;if(t.type==="SELECT_OPTION"){if(t.option===void 0)return e;t.choice={type:"VALUE",value:t.option},t.option=void 0}else if(t.type==="TAB"){if(t.url===void 0)return e;t.action={type:"SUBSTRING",substring:t.url},t.url=void 0}else if(t.type==="WAIT_FOR_URL"){if(t.url===void 0)return e;t.matcher={type:"GLOB",glob:t.url},t.url=void 0}else t.type==="AI_WAIT"&&(t.type="AI_ASSERTION",t.timeout||(t.timeout=10));return e})};var KR={name:"Migrate ",fromVersion:"1.0.20",toVersion:"1.0.21",recursiveKeys:new Set(["results","steps","blocks","elseSteps"]),stopOnFailure:!1,execute:async r=>r.map(e=>{if(e.type!=="PRESET_ACTION")return e;let t=e.command;return!t||t.type!=="MOCK_ROUTE"&&t.type!=="SET_HEADER"&&t.type!=="RECORD_REQUESTS"&&t.type!=="REGISTER_REQUEST_LISTENER"||(t.type==="REGISTER_REQUEST_LISTENER"||t.type==="RECORD_REQUESTS"?t.requestMatcher={urlMatcher:{type:"REGEX",regex:t.pattern}}:(t.type==="SET_HEADER"||t.type==="MOCK_ROUTE")&&t.urlPattern&&(t.requestMatcher={urlMatcher:{type:"REGEX",regex:t.urlPattern}})),e})};var YR={name:"Migrate API request body types",fromVersion:"1.0.21",toVersion:"1.0.22",recursiveKeys:new Set(["results","steps","blocks","elseSteps"]),stopOnFailure:!1,execute:async r=>r.map(e=>{if(e.type!=="PRESET_ACTION")return e;let t=e.command;if(!t||t.type!=="REQUEST")return e;let n=typeof t.body=="string"&&t.body.length>0?{type:"json",content:t.body}:void 0;return t.body=n,e})};var XR={name:"Migrate AI checks to preset actions",fromVersion:"1.0.0",toVersion:"1.0.1",recursiveKeys:new Set,execute:async r=>r.map(e=>{if(e.type!=="AI_ASSERTION")return e;let n={type:"PRESET_ACTION",command:{type:"AI_ASSERTION",assertion:e.text,useVision:!1,disableCache:!0}},o={...e,...n};return delete o.text,o}),stopOnFailure:!0};var Vu=new Set(["CLICK","TYPE","SELECT_OPTION"]),JR={name:"Migrate element descriptor to live in a target object",fromVersion:"1.0.3",toVersion:"1.0.4",recursiveKeys:new Set,execute:async r=>r.map(e=>{let t=e.command,n=t?.type,o=t?.elementDescriptor;return(o!==void 0||Vu.has(n))&&(t.target={elementDescriptor:o??""}),e.commands&&Array.isArray(e.commands)&&e.commands.forEach(a=>{let s=a?.elementDescriptor,c=a?.type;(s!==void 0||Vu.has(c))&&(a.target={elementDescriptor:s??""})}),e.results&&Array.isArray(e.results)&&e.results.forEach(a=>{let s=a.command,c=s?.elementDescriptor,l=s?.type;(c!==void 0||Vu.has(l))&&(s.target={elementDescriptor:c??""}),a.commands&&Array.isArray(a.commands)&&a.commands.forEach(d=>{let p=d?.elementDescriptor,m=d?.type;(p!==void 0||Vu.has(m))&&(d.target={elementDescriptor:p??""})})}),e}),stopOnFailure:!0};var QR={name:"Migrate FAILURE status to FAILED",fromVersion:"1.0.1",toVersion:"1.0.2",recursiveKeys:new Set,execute:async r=>r.map(e=>{let t=e;return t.status==="FAILURE"&&(t.status="FAILED"),typeof t.commands=="object"&&Array.isArray(t.commands)&&t.commands.forEach(n=>{if(n&&typeof n=="object"){let o=n;o?.status==="FAILURE"&&(o.status="FAILED")}}),t}),stopOnFailure:!0};var ZR={name:"Migrate preset step types to use the same",fromVersion:"1.0.2",toVersion:"1.0.3",recursiveKeys:new Set,execute:async r=>r.map(e=>{let t=e.command,n=t?.type;return n?.startsWith("PRESET_")&&(t.type=n.slice(7)),e.commands&&Array.isArray(e.commands)&&e.commands.forEach(i=>{let a=i.type;a?.startsWith("PRESET_")&&(i.type=a.slice(7))}),e.results&&Array.isArray(e.results)&&e.results.forEach(i=>{let a=i.command,s=a?.type;s?.startsWith("PRESET_")&&(a.type=s.slice(7)),i.commands&&Array.isArray(i.commands)&&i.commands.forEach(l=>{let u=l.type;u?.startsWith("PRESET_")&&(l.type=u.slice(7))})}),e}),stopOnFailure:!0};var eA=[XR,QR,ZR,JR,_R,MR,PR,OR,NR,DR,kR,UR,BR,HR,zR,GR,VR,$R,WR,qR,KR,YR];ju(Ce,eA);async function Da({metadata:r,steps:e,logger:t,toVersion:n}){return await gg({metadata:r,steps:e,logger:t,toVersion:n,migrations:eA})}import{cloneDeep as tpe}from"lodash-es";import{v4 as cpe}from"uuid";import{cloneDeep as AU}from"lodash-es";import aA from"truncate-json";import{v4 as tA}from"uuid";import{cloneDeep as Rpe,unset as Ape}from"lodash-es";function rn(r){switch(r.type){case"AI_ACTION":return`AI action: ${mt(r.text,100)}`;case"AI_ACTION_DYNAMIC":return`AI action: ${mt(r.text,100)}`;case"PRESET_ACTION":return _o(r.command);case"MODULE":return`Module: ${r.id}`;case"RESOLVED_MODULE":return`Module: ${r.name}`;case"CONDITIONAL":return"Conditional step";case"SECTION":return`Section${r.description?`with goal: ${mt(r.description,100)}`:""}`;default:return(t=>{throw new Error("You missed a case in the switch above")})(r)}}function ka(r,e){return r.split(`
35
35
  `).map(t=>" ".repeat(e)+t).join(`
@@ -43,10 +43,10 @@ ${o}`:o)(fg(r))}function xU(r,{unflattenedIndex:e,parentStep:t}){if(!(e===void 0
43
43
  ${n}`}function GU(r){let e=zU(r);return wi({steps:e,earlyStop:!1,onPresetAction:t=>{bg(t);let n;if(Nc(t.command)&&t.command.cache!==void 0){let i=VU(t.command.cache);i&&"target"in i&&(n=i.target)}let o=t.command;return n!==void 0?o.cache=n:delete o.cache,o.thoughts&&delete o.thoughts,delete o.id,"index"in t&&delete t.index,!1},onConditional:t=>(bg(t),!1),onSimpleStepContainer:t=>{if(t.type==="AI_ACTION"){let n=t,o=t.text;return Object.keys(n).forEach(i=>{delete n[i]}),n.type="AI_ACTION_DYNAMIC",n.text=o,!1}if(bg(t),t.type==="RESOLVED_MODULE"){let n=t;delete n.cacheConfig,delete n.enabled,delete n.defaultCacheKey,delete n.defaultCacheTtl,delete n.defaultCacheAllInvocations,delete n.autoAuth,delete n.advanced}return!1}}),e}function bg(r){let e=r;delete e.aiSuggested,delete e.id,delete e.retries,delete e.skipped}function jU(r){return r.selector?r.selector:r.generatedSelectors?.[0]}function Tg(r){let e=jU(r),t=r.nodeOnlySerializedHtml,n={};return e&&(n.selector=e),t&&(n.nodeOnlySerializedHtml=t),Object.keys(n).length?n:void 0}function VU(r){if(!r)return;let e={};if("target"in r)return{target:Tg(r.target)};if("fromTarget"in r||"toTarget"in r){let t=r.fromTarget?Tg(r.fromTarget):void 0,n=r.toTarget?Tg(r.toTarget):void 0;return t&&(e.fromTarget=t),n&&(e.toTarget=n),Object.keys(e).length?e:void 0}}function Io({orgId:r,client:e,gitMetadata:t,regenerateCache:n,alwaysSaveCache:o,noCache:i,bustOldestCachePercentage:a}){return i?new Cu:new vg(r,e,t,{regenerateCache:n,alwaysSaveCache:o,bustOldestCachePercentage:a})}var vg=class{constructor(e,t,n,o){this.orgId=e;this.client=t;let{regenerateCache:i,alwaysSaveCache:a,bustOldestCachePercentage:s}=o,{gitBranchName:c,gitProtectedBranches:l}=n;this.cacheHeaders=Vh(n),this.readCaches=!i;let u=c&&l.includes(c);a||!u?this.writeCaches=!0:this.writeCaches=!1,u||(this.bustOldestCachePercentage=s)}cacheHeaders;readCaches;writeCaches;bustOldestCachePercentage;async saveStepCacheEntries({entries:e,testId:t,logger:n}){if(!this.writeCaches){n.debug("Skipping cache storage because branch is protected");return}try{await this.client.updateStepCaches({entries:e,testId:t},this.cacheHeaders)}catch(o){n.error({err:o},"Failed to save step cache entries")}}async resolveStepCacheEntries(e){if(!this.readCaches){e.logger.debug("Skipping cache resolution because of regenerate flag");return}let{steps:t,beforeSteps:n,afterSteps:o}=e.stepLists,i=await this.client.getStepCacheForTest({testId:e.testId},this.cacheHeaders);if(!this.writeCaches){e.logger.debug("Skipping cache last used at update because branch is protected");return}if(this.bustOldestCachePercentage!==void 0){let s=Object.entries(i).map(([u,d])=>({key:u,time:d.value.cache?.updatedAt?.getTime()??0}));s.sort((u,d)=>u.time-d.time);let c=s.length,l=Math.max(1,Math.floor(c*this.bustOldestCachePercentage/100));s.slice(0,l).forEach(({key:u})=>{delete i[u]}),e.logger.info({nCachesToBust:l,bustOldestCachePercentage:this.bustOldestCachePercentage,totalCaches:c},"Busted oldest caches")}for(let s of[t,n,o])s&&Na({steps:s,stepCacheEntries:i,logger:e.logger});let{cachesToSave:a}=await nt({stepLists:e.stepLists,cacheCreationParams:{testId:e.testId,orgId:this.orgId}});this.client.updateStepCaches({entries:a,testId:e.testId},this.cacheHeaders)}};import $U from"path";var WU=new Ou(30,60*1e3),Cg="https://api.momentic.ai",Ag,AA=r=>{Cg=r},Er=()=>Cg,wA=()=>Ag;var za,wg,od,CA=async r=>{if(Ag&&za&&od)return za;let e=new Qe({baseUrl:Cg,apiKey:r,logger:E});Ag=e;try{let t=await e.getAuthInfo();return za=t.orgId,wg=t.userId,od=r,za}catch(t){throw new Error(`Error checking API key against server: ${t}`)}},wt=()=>{if(!za)throw new Error("Your organization ID is invalid.");return za},Po=()=>{if(!wg)throw new Error("Your user ID is invalid.");return wg},br=()=>{if(!od)throw new Error("Your API key is invalid.");return od},xg,Rg,id=(r,e)=>{xg=r,Rg?.abort(),Rg=new AbortController;let t=Rg.signal,n=[r.configFilePath];r.config.environments?.forEach(o=>{if(!o.envFile)return;let i=$U.resolve(r.rootDir,o.envFile);try{if(nd.lstatSync(i).isSymbolicLink())return;nd.existsSync(i)&&n.push(i)}catch(a){E.warn({err:a},`Failed to check if env file ${i} exists`)}});try{qU({filesToWatch:n,revalidator:e,signal:t,project:r})}catch(o){E.error({err:o},"Failed to start config file watchers")}},se=()=>xg;function qU({filesToWatch:r,revalidator:e,signal:t,project:n}){E.debug("Starting watch on the following files:"),r.forEach(o=>{E.debug(`- ${o}`)}),r.forEach(o=>{let i=async(s,c)=>{s.mtime.getTime()!==c.mtime.getTime()&&(WU.increment("setLocalProject")&&E.warn(`A file change under the ${n.rootDir} directory has caused Momentic to reload its configuration more than 30 times in the last minute. Rapid changes to files may indicate your momentic.config.yaml 'include' glob is incorrect. Please ensure temporary, library, and auto-generated files are not included in Momentic's context.`),xg=await Promise.resolve(e(n.configFilePath)))};nd.watchFile(o,{persistent:!1},i);let a=()=>{nd.unwatchFile(o,i),t.removeEventListener("abort",a)};t.addEventListener("abort",a),process.once("SIGUSR2",()=>{a(),process.kill(process.pid,"SIGUSR2")})})}function Me(r){return function(...e){let t=e[e.length-1],n=r(...e);Promise.resolve(n).catch(t)}}var Rl=KU();function vl(r){let e=se(),t=Ot.dirname(e.configFilePath);return Ot.join(t,...r)}function XU(r){let e=se(),t=Ot.dirname(e.configFilePath),n=Ot.relative(t,r);return n?n.split(Ot.sep):[]}function JU(r,e){let t=ar.statSync(r),n=XU(r);return kh.parse({name:e,absolutePath:r,relativePath:n.join(Ot.sep),pathSegments:n,isDirectory:t.isDirectory(),size:t.size,createdAt:t.birthtime,modifiedAt:t.mtime,accessedAt:t.atime})}Rl.post("/",Me(async(r,e,t)=>{let n;try{n=GT.parse(r.body).pathSegments}catch(d){e.status(400).json({error:`Failed to parse folder read body: ${d}`});return}let o=vl(n);if(!ar.existsSync(o)){e.status(404).json({error:`Path not found: ${n.join(Ot.sep)}`});return}if(!ar.statSync(o).isDirectory()){e.status(400).json({error:`Path is not a directory: ${n.join(Ot.sep)}`});return}let a=se(),s=Array.from(a.config.exclude??[]).concat(Tu),l=YU("*",{absolute:!1,cwd:o,ignore:s,dotRelative:!1,maxDepth:1,nodir:!1}).map(d=>{let p=Ot.join(o,d);return JU(p,d)}),u={absolutePath:o,pathSegments:n,contents:l};e.status(200).json(u)}));Rl.put("/",Me(async(r,e,t)=>{let n;try{n=jT.parse(r.body).pathSegments}catch(a){e.status(400).json({error:`Failed to parse folder create body: ${a}`});return}let o=vl(n);if(ar.existsSync(o)){e.status(200).json({success:!0,message:`Folder already exists: ${n.join(Ot.sep)}`,pathSegments:n});return}ar.mkdirSync(o,{recursive:!0});let i={success:!0,message:`Folder created: ${n.join(Ot.sep)}`,pathSegments:n};e.status(201).json(i)}));Rl.patch("/",Me(async(r,e,t)=>{let n,o;try{let l=VT.parse(r.body);n=l.pathSegments,o=l.newPathSegments}catch(l){e.status(400).json({error:`Failed to parse folder update body: ${l}`});return}let i=vl(n),a=vl(o);if(!ar.existsSync(i)){e.status(400).json({error:`Folder not found: ${n.join(Ot.sep)}`});return}if(ar.existsSync(a)){e.status(400).json({error:`Destination already exists: ${o.join(Ot.sep)}`});return}let s=Ot.dirname(a);ar.existsSync(s)||ar.mkdirSync(s,{recursive:!0}),ar.renameSync(i,a);let c={success:!0,message:`Folder moved from ${n.join(Ot.sep)} to ${o.join(Ot.sep)}`,pathSegments:o};e.status(200).json(c)}));Rl.delete("/",Me(async(r,e,t)=>{let n,o=!0;try{let c=$T.parse(r.body);n=c.pathSegments,o=c.recursive??!0}catch(c){e.status(400).json({error:`Failed to parse folder delete body: ${c}`});return}let i=vl(n);if(!ar.existsSync(i)){e.status(200).json({success:!0,message:`Folder not found: ${n.join(Ot.sep)}`,pathSegments:n});return}if(!ar.statSync(i).isDirectory()){e.status(400).json({error:`Path is not a directory: ${n.join(Ot.sep)}`});return}if(o)ar.rmSync(i,{recursive:!0,force:!0});else{if(ar.readdirSync(i).length>0){e.status(409).json({error:`Cannot delete non-empty directory without recursive flag: ${n.join("/")}`});return}ar.rmdirSync(i)}let s={success:!0,message:`Folder deleted: ${n.join("/")}`,pathSegments:n};e.status(200).json(s)}));var _g=Rl;import{Router as rH}from"express";import{diff as tB}from"deep-object-diff";import on from"fs";import Ii from"path";import Ga from"yaml";import{z as MA}from"zod";import{execSync as QU}from"child_process";function Xn(r,e){let t=e.hooks?.postSave;if(!t)return;let n;t.includes("$1")?n=t.replaceAll("$1",r):n=`${t} ${r}`,E.debug({postSaveCommand:n},"Executing post-save hook command");try{QU(n,{encoding:"utf-8"})}catch(o){E.warn({err:o,postSaveCommand:n},"Failed to execute post-save hook command, continuing...")}}import{diff as xA}from"deep-object-diff";import An from"fs";import{cloneDeep as ZU}from"lodash-es";import Al from"path";import{v4 as eB}from"uuid";import wl from"yaml";function Tr({content:r,schemaVersion:e,momenticFiles:t,project:n,forceSaveOnNoDiffs:o}){let i=t.modules[r.moduleId]?.fullFilePath;if(!i||!An.existsSync(i))throw new Error(`Tried to update module ${r.moduleId} that could not be found on disk`);let a=An.readFileSync(i,"utf-8"),s=wl.parse(a),c;if(r.name&&r.name!==s.name){let m=`${Ue(r.name)}.module.yaml`;if(c=Al.join(Al.dirname(i),m),An.existsSync(c))throw new Error(`A conflicting file '${r.name}' already exists at path '${c}'`)}let l={...r,schemaVersion:e},u=Rn({fileType:he.MODULE,...Bh.parse(l),steps:Je.array().parse(r.steps)}),d=xA(u,s);if(d&&Object.keys(d).length===0&&!o){E.debug(`Skipping save for module ${r.moduleId} since there are no changes`);return}let p=wl.stringify(u);An.writeFileSync(i,p,"utf-8"),c&&An.renameSync(i,c),Xn(c||i,n.config)}function _A({moduleId:r,content:e,momenticFiles:t,project:n,logger:o}){let i=t.modules[r]?.fullFilePath;if(!i)throw new Error(`Tried to update module ${r} that could not be found on disk`);let a=Jn(i,o),s={...a,...e},c=Rn({fileType:he.MODULE,...Bh.parse(s),steps:a.steps}),l=xA(c,a);if(l&&Object.keys(l).length===0){E.debug(`Skipping save for module ${r} since there are no changes`);return}let u=wl.stringify(c);An.writeFileSync(i,u,"utf-8");let d;if(e.name){let p=`${Ue(e.name)}.module.yaml`;if(d=Al.join(Al.dirname(i),p),An.existsSync(d))throw new Error(`Module with name '${e.name}' already exists at path '${d}'`);An.renameSync(i,d)}Xn(d||i,n.config)}async function ad({name:r,description:e,enabled:t,steps:n,folder:o,project:i}){let a=Ue(r),s=Al.join(o,`${a}.module.yaml`),c=eB(),{stepsToSave:l}=await nt({stepLists:{steps:n}}),u={fileType:he.MODULE,schemaVersion:Ce,moduleId:c,name:r,description:e,enabled:t,steps:l.steps},d=wl.stringify(u);return An.writeFileSync(s,d,"utf-8"),Xn(s,i.config),{moduleId:c,name:r,description:e,enabled:t,steps:n}}function Jn(r,e){let t=An.readFileSync(r,"utf-8"),n=wl.parse(t);try{return wh.parse(n)}catch(o){throw e.error({err:o,moduleFilePath:r,moduleContents:t},`${r} does not parse as a valid Momentic module`),o}}async function nn(r,e,t,n){let o=Jn(r.fullFilePath,t),{resolvedSteps:i}=await Xu({rawSteps:o.steps,migrationMetadata:{id:o.moduleId,schemaVersion:o.schemaVersion},resolvedModuleCache:n,logger:t,callbacks:{onFetchModule:async({id:s})=>{let c=e.modules[s]?.fullFilePath;if(c)return Jn(c,t)}}}),a={...o,steps:i};return n&&(n[r.id]=ZU(a)),a}async function sd(r,e){let t={};return await Promise.all(Object.values(r.modules).map(async n=>{await nn(n,r,e,t)})),Array.from(Object.values(t))}async function IA({test:r,name:e,folder:t}){let n=await yA({test:r});if(Object.keys(n.modules).length)throw new Error("A brand new test should not contain any modules in it");let i=`${Ue(e)}.test.yaml`,a=Ii.join(t,i);return on.writeFileSync(a,n.test,"utf-8"),a}function Mg(r,e,t){let n=Ii.join(t.rootDir,r);if(!on.existsSync(n))throw new Error(`Test not found at path '${r}' in project '${t.rootDir}'`);let o=on.readFileSync(n,"utf-8"),i=Ga.parse(o),a,s;if(e.name&&e.name!==i.name){let p=`${Ue(e.name)}.test.yaml`;if(a=Ii.join(Ii.dirname(r),p),s=Ii.join(t.rootDir,a),on.existsSync(s))throw new Error(`Test with name '${e.name}' already exists at path '${s}'`)}let c={...i,...e},l=Dr.parse(c),u={fileType:he.TEST,...Dr.parse(l),beforeSteps:i.beforeSteps??void 0,steps:i.steps,afterSteps:i.afterSteps??void 0},d=Ga.stringify(u);return on.writeFileSync(n,d,"utf-8"),s&&on.renameSync(n,s),Xn(n,t.config),{newRelativeTestPath:a}}function mr({relativeTestPath:r,steps:e,schemaVersion:t,project:n,forceSaveOnNoDiffs:o}){let i=Ii.join(n.rootDir,r);if(!on.existsSync(i))throw new Error(`Test not found at path '${r}' in project '${n.rootDir}'`);let a=on.readFileSync(i,"utf-8"),s=Ga.parse(a),c=Dr.parse({...s,schemaVersion:t}),l=Je.array().or(MA.undefined()).parse(e.beforeSteps),u=Je.array().parse(e.steps),d=Je.array().or(MA.undefined()).parse(e.afterSteps),p=Rn({fileType:he.TEST,...c,beforeSteps:l&&l.length>0?l:void 0,steps:u,afterSteps:d&&d.length>0?d:void 0}),m=tB(p,s);if(m&&Object.keys(m).length===0&&!o){E.debug(`Skipping save for test ${c.name} since there are no changes`);return}let h=Ga.stringify(p);on.writeFileSync(i,h,"utf-8"),E.debug(`Saving test ${c.name} to ${i}`),Xn(i,n.config)}function Cl(r,e){let t=Ii.join(e.rootDir,r);if(!t)throw new Error(`Could not find test with path ${r} in Momentic project (${e.rootDir})`);let n;try{n=on.readFileSync(t,"utf8"),n=n.replace(/\r\n|\r/g,`
44
44
  `)}catch(i){throw new Error(`Could not read test file ${t}: ${i}`)}let o;try{o=Ga.parse(n)}catch(i){throw new Error(`Could not parse test file ${t} as YAML: ${i}`)}return Yt.parse(o)}function Pi(r,e,t){let n=t.project.rootDir,o;try{o=on.readFileSync(r,"utf-8")}catch(a){throw e.error({err:a,projectRoot:n},a.message),new Error(a.message)}let i=Ga.parse(o);if(!i.steps||!Array.isArray(i.steps))throw new Error(`Test ${r} is missing steps`);return i}async function ut(r,e,t){let n=Pi(r,e,t),o;try{o=Dr.parse(n)}catch(a){throw new Error(`Test ${r} is missing metadata or has invalid metadata: ${a}`)}let{resolvedTest:i}=await fA({rawSteps:{steps:n.steps,beforeSteps:n.beforeSteps,afterSteps:n.afterSteps},metadata:o,logger:e,callbacks:{onFetchModule:async({id:a,logger:s})=>{let c=t.modules[a]?.fullFilePath;if(c)return Jn(c,s)}}});return i}import rB from"@dotenvx/dotenvx";import nB from"fs";import PA from"path";function ld(r,e){return(r.config.environments??[]).map(t=>Oi(t.name,r,e))}function OA(r){return r.includes("${")?r.replace(/\$\{([^}]+)\}/g,(e,t)=>{let[n,o]=t.split(/:-|-/,2),i=process.env[n];return t.includes(":-")?i&&i!==""?i:o||"":t.includes("-")?i!==void 0?i:o||"":i||""}):r}function oB(r){let{envVariables:e,project:t}=r;if(!e)return{};let n={};for(let[o,i]of Object.entries(e)){if(typeof i=="string"){let s=OA(i);s&&(n[o]=s);continue}let a;try{a=nB.readFileSync(PA.resolve(t.rootDir,i.fromFile),"utf-8")}catch(s){throw new Error(`Failed to read environment variable '${o}' from file '${i.fromFile}': ${s}`)}if(i.json)try{n[o]=JSON.parse(a)}catch(s){throw new Error(`Failed to parse environment variable '${o}' from file '${i.fromFile}' as JSON: ${s}`)}else n[o]=a}return Object.keys(n).length>0&&E.debug(n,"Set environment variables with interpolation from project configuration"),n}function iB(r){let{project:e,envFile:t,logger:n}=r,o={};if(!t)return o;let i=rB.config({path:PA.resolve(e.rootDir,t),processEnv:o,logLevel:"error",quiet:!0});if(i.error)throw new Error(`Failed to load .env file: ${i.error.message}`);return n.debug(o,"Set environment variables from .env file"),o}function Oi(r,e,t){let n=(e.config.environments??[]).find(c=>c.name===r);if(!n)throw new Error(`Environment ${r} not found in local project configuration file`);if(!n.baseUrl)throw new Error(`Browser environment ${r} does not have a baseUrl configured`);let o={[Tt]:OA(n.baseUrl)},i=oB({envVariables:n.envVariables,project:e});Object.assign(o,i);let a=iB({project:e,envFile:n.envFile,logger:t});return Object.assign(o,a),n.inheritFromShell&&(t.debug(process.env,"Inheriting environment variables from shell"),Object.assign(o,process.env)),{name:r,variables:o,browser:n.browser}}import{existsSync as yB,readFileSync as EB,readdirSync as bB,writeFileSync as TB}from"fs";import{glob as vB}from"glob";import Li,{dirname as DA}from"path";import{cwd as Ng}from"process";import kA from"yaml";import{z as We}from"zod";import LA from"fs";import{glob as aB}from"glob";import xl from"path";import sB from"yaml";import{z as Ig}from"zod";var NA=!1,Pg=["**/*.test.yaml","**/*.module.yaml"],Og=Ig.string().refine(r=>/^[a-zA-Z0-9-]+$/.test(r)),Lg=15,lB=Ig.object({fileType:Ig.nativeEnum(he)});async function Z(r,e=!1){let t={project:r,tests:{},modules:{},mobileTests:{},mobileModules:{},duplicateEntities:{}},n=r.config.include??Pg,o=Array.from(r.config.exclude??[]).concat(Tu),i=AbortSignal.timeout(5e3),a;try{a=await aB(n,{absolute:!1,cwd:r.rootDir,ignore:o,dotRelative:!1,maxDepth:Lg,nodir:!0,signal:i})}catch(s){throw E.error({err:s},"Failed to list all Momentic files in the current directory. This usually indicates the 'include' and 'exclude' globs are misconfigured in your momentic.config.yaml, or that your machine is severely resource constrained."),new Error("Listing Momentic files timed out after 5 seconds.",{cause:s})}for(let s of a){let c=cB(r.rootDir,s,t,e?bn:E);c&&(t.duplicateEntities[c.id]=c.paths)}return NA=!0,t}function cB(r,e,t,n){let o=xl.join(r,e),i=uB(o,n);if(!i)return;let a=dB(i,o,n);if(!a)return;let s=lB.safeParse(a);if(s.success===!1){n.warn(`Possible Momentic file at ${o} does not have a 'fileType', skipping: ${s.error}`);return}let c=s.data.fileType,l=pB(o,n);if(!l)return;let u=mB(e,o,l);switch(c){case he.TEST:try{return hB(a,t,u,o,n)}catch(d){n.warn(`Skipping file '${o}' because it is missing Momentic test metadata: ${d}`);return}case he.MODULE:try{return gB(a,t,u,o,n)}catch(d){n.warn(`Skipping file '${o}' because it is missing Momentic module metadata: ${d}`);return}case he.MOBILE_TEST:try{return SB(a,t,u,o,n)}catch(d){n.warn(`Skipping file '${o}' because it is missing Momentic mobile test metadata: ${d}`);return}case he.MOBILE_MODULE:try{return fB(a,t,u,o,n)}catch(d){n.warn(`Skipping file '${o}' because it is missing Momentic mobile module metadata: ${d}`);return}default:{let d=c;return}}}function uB(r,e){try{return LA.readFileSync(r,"utf-8")}catch(t){e.warn(`Could not read possible Momentic file at ${r}, skipping: ${t}`);return}}function dB(r,e,t){try{let n=sB.parse(r);if(typeof n!="object"||n===null)throw new Error("The YAML document should parse as a map with key-value pairs");return n}catch(n){t.warn(`Could not parse possible Momentic file at ${e}, skipping: ${n}`);return}}function pB(r,e){try{return LA.statSync(r)}catch(t){e.warn(`Skipping path '${r}' because it could not be stat, skipping: ${t}`);return}}function mB(r,e,t){return{relativePath:r,fullFilePath:e,platformSep:xl.sep,fullPathSegments:e.split(xl.sep),relativePathSegments:r.split(xl.sep),fileName:xl.basename(e),lastModified:t.mtime,createdAt:t.birthtime}}function hB(r,e,t,n,o){let i=Dr.parse(r),a;if(e.tests[i.id]){let s=e.tests[i.id].fullFilePath;a={id:i.id,paths:[s,n]}}return e.tests[i.id]={type:he.TEST,name:i.name,id:i.id,description:i.description??void 0,labels:i.labels,...t},a}function gB(r,e,t,n,o){let i=ur.parse(r),a;if(e.modules[i.moduleId]){let c=e.modules[i.moduleId].fullFilePath;a={id:i.moduleId,paths:[c,n]}}e.modules[i.moduleId]={type:he.MODULE,name:i.name,id:i.moduleId,description:i.description??void 0,...t};let s=t.fileName.replace(".module.yaml","");return!NA&&Ue(i.name)!==s&&o.warn(`The module with ID ${i.moduleId} has a name (${i.name}) that does not match its file name (${s}). We recommend renaming the module or the file to be consistent to avoid confusion and issues with module resolution.`),a}function fB(r,e,t,n,o){let i=fu.parse(r),a;if(e.mobileModules[i.moduleId]){let c=e.mobileModules[i.moduleId].fullFilePath;a={id:i.moduleId,paths:[c,n]}}let s=t.fileName.replace(".module.yaml","");return e.mobileModules[i.moduleId]={type:he.MOBILE_MODULE,name:s,id:i.moduleId,description:i.description??void 0,...t},a}function SB(r,e,t,n,o){let i=wa.parse(r),a;if(e.mobileTests[i.id]){let c=e.mobileTests[i.id].fullFilePath;a={id:i.id,paths:[c,n]}}let s=t.fileName.replace(".test.yaml","");return e.mobileTests[i.id]={type:he.MOBILE_TEST,name:s,id:i.id,description:i.description??void 0,...t},a}var ja="momentic.config.yaml",Dg="momentic.workspace.yaml",RB=We.object({projects:We.string().array().describe("list of glob patterns to find project (momentic.config.yaml) files")}),AB=We.union([We.string(),We.object({fromFile:We.string(),json:We.boolean().optional()})]),wB=We.object({name:Og,baseUrl:We.string().optional().describe("Optional for mobile tests"),envFile:We.string().optional().describe("path to a file on disk to read environment variables from. can be relative to project root or absolute."),envVariables:We.record(We.string(),AB).optional(),inheritFromShell:We.boolean().optional().describe("inherit all environment variables from the shell - might be noisy"),browser:pi.optional().describe("NB: most things should use project-level configuration only")}),CB=We.object({postSave:We.string().optional()}),xB=We.object({name:Og,include:We.string().array().optional().describe("list of glob patterns that match momentic files (optional)"),exclude:We.string().array().optional().describe("opposite of include, takes precedence over include"),goldenFileDir:We.string().optional(),reporterDir:We.string().optional(),outputDir:We.string().optional(),recordVideo:We.boolean().optional(),retries:We.number().optional().describe("number of retries per test"),parallel:We.number().optional().describe("degree of parallelism"),environments:We.array(wB).optional(),gitMainBranch:We.string().optional(),gitProtectedBranches:We.string().array().optional(),ai:Hh.optional(),browser:pi.optional(),emulator:_h.optional(),advanced:zh.optional(),hooks:CB.optional()});function FA(r,e){let t;try{t=EB(r,"utf-8")}catch(o){E.warn(`Could not read possible Momentic ${e} file at ${r}: ${o}`);return}let n;try{if(n=kA.parse(t),typeof n!="object"||n===null)throw new Error(`The ${e} file should parse as a map with key-value pairs, but is type ${typeof n} instead`)}catch(o){E.warn(`Possible Momentic ${e} file at ${r} does not parse as valid YAML: ${o}`);return}return n}function kg(r){let e=FA(r,"project configuration");if(e!==void 0)try{return xB.parse(e)}catch(t){E.warn(`Possible Momentic project configuration file at ${r} does not adhere to the required schema: ${t}`);return}}function _B(r){let e=FA(r,"workspace configuration");if(e!==void 0)try{return RB.parse(e)}catch(t){E.warn(`Possible Momentic workspace configuration file at ${r} does not adhere to the required schema: ${t}`);return}}function MB(){let r=[],e=Ng(),t=Li.parse(e).root,n=15,o=0;for(;o<n;){o++;let i=Li.basename(e);if(bu.includes(i))return E.warn(`Stopping search for Momentic projects since the current directory name (${i}) is likely a system artifact folder.`),r;for(let a of bB(e))if(a.endsWith(ja)){let s=Li.join(e,a),c=kg(s);c&&r.push({configFilePath:s,config:c,rootDir:DA(s)})}if(r.length)return r;if(e=Li.dirname(e),e===t)break}return r}async function Ct(r={}){let{configFilePath:e,nameFilter:t}=r,n=await Fg(e);if(t&&(n=n.filter(o=>o.config.name===t)),n.length>1)throw new Error(`Multiple valid projects were found in the same directory. Please use the '-c / --config' flag to disambiguate:
45
45
  ${n.map(o=>o.configFilePath)}`);if(n.length===0)throw new Error("No valid Momentic project file available.");return E.debug(`Found valid project configuration at ${n[0].configFilePath}`),n[0]}async function IB(r){let e=_B(r);if(!e||!e.projects||!e.projects.length)return;let t=e.projects.map(a=>(a.endsWith("/")||(a+="/"),`${a}*${ja}`)),n=AbortSignal.timeout(2e3),o;try{o=await vB(t,{absolute:!1,cwd:Ng(),dotRelative:!1,maxDepth:Lg,nodir:!0,signal:n})}catch(a){throw E.error({err:a},`Failed to list the available Momentic projects in the current directory. This usually indicates the 'include' or 'exclude' option in your ${Dg} is misconfigured.`),a}let i=[];for(let a of o){let s=Li.join(Ng(),a),c=kg(s);c&&i.push({configFilePath:s,config:c,rootDir:DA(s)})}return i}async function Fg(r){if(r){r=Li.resolve(r);let t=kg(r);return t||(console.error(`No valid Momentic project file found at ${r}.`),process.exit(1)),[{config:t,configFilePath:r,rootDir:Li.dirname(r)}]}if(yB(Dg)){let t=await IB(Dg);if(t)return t}return MB()}function Oo(r,e){let t=kA.stringify(r);TB(e,t)}import Va from"fs";import Ug from"path";import{z as Bg}from"zod";var UA="golden/visual-diff",BA="reports",HA="test-results";var PB=Bg.object({width:Bg.number(),height:Bg.number()}),$a=class{defaultGoldenScreenshotDir;regenerateGoldenFiles;constructor(e,t){let n=Ug.join(e.rootDir,e.config.goldenFileDir??UA);this.defaultGoldenScreenshotDir=n,this.regenerateGoldenFiles=t}async prepareGoldenScreenshotForComparison(e,t,n){if(t.screenshot?.data?.startsWith("https://")){let a=await fetch(t.screenshot.data);return{buffer:Buffer.from(await a.arrayBuffer()),width:t.screenshot.width,height:t.screenshot.height}}let o=t.screenshot?.data;o||(o=Ug.join(this.defaultGoldenScreenshotDir,`${t.id}.jpg`));let i=`${o}.metadata.json`;if(this.regenerateGoldenFiles)return Va.mkdirSync(Ug.dirname(o),{recursive:!0}),Va.writeFileSync(o,n.buffer),Va.writeFileSync(i,JSON.stringify({width:n.width,height:n.height})),{buffer:Buffer.from(n.buffer),width:n.width,height:n.height};if(Va.existsSync(o)){let a=Va.readFileSync(o),s=PB.parse(JSON.parse(Va.readFileSync(i,"utf-8")));return{buffer:a,width:s.width,height:s.height}}else throw new _("UserConfigurationError",`Cannot execute visual diff without a saved baseline screenshot at ${o}`)}};import{execFile as OB}from"node:child_process";import{promisify as LB}from"node:util";import NB from"simple-git";var qe=NB(),zA=LB(OB);async function DB(r){let e=await Ze(r,qe.raw(["config","--list"])),t={};if(!e)return t;for(let n of e.split(`
46
- `)){let o=n.indexOf("=");if(o===-1)continue;let i=n.slice(0,o),a=n.slice(o+1).trim();t[i]=a}return t}async function kB(r,e,t){try{let o=t["github.user"]||void 0;if(o)return o}catch{}let n;try{if(e?.startsWith("http://")||e?.startsWith("https://"))n=new URL(e).host;else if(e?.startsWith("git@")){let o=e.indexOf("@"),i=e.indexOf(":",o+1);o!==-1&&i!==-1&&(n=e.slice(o+1,i))}}catch{}if(n=n?.toLowerCase(),!!n){try{if(e?.startsWith("git@")&&n?.includes("github")){let{stdout:o,stderr:i}=await zA("ssh",["-T","-o","BatchMode=yes",`git@${n}`],{timeout:5e3}),s=`${o??""}${i??""}`.trim().match(/Hi\s+([A-Za-z0-9_-]+)!/);if(s?.[1])return s[1]}}catch{}try{let o=n&&n!=="github.com"?["api","--hostname",n,"user","-q",".login"]:["api","user","-q",".login"],{stdout:i}=await zA("gh",o,{timeout:5e3}),a=i?.toString().trim();if(a)return a}catch{}}}async function FB(r,e,t){let n=e?.includes("github.com"),o=e?.includes("gitlab.com");try{if(n)return kB(r,e,t);if(o)return}catch{}}function cd(r){if(r.startsWith("git@")){let e=r.split(":");if(e.length===2){let t=e[1].replace(".git","").split("/");if(t.length===2){let n=t[0],o=t[1];return`${n}/${o}`}}}else if(r.startsWith("http")||r.startsWith("https")){let t=new URL(r).pathname.split("/").filter(Boolean);if(t.length>=2){let n=t[0],o=t[1].replace(".git","");return`${n}/${o}`}}}async function Ze(r,e){try{return(await e).trim()}catch(t){r.error({err:t},"Failed to run git command");return}}function UB(){if(process.env.GITHUB_ACTION)return"GithubActions";if(process.env.GITLAB_CI)return"GitlabCI";if(process.env.CIRCLECI)return"CircleCI";if(process.env.BUILDKITE)return"Buildkite";if(process.env["System.CollectionUri"]?.includes("azure"))return"AzureDevOps";if(process.env.PROJECT_ID&&process.env.BUILD_ID)return"GCPCloudBuild"}async function BB(r){let[e,t,n]=await Promise.all([Ze(r,qe.show(["--no-patch","--format=%ci"])),Ze(r,qe.show(["-s","--pretty=%B"])),Ze(r,qe.show(["-s","--pretty=%an"]))]),o=process.env.GITHUB_SERVER_URL&&process.env.GITHUB_REPOSITORY?`${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}`:void 0;return{ciProvider:"GithubActions",gitCommitSha:process.env.GITHUB_SHA,gitCommitShaShort:process.env.GITHUB_SHA?.slice(0,6),gitCommitTimestamp:e?new Date(e):void 0,gitBranchName:process.env.GITHUB_HEAD_REF||process.env.GITHUB_REF_NAME,gitOriginUrl:o,gitCommitMessage:t,gitCommitAuthorName:n,githubRepository:process.env.GITHUB_REPOSITORY,pipelineId:process.env.GITHUB_RUN_ID}}async function HB(r){let[e,t,n]=await Promise.all([Ze(r,qe.listRemote(["--get-url","origin"])),Ze(r,qe.show(["-s","--pretty=%B"])),Ze(r,qe.show(["-s","--pretty=%an"]))]);return{ciProvider:"GitlabCI",gitCommitSha:process.env.CI_COMMIT_SHA,gitCommitShaShort:process.env.CI_COMMIT_SHORT_SHA,gitCommitTimestamp:process.env.CI_COMMIT_TIMESTAMP?new Date(process.env.CI_COMMIT_TIMESTAMP):void 0,gitBranchName:process.env.CI_COMMIT_BRANCH||process.env.CI_COMMIT_REF_NAME,gitOriginUrl:e,gitCommitMessage:t,gitCommitAuthorName:n,gitlabProjectPath:process.env.CI_PROJECT_PATH,pipelineId:`${process.env.CI_PIPELINE_ID}:${process.env.CI_JOB_ID}`}}async function zB(r){let[e,t,n,o]=await Promise.all([Ze(r,qe.show(["--no-patch","--format=%ci"])),Ze(r,qe.listRemote(["--get-url","origin"])),Ze(r,qe.show(["-s","--pretty=%B"])),Ze(r,qe.show(["-s","--pretty=%an"]))]),i=process.env.CIRCLE_REPOSITORY_URL??t,a=i?.includes("github.com"),s=i?.includes("gitlab.com"),c=i?cd(i):void 0;return{ciProvider:"CircleCI",gitCommitSha:process.env.CIRCLE_SHA1,gitCommitShaShort:process.env.CIRCLE_SHA1?.slice(0,6),gitCommitTimestamp:e?new Date(e):void 0,gitBranchName:process.env.CIRCLE_BRANCH,gitOriginUrl:i,gitCommitMessage:n,gitCommitAuthorName:o,githubRepository:a?c:void 0,gitlabProjectPath:s?c:void 0,pipelineId:process.env.CIRCLE_PIPELINE_ID}}async function GB(r){let[e,t,n]=await Promise.all([Ze(r,qe.show(["--no-patch","--format=%ci"])),Ze(r,qe.show(["-s","--pretty=%B"])),Ze(r,qe.show(["-s","--pretty=%an"]))]),o=process.env.BUILDKITE_REPO,i=o?.includes("github.com"),a=o?.includes("gitlab.com"),s=o?cd(o):void 0;return{ciProvider:"Buildkite",gitCommitSha:process.env.BUILDKITE_COMMIT,gitCommitShaShort:process.env.BUILDKITE_COMMIT?.slice(0,6),gitCommitTimestamp:e?new Date(e):void 0,gitBranchName:process.env.BUILDKITE_BRANCH,gitOriginUrl:o,gitCommitMessage:t,gitCommitAuthorName:n,githubRepository:i?s:void 0,gitlabProjectPath:a?s:void 0,pipelineId:`${process.env.BUILDKITE_PIPELINE_ID}:${process.env.BUILDKITE_BUILD_ID}:${process.env.BUILDKITE_JOB_ID}`}}async function jB(r){let[e,t,n]=await Promise.all([Ze(r,qe.show(["--no-patch","--format=%ci"])),Ze(r,qe.show(["-s","--pretty=%B"])),Ze(r,qe.show(["-s","--pretty=%an"]))]),o=process.env["Build.Repository.Uri"],i=o?.includes("github.com"),a=o?.includes("gitlab.com"),s=o?cd(o):void 0;return{ciProvider:"AzureDevOps",gitCommitSha:process.env["Build.SourceVersion"],gitCommitShaShort:process.env["Build.SourceVersion"]?.slice(0,6),gitCommitTimestamp:e?new Date(e):void 0,gitBranchName:process.env["System.PullRequest.SourceBranch"]??process.env["Build.SourceBranchName"],gitOriginUrl:o,gitCommitMessage:t,gitCommitAuthorName:n,githubRepository:i?s:void 0,gitlabProjectPath:a?s:void 0,pipelineId:`${process.env["System.JobId"]}:${process.env["System.JobAttempt"]}`}}async function VB(r,e){let[t,n,o,i,a,s,c,l,u]=await Promise.all([Ze(r,qe.revparse(["HEAD"])),Ze(r,qe.revparse(["--short","HEAD"])),Ze(r,qe.revparse(["--abbrev-ref","HEAD"])),Ze(r,qe.listRemote(["--get-url","origin"])),Ze(r,qe.show(["--no-patch","--format=%ci"])),Ze(r,qe.show(["-s","--pretty=%B"])),Ze(r,qe.show(["-s","--pretty=%an"])),e?Ze(r,qe.raw(["merge-base","--fork-point",e])):Promise.resolve(void 0),DB(r)]),d=l?await Ze(r,qe.show(["--no-patch","--format=%ci",l])):void 0,p=i?.includes("github.com"),m=i?.includes("gitlab.com"),h=i?cd(i):void 0,g=u["user.email"]||void 0,f=u["user.name"]||void 0,y=u["user.username"]||void 0,S=await FB(r,i,u)??y??void 0;return{ciProvider:"none",gitCommitSha:t,gitCommitShaShort:n,gitBranchName:o,gitOriginUrl:i,gitCommitTimestamp:a?new Date(a):void 0,gitCommitMessage:s,gitCommitAuthorName:c,gitLocalUsername:S,gitLocalEmail:g,gitLocalName:f,lastCommitOnMainSha:l,lastCommitOnMainTimestamp:d?new Date(d):void 0,githubRepository:p?h:void 0,gitlabProjectPath:m?h:void 0,pipelineId:void 0}}async function $B(){let r=process.env._HEAD_REPO_URL;return{ciProvider:"GCPCloudBuild",gitCommitSha:process.env.COMMIT_SHA,gitCommitShaShort:process.env.COMMIT_SHA?.slice(0,6),gitBranchName:process.env.BRANCH_NAME,gitOriginUrl:r?process.env._HEAD_REPO_URL:void 0,gitCommitTimestamp:void 0,gitCommitMessage:void 0,gitCommitAuthorName:void 0,githubRepository:r?process.env.REPO_FULL_NAME:void 0,pipelineId:`${process.env.PROJECT_ID}:${process.env.BUILD_ID}`}}async function WB(r){let e=r.config.gitProtectedBranches??[];return r.config.gitMainBranch&&e.push(r.config.gitMainBranch),{gitMainBranch:r.config.gitMainBranch,gitProtectedBranches:e}}async function Qn(r,e){let t=UB();if(!t)return VB(r,e);switch(t){case"GithubActions":return BB(r);case"GitlabCI":return HB(r);case"CircleCI":return zB(r);case"Buildkite":return GB(r);case"AzureDevOps":return jB(r);case"GCPCloudBuild":return $B()}}async function qB(r,e,t,n){let o=n;if(!n.gitCommitSha)return o;if(n.gitMainBranch&&(!o.lastCommitOnMainSha||!o.lastCommitOnMainTimestamp))try{let i=await e.getMergeBaseCommitFromGitlab(t,n.gitMainBranch,n.gitCommitSha);o={...o,lastCommitOnMainSha:i.sha,lastCommitOnMainTimestamp:i.committer.date}}catch(i){r.warn({err:i},"Failed to get merge base commit from Gitlab")}if(!o.gitCommitTimestamp||!o.gitCommitAuthorName||!o.gitCommitMessage||!o.gitCommitAuthorName)try{let i=await e.getCommitFromGitlab(t,n.gitCommitSha);i&&(o={...o,gitCommitTimestamp:o.gitCommitTimestamp??i.committer.date,gitCommitAuthorName:o.gitCommitAuthorName??i.author.name,gitCommitMessage:o.gitCommitMessage??i.message})}catch(i){r.warn({err:i},"Failed to get commit from Gitlab")}if(n.gitBranchName&&n.gitBranchName===n.gitMainBranch&&!o.mergedGitBranchName)try{let i=await e.getMergedBranchFromGitlab(t,n.gitBranchName??"",n.gitCommitSha);i.mergedBranch&&(o={...o,mergedGitBranchName:i.mergedBranch})}catch(i){r.warn({err:i},"Failed to get merged branch from Gitlab")}return o}async function KB(r,e,t,n,o){let i=o;if(!o.gitCommitSha)return i;if(o.gitMainBranch&&(!i.lastCommitOnMainSha||!i.lastCommitOnMainTimestamp))try{let a=await e.getMergeBaseCommitFromGithub(t,n,o.gitMainBranch,o.gitCommitSha);i={...i,lastCommitOnMainSha:a.sha,lastCommitOnMainTimestamp:a.committer.date}}catch(a){r.warn({err:a},"Failed to get merge base commit from GitHub")}if(!i.gitCommitTimestamp||!i.gitCommitAuthorName||!i.gitCommitMessage||!i.gitCommitAuthorName)try{let a=await e.getCommitFromGithub(t,n,o.gitCommitSha);a&&(i={...i,gitCommitTimestamp:i.gitCommitTimestamp??a.committer.date,gitCommitAuthorName:i.gitCommitAuthorName??a.author.name,gitCommitMessage:i.gitCommitMessage??a.message})}catch(a){r.warn({err:a},"Failed to get commit from GitHub")}if(o.gitBranchName&&o.gitBranchName===o.gitMainBranch&&!i.mergedGitBranchName)try{let a=await e.getMergedBranchFromGithub(t,n,o.gitBranchName??"",o.gitCommitSha);a.mergedBranch&&(i={...i,mergedGitBranchName:a.mergedBranch})}catch(a){r.warn({err:a},"Failed to get merged branch from GitHub")}return i}async function YB(r,e,t){try{if(t.githubRepository){let[n,o]=t.githubRepository.split("/");return await KB(r,e,n,o,t)}else if(t.gitlabProjectPath)return await qB(r,e,t.gitlabProjectPath,t)}catch(n){r.warn({err:n},"Failed to get remote git metadata")}return t}async function Fr(r,e,t){let n=await WB(t),o=await Qn(r,n.gitMainBranch),i={...n,...o};(!i.lastCommitOnMainSha||!i.lastCommitOnMainTimestamp)&&i.gitBranchName===n.gitMainBranch&&(i.lastCommitOnMainSha=i.gitCommitSha,i.lastCommitOnMainTimestamp=i.gitCommitTimestamp);let a=await YB(r,e,i);return{...n,...o,...a}}async function GA(){try{return!!(await qe.show(["--no-patch","--format=%ci"])).trim()}catch{return null}}import{diff as WSe}from"deep-object-diff";import{cloneDeep as KSe}from"lodash-es";import{v4 as aye}from"uuid";import lye from"yaml";import Cye from"yaml";import _ye from"zod";import{randomUUID as XB}from"crypto";import Lo from"fs";import Wa from"path";var jA=new Set([".DS_Store","__MACOSX"]),VA={status:(r,e)=>{if(r.status===e.status)return r.status;if(r.status==="FAILED"||e.status==="FAILED")return"FAILED";if(r.status==="CANCELLED"||e.status==="CANCELLED")return"CANCELLED";if(r.status==="RETRYING"||e.status==="RETRYING")return"RETRYING";if(r.status==="RUNNING"||e.status==="RUNNING")return"RUNNING";if(r.status==="PENDING"||e.status==="PENDING")return"PENDING";throw new Error(`Invalid run status merge: ${r.status} and ${e.status}`)},startedAt:(r,e)=>r.startedAt<e.startedAt?r.startedAt:e.startedAt,updatedAt:(r,e)=>r.updatedAt>e.updatedAt?r.updatedAt:e.updatedAt,finishedAt:(r,e)=>!r.finishedAt||!e.finishedAt?new Date:r.finishedAt>e.finishedAt?r.finishedAt:e.finishedAt,gitCommitTimestamp:(r,e)=>{if(!(!r&&!e)){if(!r.gitCommitTimestamp||!e.gitCommitTimestamp||r.gitCommitTimestamp.getTime()!==e.gitCommitTimestamp.getTime())throw new Error(`Git commit timestamps must match to be merged: ${r.gitCommitTimestamp} and ${e.gitCommitTimestamp}`);return r.gitCommitTimestamp}},pipelineId:(r,e)=>r.pipelineId===e.pipelineId?r.pipelineId:!r.pipelineId&&e.pipelineId?e.pipelineId:!e.pipelineId&&r.pipelineId?r.pipelineId:r.startedAt<e.startedAt?e.pipelineId:r.pipelineId,labels:(r,e)=>{let t=new Set([...r.labels??[],...e.labels??[]]);return Array.from(t)}};function JB(r,e,t){if(VA[t]){let i=VA[t];return i(r,e)}let n=r[t],o=e[t];if(n!==o)throw new Error(`Metadata values for key "${t}" do not match: "${n}" vs "${o}"`);return n}var Hg=class extends Error{constructor(e,t){let n=`${e} contains invalid Momentic results: ${t}. Please ensure that the path points to a folder containing only valid results. If you passed \`--output-dir test-results/results-1\` to the \`run\` command, your results path for merging should be \`test-results\`.`;super(n),this.name="InvalidMomenticResultsPathError"}};function $A(r,e){try{let t=Wa.join(e,"metadata.json");return xu.parse(JSON.parse(Lo.readFileSync(t,"utf-8")))}catch{throw new Hg(r,e)}}function WA(r,e,t){let n=XB(),o=r.child({runGroupId:n});Lo.rmSync(e,{recursive:!0,force:!0});let i=Lo.readdirSync(t).filter(c=>!jA.has(c)).map(c=>Wa.join(t,c));if(i.length===0)throw new Error(`No run groups found in results path: ${t}`);Lo.mkdirSync(e,{recursive:!0});let a={...$A(t,i[0]),id:n};for(let c of i){let l=Wa.join(c,"runs");if(!Lo.existsSync(l))continue;let u=$A(t,c);o.info({oldRunGroupId:u.id},"Merging run groups");for(let p in u){if(p==="id")continue;let m=p;a[m]=JB(a,u,m)}let d=Lo.readdirSync(l);for(let p of d){if(jA.has(p))continue;let m=Wa.join(l,p),h=Wa.join(e,"runs",p);Lo.cpSync(m,h,{recursive:!0})}}let s=Wa.join(e,"metadata.json");Lo.writeFileSync(s,JSON.stringify(a,null,2))}import qA from"adm-zip";import zg from"fs";import ud from"path";function QB(r){let e=new qA,t=ud.join(r,"metadata.json"),n=xu.parse(JSON.parse(zg.readFileSync(t,"utf-8")));e.addLocalFile(t);for(let o of zg.readdirSync(ud.join(r,"runs"))){if(!o.endsWith(".zip"))continue;let i=o.replace(/\.zip$/,""),a=new qA(ud.join(r,"runs",o));for(let s of a.getEntries())s.isDirectory||e.addFile(ud.join("runs",i,s.entryName),s.getData())}return{runGroupId:n.id,buffer:e.toBuffer()}}async function dd(r){let{client:e,consoleLogger:t,resultsPath:n}=r;if(!zg.existsSync(n)){t.warn("Results path does not exist, skipping upload.");return}let o=new Nu(e);try{let{runGroupId:i,buffer:a}=QB(n),s=await o.uploadResultsArchive(i,a),c=`${e.getAppUrl()}/run-groups/${s}`;t.success(`Successfully uploaded test results. Once processed, your results can be found at ${c}`);return}catch(i){let a;i instanceof Error?a=i.message:typeof i=="string"?a=i:a="Unknown error",t.error(`Failed to upload test results: ${a}.`);return}}import ZB from"adm-zip";import Ht from"fs";import vr from"path";var _l=class r{constructor(e){this.filePath=e;Ht.rmSync(this.filePath,{recursive:!0,force:!0}),Ht.mkdirSync(this.filePath,{recursive:!0})}cd(e){return new r(vr.join(this.filePath,e))}cwd(){return this.filePath}mkdir(e){Ht.mkdirSync(vr.join(this.filePath,e),{recursive:!0})}readFile(e){let t=vr.join(this.filePath,e);if(Ht.existsSync(t))return Ht.readFileSync(t)}storeFile(e){let{name:t,contents:n}=e,o=vr.join(this.filePath,t);try{Ht.writeFileSync(o,n)}catch{}}createFileStream(e){let t=vr.join(this.filePath,e);return Ht.createWriteStream(t)}createRunArchive(e){return new Gg(vr.join(this.filePath,"runs"),e)}},Gg=class{constructor(e,t){this.filePath=e;this.tempPath=vr.join(e,`.${t}`),this.finalPath=vr.join(e,`${t}.zip`),Ht.rmSync(this.tempPath,{recursive:!0,force:!0}),Ht.rmSync(this.finalPath,{recursive:!0,force:!0}),Ht.mkdirSync(this.tempPath,{recursive:!0})}tempPath;finalPath;readFile(e){let t=vr.join(this.tempPath,e);if(Ht.existsSync(t))return Ht.readFileSync(t)}mkdir(e){Ht.mkdirSync(vr.join(this.tempPath,e),{recursive:!0})}cd(e){return new _l(vr.join(this.tempPath,e))}cwd(){return this.tempPath}storeFile(e){let{name:t,contents:n}=e,o=vr.join(this.tempPath,t);Ht.writeFileSync(o,n)}createFileStream(e){let t=vr.join(this.tempPath,e);return Ht.createWriteStream(t)}close(){let e=new ZB;e.addLocalFolder(this.tempPath,void 0,n=>n!==".DS_Store");let t=e.toBuffer();Ht.writeFileSync(this.finalPath,t),Ht.rmSync(this.tempPath,{recursive:!0,force:!0})}};import{hostname as eH}from"os";var tH="2.27.2",Ml=Ma({app:"desktop-server",hostname:eH(),disableConsoleLogs:!0}).child({cliVersion:tH});(async()=>{try{let r=await Qn(Ml);r.gitBranchName&&Ml.addBinding("branch",r.gitBranchName)}catch{}})();var KA=rH();KA.get("/",async(r,e)=>{let t=se(),n=wA();if(!n){e.status(500).json({message:"API client not initialized"});return}let o=await Fr(Ml,n,t);e.status(200).json(o)});var jg=KA;import Xq from"events";import UP,{Router as Jq}from"express";import Qq from"http";import Zq from"path";import{Server as yW}from"socket.io";var nH=({metadata:r,logger:e,globalE2eStateManager:t})=>{let{sessionId:n}=r;return async()=>{e.info({sessionId:n},"Cancel event received");let o=t.getSession(n);if(!o)throw new Error("No active session found");try{o.controller.setClosed()}catch{}}},YA={event:"cancel",createHandler:nH};var oH=({metadata:r,logger:e,globalE2eStateManager:t})=>{let{sessionId:n}=r;return async(o,i)=>{let a=t.getSession(n);if(!a)throw new Error("No active session found");a.controller.setOpen();let s=a.controller.browser;try{let l=(await s.getBrowserState({skipWait:!0})).serialize();e.debug({a11yTree:l},"Fetched a11y tree from the browser"),i({a11yTree:l})}catch(c){e.error({err:c},"Error fetching a11y tree from the browser"),i({err:c.message})}}},XA={event:"fetchA11yTree",createHandler:oH};var iH=({metadata:r,logger:e,globalE2eStateManager:t})=>{let{sessionId:n}=r;return async(o,i)=>{let a=t.getSession(n);if(!a)throw new Error("No active session found");a.controller.setOpen();let s=a.controller.browser;try{let c=await s.html();i({html:c})}catch(c){e.error({err:c},"Error fetching DOM from the browser"),c.name==="TimeoutError"?i({err:"Timed out fetching DOM tree. This page may be too large for Momentic to process."}):i({err:c.message})}}},JA={event:"fetchDom",createHandler:iH};var aH=({metadata:r,logger:e,globalE2eStateManager:t})=>{let{sessionId:n}=r;return o=>{e.info({sessionId:n,reason:o},`Disconnect event received (${o})`),t.removeSession(n,e)}},QA={event:"disconnect",createHandler:aH};function an(r){let{result:e,nestedResults:t}=r;if(!r.nestedResults.length)return;let{firstMetadata:n,lastMetadata:o}=sH(t);lH(e,n,o);let i=[...r.asyncTasks];r.asyncTasks.push((async()=>{try{await cH(i,e,n,o)}catch(a){r.logger.error({result:r.result,err:a},"Error hoisting scalar result metadata")}})())}function sH(r){let e=r[0],t;for(;;){switch(e.type){case"PRESET_ACTION":{t=e;break}case"CONDITIONAL":t=r[0];break;case"AI_ACTION_DYNAMIC":case"AI_ACTION":case"MODULE":case"SECTION":if(!e.results.length){t=e;break}e=e.results[0];break;default:return(a=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(e)}if(t)break}let n=r[r.length-1],o;for(;;){switch(n.type){case"PRESET_ACTION":{o=n;break}case"AI_ACTION_DYNAMIC":case"CONDITIONAL":case"AI_ACTION":case"MODULE":case"SECTION":if(!n.results.length){o=n;break}n=n.results[n.results.length-1];break;default:return(a=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(n)}if(o)break}return{firstMetadata:t,lastMetadata:o}}function lH(r,e,t){e&&(r.beforeUrl=e.beforeUrl),t&&(r.afterUrl=t.afterUrl,r.data=t.data,t.status!=="SUCCESS"&&(r.message=t.message))}async function cH(r,e,t,n){await Promise.allSettled(r),t&&(e.beforeSnapshot=t.beforeSnapshot),n&&(e.afterSnapshot=n.afterSnapshot)}import{randomUUID as bH}from"crypto";import{faker as uH}from"@faker-js/faker";import dH from"assert";import pH from"axios";import*as mH from"child_process";import hH from"moment";import*as gH from"otpauth";import fH from"pg";async function ZA(r){let e;try{e=new URL(r.url).hostname}catch{}let t=[];return r.headers.getSetCookie()?.forEach(n=>{let o=cu(n,e);t.push(...o)}),t}function SH(r,e){if(!r&&!e)return;let t;if(r){let{url:o,options:i}=r;t=new Request(o,i)}let n;if(e){let{body:o,options:i}=e;n=new Response(o??null,i)}return{request:t,response:n}}async function yH(r,e){switch(r){case"RAW":return e;case"RESPONSE":if(e instanceof Response){let t=[];return e.headers.forEach((o,i)=>{t.push([i,o])}),{status:e.status,headers:t,body:await e.text()}}else throw new Error("Result is not a Response object")}}var EH=Object.getPrototypeOf(async function(){}).constructor;async function ew(r,e,t){let n=e.code;e.options.fragment&&(n=`return ${e.code}`);let{env:o,additionalBindings:i,request:a,response:s}=e.bindings,c=e.tools,l={},u=(T,A)=>{o[T]=A,l[T]=A},d={},p=(T,A)=>{o[T]=A,d[T]=A},m;n.includes("Octokit")&&(m=(await import("@octokit/rest")).Octokit);let h;n.includes("createAppAuth")&&(h=(await import("@octokit/auth-app")).createAppAuth);let g=async()=>await Promise.resolve(new EH("axios","moment","faker","assert","pg","Octokit","createAppAuth","OTPAuth","child_process","extractCookiesFromResponse","env","setVariable","setPersistentVariable","sendSms","waitForLatestSms","email","sms","ai","mock",...Object.keys(i??{}),n)(pH,hH,c.fakerInstance??uH,dH,fH,m,h,gH,mH,ZA,o,e.options.disallowVariableUpdates?void 0:u,e.options.disallowVariableUpdates?void 0:p,A=>c.sms.send(A),A=>c.sms.fetchLatest(A),c.email,c.sms,c.ai,SH(a,s),...Object.values(i??{}))),f=!0,y,S;try{let T=await j(g(),{milliseconds:e.options.timeoutMs,message:`Timeout of ${e.options.timeoutMs}ms exceeded for code execution`,signal:e.signal});y=await yH(e.options.responseSerialization??"RAW",T)}catch(T){t.error({err:T,env:o,evalCode:n},`[${r}] Error executing code: ${T}`),f=!1,T instanceof Co?S=`Timeout of ${e.options.timeoutMs}ms exceeded for code execution`:S=T instanceof Error?T.message:`${T}`}return{result:y,variableUpdates:l,persistentVariableUpdates:d,success:f,error:S}}async function tw({code:r,fragment:e,context:t,localTools:n,logger:o,signal:i,timeoutMs:a=vo,disallowVariableUpdates:s,additionalBindings:c,responseSerialization:l,mock:u}){let d=bH(),p=await ew(d,{code:r,options:{fragment:e,timeoutMs:a,disallowVariableUpdates:s,responseSerialization:l},bindings:{...t.toObjectCopy(),...u,additionalBindings:c},tools:n,signal:i},o);return E.debug(`[${d}] Got execution result: ${JSON.stringify(p)}`),p}import{createHmac as TH,randomUUID as vH}from"crypto";import RH from"fetch-retry";var AH=RH(global.fetch,{retries:3,retryOn:function(r,e,t){return!!(e!==null||t&&t.status>=500)},retryDelay:function(r){return Math.pow(2,r)*500}}),rw=process.env.GCP_JS_EVAL_FUNCTION_ENDPOINT,nw=process.env.MOMENTIC_LAMBDA_AUTH_SECRET;async function ow({orgId:r,code:e,fragment:t,context:n,timeoutMs:o=vo,retries:i=2,signal:a,logger:s,additionalBindings:c,disallowVariableUpdates:l,responseSerialization:u,mock:d}){if(!rw)throw new Error("GCP_JS_EVAL_FUNCTION_ENDPOINT environment variable not set");let p,m,h=0;if(!nw)throw new Error("Missing lambda auth secret.");let g=TH("sha256",nw).update(r).digest("hex");for(;h<=i;){h++,a?.throwIfAborted();let y={id:vH(),orgId:r,momenticLambdaAuthHash:g,code:e,fragment:t,state:{...n.toObjectCopy(),...d,additionalBindings:c},timeoutMs:o,disallowVariableUpdates:l,responseSerialization:u};try{if(p=await j(AH(rw,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(y)}),{milliseconds:o,message:`Timeout of ${o}ms exceeded for code execution`,signal:a}),!p)throw new Error("Got empty response from code evaluation server");if(!p.ok)throw new Error(`Code evaluation server returned error code ${p.status}`);m=void 0;break}catch(S){m=S}}if(m)throw s.error({err:m},"Failed to evaluate code remotely"),m;if(!p)throw new Error(`An unexpected code evaluation error occurred${m?`: ${m}`:""}`);let f;try{f=wT.parse(await p.json())}catch(y){throw new Error(`Code evaluation server returned invalid response: ${y}`)}if(f.error)throw new Error(`Code evaluation error: ${f.error}`);return f}async function No(r){let e;if(process.env.GCP_JS_EVAL_FUNCTION_ENDPOINT)e=await ow(r);else if(r.localTools)e=await tw({...r,localTools:r.localTools});else throw new Error("No code evaluation environment available");if(e.error){let t=`Failed to evaluate code:
46
+ `)){let o=n.indexOf("=");if(o===-1)continue;let i=n.slice(0,o),a=n.slice(o+1).trim();t[i]=a}return t}async function kB(r,e,t){try{let o=t["github.user"]||void 0;if(o)return o}catch{}let n;try{if(e?.startsWith("http://")||e?.startsWith("https://"))n=new URL(e).host;else if(e?.startsWith("git@")){let o=e.indexOf("@"),i=e.indexOf(":",o+1);o!==-1&&i!==-1&&(n=e.slice(o+1,i))}}catch{}if(n=n?.toLowerCase(),!!n){try{if(e?.startsWith("git@")&&n?.includes("github")){let{stdout:o,stderr:i}=await zA("ssh",["-T","-o","BatchMode=yes",`git@${n}`],{timeout:5e3}),s=`${o??""}${i??""}`.trim().match(/Hi\s+([A-Za-z0-9_-]+)!/);if(s?.[1])return s[1]}}catch{}try{let o=n&&n!=="github.com"?["api","--hostname",n,"user","-q",".login"]:["api","user","-q",".login"],{stdout:i}=await zA("gh",o,{timeout:5e3}),a=i?.toString().trim();if(a)return a}catch{}}}async function FB(r,e,t){let n=e?.includes("github.com"),o=e?.includes("gitlab.com");try{if(n)return kB(r,e,t);if(o)return}catch{}}function cd(r){if(r.startsWith("git@")){let e=r.split(":");if(e.length===2){let t=e[1].replace(".git","").split("/");if(t.length===2){let n=t[0],o=t[1];return`${n}/${o}`}}}else if(r.startsWith("http")||r.startsWith("https")){let t=new URL(r).pathname.split("/").filter(Boolean);if(t.length>=2){let n=t[0],o=t[1].replace(".git","");return`${n}/${o}`}}}async function Ze(r,e){try{return(await e).trim()}catch(t){r.error({err:t},"Failed to run git command");return}}function UB(){if(process.env.GITHUB_ACTION)return"GithubActions";if(process.env.GITLAB_CI)return"GitlabCI";if(process.env.CIRCLECI)return"CircleCI";if(process.env.BUILDKITE)return"Buildkite";if(process.env["System.CollectionUri"]?.includes("azure"))return"AzureDevOps";if(process.env.PROJECT_ID&&process.env.BUILD_ID)return"GCPCloudBuild"}async function BB(r){let[e,t,n]=await Promise.all([Ze(r,qe.show(["--no-patch","--format=%ci"])),Ze(r,qe.show(["-s","--pretty=%B"])),Ze(r,qe.show(["-s","--pretty=%an"]))]),o=process.env.GITHUB_SERVER_URL&&process.env.GITHUB_REPOSITORY?`${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}`:void 0;return{ciProvider:"GithubActions",gitCommitSha:process.env.GITHUB_SHA,gitCommitShaShort:process.env.GITHUB_SHA?.slice(0,6),gitCommitTimestamp:e?new Date(e):void 0,gitBranchName:process.env.GITHUB_HEAD_REF||process.env.GITHUB_REF_NAME,gitOriginUrl:o,gitCommitMessage:t,gitCommitAuthorName:n,githubRepository:process.env.GITHUB_REPOSITORY,pipelineId:process.env.GITHUB_RUN_ID}}async function HB(r){let[e,t,n]=await Promise.all([Ze(r,qe.listRemote(["--get-url","origin"])),Ze(r,qe.show(["-s","--pretty=%B"])),Ze(r,qe.show(["-s","--pretty=%an"]))]);return{ciProvider:"GitlabCI",gitCommitSha:process.env.CI_COMMIT_SHA,gitCommitShaShort:process.env.CI_COMMIT_SHORT_SHA,gitCommitTimestamp:process.env.CI_COMMIT_TIMESTAMP?new Date(process.env.CI_COMMIT_TIMESTAMP):void 0,gitBranchName:process.env.CI_COMMIT_BRANCH||process.env.CI_COMMIT_REF_NAME,gitOriginUrl:e,gitCommitMessage:t,gitCommitAuthorName:n,gitlabProjectPath:process.env.CI_PROJECT_PATH,pipelineId:`${process.env.CI_PIPELINE_ID}:${process.env.CI_JOB_ID}`}}async function zB(r){let[e,t,n,o]=await Promise.all([Ze(r,qe.show(["--no-patch","--format=%ci"])),Ze(r,qe.listRemote(["--get-url","origin"])),Ze(r,qe.show(["-s","--pretty=%B"])),Ze(r,qe.show(["-s","--pretty=%an"]))]),i=process.env.CIRCLE_REPOSITORY_URL??t,a=i?.includes("github.com"),s=i?.includes("gitlab.com"),c=i?cd(i):void 0;return{ciProvider:"CircleCI",gitCommitSha:process.env.CIRCLE_SHA1,gitCommitShaShort:process.env.CIRCLE_SHA1?.slice(0,6),gitCommitTimestamp:e?new Date(e):void 0,gitBranchName:process.env.CIRCLE_BRANCH,gitOriginUrl:i,gitCommitMessage:n,gitCommitAuthorName:o,githubRepository:a?c:void 0,gitlabProjectPath:s?c:void 0,pipelineId:process.env.CIRCLE_PIPELINE_ID}}async function GB(r){let[e,t,n]=await Promise.all([Ze(r,qe.show(["--no-patch","--format=%ci"])),Ze(r,qe.show(["-s","--pretty=%B"])),Ze(r,qe.show(["-s","--pretty=%an"]))]),o=process.env.BUILDKITE_REPO,i=o?.includes("github.com"),a=o?.includes("gitlab.com"),s=o?cd(o):void 0;return{ciProvider:"Buildkite",gitCommitSha:process.env.BUILDKITE_COMMIT,gitCommitShaShort:process.env.BUILDKITE_COMMIT?.slice(0,6),gitCommitTimestamp:e?new Date(e):void 0,gitBranchName:process.env.BUILDKITE_BRANCH,gitOriginUrl:o,gitCommitMessage:t,gitCommitAuthorName:n,githubRepository:i?s:void 0,gitlabProjectPath:a?s:void 0,pipelineId:`${process.env.BUILDKITE_PIPELINE_ID}:${process.env.BUILDKITE_BUILD_ID}:${process.env.BUILDKITE_JOB_ID}`}}async function jB(r){let[e,t,n]=await Promise.all([Ze(r,qe.show(["--no-patch","--format=%ci"])),Ze(r,qe.show(["-s","--pretty=%B"])),Ze(r,qe.show(["-s","--pretty=%an"]))]),o=process.env["Build.Repository.Uri"],i=o?.includes("github.com"),a=o?.includes("gitlab.com"),s=o?cd(o):void 0;return{ciProvider:"AzureDevOps",gitCommitSha:process.env["Build.SourceVersion"],gitCommitShaShort:process.env["Build.SourceVersion"]?.slice(0,6),gitCommitTimestamp:e?new Date(e):void 0,gitBranchName:process.env["System.PullRequest.SourceBranch"]??process.env["Build.SourceBranchName"],gitOriginUrl:o,gitCommitMessage:t,gitCommitAuthorName:n,githubRepository:i?s:void 0,gitlabProjectPath:a?s:void 0,pipelineId:`${process.env["System.JobId"]}:${process.env["System.JobAttempt"]}`}}async function VB(r,e){let[t,n,o,i,a,s,c,l,u]=await Promise.all([Ze(r,qe.revparse(["HEAD"])),Ze(r,qe.revparse(["--short","HEAD"])),Ze(r,qe.revparse(["--abbrev-ref","HEAD"])),Ze(r,qe.listRemote(["--get-url","origin"])),Ze(r,qe.show(["--no-patch","--format=%ci"])),Ze(r,qe.show(["-s","--pretty=%B"])),Ze(r,qe.show(["-s","--pretty=%an"])),e?Ze(r,qe.raw(["merge-base","--fork-point",e])):Promise.resolve(void 0),DB(r)]),d=l?await Ze(r,qe.show(["--no-patch","--format=%ci",l])):void 0,p=i?.includes("github.com"),m=i?.includes("gitlab.com"),h=i?cd(i):void 0,g=u["user.email"]||void 0,f=u["user.name"]||void 0,y=u["user.username"]||void 0,S=await FB(r,i,u)??y??void 0;return{ciProvider:"none",gitCommitSha:t,gitCommitShaShort:n,gitBranchName:o,gitOriginUrl:i,gitCommitTimestamp:a?new Date(a):void 0,gitCommitMessage:s,gitCommitAuthorName:c,gitLocalUsername:S,gitLocalEmail:g,gitLocalName:f,lastCommitOnMainSha:l,lastCommitOnMainTimestamp:d?new Date(d):void 0,githubRepository:p?h:void 0,gitlabProjectPath:m?h:void 0,pipelineId:void 0}}async function $B(){let r=process.env._HEAD_REPO_URL;return{ciProvider:"GCPCloudBuild",gitCommitSha:process.env.COMMIT_SHA,gitCommitShaShort:process.env.COMMIT_SHA?.slice(0,6),gitBranchName:process.env.BRANCH_NAME,gitOriginUrl:r?process.env._HEAD_REPO_URL:void 0,gitCommitTimestamp:void 0,gitCommitMessage:void 0,gitCommitAuthorName:void 0,githubRepository:r?process.env.REPO_FULL_NAME:void 0,pipelineId:`${process.env.PROJECT_ID}:${process.env.BUILD_ID}`}}async function WB(r){let e=r.config.gitProtectedBranches??[];return r.config.gitMainBranch&&e.push(r.config.gitMainBranch),{gitMainBranch:r.config.gitMainBranch,gitProtectedBranches:e}}async function Qn(r,e){let t=UB();if(!t)return VB(r,e);switch(t){case"GithubActions":return BB(r);case"GitlabCI":return HB(r);case"CircleCI":return zB(r);case"Buildkite":return GB(r);case"AzureDevOps":return jB(r);case"GCPCloudBuild":return $B()}}async function qB(r,e,t,n){let o=n;if(!n.gitCommitSha)return o;if(n.gitMainBranch&&(!o.lastCommitOnMainSha||!o.lastCommitOnMainTimestamp))try{let i=await e.getMergeBaseCommitFromGitlab(t,n.gitMainBranch,n.gitCommitSha);o={...o,lastCommitOnMainSha:i.sha,lastCommitOnMainTimestamp:i.committer.date}}catch(i){r.warn({err:i},"Failed to get merge base commit from Gitlab")}if(!o.gitCommitTimestamp||!o.gitCommitAuthorName||!o.gitCommitMessage||!o.gitCommitAuthorName)try{let i=await e.getCommitFromGitlab(t,n.gitCommitSha);i&&(o={...o,gitCommitTimestamp:o.gitCommitTimestamp??i.committer.date,gitCommitAuthorName:o.gitCommitAuthorName??i.author.name,gitCommitMessage:o.gitCommitMessage??i.message})}catch(i){r.warn({err:i},"Failed to get commit from Gitlab")}if(n.gitBranchName&&n.gitBranchName===n.gitMainBranch&&!o.mergedGitBranchName)try{let i=await e.getMergedBranchFromGitlab(t,n.gitBranchName??"",n.gitCommitSha);i.mergedBranch&&(o={...o,mergedGitBranchName:i.mergedBranch})}catch(i){r.warn({err:i},"Failed to get merged branch from Gitlab")}return o}async function KB(r,e,t,n,o){let i=o;if(!o.gitCommitSha)return i;if(o.gitMainBranch&&(!i.lastCommitOnMainSha||!i.lastCommitOnMainTimestamp))try{let a=await e.getMergeBaseCommitFromGithub(t,n,o.gitMainBranch,o.gitCommitSha);i={...i,lastCommitOnMainSha:a.sha,lastCommitOnMainTimestamp:a.committer.date}}catch(a){r.warn({err:a},"Failed to get merge base commit from GitHub")}if(!i.gitCommitTimestamp||!i.gitCommitAuthorName||!i.gitCommitMessage||!i.gitCommitAuthorName)try{let a=await e.getCommitFromGithub(t,n,o.gitCommitSha);a&&(i={...i,gitCommitTimestamp:i.gitCommitTimestamp??a.committer.date,gitCommitAuthorName:i.gitCommitAuthorName??a.author.name,gitCommitMessage:i.gitCommitMessage??a.message})}catch(a){r.warn({err:a},"Failed to get commit from GitHub")}if(o.gitBranchName&&o.gitBranchName===o.gitMainBranch&&!i.mergedGitBranchName)try{let a=await e.getMergedBranchFromGithub(t,n,o.gitBranchName??"",o.gitCommitSha);a.mergedBranch&&(i={...i,mergedGitBranchName:a.mergedBranch})}catch(a){r.warn({err:a},"Failed to get merged branch from GitHub")}return i}async function YB(r,e,t){try{if(t.githubRepository){let[n,o]=t.githubRepository.split("/");return await KB(r,e,n,o,t)}else if(t.gitlabProjectPath)return await qB(r,e,t.gitlabProjectPath,t)}catch(n){r.warn({err:n},"Failed to get remote git metadata")}return t}async function Fr(r,e,t){let n=await WB(t),o=await Qn(r,n.gitMainBranch),i={...n,...o};(!i.lastCommitOnMainSha||!i.lastCommitOnMainTimestamp)&&i.gitBranchName===n.gitMainBranch&&(i.lastCommitOnMainSha=i.gitCommitSha,i.lastCommitOnMainTimestamp=i.gitCommitTimestamp);let a=await YB(r,e,i);return{...n,...o,...a}}async function GA(){try{return!!(await qe.show(["--no-patch","--format=%ci"])).trim()}catch{return null}}import{diff as WSe}from"deep-object-diff";import{cloneDeep as KSe}from"lodash-es";import{v4 as aye}from"uuid";import lye from"yaml";import Cye from"yaml";import _ye from"zod";import{randomUUID as XB}from"crypto";import Lo from"fs";import Wa from"path";var jA=new Set([".DS_Store","__MACOSX"]),VA={status:(r,e)=>{if(r.status===e.status)return r.status;if(r.status==="FAILED"||e.status==="FAILED")return"FAILED";if(r.status==="CANCELLED"||e.status==="CANCELLED")return"CANCELLED";if(r.status==="RETRYING"||e.status==="RETRYING")return"RETRYING";if(r.status==="RUNNING"||e.status==="RUNNING")return"RUNNING";if(r.status==="PENDING"||e.status==="PENDING")return"PENDING";throw new Error(`Invalid run status merge: ${r.status} and ${e.status}`)},startedAt:(r,e)=>r.startedAt<e.startedAt?r.startedAt:e.startedAt,updatedAt:(r,e)=>r.updatedAt>e.updatedAt?r.updatedAt:e.updatedAt,finishedAt:(r,e)=>!r.finishedAt||!e.finishedAt?new Date:r.finishedAt>e.finishedAt?r.finishedAt:e.finishedAt,gitCommitTimestamp:(r,e)=>{if(!(!r&&!e)){if(!r.gitCommitTimestamp||!e.gitCommitTimestamp||r.gitCommitTimestamp.getTime()!==e.gitCommitTimestamp.getTime())throw new Error(`Git commit timestamps must match to be merged: ${r.gitCommitTimestamp} and ${e.gitCommitTimestamp}`);return r.gitCommitTimestamp}},pipelineId:(r,e)=>r.pipelineId===e.pipelineId?r.pipelineId:!r.pipelineId&&e.pipelineId?e.pipelineId:!e.pipelineId&&r.pipelineId?r.pipelineId:r.startedAt<e.startedAt?e.pipelineId:r.pipelineId,labels:(r,e)=>{let t=new Set([...r.labels??[],...e.labels??[]]);return Array.from(t)}};function JB(r,e,t){if(VA[t]){let i=VA[t];return i(r,e)}let n=r[t],o=e[t];if(n!==o)throw new Error(`Metadata values for key "${t}" do not match: "${n}" vs "${o}"`);return n}var Hg=class extends Error{constructor(e,t){let n=`${e} contains invalid Momentic results: ${t}. Please ensure that the path points to a folder containing only valid results. If you passed \`--output-dir test-results/results-1\` to the \`run\` command, your results path for merging should be \`test-results\`.`;super(n),this.name="InvalidMomenticResultsPathError"}};function $A(r,e){try{let t=Wa.join(e,"metadata.json");return xu.parse(JSON.parse(Lo.readFileSync(t,"utf-8")))}catch{throw new Hg(r,e)}}function WA(r,e,t){let n=XB(),o=r.child({runGroupId:n});Lo.rmSync(e,{recursive:!0,force:!0});let i=Lo.readdirSync(t).filter(c=>!jA.has(c)).map(c=>Wa.join(t,c));if(i.length===0)throw new Error(`No run groups found in results path: ${t}`);Lo.mkdirSync(e,{recursive:!0});let a={...$A(t,i[0]),id:n};for(let c of i){let l=Wa.join(c,"runs");if(!Lo.existsSync(l))continue;let u=$A(t,c);o.info({oldRunGroupId:u.id},"Merging run groups");for(let p in u){if(p==="id")continue;let m=p;a[m]=JB(a,u,m)}let d=Lo.readdirSync(l);for(let p of d){if(jA.has(p))continue;let m=Wa.join(l,p),h=Wa.join(e,"runs",p);Lo.cpSync(m,h,{recursive:!0})}}let s=Wa.join(e,"metadata.json");Lo.writeFileSync(s,JSON.stringify(a,null,2))}import qA from"adm-zip";import zg from"fs";import ud from"path";function QB(r){let e=new qA,t=ud.join(r,"metadata.json"),n=xu.parse(JSON.parse(zg.readFileSync(t,"utf-8")));e.addLocalFile(t);for(let o of zg.readdirSync(ud.join(r,"runs"))){if(!o.endsWith(".zip"))continue;let i=o.replace(/\.zip$/,""),a=new qA(ud.join(r,"runs",o));for(let s of a.getEntries())s.isDirectory||e.addFile(ud.join("runs",i,s.entryName),s.getData())}return{runGroupId:n.id,buffer:e.toBuffer()}}async function dd(r){let{client:e,consoleLogger:t,resultsPath:n}=r;if(!zg.existsSync(n)){t.warn("Results path does not exist, skipping upload.");return}let o=new Nu(e);try{let{runGroupId:i,buffer:a}=QB(n),s=await o.uploadResultsArchive(i,a),c=`${e.getAppUrl()}/run-groups/${s}`;t.success(`Successfully uploaded test results. Once processed, your results can be found at ${c}`);return}catch(i){let a;i instanceof Error?a=i.message:typeof i=="string"?a=i:a="Unknown error",t.error(`Failed to upload test results: ${a}.`);return}}import ZB from"adm-zip";import Ht from"fs";import vr from"path";var _l=class r{constructor(e){this.filePath=e;Ht.rmSync(this.filePath,{recursive:!0,force:!0}),Ht.mkdirSync(this.filePath,{recursive:!0})}cd(e){return new r(vr.join(this.filePath,e))}cwd(){return this.filePath}mkdir(e){Ht.mkdirSync(vr.join(this.filePath,e),{recursive:!0})}readFile(e){let t=vr.join(this.filePath,e);if(Ht.existsSync(t))return Ht.readFileSync(t)}storeFile(e){let{name:t,contents:n}=e,o=vr.join(this.filePath,t);try{Ht.writeFileSync(o,n)}catch{}}createFileStream(e){let t=vr.join(this.filePath,e);return Ht.createWriteStream(t)}createRunArchive(e){return new Gg(vr.join(this.filePath,"runs"),e)}},Gg=class{constructor(e,t){this.filePath=e;this.tempPath=vr.join(e,`.${t}`),this.finalPath=vr.join(e,`${t}.zip`),Ht.rmSync(this.tempPath,{recursive:!0,force:!0}),Ht.rmSync(this.finalPath,{recursive:!0,force:!0}),Ht.mkdirSync(this.tempPath,{recursive:!0})}tempPath;finalPath;readFile(e){let t=vr.join(this.tempPath,e);if(Ht.existsSync(t))return Ht.readFileSync(t)}mkdir(e){Ht.mkdirSync(vr.join(this.tempPath,e),{recursive:!0})}cd(e){return new _l(vr.join(this.tempPath,e))}cwd(){return this.tempPath}storeFile(e){let{name:t,contents:n}=e,o=vr.join(this.tempPath,t);Ht.writeFileSync(o,n)}createFileStream(e){let t=vr.join(this.tempPath,e);return Ht.createWriteStream(t)}close(){let e=new ZB;e.addLocalFolder(this.tempPath,void 0,n=>n!==".DS_Store");let t=e.toBuffer();Ht.writeFileSync(this.finalPath,t),Ht.rmSync(this.tempPath,{recursive:!0,force:!0})}};import{hostname as eH}from"os";var tH="2.28.1",Ml=Ma({app:"desktop-server",hostname:eH(),disableConsoleLogs:!0}).child({cliVersion:tH});(async()=>{try{let r=await Qn(Ml);r.gitBranchName&&Ml.addBinding("branch",r.gitBranchName)}catch{}})();var KA=rH();KA.get("/",async(r,e)=>{let t=se(),n=wA();if(!n){e.status(500).json({message:"API client not initialized"});return}let o=await Fr(Ml,n,t);e.status(200).json(o)});var jg=KA;import Xq from"events";import UP,{Router as Jq}from"express";import Qq from"http";import Zq from"path";import{Server as yW}from"socket.io";var nH=({metadata:r,logger:e,globalE2eStateManager:t})=>{let{sessionId:n}=r;return async()=>{e.info({sessionId:n},"Cancel event received");let o=t.getSession(n);if(!o)throw new Error("No active session found");try{o.controller.setClosed()}catch{}}},YA={event:"cancel",createHandler:nH};var oH=({metadata:r,logger:e,globalE2eStateManager:t})=>{let{sessionId:n}=r;return async(o,i)=>{let a=t.getSession(n);if(!a)throw new Error("No active session found");a.controller.setOpen();let s=a.controller.browser;try{let l=(await s.getBrowserState({skipWait:!0})).serialize();e.debug({a11yTree:l},"Fetched a11y tree from the browser"),i({a11yTree:l})}catch(c){e.error({err:c},"Error fetching a11y tree from the browser"),i({err:c.message})}}},XA={event:"fetchA11yTree",createHandler:oH};var iH=({metadata:r,logger:e,globalE2eStateManager:t})=>{let{sessionId:n}=r;return async(o,i)=>{let a=t.getSession(n);if(!a)throw new Error("No active session found");a.controller.setOpen();let s=a.controller.browser;try{let c=await s.html();i({html:c})}catch(c){e.error({err:c},"Error fetching DOM from the browser"),c.name==="TimeoutError"?i({err:"Timed out fetching DOM tree. This page may be too large for Momentic to process."}):i({err:c.message})}}},JA={event:"fetchDom",createHandler:iH};var aH=({metadata:r,logger:e,globalE2eStateManager:t})=>{let{sessionId:n}=r;return o=>{e.info({sessionId:n,reason:o},`Disconnect event received (${o})`),t.removeSession(n,e)}},QA={event:"disconnect",createHandler:aH};function an(r){let{result:e,nestedResults:t}=r;if(!r.nestedResults.length)return;let{firstMetadata:n,lastMetadata:o}=sH(t);lH(e,n,o);let i=[...r.asyncTasks];r.asyncTasks.push((async()=>{try{await cH(i,e,n,o)}catch(a){r.logger.error({result:r.result,err:a},"Error hoisting scalar result metadata")}})())}function sH(r){let e=r[0],t;for(;;){switch(e.type){case"PRESET_ACTION":{t=e;break}case"CONDITIONAL":t=r[0];break;case"AI_ACTION_DYNAMIC":case"AI_ACTION":case"MODULE":case"SECTION":if(!e.results.length){t=e;break}e=e.results[0];break;default:return(a=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(e)}if(t)break}let n=r[r.length-1],o;for(;;){switch(n.type){case"PRESET_ACTION":{o=n;break}case"AI_ACTION_DYNAMIC":case"CONDITIONAL":case"AI_ACTION":case"MODULE":case"SECTION":if(!n.results.length){o=n;break}n=n.results[n.results.length-1];break;default:return(a=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(n)}if(o)break}return{firstMetadata:t,lastMetadata:o}}function lH(r,e,t){e&&(r.beforeUrl=e.beforeUrl),t&&(r.afterUrl=t.afterUrl,r.data=t.data,t.status!=="SUCCESS"&&(r.message=t.message))}async function cH(r,e,t,n){await Promise.allSettled(r),t&&(e.beforeSnapshot=t.beforeSnapshot),n&&(e.afterSnapshot=n.afterSnapshot)}import{randomUUID as bH}from"crypto";import{faker as uH}from"@faker-js/faker";import dH from"assert";import pH from"axios";import*as mH from"child_process";import hH from"moment";import*as gH from"otpauth";import fH from"pg";async function ZA(r){let e;try{e=new URL(r.url).hostname}catch{}let t=[];return r.headers.getSetCookie()?.forEach(n=>{let o=cu(n,e);t.push(...o)}),t}function SH(r,e){if(!r&&!e)return;let t;if(r){let{url:o,options:i}=r;t=new Request(o,i)}let n;if(e){let{body:o,options:i}=e;n=new Response(o??null,i)}return{request:t,response:n}}async function yH(r,e){switch(r){case"RAW":return e;case"RESPONSE":if(e instanceof Response){let t=[];return e.headers.forEach((o,i)=>{t.push([i,o])}),{status:e.status,headers:t,body:await e.text()}}else throw new Error("Result is not a Response object")}}var EH=Object.getPrototypeOf(async function(){}).constructor;async function ew(r,e,t){let n=e.code;e.options.fragment&&(n=`return ${e.code}`);let{env:o,additionalBindings:i,request:a,response:s}=e.bindings,c=e.tools,l={},u=(T,A)=>{o[T]=A,l[T]=A},d={},p=(T,A)=>{o[T]=A,d[T]=A},m;n.includes("Octokit")&&(m=(await import("@octokit/rest")).Octokit);let h;n.includes("createAppAuth")&&(h=(await import("@octokit/auth-app")).createAppAuth);let g=async()=>await Promise.resolve(new EH("axios","moment","faker","assert","pg","Octokit","createAppAuth","OTPAuth","child_process","extractCookiesFromResponse","env","setVariable","setPersistentVariable","sendSms","waitForLatestSms","email","sms","ai","mock",...Object.keys(i??{}),n)(pH,hH,c.fakerInstance??uH,dH,fH,m,h,gH,mH,ZA,o,e.options.disallowVariableUpdates?void 0:u,e.options.disallowVariableUpdates?void 0:p,A=>c.sms.send(A),A=>c.sms.fetchLatest(A),c.email,c.sms,c.ai,SH(a,s),...Object.values(i??{}))),f=!0,y,S;try{let T=await j(g(),{milliseconds:e.options.timeoutMs,message:`Timeout of ${e.options.timeoutMs}ms exceeded for code execution`,signal:e.signal});y=await yH(e.options.responseSerialization??"RAW",T)}catch(T){t.error({err:T,env:o,evalCode:n},`[${r}] Error executing code: ${T}`),f=!1,T instanceof Co?S=`Timeout of ${e.options.timeoutMs}ms exceeded for code execution`:S=T instanceof Error?T.message:`${T}`}return{result:y,variableUpdates:l,persistentVariableUpdates:d,success:f,error:S}}async function tw({code:r,fragment:e,context:t,localTools:n,logger:o,signal:i,timeoutMs:a=vo,disallowVariableUpdates:s,additionalBindings:c,responseSerialization:l,mock:u}){let d=bH(),p=await ew(d,{code:r,options:{fragment:e,timeoutMs:a,disallowVariableUpdates:s,responseSerialization:l},bindings:{...t.toObjectCopy(),...u,additionalBindings:c},tools:n,signal:i},o);return E.debug(`[${d}] Got execution result: ${JSON.stringify(p)}`),p}import{createHmac as TH,randomUUID as vH}from"crypto";import RH from"fetch-retry";var AH=RH(global.fetch,{retries:3,retryOn:function(r,e,t){return!!(e!==null||t&&t.status>=500)},retryDelay:function(r){return Math.pow(2,r)*500}}),rw=process.env.GCP_JS_EVAL_FUNCTION_ENDPOINT,nw=process.env.MOMENTIC_LAMBDA_AUTH_SECRET;async function ow({orgId:r,code:e,fragment:t,context:n,timeoutMs:o=vo,retries:i=2,signal:a,logger:s,additionalBindings:c,disallowVariableUpdates:l,responseSerialization:u,mock:d}){if(!rw)throw new Error("GCP_JS_EVAL_FUNCTION_ENDPOINT environment variable not set");let p,m,h=0;if(!nw)throw new Error("Missing lambda auth secret.");let g=TH("sha256",nw).update(r).digest("hex");for(;h<=i;){h++,a?.throwIfAborted();let y={id:vH(),orgId:r,momenticLambdaAuthHash:g,code:e,fragment:t,state:{...n.toObjectCopy(),...d,additionalBindings:c},timeoutMs:o,disallowVariableUpdates:l,responseSerialization:u};try{if(p=await j(AH(rw,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(y)}),{milliseconds:o,message:`Timeout of ${o}ms exceeded for code execution`,signal:a}),!p)throw new Error("Got empty response from code evaluation server");if(!p.ok)throw new Error(`Code evaluation server returned error code ${p.status}`);m=void 0;break}catch(S){m=S}}if(m)throw s.error({err:m},"Failed to evaluate code remotely"),m;if(!p)throw new Error(`An unexpected code evaluation error occurred${m?`: ${m}`:""}`);let f;try{f=wT.parse(await p.json())}catch(y){throw new Error(`Code evaluation server returned invalid response: ${y}`)}if(f.error)throw new Error(`Code evaluation error: ${f.error}`);return f}async function No(r){let e;if(process.env.GCP_JS_EVAL_FUNCTION_ENDPOINT)e=await ow(r);else if(r.localTools)e=await tw({...r,localTools:r.localTools});else throw new Error("No code evaluation environment available");if(e.error){let t=`Failed to evaluate code:
47
47
  ${e.error}
48
48
  Code received:
49
- ${r.code}`;throw r.logger.error({err:e.error,code:r.code,env:r.context.toObjectCopy()},t),new Error(t)}if(e.variableUpdates)for(let[t,n]of Object.entries(e.variableUpdates))r.context.setVariable(t,n);if(e.persistentVariableUpdates&&Object.keys(e.persistentVariableUpdates).length>0){await r.callbacks?.onPersistentVariableUpdates?.(e.persistentVariableUpdates);for(let[t,n]of Object.entries(e.persistentVariableUpdates))r.context.setVariable(t,n)}return e.result}import{set as wH}from"lodash-es";async function sr(r){let{orgId:e,s:t,context:n,logger:o,signal:i,retries:a=2,timeoutMs:s=vo,allowUndefined:c=!1}=r,l=/{{(.*?)}}/g,u=t.matchAll(l),d=t;for(let p of u){if(p.length<2)continue;let m=p[1].trim(),h;try{h=await No({orgId:e,code:m,fragment:!0,context:n,timeoutMs:s,logger:o,retries:a,localTools:r.localTools,signal:i})}catch(f){throw o.error({err:f,value:t},"Error evaluating template string"),f}if(h===void 0&&!c)throw new _("UserConfigurationError",`Template fragment '${m}' evaluated to undefined. Please ensure that the variable name is spelled correctly and it is only referenced after being assigned a value.`);let g=typeof h=="string"?h:`${h}`;g=g.replaceAll(/\$/g,"$$$$"),d=d.replace(p[0],g)}return d}async function pd(r){return iw(r)}async function iw({obj:r,bannedKeys:e,allowList:t,context:n,prefixPath:o=[],replacements:i=[],...a}){for(let s in r){if(e.includes(s))continue;let c=!1;if(t)if(t.includes(s))c=!0;else continue;let l=r[s],u=[...o,s];if(typeof l=="string"&&l.includes("{{")){let d=await sr({s:l,context:n,...a});if(l===d)continue;i.push({path:u,original:l}),r[s]=d}else typeof l=="object"&&l!==null&&!Array.isArray(l)&&await iw({obj:l,bannedKeys:e,context:n,prefixPath:u,replacements:i,allowList:c?void 0:t,...a})}return i}function aw(r,e){for(let{path:t,original:n}of e)wH(r,t,n)}import CH from"fetch-retry";var zbe=process.env.MAILINATOR_API_KEY,Gbe=CH(global.fetch,{retryOn:function(r,e,t){return r>3?!1:!!(e!==null||t&&t.status>=400)},retryDelay:function(r){return 500}});import{hostname as NH}from"os";import{cloneDeep as lw}from"lodash-es";async function cw(r){let{command:e,timeoutMs:t,fixtures:n}=r,{abortSignal:o}=n,i=()=>Ny(e.cache)?e.cache:void 0,a=i(),s=lw(a),c=(g=!1)=>{if(a=i(),!!a)if(g){let f=mg(s,a);a.target=f.target,a.updatedAt=f.updatedAt}else{if(!s){a=void 0;return}a.target=s.target,a.updatedAt=s.updatedAt}},l=Date.now(),u=0,d,p=500,m=!1;for(;u<2||Date.now()-l<t;){u++,u>1&&await ae(p,o),o?.throwIfAborted(),a=i();let{result:g,elementWasFound:f}=await sw({cacheToUse:a,params:r});if(d=g,m=f,g.success)break;c(),p=Math.min(p*2,1e4)}if(!d)throw new _("InternalPlatformError",`Failed to evaluate manual element assertion in ${t}ms.`);if(o?.throwIfAborted(),!d.success&&a?.target&&Ac(a.target)){let g=a?.target?.memory?{target:{id:-1,memory:a.target.memory}}:void 0,{result:f}=await sw({cacheToUse:g,params:r});d=f,d.success||c(!0)}let h=i();return d.success&&h?.target&&!m&&(h.target=Sl(h.target),h.updatedAt=new Date),d}async function sw({cacheToUse:r,params:e}){let{command:t,disableCache:n,fixtures:o,tracer:i,targetingWrapper:a}=e,{logger:s}=o;if(t.target&&!po(t.target))throw new Error("Element assertion with x/y is not supported yet");let c=yR(t.assertion),l,u=!1,d=lw(r);try{let{elementInteractedDisplayString:p,result:m,thoughts:h}=await a({ctx:o.ctx,tracer:i,command:t,target:t.target,cache:d?.target,action:async g=>xH(g.locator,e),options:{...t,allowNotActionableNodesOverride:!0,disableCache:n,memory:d?.target?.memory,disableGlobalLocatorRedirect:!0,source:di(t),targetName:"target"}});return l={success:m.success,data:m.data,err:m.err,elementInteractedDisplayString:p,thoughts:h},u=!0,m.success||(s.warn({aiThoughts:h,elementString:p,err:m.err},"Element check found an element but failed"),l={...m,thoughts:h}),{result:l,elementWasFound:u}}catch(p){if(c)return l={success:!0,thoughts:`The element described does not exist on the page: ${p.message}`,err:void 0,data:void 0},{result:l,elementWasFound:u};if(!(p instanceof _)||p.reason!="ActionFailureError")throw p;return l={success:!1,err:p,data:void 0,thoughts:void 0},s.warn({err:p},"Element check did not find an element and failed"),{result:l,elementWasFound:u}}}async function xH(r,{command:e,fixtures:t}){return await t.browser.highlight(r),await _H(r,e.assertion)}async function _H(r,e){let t=!0,n,o;switch(e.type){case"ELEMENT_CONTENT":{let a=await r.textContent()??"";if(o={elementTextContent:mt(a,500,!0)},!fl(a,e.value,e.operation,{negated:!!e.negated,ignoreCase:!1})){let s=La(e);t=!1,n=new _("AssertionFailureError",`The content ${s} '${e.value}': ${a}`)}break}case"ELEMENT_ATTRIBUTE":{o={elementOuterHtml:mt(await r.evaluate(s=>s.cloneNode(!1).outerHTML),500,!0)};let a;try{a=await r.getAttribute(e.attr,{timeout:3e3})??""}catch(s){n=new _("AssertionFailureError",`The element does not have an attribute named ${e.attr}: ${s}`),t=!1;break}if(!fl(a,e.value,e.operation,{negated:!!e.negated,ignoreCase:!1})){let s=La(e);t=!1,e.operation==="EXISTS"?n=new _("AssertionFailureError",`The attribute ${e.attr} ${s}`):n=new _("AssertionFailureError",`The attribute ${e.attr} ${s} '${e.value}': ${a}`)}break}case"ELEMENT_EXISTENCE":{switch(e.condition){case"VISIBLE":{t=await r.evaluate(async(s,c)=>{let l=Date.now();for(;Date.now()-l<c;){await new Promise(d=>setTimeout(d,250));let u=s.getBoundingClientRect();if(!(u.width===0||u.height===0)&&window.getComputedStyle(s).visibility!=="hidden"&&window.getComputedStyle(s).display!=="none")return!0}return!1},hn*1e3);break}case"EDITABLE":{t=await r.isEditable({timeout:hn*1e3});break}case"EXISTS":{t=!0;break}case"ENABLED":{t=await r.isEnabled({timeout:hn*1e3});break}case"FOCUSED":{t=await r.evaluate(s=>s===document.activeElement);break}default:return(s=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(e.condition)}if(t=e.negated?!t:t,!t){let a=La(e);n=new _("AssertionFailureError",`The element ${a}`)}break}case"ELEMENT_NAME":{let a=await r.evaluate(s=>s.tagName);if(!fl(a,e.value,e.operation,{negated:!!e.negated,ignoreCase:!0})){let s=La(e);t=!1,n=new _("AssertionFailureError",`The element tag name ${s} '${e.value}': ${a}`)}break}case"ELEMENT_STYLE":{let a=await r.evaluate((s,c)=>window.getComputedStyle(s).getPropertyValue(c),e.property);if(!fl(a,e.value,e.operation,{negated:!!e.negated,ignoreCase:!1})){let s=La(e);t=!1,e.operation==="EXISTS"?n=new _("AssertionFailureError",`The style property ${e.property} ${s}`):n=new _("AssertionFailureError",`The style property ${e.property} ${s} '${e.value}': ${a}`)}break}default:return(a=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(e)}return{thoughts:void 0,success:t,data:o,err:n}}function uw(r){return r.type==="ELEMENT_EXISTENCE"&&r.negated&&r.condition==="EXISTS"}import{Jimp as MH}from"jimp";async function Il(r,e){let t=await r.screenshot(e),n=await MH.fromBuffer(t);return{buffer:t,width:Math.ceil(n.bitmap.width??0),height:Math.ceil(n.bitmap.height??0)}}import{Jimp as dw}from"jimp";import Vg from"jpeg-js";import IH from"pixelmatch";async function pw({ctx:r,tracer:e,command:t,disableCache:n,browser:o,targetingWrapper:i,logger:a,screenshotStorage:s}){if(t.target&&!po(t.target))throw new Error("Visual Diff with x/y is not supported yet");await o.waitForDOMStability({logger:a});let c={clearHighlights:!0,hideCaret:!0},l;t.target?.elementDescriptor?l=(await i({ctx:r,tracer:e,command:t,target:t.target,cache:t.cache?.target,action:async V=>Il(o,{locator:V.locator,...c}),options:{...t,disableCache:n,disableGlobalLocatorRedirect:!0,memory:t.cache?.target?.memory,targetName:"target"}})).result:l=await Il(o,c);let u=await s.prepareGoldenScreenshotForComparison(a,t,l);if((l.height!==u.height||l.width!==u.width)&&a.warn({currHeight:l.height,currWidth:l.width,savedHeight:u.height,savedWidth:u.width},"Mismatched before and after visual diff screenshot sizes"),Math.abs(l.height-u.height)>10||Math.abs(l.width-u.width)>10){let U=`${l.width}x${l.height}`,V=`${u.width}x${u.height}`;return{fail:!0,thoughts:`Current screenshot (${U}) does not match saved screenshot dimensions (${V}) - did you change the size of the target or the viewport?`,beforeScreenshotOverride:u.buffer,afterScreenshotOverride:l.buffer,succeedImmediately:!1,urlAfterCommand:o.url()}}let d=await dw.fromBuffer(l.buffer),p={width:l.width,height:l.height},m=await dw.fromBuffer(u.buffer),h={width:u.width,height:u.height},g,f=p.width*p.height,y=h.width*h.height,S=Math.abs(p.height-h.height),T=Math.abs(p.width-h.width);if(f>y){let U=d.cover({w:h.width,h:h.height});l.buffer=await U.getBuffer("image/jpeg"),g="current",l.width=h.width,l.height=h.height}else if(y>f){let U=m.cover({w:p.width,h:p.height});u.buffer=await U.getBuffer("image/jpeg"),g="saved"}let A={data:Buffer.alloc(l.width*l.height*4),width:l.width,height:l.height},b=t.threshold??.1,x=IH(Vg.decode(u.buffer).data,Vg.decode(l.buffer).data,A.data,l.width,l.height,{threshold:b,diffColorAlt:[0,255,0]})/(l.width*l.height)*100,M=x>b*100,P=`Visual diff of ${x.toFixed(2)}% detected, which is ${M?"over":"under"} the threshold of ${b*100}%.`;if(g&&(P+=` The ${g} screenshot was cropped since it was taller by ${S} pixels and wider by ${T} pixels.`),M)throw new _("ActionFailureError",P);return{fail:M,thoughts:P,beforeScreenshotOverride:l.buffer,afterScreenshotOverride:Vg.encode(A,75).data,succeedImmediately:!1,urlAfterCommand:o.url()}}var PH=3e4;function OH(r){if(!r.body)return{};switch(r.body.type){case"json":return{content:r.body.content,contentType:"application/json"};case"form-urlencoded":{let e=new URLSearchParams;return Object.entries(r.body.content).forEach(([t,n])=>{e.append(t,n)}),{content:e.toString(),contentType:"application/x-www-form-urlencoded;charset=UTF-8"}}}}async function mw({command:r,logger:e,baseUrl:t,fetchImplementation:n=fetch}){let o=r.timeout??PH/1e3,i=Object.fromEntries(Object.entries(r.headers||{}).filter(([m,h])=>m&&h)),a=new URLSearchParams;Object.entries(r.params||{}).filter(([m,h])=>m&&h).forEach(([m,h])=>{a.append(m,h)});let s=a.toString(),c;if(Ba(r.url)&&(c=r.url),t&&Ha(r.url,t)&&(c=new URL(r.url,t).toString()),!c)throw new _("ActionFailureError",`Invalid URL: ${r.url}`);e.info({url:c,searchParams:s,headers:i,body:r.body,method:r.method},"Making HTTP request");let u=await j((async()=>{let m=s?`${c}?${s}`:c;try{let h=OH(r);return await n(m,{headers:{...h.contentType?{"Content-Type":h.contentType}:{},...i},method:r.method,body:h.content})}catch(h){throw e.error({err:h},"Failed to make HTTP request"),new Error(`Failed to make HTTP request: ${h}`)}})(),{milliseconds:o*1e3,fallback:()=>{throw new _("ActionFailureError",`Fetch request timed out after ${o} seconds`)}});if(!u.ok){let m;try{m=await u.text()}catch(h){m=`Failed to read response body: ${h}`}throw new _("ActionFailureError",`Fetch request failed with status ${u.status}: ${m}`)}let d={};u.headers.forEach((m,h)=>{d[h]=m});let p={status:u.status,headers:d};if(u.headers.get("content-type")?.includes("json"))try{p.json=await u.json()}catch{}else u.headers.get("content-type")?.includes("text")&&(p.text=await u.text());return p}var LH=5e3;async function md({timeout:r=hn,...e}){let t=Date.now(),n=r*1e3,o=n+1e4,i,a=0,s=500;for(;a-t<n;){if(Date.now()-t>o){e.logger.warn("Exceeded max system timeout for page assertion, exiting...");break}e.signal?.throwIfAborted();let c=Date.now();i=await hw(e),a=Date.now();let l=a-c;if(l>1e3&&e.logger.warn({pageAssertDuration:l},"Page assertion took longer than expected"),!i.success)await ae(s,e.signal),s=Math.min(Math.floor(s*1.5),LH);else return i}return i=await hw(e),i}async function hw({assertion:r,browser:e,autoExpandIframes:t}){switch(r.type){case"CONTENT":case"CONTENT":{let o,i=!1,a;try{let s;if(t){let c=await e.evaluateFunctionInAllFrames(gw,{value:r.value,negated:!!r.negated,returnHtml:!1});i=r.negated?c.every(l=>l.evaluation):c.some(l=>l.evaluation),s=c.find(l=>l.pageHtml)?.pageHtml}else({evaluation:i,pageHtml:s}=await e.evaluateFunctionInPage(gw,{value:r.value,negated:!!r.negated,returnHtml:!0},"checking page content"));if(!i){let c=r.negated?Kn.CONTAINS:Yn.CONTAINS;a=new _("AssertionFailureError",`The page ${c} '${r.value}'.`),o=s}}catch(s){a=new _("AssertionFailureError",`Failed to evaluate page content assertion: ${s instanceof Error?s.message:`${s}`}`)}return{success:i,err:a,data:i||!o?void 0:{pageContent:o}}}default:return(o=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(r)}}function gw({value:r,negated:e,returnHtml:t}){let n=document.documentElement.outerHTML,o=n.includes(r)===!e;return n.length>1e4&&(n=n.slice(0,1e4)+"...TRUNCATED"),{evaluation:o,pageHtml:!o&&t?n:void 0}}var $g=async r=>{let{step:e,resolvedInputs:t}=r.moduleParams,{logger:n,context:o,storage:i,codeEvalTools:a,controller:s}=r.fixtures,c=s.browser,{orgId:l,runId:u}=r.inputs,d=s.executeAbortController.signal;Object.keys(t).length>0&&(o.setInputs(t),n.info(Ua({json:{inputs:t,moduleId:e.moduleId},maxJsonStringSize:1e3}),"Set module inputs"));let p,m=!1,h,g;if(e.cacheConfig||e.defaultCacheAllInvocations){let f=e.cacheConfig?.cacheKey||e.defaultCacheKey||"",y=await sr({orgId:l,s:f,context:o,logger:n,localTools:a,signal:d});g={orgId:l,cacheKeys:[y,...Object.entries(t).map(([T,A])=>`${T}:${A}`)]},n.info({original:f,keyParams:g},"Module cache key params");let S=Date.now();for(;Date.now()-S<JT;){d?.throwIfAborted();let T=await i.getCacheResult(g);if(T){n.info({cacheResult:mt(T,1e3,!0)},"Got result from module execution cache"),p=hd(e,t,"SUCCESS"),p.message="Used cached module result.",p.data=JSON.parse(T),m=!0;break}else n.info({cacheKey:f,keyParams:g},"No cache result found, continuing with lock acquisition");let A=await i.acquireCacheLock({keyParams:g,clientMetadata:`hostName:${NH()};runId:${u}`},d);if(A.acquired){h=A.keyPrefix,n.info({cacheKeyPrefixIfLockAcquired:h,cacheKey:f,keyParams:g},"Acquired cache lock and proceeding with module execution");break}else n.debug({cacheKeyPrefixIfLockAcquired:h,cacheKey:f,keyParams:g},"Failed to acquire cache lock, retrying...");await ae(2500+Math.random()*1e4,d)}}try{if(!p)p=await DH(r);else if(e.autoAuth){let f=uu.safeParse(p.data);if(!f.success)throw new _("UserConfigurationError",`Cached authentication module result is not a valid storage state: ${f.error.message}`);n.debug("Automatically loading auth state after cached module result"),await c.loadAuthState(f.data);let y=!1,S=e.advanced?.cacheInvalidation;if(S&&S.type==="PAGE_CHECK"){let T={type:"CONTENT",value:S.substring},A=await md({timeout:hn,assertion:T,browser:c,logger:n,signal:d,autoExpandIframes:!!c.userBrowserSettings.autoExpandIframes});A.success?n.debug({invalResult:A},"Cached result still valid after page check, continuing..."):(n.info({invalResult:A},"Invalidating cached result due to page check failure"),y=!0)}if(g&&y)return await i.deleteCacheResult(g),$g(r)}}finally{try{h!==void 0&&!m&&p?.status==="SUCCESS"&&await kH({step:e,result:p,browser:s.browser,cacheKeyPrefix:h,logger:n,storage:i})}finally{h!==void 0&&await i.releaseCacheLock(h)}}return p},DH=async r=>{let{step:e,tracer:t}=r.moduleParams,n=hd(e,r.moduleParams.resolvedInputs,"SUCCESS"),o=await t.startSubSteps(),{status:i,results:a}=await r.executeStepList({...r,listParams:{steps:e.steps,containerName:`module ('${e.name}')`,tracer:o}});return n.results=a,n.status=i,n.finishedAt=new Date,an({asyncTasks:r.work.asyncTasks,nestedResults:a,result:n,logger:r.fixtures.logger}),n};function hd(r,e,t){let n={};return Object.entries(e).forEach(([i,a])=>{n[i]=JSON.stringify(a)}),{type:"MODULE",id:r.id,moduleId:r.moduleId,moduleName:r.name,startedAt:new Date,cacheConfig:r.cacheConfig,inputs:n,results:[],finishedAt:new Date,status:t}}async function fw({orgId:r,step:e,context:t,logger:n,codeEvalTools:o,signal:i}){let a={};try{for(let s of e.parameters??[]){let c=e.inputs?.[s]??e.defaultParameters?.[s];if(!c){n.warn(`No value or default found for parameter '${s}' that is required by module '${e.name}'`);continue}a[s]=await No({orgId:r,code:c,fragment:!0,context:t,logger:n,localTools:o,signal:i})}return a}catch(s){throw i?.throwIfAborted(),new _("UserConfigurationError",`Failed to evaluate module inputs: ${s}`)}}async function kH({step:r,result:e,browser:t,cacheKeyPrefix:n,logger:o,storage:i}){let a=r.cacheConfig?.cacheExpiryMs;(!a||a===Uv)&&(a=r.defaultCacheTtl??Bv);let s;r.autoAuth?s=JSON.stringify(await t.saveAuthState()):e.data!==void 0?s=JSON.stringify(e.data):s='""',o.debug({cacheKeyPrefix:n,ttlMs:a,truncatedCacheResultJson:Ua({json:s,maxJsonStringSize:1e4})},"Setting module cache result"),await i.setCacheResult({result:s,keyPrefix:n,ttlMs:a})}async function Ni(r,e,t){return FH(r,e,t)}async function FH(r,e,t){let n=new Date;try{return t.throwIfAborted(),await e()}catch(o){let i=new Date,a="FAILED",s;if(t.aborted||o instanceof DOMException&&o.name==="AbortError"?(s="Step aborted by user.",a="CANCELLED"):o instanceof _?s=`${o}`:s=`An unexpected error occurred: ${o.message}`,r.type==="RESOLVED_MODULE"){let c=hd(r,{},"FAILED");return c.message=s,c.startedAt=n,c.finishedAt=i,c}return{...Qu(r),startedAt:n,finishedAt:i,status:a,data:null,message:s,results:[]}}}async function qa(r,e){let t=!1;try{return r&&!r.state.failureRecoveryDisabled&&(r.state.failureRecoveryDisabled=!0,t=!0),await e()}finally{r&&t&&(r.state.failureRecoveryDisabled=void 0)}}import{cloneDeep as Tj}from"lodash-es";import{randomUUID as Sw}from"crypto";import{diff as UH}from"deep-object-diff";import{cloneDeep as yw}from"lodash-es";var gd=async r=>{let{step:e,tracer:t}=r.presetParams,{logger:n,controller:o,context:i}=r.fixtures,{collectDebugData:a}=r.options,{testMetadata:s}=r.inputs,c=e.command.type,l=n.child({commandType:c,stepId:e.id,commandId:e.command.id}),u="cache"in e.command&&e.command.cache?yw(e.command.cache):{},d=o.browser.url(),p=new Date,m,h=Sw(),g=Sw();if(a)try{if(m=await o.browser.screenshot({retries:1,clearHighlights:!0,quality:75}),!o.browser.userBrowserSettings.disableHtmlSnapshots){let A=await o.browser.getRawCondensedHtml();t.attachBeforeHtmlSnapshot({logger:l,snapshotId:h,html:A})}}catch(A){l.debug({err:A},"Failed to take before screenshot, continuing...")}let f,y,S,T=au();try{let A=await o.executePresetCommand(T,t,e.command,i,s?.advanced.disableAICaching??!1);A.beforeScreenshotOverride&&(m=A.beforeScreenshotOverride),S=A.afterScreenshotOverride;let b=new Date,C=o.browser.url();y={beforeUrl:d,afterUrl:C,startedAt:p,finishedAt:b,viewport:o.browser.getViewport(),status:A.fail?"FAILED":"SUCCESS",elementInteracted:A.elementInteracted},f={...e,message:A.thoughts??"Successfully executed preset action.",beforeUrl:d,afterUrl:C,finishedAt:b,startedAt:p,status:A.fail?"FAILED":"SUCCESS",data:A.data,results:[y],details:T.details},"assertion"in e.command&&(f.message=A.thoughts||"Assertion passed.")}catch(A){l.error({message:A.message,stack:A.stack},`Failed executing preset step ${_o(e.command)}`);let b=o.browser.url(),C=new Date,x=A instanceof Error?A.message:`${A}`;y={beforeUrl:d,afterUrl:b,startedAt:p,finishedAt:C,viewport:o.browser.getViewport(),status:A instanceof DOMException&&A.name==="AbortError"?"CANCELLED":"FAILED",message:x},f={...e,startedAt:p,finishedAt:C,beforeUrl:d,afterUrl:b,status:A instanceof DOMException&&A.name==="AbortError"?"CANCELLED":"FAILED",message:x,failureReason:A instanceof _?A.reason:void 0,results:[y],details:T.details}}finally{let A="cache"in e.command&&e.command.cache?yw(e.command.cache):{},b=UH(u,A);b&&Object.keys(b).length>0&&l.info({diffs:b},"Updated cache")}if(a)try{if(S||(S=await o.browser.screenshot({retries:1,quality:75})),!o.browser.userBrowserSettings.disableHtmlSnapshots){let A=await o.browser.getRawCondensedHtml();t.attachAfterHtmlSnapshot({logger:l,snapshotId:g,html:A})}}catch(A){l.debug({err:A},"Failed to store debug data after step, likely because the page is still loading. This is non-fatal and does not affect the test.")}return y.beforeSnapshot=h,f.beforeSnapshot=h,y.afterSnapshot=g,f.afterSnapshot=g,m&&t.attachBeforeScreenshot({logger:l,snapshotId:h,screenshot:m}),S&&t.attachAfterScreenshot({logger:l,snapshotId:g,screenshot:S}),f};async function Ew(r){let{step:e,tracer:t}=r.conditionalParams,{logger:n,controller:o}=r.fixtures,i=new Date,a=Qu(e),s=e.elseSteps,c=!0,l=[],u,d=au();for(let f=0;f<e.blocks.length;f++){n.info(`Evaluating condition ${f} in conditional step`);let y=e.blocks[f];try{let S=await gd({...r,presetParams:{tracer:t,step:y.assertion}});l.push(S),u=S,S.status==="SUCCESS"?(n.info(`Condition ${f} resolved to true, executing the corresponding ${y.steps.length} steps`),c=!1,s=y.steps):n.info(S.message,`Condition ${f} resolved to false`)}catch(S){n.info({err:S},`Condition ${f} resolved to false`)}finally{o.throwIfClosed()}}if(s)c&&n.info("No conditions resolved to true, executing the else block steps");else{n.warn("No conditions resolved to true and no else block was provided, causing the entire conditional step to be skipped");let f={...a,assertionResult:u,status:"SUCCESS",startedAt:i,data:l[l.length-1]?.data,message:l[l.length-1]?.message,results:[],finishedAt:new Date,details:d.details};return an({asyncTasks:r.work.asyncTasks,nestedResults:[...l],result:f,logger:n}),f}n.info(`Executing ${s.length} steps in the selected conditional block`);let p=await r.conditionalParams.tracer.startSubSteps(),m=await r.executeStepList({...r,listParams:{steps:s,containerName:"conditional block",tracer:p}}),g={...a,assertionResult:u,...m,startedAt:i,finishedAt:new Date};return an({asyncTasks:r.work.asyncTasks,nestedResults:[...l,...m.results],result:g,logger:n}),g}import{randomUUID as bw}from"crypto";var Tw=async r=>{let{tracer:e}=r.aiStepParams,{controller:t,logger:n}=r.fixtures;await t.browser.waitForDOMStability();let o=await t.browser.screenshot({}),i=await BH(r);i.finishedAt=new Date,an({asyncTasks:r.work.asyncTasks,result:i,nestedResults:i.results,logger:r.fixtures.logger});let a=await t.browser.screenshot({}),s=bw();i.beforeSnapshot=s,e.attachBeforeScreenshot({logger:n,snapshotId:s,screenshot:o});let c=bw();return i.afterSnapshot=c,e.attachAfterScreenshot({logger:n,snapshotId:c,screenshot:a}),i},BH=async r=>{let{step:e,tracer:t}=r.aiStepParams,{controller:n,context:o,logger:i}=r.fixtures,a={...e,startedAt:new Date,beforeTestContext:o.toRedactedDisplayCopy(),finishedAt:new Date,results:[],status:"SUCCESS"};if(!("steps"in e&&e.steps&&e.steps.length>0&&e.steps[e.steps.length-1]?.command.type==="SUCCESS"))throw new _("UserConfigurationError","AI action has been fully deprecated. Please delete this step and transition to Dynamic AI Action.");try{let c=await t.startSubSteps(),{status:l}=await r.executeStepList({...r,listParams:{steps:e.steps,containerName:"AI action",results:a.results,tracer:c}});return a.finishedAt=new Date,a.status=l,a}catch(c){i.warn({err:c},"Failed executing saved deprecated AI action steps");let l=n.executeAbortController.signal.aborted;a.message=c instanceof Error?c.message:`${c}`,a.status=l?"CANCELLED":"FAILED"}return a};import{randomUUID as Wg}from"crypto";var vw=15,HH=7,Rw=async r=>{let{tracer:e}=r.aiStepParams,{logger:t,controller:n}=r.fixtures;await n.browser.waitForDOMStability();let o=await n.browser.screenshot({quality:75}),i=await zH(r);i.finishedAt=new Date,an({asyncTasks:r.work.asyncTasks,result:i,nestedResults:i.results,logger:r.fixtures.logger});let a=await n.browser.screenshot({quality:75}),s=Wg();i.beforeSnapshot=s,e.attachBeforeScreenshot({logger:t,snapshotId:s,screenshot:o});let c=Wg();return i.afterSnapshot=c,e.attachAfterScreenshot({logger:t,snapshotId:c,screenshot:a}),i},zH=async r=>{let{step:e,tracer:t}=r.aiStepParams,{testMetadata:n,orgId:o}=r.inputs,{controller:i,context:a,logger:s,codeEvalTools:c}=r.fixtures,{step:l}=r.callbacks,u=`${e.id}-${Date.now()}`,d=s.child({stepId:e.id,langfuseSessionId:u}),p={...e,startedAt:new Date,beforeTestContext:a.toRedactedDisplayCopy(),results:[],finishedAt:new Date,status:"SUCCESS"},m=await sr({orgId:o,s:e.text,context:a,logger:d,localTools:c});await i.browser.waitForDOMStability({logger:d});let g=`data:image/jpeg;base64,${(await i.browser.screenshot({clearHighlights:!0,retries:2})).toString("base64")}`,f=[],y=0,S=0,T,A;for(;;){if(y>vw)return p.message=`Exceeded the maximum number of commands allowed per AI step (${vw})`,p.status="FAILED",p;if(i.executeAbortController.signal.aborted)return p.message="Test execution was cancelled",p.status="CANCELLED",p;l.onDynamicAIActionStatusUpdateEvent?.({parentStepId:e.id,message:"Evaluating current state..."});let b=await i.evaluateAiAction({goal:m,startingScreenshot:y===0?void 0:g,history:f,logger:d,langfuseSessionId:u,lastError:A}),{evaluation:C,reasoning:x,summary:M}=b;d.info(b,"Got AI evaluation");let P=p.results[y-1]?.id;switch(C.type){case"DONE":return p.message=`Our AI evaluator confirmed all tasks are complete: ${x}`,p.status="SUCCESS",P&&l.onDynamicAIActionEvaluatingEvent?.({stepId:P,status:"SUCCESS",message:`${M}
49
+ ${r.code}`;throw r.logger.error({err:e.error,code:r.code,env:r.context.toObjectCopy()},t),new Error(t)}if(e.variableUpdates)for(let[t,n]of Object.entries(e.variableUpdates))r.context.setVariable(t,n);if(e.persistentVariableUpdates&&Object.keys(e.persistentVariableUpdates).length>0){await r.callbacks?.onPersistentVariableUpdates?.(e.persistentVariableUpdates);for(let[t,n]of Object.entries(e.persistentVariableUpdates))r.context.setVariable(t,n)}return e.result}import{set as wH}from"lodash-es";async function sr(r){let{orgId:e,s:t,context:n,logger:o,signal:i,retries:a=2,timeoutMs:s=vo,allowUndefined:c=!1}=r,l=/{{(.*?)}}/g,u=t.matchAll(l),d=t;for(let p of u){if(p.length<2)continue;let m=p[1].trim(),h;try{h=await No({orgId:e,code:m,fragment:!0,context:n,timeoutMs:s,logger:o,retries:a,localTools:r.localTools,signal:i})}catch(f){throw o.error({err:f,value:t},"Error evaluating template string"),f}if(h===void 0&&!c)throw new _("UserConfigurationError",`Template fragment '${m}' evaluated to undefined. Please ensure that the variable name is spelled correctly and it is only referenced after being assigned a value.`);let g=typeof h=="string"?h:`${h}`;g=g.replaceAll(/\$/g,"$$$$"),d=d.replace(p[0],g)}return d}async function pd(r){return iw(r)}async function iw({obj:r,bannedKeys:e,allowList:t,context:n,prefixPath:o=[],replacements:i=[],...a}){for(let s in r){if(e.includes(s))continue;let c=!1;if(t)if(t.includes(s))c=!0;else continue;let l=r[s],u=[...o,s];if(typeof l=="string"&&l.includes("{{")){let d=await sr({s:l,context:n,...a});if(l===d)continue;i.push({path:u,original:l}),r[s]=d}else typeof l=="object"&&l!==null&&!Array.isArray(l)&&await iw({obj:l,bannedKeys:e,context:n,prefixPath:u,replacements:i,allowList:c?void 0:t,...a})}return i}function aw(r,e){for(let{path:t,original:n}of e)wH(r,t,n)}import CH from"fetch-retry";var zbe=process.env.MAILINATOR_API_KEY,Gbe=CH(global.fetch,{retryOn:function(r,e,t){return r>3?!1:!!(e!==null||t&&t.status>=400)},retryDelay:function(r){return 500}});import{hostname as NH}from"os";import{cloneDeep as lw}from"lodash-es";async function cw(r){let{command:e,timeoutMs:t,fixtures:n}=r,{abortSignal:o}=n,i=()=>Ny(e.cache)?e.cache:void 0,a=i(),s=lw(a),c=(g=!1)=>{if(a=i(),!!a)if(g){let f=mg(s,a);a.target=f.target,a.updatedAt=f.updatedAt}else{if(!s){a=void 0;return}a.target=s.target,a.updatedAt=s.updatedAt}},l=Date.now(),u=0,d,p=500,m=!1;for(;u<2||Date.now()-l<t;){u++,u>1&&await ae(p,o),o?.throwIfAborted(),a=i();let{result:g,elementWasFound:f}=await sw({cacheToUse:a,params:r});if(d=g,m=f,g.success)break;c(),p=Math.min(p*2,1e4)}if(!d)throw new _("InternalPlatformError",`Failed to evaluate manual element assertion in ${t}ms.`);if(o?.throwIfAborted(),!d.success&&a?.target&&Ac(a.target)){let g=a?.target?.memory?{target:{id:-1,memory:a.target.memory}}:void 0,{result:f}=await sw({cacheToUse:g,params:r});d=f,d.success||c(!0)}let h=i();return d.success&&h?.target&&!m&&(h.target=Sl(h.target),h.updatedAt=new Date),d}async function sw({cacheToUse:r,params:e}){let{command:t,disableCache:n,fixtures:o,tracer:i,targetingWrapper:a}=e,{logger:s}=o;if(t.target&&!po(t.target))throw new Error("Element assertion with x/y is not supported yet");let c=yR(t.assertion),l,u=!1,d=lw(r);try{let{elementInteractedDisplayString:p,result:m,thoughts:h}=await a({ctx:o.ctx,tracer:i,command:t,target:t.target,cache:d?.target,action:async g=>xH(g.locator,e),options:{...t,allowNotActionableNodesOverride:!0,disableCache:n,memory:d?.target?.memory,disableGlobalLocatorRedirect:!0,source:di(t),targetName:"target"}});return l={success:m.success,data:m.data,err:m.err,elementInteractedDisplayString:p,thoughts:h},u=!0,m.success||(s.warn({aiThoughts:h,elementString:p,err:m.err},"Element check found an element but failed"),l={...m,thoughts:h}),{result:l,elementWasFound:u}}catch(p){if(c)return l={success:!0,thoughts:`The element described does not exist on the page: ${p.message}`,err:void 0,data:void 0},{result:l,elementWasFound:u};if(!(p instanceof _)||p.reason!="ActionFailureError")throw p;return l={success:!1,err:p,data:void 0,thoughts:void 0},s.warn({err:p},"Element check did not find an element and failed"),{result:l,elementWasFound:u}}}async function xH(r,{command:e,fixtures:t}){return await t.browser.highlight(r),await _H(r,e.assertion)}async function _H(r,e){let t=!0,n,o;switch(e.type){case"ELEMENT_CONTENT":{let a=await r.textContent()??"";if(o={elementTextContent:mt(a,500,!0)},!fl(a,e.value,e.operation,{negated:!!e.negated,ignoreCase:!1})){let s=La(e);t=!1,n=new _("AssertionFailureError",`The content ${s} '${e.value}': ${a}`)}break}case"ELEMENT_ATTRIBUTE":{o={elementOuterHtml:mt(await r.evaluate(s=>s.cloneNode(!1).outerHTML),500,!0)};let a;try{a=await r.getAttribute(e.attr,{timeout:3e3})??""}catch(s){n=new _("AssertionFailureError",`The element does not have an attribute named ${e.attr}: ${s}`),t=!1;break}if(!fl(a,e.value,e.operation,{negated:!!e.negated,ignoreCase:!1})){let s=La(e);t=!1,e.operation==="EXISTS"?n=new _("AssertionFailureError",`The attribute ${e.attr} ${s}`):n=new _("AssertionFailureError",`The attribute ${e.attr} ${s} '${e.value}': ${a}`)}break}case"ELEMENT_EXISTENCE":{switch(e.condition){case"VISIBLE":{t=await r.evaluate(async(s,c)=>{let l=Date.now();for(;Date.now()-l<c;){await new Promise(d=>setTimeout(d,250));let u=s.getBoundingClientRect();if(!(u.width===0||u.height===0)&&window.getComputedStyle(s).visibility!=="hidden"&&window.getComputedStyle(s).display!=="none")return!0}return!1},hn*1e3);break}case"EDITABLE":{t=await r.isEditable({timeout:hn*1e3});break}case"EXISTS":{t=!0;break}case"ENABLED":{t=await r.isEnabled({timeout:hn*1e3});break}case"FOCUSED":{t=await r.evaluate(s=>s===document.activeElement);break}default:return(s=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(e.condition)}if(t=e.negated?!t:t,!t){let a=La(e);n=new _("AssertionFailureError",`The element ${a}`)}break}case"ELEMENT_NAME":{let a=await r.evaluate(s=>s.tagName);if(!fl(a,e.value,e.operation,{negated:!!e.negated,ignoreCase:!0})){let s=La(e);t=!1,n=new _("AssertionFailureError",`The element tag name ${s} '${e.value}': ${a}`)}break}case"ELEMENT_STYLE":{let a=await r.evaluate((s,c)=>window.getComputedStyle(s).getPropertyValue(c),e.property);if(!fl(a,e.value,e.operation,{negated:!!e.negated,ignoreCase:!1})){let s=La(e);t=!1,e.operation==="EXISTS"?n=new _("AssertionFailureError",`The style property ${e.property} ${s}`):n=new _("AssertionFailureError",`The style property ${e.property} ${s} '${e.value}': ${a}`)}break}default:return(a=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(e)}return{thoughts:void 0,success:t,data:o,err:n}}function uw(r){return r.type==="ELEMENT_EXISTENCE"&&r.negated&&r.condition==="EXISTS"}import{Jimp as MH}from"jimp";async function Il(r,e){let t=await r.screenshot(e),n=await MH.fromBuffer(t);return{buffer:t,width:Math.ceil(n.bitmap.width??0),height:Math.ceil(n.bitmap.height??0)}}import{Jimp as dw}from"jimp";import Vg from"jpeg-js";import IH from"pixelmatch";async function pw({ctx:r,tracer:e,command:t,disableCache:n,browser:o,targetingWrapper:i,logger:a,screenshotStorage:s}){if(t.target&&!po(t.target))throw new Error("Visual Diff with x/y is not supported yet");await o.waitForDOMStability({logger:a});let c={clearHighlights:!0,hideCaret:!0},l;t.target?.elementDescriptor?l=(await i({ctx:r,tracer:e,command:t,target:t.target,cache:t.cache?.target,action:async V=>Il(o,{locator:V.locator,...c}),options:{...t,disableCache:n,disableGlobalLocatorRedirect:!0,memory:t.cache?.target?.memory,targetName:"target"}})).result:l=await Il(o,c);let u=await s.prepareGoldenScreenshotForComparison(a,t,l);if((l.height!==u.height||l.width!==u.width)&&a.warn({currHeight:l.height,currWidth:l.width,savedHeight:u.height,savedWidth:u.width},"Mismatched before and after visual diff screenshot sizes"),Math.abs(l.height-u.height)>10||Math.abs(l.width-u.width)>10){let U=`${l.width}x${l.height}`,V=`${u.width}x${u.height}`;return{fail:!0,thoughts:`Current screenshot (${U}) does not match saved screenshot dimensions (${V}) - did you change the size of the target or the viewport?`,beforeScreenshotOverride:u.buffer,afterScreenshotOverride:l.buffer,succeedImmediately:!1,urlAfterCommand:o.url()}}let d=await dw.fromBuffer(l.buffer),p={width:l.width,height:l.height},m=await dw.fromBuffer(u.buffer),h={width:u.width,height:u.height},g,f=p.width*p.height,y=h.width*h.height,S=Math.abs(p.height-h.height),T=Math.abs(p.width-h.width);if(f>y){let U=d.cover({w:h.width,h:h.height});l.buffer=await U.getBuffer("image/jpeg"),g="current",l.width=h.width,l.height=h.height}else if(y>f){let U=m.cover({w:p.width,h:p.height});u.buffer=await U.getBuffer("image/jpeg"),g="saved"}let A={data:Buffer.alloc(l.width*l.height*4),width:l.width,height:l.height},b=t.threshold??.1,x=IH(Vg.decode(u.buffer).data,Vg.decode(l.buffer).data,A.data,l.width,l.height,{threshold:b,diffColorAlt:[0,255,0]})/(l.width*l.height)*100,M=x>b*100,P=`Visual diff of ${x.toFixed(2)}% detected, which is ${M?"over":"under"} the threshold of ${b*100}%.`;if(g&&(P+=` The ${g} screenshot was cropped since it was taller by ${S} pixels and wider by ${T} pixels.`),M)throw new _("ActionFailureError",P);return{fail:M,thoughts:P,beforeScreenshotOverride:l.buffer,afterScreenshotOverride:Vg.encode(A,75).data,succeedImmediately:!1,urlAfterCommand:o.url()}}var PH=3e4;function OH(r){if(!r.body)return{};switch(r.body.type){case"json":return{content:r.body.content,contentType:"application/json"};case"form-urlencoded":{let e=new URLSearchParams;return Object.entries(r.body.content).forEach(([t,n])=>{e.append(t,n)}),{content:e.toString(),contentType:"application/x-www-form-urlencoded;charset=UTF-8"}}}}async function mw({command:r,logger:e,baseUrl:t,fetchImplementation:n=fetch}){let o=r.timeout??PH/1e3,i=Object.fromEntries(Object.entries(r.headers||{}).filter(([h,g])=>h&&g)),a=new URLSearchParams;Object.entries(r.params||{}).filter(([h,g])=>h&&g).forEach(([h,g])=>{a.append(h,g)});let s=a.toString(),c;if(Ba(r.url)&&(c=r.url),t&&Ha(r.url,t)&&(c=new URL(r.url,t).toString()),!c)throw new _("ActionFailureError",`Invalid URL: ${r.url}`);let l=c;e.info({url:l,searchParams:s,headers:i,body:r.body,method:r.method},"Making HTTP request");let d=await j((async()=>{let h=s?`${l}?${s}`:l;try{let g=OH(r),f=new Headers(i);return g.contentType&&!f.has("Content-Type")&&f.set("Content-Type",g.contentType),await n(h,{headers:f,method:r.method,body:g.content})}catch(g){throw e.error({err:g},"Failed to make HTTP request"),new Error(`Failed to make HTTP request: ${g}`)}})(),{milliseconds:o*1e3,fallback:()=>{throw new _("ActionFailureError",`Fetch request timed out after ${o} seconds`)}});if(!d.ok){let h;try{h=await d.text()}catch(g){h=`Failed to read response body: ${g}`}throw new _("ActionFailureError",`Fetch request failed with status ${d.status}: ${h}`)}let p={};d.headers.forEach((h,g)=>{p[g]=h});let m={status:d.status,headers:p};if(d.headers.get("content-type")?.includes("json"))try{m.json=await d.json()}catch{}else d.headers.get("content-type")?.includes("text")&&(m.text=await d.text());return m}var LH=5e3;async function md({timeout:r=hn,...e}){let t=Date.now(),n=r*1e3,o=n+1e4,i,a=0,s=500;for(;a-t<n;){if(Date.now()-t>o){e.logger.warn("Exceeded max system timeout for page assertion, exiting...");break}e.signal?.throwIfAborted();let c=Date.now();i=await hw(e),a=Date.now();let l=a-c;if(l>1e3&&e.logger.warn({pageAssertDuration:l},"Page assertion took longer than expected"),!i.success)await ae(s,e.signal),s=Math.min(Math.floor(s*1.5),LH);else return i}return i=await hw(e),i}async function hw({assertion:r,browser:e,autoExpandIframes:t}){switch(r.type){case"CONTENT":case"CONTENT":{let o,i=!1,a;try{let s;if(t){let c=await e.evaluateFunctionInAllFrames(gw,{value:r.value,negated:!!r.negated,returnHtml:!1});i=r.negated?c.every(l=>l.evaluation):c.some(l=>l.evaluation),s=c.find(l=>l.pageHtml)?.pageHtml}else({evaluation:i,pageHtml:s}=await e.evaluateFunctionInPage(gw,{value:r.value,negated:!!r.negated,returnHtml:!0},"checking page content"));if(!i){let c=r.negated?Kn.CONTAINS:Yn.CONTAINS;a=new _("AssertionFailureError",`The page ${c} '${r.value}'.`),o=s}}catch(s){a=new _("AssertionFailureError",`Failed to evaluate page content assertion: ${s instanceof Error?s.message:`${s}`}`)}return{success:i,err:a,data:i||!o?void 0:{pageContent:o}}}default:return(o=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(r)}}function gw({value:r,negated:e,returnHtml:t}){let n=document.documentElement.outerHTML,o=n.includes(r)===!e;return n.length>1e4&&(n=n.slice(0,1e4)+"...TRUNCATED"),{evaluation:o,pageHtml:!o&&t?n:void 0}}var $g=async r=>{let{step:e,resolvedInputs:t}=r.moduleParams,{logger:n,context:o,storage:i,codeEvalTools:a,controller:s}=r.fixtures,c=s.browser,{orgId:l,runId:u}=r.inputs,d=s.executeAbortController.signal;Object.keys(t).length>0&&(o.setInputs(t),n.info(Ua({json:{inputs:t,moduleId:e.moduleId},maxJsonStringSize:1e3}),"Set module inputs"));let p,m=!1,h,g;if(e.cacheConfig||e.defaultCacheAllInvocations){let f=e.cacheConfig?.cacheKey||e.defaultCacheKey||"",y=await sr({orgId:l,s:f,context:o,logger:n,localTools:a,signal:d});g={orgId:l,cacheKeys:[y,...Object.entries(t).map(([T,A])=>`${T}:${A}`)]},n.info({original:f,keyParams:g},"Module cache key params");let S=Date.now();for(;Date.now()-S<JT;){d?.throwIfAborted();let T=await i.getCacheResult(g);if(T){n.info({cacheResult:mt(T,1e3,!0)},"Got result from module execution cache"),p=hd(e,t,"SUCCESS"),p.message="Used cached module result.",p.data=JSON.parse(T),m=!0;break}else n.info({cacheKey:f,keyParams:g},"No cache result found, continuing with lock acquisition");let A=await i.acquireCacheLock({keyParams:g,clientMetadata:`hostName:${NH()};runId:${u}`},d);if(A.acquired){h=A.keyPrefix,n.info({cacheKeyPrefixIfLockAcquired:h,cacheKey:f,keyParams:g},"Acquired cache lock and proceeding with module execution");break}else n.debug({cacheKeyPrefixIfLockAcquired:h,cacheKey:f,keyParams:g},"Failed to acquire cache lock, retrying...");await ae(2500+Math.random()*1e4,d)}}try{if(!p)p=await DH(r);else if(e.autoAuth){let f=uu.safeParse(p.data);if(!f.success)throw new _("UserConfigurationError",`Cached authentication module result is not a valid storage state: ${f.error.message}`);n.debug("Automatically loading auth state after cached module result"),await c.loadAuthState(f.data);let y=!1,S=e.advanced?.cacheInvalidation;if(S&&S.type==="PAGE_CHECK"){let T={type:"CONTENT",value:S.substring},A=await md({timeout:hn,assertion:T,browser:c,logger:n,signal:d,autoExpandIframes:!!c.userBrowserSettings.autoExpandIframes});A.success?n.debug({invalResult:A},"Cached result still valid after page check, continuing..."):(n.info({invalResult:A},"Invalidating cached result due to page check failure"),y=!0)}if(g&&y)return await i.deleteCacheResult(g),$g(r)}}finally{try{h!==void 0&&!m&&p?.status==="SUCCESS"&&await kH({step:e,result:p,browser:s.browser,cacheKeyPrefix:h,logger:n,storage:i})}finally{h!==void 0&&await i.releaseCacheLock(h)}}return p},DH=async r=>{let{step:e,tracer:t}=r.moduleParams,n=hd(e,r.moduleParams.resolvedInputs,"SUCCESS"),o=await t.startSubSteps(),{status:i,results:a}=await r.executeStepList({...r,listParams:{steps:e.steps,containerName:`module ('${e.name}')`,tracer:o}});return n.results=a,n.status=i,n.finishedAt=new Date,an({asyncTasks:r.work.asyncTasks,nestedResults:a,result:n,logger:r.fixtures.logger}),n};function hd(r,e,t){let n={};return Object.entries(e).forEach(([i,a])=>{n[i]=JSON.stringify(a)}),{type:"MODULE",id:r.id,moduleId:r.moduleId,moduleName:r.name,startedAt:new Date,cacheConfig:r.cacheConfig,inputs:n,results:[],finishedAt:new Date,status:t}}async function fw({orgId:r,step:e,context:t,logger:n,codeEvalTools:o,signal:i}){let a={};try{for(let s of e.parameters??[]){let c=e.inputs?.[s]??e.defaultParameters?.[s];if(!c){n.warn(`No value or default found for parameter '${s}' that is required by module '${e.name}'`);continue}a[s]=await No({orgId:r,code:c,fragment:!0,context:t,logger:n,localTools:o,signal:i})}return a}catch(s){throw i?.throwIfAborted(),new _("UserConfigurationError",`Failed to evaluate module inputs: ${s}`)}}async function kH({step:r,result:e,browser:t,cacheKeyPrefix:n,logger:o,storage:i}){let a=r.cacheConfig?.cacheExpiryMs;(!a||a===Uv)&&(a=r.defaultCacheTtl??Bv);let s;r.autoAuth?s=JSON.stringify(await t.saveAuthState()):e.data!==void 0?s=JSON.stringify(e.data):s='""',o.debug({cacheKeyPrefix:n,ttlMs:a,truncatedCacheResultJson:Ua({json:s,maxJsonStringSize:1e4})},"Setting module cache result"),await i.setCacheResult({result:s,keyPrefix:n,ttlMs:a})}async function Ni(r,e,t){return FH(r,e,t)}async function FH(r,e,t){let n=new Date;try{return t.throwIfAborted(),await e()}catch(o){let i=new Date,a="FAILED",s;if(t.aborted||o instanceof DOMException&&o.name==="AbortError"?(s="Step aborted by user.",a="CANCELLED"):o instanceof _?s=`${o}`:s=`An unexpected error occurred: ${o.message}`,r.type==="RESOLVED_MODULE"){let c=hd(r,{},"FAILED");return c.message=s,c.startedAt=n,c.finishedAt=i,c}return{...Qu(r),startedAt:n,finishedAt:i,status:a,data:null,message:s,results:[]}}}async function qa(r,e){let t=!1;try{return r&&!r.state.failureRecoveryDisabled&&(r.state.failureRecoveryDisabled=!0,t=!0),await e()}finally{r&&t&&(r.state.failureRecoveryDisabled=void 0)}}import{cloneDeep as Tj}from"lodash-es";import{randomUUID as Sw}from"crypto";import{diff as UH}from"deep-object-diff";import{cloneDeep as yw}from"lodash-es";var gd=async r=>{let{step:e,tracer:t}=r.presetParams,{logger:n,controller:o,context:i}=r.fixtures,{collectDebugData:a}=r.options,{testMetadata:s}=r.inputs,c=e.command.type,l=n.child({commandType:c,stepId:e.id,commandId:e.command.id}),u="cache"in e.command&&e.command.cache?yw(e.command.cache):{},d=o.browser.url(),p=new Date,m,h=Sw(),g=Sw();if(a)try{if(m=await o.browser.screenshot({retries:1,clearHighlights:!0,quality:75}),!o.browser.userBrowserSettings.disableHtmlSnapshots){let A=await o.browser.getRawCondensedHtml();t.attachBeforeHtmlSnapshot({logger:l,snapshotId:h,html:A})}}catch(A){l.debug({err:A},"Failed to take before screenshot, continuing...")}let f,y,S,T=au();try{let A=await o.executePresetCommand(T,t,e.command,i,s?.advanced.disableAICaching??!1);A.beforeScreenshotOverride&&(m=A.beforeScreenshotOverride),S=A.afterScreenshotOverride;let b=new Date,C=o.browser.url();y={beforeUrl:d,afterUrl:C,startedAt:p,finishedAt:b,viewport:o.browser.getViewport(),status:A.fail?"FAILED":"SUCCESS",elementInteracted:A.elementInteracted},f={...e,message:A.thoughts??"Successfully executed preset action.",beforeUrl:d,afterUrl:C,finishedAt:b,startedAt:p,status:A.fail?"FAILED":"SUCCESS",data:A.data,results:[y],details:T.details},"assertion"in e.command&&(f.message=A.thoughts||"Assertion passed.")}catch(A){l.error({message:A.message,stack:A.stack},`Failed executing preset step ${_o(e.command)}`);let b=o.browser.url(),C=new Date,x=A instanceof Error?A.message:`${A}`;y={beforeUrl:d,afterUrl:b,startedAt:p,finishedAt:C,viewport:o.browser.getViewport(),status:A instanceof DOMException&&A.name==="AbortError"?"CANCELLED":"FAILED",message:x},f={...e,startedAt:p,finishedAt:C,beforeUrl:d,afterUrl:b,status:A instanceof DOMException&&A.name==="AbortError"?"CANCELLED":"FAILED",message:x,failureReason:A instanceof _?A.reason:void 0,results:[y],details:T.details}}finally{let A="cache"in e.command&&e.command.cache?yw(e.command.cache):{},b=UH(u,A);b&&Object.keys(b).length>0&&l.info({diffs:b},"Updated cache")}if(a)try{if(S||(S=await o.browser.screenshot({retries:1,quality:75})),!o.browser.userBrowserSettings.disableHtmlSnapshots){let A=await o.browser.getRawCondensedHtml();t.attachAfterHtmlSnapshot({logger:l,snapshotId:g,html:A})}}catch(A){l.debug({err:A},"Failed to store debug data after step, likely because the page is still loading. This is non-fatal and does not affect the test.")}return y.beforeSnapshot=h,f.beforeSnapshot=h,y.afterSnapshot=g,f.afterSnapshot=g,m&&t.attachBeforeScreenshot({logger:l,snapshotId:h,screenshot:m}),S&&t.attachAfterScreenshot({logger:l,snapshotId:g,screenshot:S}),f};async function Ew(r){let{step:e,tracer:t}=r.conditionalParams,{logger:n,controller:o}=r.fixtures,i=new Date,a=Qu(e),s=e.elseSteps,c=!0,l=[],u,d=au();for(let f=0;f<e.blocks.length;f++){n.info(`Evaluating condition ${f} in conditional step`);let y=e.blocks[f];try{let S=await gd({...r,presetParams:{tracer:t,step:y.assertion}});l.push(S),u=S,S.status==="SUCCESS"?(n.info(`Condition ${f} resolved to true, executing the corresponding ${y.steps.length} steps`),c=!1,s=y.steps):n.info(S.message,`Condition ${f} resolved to false`)}catch(S){n.info({err:S},`Condition ${f} resolved to false`)}finally{o.throwIfClosed()}}if(s)c&&n.info("No conditions resolved to true, executing the else block steps");else{n.warn("No conditions resolved to true and no else block was provided, causing the entire conditional step to be skipped");let f={...a,assertionResult:u,status:"SUCCESS",startedAt:i,data:l[l.length-1]?.data,message:l[l.length-1]?.message,results:[],finishedAt:new Date,details:d.details};return an({asyncTasks:r.work.asyncTasks,nestedResults:[...l],result:f,logger:n}),f}n.info(`Executing ${s.length} steps in the selected conditional block`);let p=await r.conditionalParams.tracer.startSubSteps(),m=await r.executeStepList({...r,listParams:{steps:s,containerName:"conditional block",tracer:p}}),g={...a,assertionResult:u,...m,startedAt:i,finishedAt:new Date};return an({asyncTasks:r.work.asyncTasks,nestedResults:[...l,...m.results],result:g,logger:n}),g}import{randomUUID as bw}from"crypto";var Tw=async r=>{let{tracer:e}=r.aiStepParams,{controller:t,logger:n}=r.fixtures;await t.browser.waitForDOMStability();let o=await t.browser.screenshot({}),i=await BH(r);i.finishedAt=new Date,an({asyncTasks:r.work.asyncTasks,result:i,nestedResults:i.results,logger:r.fixtures.logger});let a=await t.browser.screenshot({}),s=bw();i.beforeSnapshot=s,e.attachBeforeScreenshot({logger:n,snapshotId:s,screenshot:o});let c=bw();return i.afterSnapshot=c,e.attachAfterScreenshot({logger:n,snapshotId:c,screenshot:a}),i},BH=async r=>{let{step:e,tracer:t}=r.aiStepParams,{controller:n,context:o,logger:i}=r.fixtures,a={...e,startedAt:new Date,beforeTestContext:o.toRedactedDisplayCopy(),finishedAt:new Date,results:[],status:"SUCCESS"};if(!("steps"in e&&e.steps&&e.steps.length>0&&e.steps[e.steps.length-1]?.command.type==="SUCCESS"))throw new _("UserConfigurationError","AI action has been fully deprecated. Please delete this step and transition to Dynamic AI Action.");try{let c=await t.startSubSteps(),{status:l}=await r.executeStepList({...r,listParams:{steps:e.steps,containerName:"AI action",results:a.results,tracer:c}});return a.finishedAt=new Date,a.status=l,a}catch(c){i.warn({err:c},"Failed executing saved deprecated AI action steps");let l=n.executeAbortController.signal.aborted;a.message=c instanceof Error?c.message:`${c}`,a.status=l?"CANCELLED":"FAILED"}return a};import{randomUUID as Wg}from"crypto";var vw=15,HH=7,Rw=async r=>{let{tracer:e}=r.aiStepParams,{logger:t,controller:n}=r.fixtures;await n.browser.waitForDOMStability();let o=await n.browser.screenshot({quality:75}),i=await zH(r);i.finishedAt=new Date,an({asyncTasks:r.work.asyncTasks,result:i,nestedResults:i.results,logger:r.fixtures.logger});let a=await n.browser.screenshot({quality:75}),s=Wg();i.beforeSnapshot=s,e.attachBeforeScreenshot({logger:t,snapshotId:s,screenshot:o});let c=Wg();return i.afterSnapshot=c,e.attachAfterScreenshot({logger:t,snapshotId:c,screenshot:a}),i},zH=async r=>{let{step:e,tracer:t}=r.aiStepParams,{testMetadata:n,orgId:o}=r.inputs,{controller:i,context:a,logger:s,codeEvalTools:c}=r.fixtures,{step:l}=r.callbacks,u=`${e.id}-${Date.now()}`,d=s.child({stepId:e.id,langfuseSessionId:u}),p={...e,startedAt:new Date,beforeTestContext:a.toRedactedDisplayCopy(),results:[],finishedAt:new Date,status:"SUCCESS"},m=await sr({orgId:o,s:e.text,context:a,logger:d,localTools:c});await i.browser.waitForDOMStability({logger:d});let g=`data:image/jpeg;base64,${(await i.browser.screenshot({clearHighlights:!0,retries:2})).toString("base64")}`,f=[],y=0,S=0,T,A;for(;;){if(y>vw)return p.message=`Exceeded the maximum number of commands allowed per AI step (${vw})`,p.status="FAILED",p;if(i.executeAbortController.signal.aborted)return p.message="Test execution was cancelled",p.status="CANCELLED",p;l.onDynamicAIActionStatusUpdateEvent?.({parentStepId:e.id,message:"Evaluating current state..."});let b=await i.evaluateAiAction({goal:m,startingScreenshot:y===0?void 0:g,history:f,logger:d,langfuseSessionId:u,lastError:A}),{evaluation:C,reasoning:x,summary:M}=b;d.info(b,"Got AI evaluation");let P=p.results[y-1]?.id;switch(C.type){case"DONE":return p.message=`Our AI evaluator confirmed all tasks are complete: ${x}`,p.status="SUCCESS",P&&l.onDynamicAIActionEvaluatingEvent?.({stepId:P,status:"SUCCESS",message:`${M}
50
50
  ${x}`}),p;case"RIGHT_TRACK":{T=void 0,y===0?l.onDynamicAIActionEvaluatingEvent?.({stepId:e.id,status:"RUNNING",message:x}):P&&l.onDynamicAIActionEvaluatingEvent?.({stepId:P,status:"SUCCESS",message:x});break}case"WRONG_TRACK":{if(T=`${x}
51
51
  ${C.feedback}`,S++,S>=HH)return p.message=`Our AI agent requires additional information to achieve this goal:
52
52
  ${x}
@@ -4343,7 +4343,7 @@ ${c}`,{errOptions:{cause:r}})}if(i.includes("element is not visible")){let c="Th
4343
4343
  writable: false,
4344
4344
  configurable: false,
4345
4345
  });`),`${t}
4346
- //# sourceURL=momentic-injected/extra-scripts.js`}async function vM(r){try{return await TV(r)}catch(e){r.logger.warn({err:e},"Failed to transform locator for Chakra click, continuing...");return}}async function TV({locator:r,logger:e}){let[t,n]=await r.evaluate(c=>[c.id,c.tagName.toLowerCase()],{timeout:ce}),o=await un(r,e,500),i=await r.boundingBox({timeout:ce});if(i===null){e.warn({elementDisplayString:o},"Attempting to click on element with no bounding box, not performing Chakra redirection");return}if(i.width>5||i.height>5||n!=="input")return;if(t)try{let c=r.page().locator(`label[for=${JSON.stringify(t)}]`);return await c.waitFor({state:"visible",timeout:ce}),{locator:c,relativePoint:void 0}}catch{}let a=await r.evaluate(c=>{let l=window,u=c.parentElement;if(!u)return{type:"error",error:"Input click target has no parent for redirection"};let d=c.getBoundingClientRect(),p=u.getBoundingClientRect();if(p.width===0||p.height===0)return{type:"error",error:"Parent element has no width or height"};let m={x:Math.min(Math.max(1,d.left-p.left),p.width-1),y:Math.min(Math.max(1,d.top-p.top),p.height-1)},h=l._MOMENTIC_FEATURE_FLAGS?.[hp],g=c.getAttribute(to),f=!h&&g?cn(g):l.getMPath?.(c)?.join(" >");return f?{type:"result",selector:f,relativePoint:m,serializedForm:u.outerHTML.slice(0,500)}:{type:"error",error:"Could not generate selector for parent element"}},{timeout:ce});if(a.type==="error")throw new Error(a.error);let s=r.page().locator(a.selector);return await s.waitFor({state:"visible",timeout:ce}),e.info({parentElementResult:a,originalElementDisplayString:o},`Redirected click to parent element with selector: ${a.selector}`),{locator:s,relativePoint:a.relativePoint}}var AM=["date","datetime-local","month","time","week"],RM={date:/^\d{4}-\d{2}-\d{2}$/,"datetime-local":/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}$/,month:/^\d{4}-\d{2}$/,time:/^\d{2}:\d{2}$/,week:/^\d{4}-W\d{2}$/};async function wM(r){try{await j(vV(r),{milliseconds:le})}catch(e){r.logger.warn({err:e},"Failed to transform native datetime input, continuing...")}}async function vV({root:r,text:e,options:t,logger:n,callbacks:o}){let i=(await xt({root:r,fn:()=>document.activeElement?.getAttribute("type")??"",timeout:ce,arg:void 0,waitForPageLoad:o.waitForPageLoad,codePath:"transforming native datetime input"})).toLowerCase();if(!RM[i])return;RM[i].test(e)&&n.warn(`Detected datetime input (${e}) in normalized format - this may fail to fill correctly as it is not how the user would input the value`),t.clearContent=!1,n.info("Transforming datetime input to use sequential key presses")}import{z as hr}from"zod";var CM=hr.object({doubleClick:hr.boolean().optional(),rightClick:hr.boolean().optional(),force:hr.boolean().optional(),waitForDownload:hr.boolean().optional(),delayMs:hr.number().optional(),downloadTimeoutMs:hr.number().optional(),relativePosition:hr.object({x:hr.number(),y:hr.number()}).optional()}),lke=hr.object({repeat:hr.number().optional(),convertMeta:hr.boolean().optional().describe("misleading name due to backcompat. converts keyshortcuts + meta/control to platform-specific combos. defaults to true"),delayMs:hr.number().optional()});async function bp({locator:r,callbacks:e,logger:t,timeoutMs:n=ce}){try{await ES(e,n);let o=r.evaluate(i=>{let a=window;a.momenticIsEligible=d=>{let m=window.getComputedStyle(d,null).getPropertyValue("display");if(m==="none"||m==="contents")return!1;let h=d.getBoundingClientRect();return!(!h.height||!h.width)},a.removeHighlightTimers=a.removeHighlightTimers||[],a.removeHighlightFunctions=a.removeHighlightFunctions||{};let s=0;for(;!a.momenticIsEligible(i)&&s<3;){if(!i.parentElement)throw new Error("No eligible non-empty parent found for highlighting");i=i.parentElement,s++}let c=i.style.getPropertyValue("outline"),l=i.style.getPropertyPriority("outline");i.style.setProperty("outline","5px dashed rgb(255, 0, 153)","important");let u=`momentic${Math.floor(Math.random()*1e7)}`;a[u]=()=>{i.style.removeProperty("outline"),i.style.setProperty("outline",c,l),i.getAttribute("style")||i.removeAttribute("style")},a.removeHighlightTimers.push(setTimeout(()=>{a[u](),a.removeHighlightFunctions?.[u]&&delete a.removeHighlightFunctions[u]},5e3)),a.removeHighlightFunctions[u]=a[u]},void 0,{timeout:n});return await j(o,{milliseconds:n}),!0}catch(o){return t.debug({err:o},"Failed to add node highlight, a page navigation likely occurred. This is non-fatal for tests."),!1}}async function ES(r,e=ce){let t=await r.state.getRoot();await xt({root:t,fn:()=>{let o=window,i=o.removeHighlightTimers||[];for(;i.length;){let a=i.pop();clearTimeout(a)}Object.values(o.removeHighlightFunctions??{}).forEach(a=>{a()})},timeout:e,arg:void 0,waitForPageLoad:r.waitForPageLoad,codePath:"removing element highlights"})}async function bS(r){let e=!!r.browserCallbacks.state.userBrowserSettings.visualActions;return $i({action:"clicking element",targetingResult:r.targetingResult,logger:r.logger,retryTimeoutMs:r.retryTimeoutMs,callbacks:r.browserCallbacks,func:async t=>_M({...r,targetingResult:t,useVisualClick:e})})}async function CV(r,e){let{redirectionAttempts:t=0}=e;if(t>=2)throw r;try{return await xV(r,e)}catch(n){throw e.redirectionAttempts===0?(e.logger.error({redirectionAttemptError:n,originalError:r},"Error handling click error, rethrowing original error"),r):n}}async function xV(r,e){let{logger:t,redirectionAttempts:n=0}=e,o=e.targetingResult.locator;if(r.message.includes("label")&&r.message.includes("for=")&&r.message.includes("intercepts pointer events")){let i=await o.getAttribute("id",{timeout:ce});if(!i)throw r;let a=o.page().locator(`[for=${JSON.stringify(i)}]`);return await a.waitFor({state:"visible",timeout:ce}),t.warn({err:r},"Attempting locator redirection due to input being covered by label"),_M({...e,targetingResult:{locator:a},redirectionAttempts:n+1})}else throw t.error({err:r},"Click error does not match any known recoverable patterns, rethrowing"),r}async function _V(r){let{logger:e,targetingResult:t,position:n,options:o}=r,i=CM.safeParse(o),a=Date.now(),{clickX:s,clickY:c,reason:l}=await PV({targetingResult:t,position:n,options:o,logger:e,isAndroid:r.isAndroid});return e.info({position:n,options:i.success?i.data:void 0,clickLocation:{clickX:s,clickY:c,reason:l},duration:Date.now()-a},"Visual click"),{x:s,y:c}}async function MV(r){let{actionSource:e,targetingResult:t,options:n,logger:o}=r,i=r.targetingResult.locator,a=n?.relativePosition??r.position;if(e==="click"&&!a){let l=await vM({locator:i,logger:o});l&&(i=l.locator,a=l.relativePoint??a)}let s=n?.force||t.hints?.force||!1;s&&!a&&t.hints?.relativeXYToLocator&&(a=t.hints.relativeXYToLocator);let c=i.toString();o.info({locator:c},"Locator click");try{n?.doubleClick?await i.dblclick({button:n.rightClick?"right":"left",timeout:le,position:a,delay:n?.delayMs??25,force:s}):await i.click({button:n?.rightClick?"right":"left",timeout:le,position:a,delay:n?.delayMs??25,force:s})}catch(l){let u=l;if(LV(u))o.warn({err:u},"Click action timed out while waiting for navigation after completion, continuing...");else return o.error({err:u},"Error clicking on locator, attempting to recover..."),CV(u,{...r,targetingResult:{...i,locator:i}})}return{locatorSource:c}}async function _M(r){let{options:e,logger:t,browserCallbacks:n,controllerCallbacks:o,useVisualClick:i,targetingResult:a}=r,s;e?.waitForDownload&&(s=(async()=>{let u=e.downloadTimeoutMs??Qf;try{return await a.locator.page().waitForEvent("download",{timeout:u})}catch(d){return d instanceof wV.TimeoutError?new _("ActionFailureError",`Download did not complete in ${u}ms`):new _("ActionFailureError",`Download failed: ${d.message}`)}})());try{await bp({locator:a.locator,callbacks:n,logger:t,timeoutMs:ce})}catch(u){t.warn({err:u},"Error highlighting locator in click, continuing...")}let c,l;if(i?c=await _V(r):l=(await MV(r)).locatorSource,e?.waitForDownload)if(s){if(!o?.createIsolatedFolder)throw new _("InternalWebAgentError","Cannot wait for download without a callback to create an isolated folder");t.info("Waiting for download to start and complete");let u=await j(s,{milliseconds:e.downloadTimeoutMs??Qf});if(u instanceof Error)throw u;return{downloadedFile:await OV(u,o.createIsolatedFolder,t),coordinates:c,locatorSource:l}}else throw new Error("No download promise or error but the step requested to wait for a download");return{coordinates:c,locatorSource:l}}async function IV(r,e){let t=await r.locator.boundingBox({timeout:le});if(!t){let i=await un(r.locator,e,500);throw new _("ActionFailureError",`${Lm}${i?`: ${i}`:""}`)}if(r.hints?.relativeXYToLocator){let i=t.x+r.hints.relativeXYToLocator.x,a=t.y+r.hints.relativeXYToLocator.y;return[{x:i,y:a},"targeting hint"]}let n=t.x+t.width/2,o=t.y+t.height/2;return[{x:n,y:o},"halfway point"]}async function PV({options:r,targetingResult:e,position:t,logger:n}){let o,i,a;if(r?.relativePosition){let u=await e.locator.boundingBox({timeout:le}),d=r.relativePosition.x,p=r.relativePosition.y;u?.width&&(d=Math.max(0,Math.min(r.relativePosition.x,u.width))),u?.height&&(p=Math.max(0,Math.min(r.relativePosition.y,u.height))),o=(u?.x??0)+d,i=(u?.y??0)+p,a="relative position from user"}else if(t){let u=await e.locator.boundingBox({timeout:le});o=(u?.x??0)+t.x,i=(u?.y??0)+t.y,a="predefined position"}else{let[u,d]=await IV(e,n);o=u.x,i=u.y,a=d}let s=e.locator.page(),c=r?.rightClick?"right":"left",l=r?.delayMs??25;return r?.doubleClick?await s.mouse.dblclick(o,i,{button:c,delay:l}):await s.mouse.click(o,i,{button:c,delay:l}),{clickX:o,clickY:i,reason:a}}async function OV(r,e,t){t.info("Download detected, saving file to disk");let n=await r.path(),o=lS(r.suggestedFilename()),i=e();await r.saveAs(AV(i,o)),xM(n,{force:!0}),setTimeout(()=>{xM(i,{recursive:!0,force:!0})},5*60*1e3);let a=eM(RV(i),o);return t.info({uri:a,downloadFolder:i},"Saved download to isolated folder"),a}function LV(r){return r.message.includes("locator.click: Timeout")&&r.message.includes("click action done")}import{platform as NV}from"os";var DV={goToNextWord:{win32:"Control+ArrowRight",darwin:"Alt+ArrowRight",linux:"Control+ArrowRight"},goToPreviousWord:{win32:"Control+ArrowLeft",darwin:"Alt+ArrowLeft",linux:"Control+ArrowLeft"},selectNextWord:{win32:"Control+Shift+ArrowRight",darwin:"Alt+Shift+ArrowRight",linux:"Control+Shift+ArrowRight"},selectPreviousWord:{win32:"Control+Shift+ArrowLeft",darwin:"Alt+Shift+ArrowLeft",linux:"Control+Shift+ArrowLeft"},selectToStartOfLine:{win32:"Shift+Home",darwin:"Meta+Shift+LeftArrow",linux:"Shift+Home"},selectToEndOfLine:{win32:"Shift+End",darwin:"Meta+Shift+RightArrow",linux:"Shift+End"},deleteNextWord:{win32:"Control+Delete",darwin:"Alt+Fn+Delete",linux:"Control+Delete"},deletePreviousWord:{win32:"Control+Backspace",darwin:"Alt+Delete",linux:"Control+Backspace"}};function kV(){let r=NV();return r==="win32"?"win32":r==="darwin"?"darwin":"linux"}function MM(r){return JSON.stringify(r.split("+").sort())}function Tp(r,e){let t=kV(),n=MM(r);for(let o of Object.values(DV))if(Object.values(o).some(i=>MM(i)===n))return o[t];return process.platform==="darwin"&&!e?r=r.replaceAll("Control","Meta"):r=r.replaceAll("Meta","Control"),r}async function TS({frame:r,page:e,deltaX:t,directionX:n,deltaY:o,directionY:i,signal:a,callbacks:s,logger:c}){if(!t&&!o)return;let l=n==="left"?-1:1,u=i==="up"?-1:1;if(r)await xt({root:r,fn:([d,p,m,h])=>window.scrollTo(window.scrollX+(d??window.innerWidth)*m,window.scrollY+(p??window.innerHeight)*h),arg:[t,o,l,u],waitForPageLoad:s.waitForPageLoad,timeout:Oe,codePath:"scrolling page"});else{let d=e.viewportSize()||Kt,p=await xt({root:e,fn:()=>document.body.scrollHeight,arg:void 0,waitForPageLoad:s.waitForPageLoad,timeout:Oe,codePath:"computing page height"}),[m,h,g]=await xt({root:e,fn:()=>{let f=document.activeElement;if(!f)return[void 0,void 0,void 0];let y=f.getBoundingClientRect();return[f.scrollTop,y.x,y.y]},arg:void 0,waitForPageLoad:s.waitForPageLoad,timeout:Oe,codePath:"computing active element position"});await e.mouse.wheel((t??d.width)*l,(o??d.height)*u);try{let f=Date.now();for(;Date.now()-f<Oe;){a?.throwIfAborted();let y=await j(e.evaluate(()=>document.body.scrollHeight),{milliseconds:ce}),[S,T,A]=await j(e.evaluate(()=>{let b=document.activeElement;if(!b)return[void 0,void 0,void 0];let C=b.getBoundingClientRect();return[b.scrollTop,C.x,C.y]}),{milliseconds:ce});if(y===p&&S===m&&T===h&&A===g)break;p=y,m=S,h=T,g=A,await ae(It)}}catch(f){c.warn({err:f},"Failed to wait for scroll to complete, continuing...")}}}async function vS(r,e){let t,n;for(let o=0;o<4;o++)try{return t=r.pages(),await Promise.all(t.map(async i=>{let a="";try{a=e?.getTitles?await i.title():""}catch{a="Unknown page"}return{title:a,url:i.url()}}))}catch(i){n=i,await ae(It)}throw new Error(`Failed to get tab titles after all retries: ${n?.message}`)}async function IM(r){let{page:e,deltaX:t,deltaY:n,steps:o,visualTarget:i,isAndroid:a,delayMs:s}=r;if(a){await FV(e,t,n,o,s,i);return}await e.mouse.move(i.x,i.y),await e.mouse.down(),await e.mouse.move(t+i.x,n+i.y,{steps:o}),await ae(s??ji),await e.mouse.up()}async function PM(r,e,t,n){await r.mouse.move(e.x,e.y,{steps:3}),await r.mouse.down(),await r.mouse.move(t.x,t.y,{steps:3}),await ae(n.hoverSeconds?Math.min(n.hoverSeconds*1e3,gp):500),await r.mouse.up()}async function FV(r,e,t,n,o,i){let a=Math.max(1,n??1),s=i.x,c=i.y,l=i.x+e,u=i.y+t;await r.evaluate(async({startX:d,startY:p,endX:m,endY:h,stepCount:g,delayMs:f})=>{let y=document.elementFromPoint(d,p)??document.body??document.documentElement,T=window._momenticMobileUtilities.dispatchTouch;T(y,"touchstart",d,p);for(let A=1;A<=g;A+=1){let b=d+(m-d)*A/g,C=p+(h-p)*A/g;T(y,"touchmove",b,C),await new Promise(x=>setTimeout(x,Math.floor((f??500)/g)))}T(y,"touchend",m,h)},{startX:s,startY:c,endX:l,endY:u,stepCount:a,delayMs:o})}import{randomUUID as $V}from"crypto";import{cloneDeep as wS}from"lodash-es";function Vo(r,e){let t=r.findIndex(n=>n===e);if(!(t===-1||!r[t+1]))return r[t+1]}import{createHash as UV}from"crypto";var BV="v1";function RS(r,e){if(r.tagName.toLowerCase()==="svg"&&!zV(r))try{let t=OM(r,e),n=HV(JSON.stringify(t));return{version:BV,json:t,hash:n}}catch{return}}function HV(r){return UV("md5").update(r).digest("hex")}function OM(r,e){let t=r.tagName.toLowerCase(),n=GV(r);if(t==="image"&&n["xlink:href"])throw new Error("Image tags within SVGs are not supported");let o={type:t,props:n,children:[]};for(let i of r.childrenBackendIds){let a=e.backendIdToNode[i];if(a&&a.nodeType===1){let s=OM(a,e);s&&o.children.push(s)}}return o}function zV(r){let e=r.computedStyles.display,t=r.computedStyles.visibility,n=r.computedStyles.opacity;return e==="none"||t==="hidden"||n==="0"}function GV(r){let e={},t=r.attributes;for(let n of Object.keys(t))jr.visualAttributesForSvgSerialization.includes(n)&&(e[n]=t[n]);return t.id&&r.tagName.toLowerCase()!=="svg"&&(e.id=t.id),e}var Wi={r:147,g:196,b:125,a:.55},NM={showRulers:!1,showStyles:!1,showExtensionLines:!1,contrastAlgorithm:"aa",contentColor:Wi,paddingColor:Wi,borderColor:Wi,marginColor:Wi,eventTargetColor:Wi,shapeColor:Wi,shapeMarginColor:Wi,showInfo:!0,showAccessibilityInfo:!0};function DM({snapshot:r,devicePixelRatio:e,computedStylesToFetch:t,logger:n}){let o=r.strings,i=r.documents,a={},s={},c={roots:[],backendIdToNode:a,frameIndexToIframeNode:s};return i.forEach((l,u)=>{let d=jV({allDocuments:i,stringConstants:o,computedStylesToFetch:t,devicePixelRatio:e,frameIndex:u,backendIdToNode:a,frameIndexToIframeNode:s,logger:n});c.roots.push(d)}),c}function jV({allDocuments:r,stringConstants:e,computedStylesToFetch:t,devicePixelRatio:n,frameIndex:o,frameIndexToIframeNode:i,backendIdToNode:a,logger:s}){let c=r[o],l=c.layout,u={};l.nodeIndex.forEach((x,M)=>{u[x]=M});let d=l.styles,p=l.bounds??[],m=c.nodes,h=m.contentDocumentIndex??{index:[],value:[]},g=m.backendNodeId??[],f=m.attributes??[],y=m.parentIndex??[],S=m.nodeName??[],T=m.nodeType??[],A=m.pseudoType??{index:[],value:[]},b=m.inputChecked??{index:[]},C=e[c.frameId];for(let x=0;x<g.length;x++){let M=g[x],P=T[x],U=f[x]??[],V=y[x]!==void 0&&y[x]>=0?y[x]:void 0,k=V!==void 0?g[V]:void 0,z=k!==void 0?a[k]:void 0,Q=A.index.indexOf(x),Y=Q!==-1?e[A.value[Q]]:void 0,Te=u[x],q;Te?q=p[Te]??[]:q=[];let it=S[x]!==void 0?e[S[x]]?.toLowerCase():void 0;if(!it){s.warn({backendNodeId:M,frameId:C,frameIndex:o,nodeBounds:q},"DOM node has no tag name");continue}let Ge={backendNodeId:M,psuedoType:Y,nodeType:P,frameIndex:o,parentFrameId:C,ownedFrameId:void 0,bounds:{x:q[0]??null,y:q[1]??null,width:q[2]??null,height:q[3]??null},computedStyles:{},attributes:{},parentBackendNodeId:k??null,tagName:it,parent:z??void 0,childrenBackendIds:[],momenticIgnored:void 0,mPathSelector:void 0};z&&z.childrenBackendIds.push(M);let Ye=h.index.indexOf(x);if(Ye!==-1){let Ie=h.value[Ye];i[Ie]=Ge;let oe=r[Ie]?.frameId;Ge.ownedFrameId=oe!==void 0?e[oe]:void 0}for(let Ie of Object.keys(Ge.bounds)){let oe=Ie;Ge.bounds[oe]!==null&&(Ge.bounds[oe]/=n)}let Nt=Te!==void 0?d[Te]??[]:[];for(let Ie=0;Ie<Nt.length&&!(Ie>=t.length);Ie++){let oe=Nt[Ie];if(oe===void 0||isNaN(oe))continue;let jt=e[oe];if(jt===void 0)continue;let Fn=t[Ie];Ge.computedStyles[Fn]=jt}for(let Ie=0;Ie<U.length;Ie+=2){let oe=U[Ie],jt=U[Ie+1];if(!oe||!jt)continue;let Fn=e[oe],Un=e[jt];!Fn||!Un||(Ge.attributes[Fn]=Un)}b.index.includes(x)&&(Ge.attributes.checked="true"),a[Ge.backendNodeId]=Ge}return a[g[0]]}function AS(r,e){if(r.mPathSelector)return r.mPathSelector;let t=r.parent,n;if(!t)n=r.tagName;else if(r.tagName==="body")n="body";else{let i=t.childrenBackendIds.filter(c=>e.backendIdToNode[c]?.nodeType===1&&!e.backendIdToNode[c]?.psuedoType).indexOf(r.backendNodeId),a=` > ${r.tagName}:nth-child(${i+1})`;n=`${AS(t,e)}${a}`}return r.mPathSelector=n,n}function LM(r,e){return r.parentBackendNodeId!==null?e.backendIdToNode[r.parentBackendNodeId]:r.frameIndex===0?void 0:e.frameIndexToIframeNode[r.frameIndex]}var VV=["html","#document","#document-fragment"];function kM({node:r,domGraph:e}){let t=[],n=r,o=LM(r,e);if(!o)return[r.tagName];let i=()=>{if(n=o,o=LM(o,e),!o&&n.frameIndex!==0)throw new Error("No parent node but not in main frame")},a=0;for(;o&&a<1e6;){if(a++,VV.includes(n.tagName)){i();continue}if(n.tagName==="body")t.push("body");else{let c=!1,l=1;for(let u=0;u<o.childrenBackendIds.length;u++){let d=o.childrenBackendIds[u],p=e.backendIdToNode[d];if(d===n.backendNodeId){t.push(`${n.tagName}:nth-child(${l})`),c=!0;break}else p?.nodeType===1&&!p.psuedoType&&l++}if(!c)throw new Error(`Could not find child (${n.tagName}) in parent's children list (${o.tagName})`)}i()}return t.reverse()}function FM(r,e){let t=r.locator("html"),n=[];for(let o=0;o<e.length;o++){let i=e[o];if(n.push(i),i.startsWith("iframe")){let a=n.join(" > ");n=[],o<e.length-1?t=t.frameLocator(a):t=t.locator(a)}}if(n.length&&(t=t.locator(n.join(" > "))),"owner"in t)throw new Error("Final locator from mpath is a frame locator");return t}async function UM(r,e){await r.send({method:"DOM.getDocument",params:{depth:0},timeout:Oe});let t=await r.send({method:"DOM.requestNode",params:{objectId:e},timeout:Oe}),o=(await r.send({method:"DOM.getAttributes",params:{nodeId:t.nodeId},timeout:Oe})).attributes,i=Vo(o,to);if(!i)throw new Error(`Could not find attribute ${to} for object ${e}`);return i}var WV=["focusable","keyshortcuts","controls","live","relevant","orientation"],qV=["selected","readonly","modal","required","invalid"],KV=["id","name","role","content"],BM=["absolute","fixed","sticky"],YV=["i","label"],XV=["path"],JV=["statictext","textbox","checkbox","combobox","iframe","rootwebarea","table","caption","columnheader","rowheader","gridcell","grid","row","rowgroup","cell","image","graphics-symbol","graphics-document","graphics-object","svgroot","button","link","list","listitem","tablist","tabpanel","tab","searchbox","menu","menubar","form","dialog","alertdialog","banner","navigation","main","menuitem","menuitemcheckbox","menuitemradio","option","radio","progressbar","switch","tree","treeitem","separator","LabelText"],GM=["ariaHiddenElement","ariaHiddenSubtree","hiddenByChildTree","inertElement","inertSubtree","notRendered","notVisible"],jM=["activeAriaModalDialog","activeFullscreenElement","activeModalDialog"],QV=["menulistpopup","statictext","inlinetextbox"],ZV=80,HM=100,VM=50,_S=["StaticText","ListMarker","RootWebArea","LineBreak","emphasis","::before","::after"],e$=["cite"],t$={LabelText:["label"],listitem:["li"],image:["img","svg"],link:["a"],RootWebArea:["#document"],paragraph:["p"],LineBreak:["br"],separator:["hr"],"graphics-symbol":["svg","rect"],gridcell:["td","th"],SvgRoot:["svg"],navigation:["nav"],cell:["td","th"],row:["tr"],list:["ul"],heading:["h1","h2","h3","h4","h5","h6"]},r$={name:!0,value:!0,title:!0,alt:!0,placeholder:!0,checked:!0,selected:!0,contenteditable:!0},zM={indentLevel:0},CS=class r{id;role;name;nameSources;tagName;content;properties;internalProperties;ignoredReasons;dataMomenticId;importantProperties;pathFromRoot;mPathSelector;parent;children;parentFrame;domNode;backendNodeId;ignoredByCDP;flagNotActionableNodes;constructor(e){if(this.id=e.id,this.role=e.role,this.name=e.name,this.nameSources=e.nameSources,this.content=e.content,this.properties={},this.pathFromRoot=e.pathFromRoot,this.children=e.children,this.backendNodeId=e.backendNodeID,this.ignoredByCDP=e.ignoredByCDP,this.internalProperties=e.internalProperties??{},this.parentFrame=e.parentFrame,this.ignoredReasons=e.ignoredReasons,this.importantProperties=e.importantProperties,this.flagNotActionableNodes=e.flagNotActionableNodes,e.properties&&e.properties.forEach(t=>{t.name==="keyshortcuts"?this.dataMomenticId=parseInt(t.value.value):this.properties[t.name]=t.value.value}),e.domNode){this.domNode=e.domNode,this.tagName=e.domNode.tagName||void 0;let t=e.domNode.attributes.id;this.name=this.name||e.domNode.attributes.name||(t&&t.length<VM?t:""),this.role=this.role||(e.domNode.attributes.role??""),a$(this.properties,e.domNode,e.importantProperties)}l$(this)}getSerializedFormWithContext(){return this.serialize({noId:!0,maxLevel:1,neighbors:1})}getNodeOnlySerializedForm(){return this.serialize({noId:!0,noChildren:!0,noContent:!0})}getLogForm(){return JSON.stringify({id:this.id,name:this.name??"",role:this.role??"",backendNodeId:this.backendNodeId})}isInteresting(e){if(this.domNode&&XV.includes(this.domNode.tagName)||this.ignoredReasons.some(n=>jM.includes(n)))return!1;if(e){if(Object.keys(this.domNode?.attributes??{}).some(o=>YM(o,e)))return!0;let n=this.domNode?.attributes.class?.split(" ");if(n&&n.length>0&&n.some(o=>XM(o,e))||e.styles?.some(o=>{let i=o.split(":");if(i.length!==2)return!1;let a=i[0]?.trim(),s=i[1]?.trim();if(a===void 0||s===void 0)return!1;let c=this.domNode?.computedStyles[a];return c!==void 0&&(c===s||s==="*")}))return!0}if(this.domNode&&YV.includes(this.domNode.tagName)||JV.includes(this.role.toLowerCase())||this.domNode?.computedStyles["background-image"]&&this.domNode?.computedStyles["background-image"]!=="none"&&this.children.length===0||this.role.toLowerCase()==="inlinetextbox"&&this.tagName||!this.properties.hidden&&(this.properties.focusable||this.properties.settable)||jr.alwaysInterestingTruthyPropertyNames.some(n=>!!this.properties[n]))return!0;let t=this.properties.class;return typeof t=="string"&&t.split(" ").some(n=>KM(n))?!0:this.children.every(n=>n.role==="StaticText")&&this.internalProperties?.inCodeMirrorEditor?!1:this.children.some(n=>n.role==="StaticText")||this.children.length>1&&this.children.some(n=>n.tagName==="input")||this.children.some(n=>n.isIneligible())?!0:this.domNode&&(this.domNode.bounds.x===null||this.domNode.bounds.y===null||!this.domNode.bounds.width||!this.domNode.bounds.height)?!1:!!this.name.trim()||!!this.content||Object.keys(this.properties).some(n=>n.startsWith("data"))}shouldSerializeBounds(){let e=this.domNode?.computedStyles.position;return!!(e&&(e==="absolute"||e==="fixed"||e==="sticky"))}isIneligible(){return!!(this.domNode?.computedStyles.display==="contents"||this.domNode&&(this.domNode.bounds.x===null||this.domNode.bounds.y===null||!this.domNode.bounds.width||!this.domNode.bounds.height))}serialize(e=zM){let t=Object.assign({},zM,e),{indentLevel:n,noChildren:o,noProperties:i,noId:a,noContent:s,condensedMode:c}=t,l=wS(this.properties),u=" ".repeat(n),d=this.role||"",p=this.tagName??"unknown",m=this.name;d==="heading"&&m==="heading"&&(m=""),this.nameSources?.find(b=>!b.superseded&&b.type==="contents")&&this.children.length>0&&(m="");let g=this.nameSources?.find(b=>!b.superseded);if(g&&!g.nativeSource&&g.type==="relatedElement"){let b=g.attributeValue?.relatedNodes??[];b.length===1&&b[0].text&&b[0].text===m&&(m="")}let f=_S.includes(this.role)||e$.includes(this.tagName||"");if(this.role==="StaticText"||this.role==="ListMarker")return`${u}${m}
4346
+ //# sourceURL=momentic-injected/extra-scripts.js`}async function vM(r){try{return await TV(r)}catch(e){r.logger.warn({err:e},"Failed to transform locator for Chakra click, continuing...");return}}async function TV({locator:r,logger:e}){let[t,n]=await r.evaluate(c=>[c.id,c.tagName.toLowerCase()],{timeout:ce}),o=await un(r,e,500),i=await r.boundingBox({timeout:ce});if(i===null){e.warn({elementDisplayString:o},"Attempting to click on element with no bounding box, not performing Chakra redirection");return}if(i.width>5||i.height>5||n!=="input")return;if(t)try{let c=r.page().locator(`label[for=${JSON.stringify(t)}]`);return await c.waitFor({state:"visible",timeout:ce}),{locator:c,relativePoint:void 0}}catch{}let a=await r.evaluate(c=>{let l=window,u=c.parentElement;if(!u)return{type:"error",error:"Input click target has no parent for redirection"};let d=c.getBoundingClientRect(),p=u.getBoundingClientRect();if(p.width===0||p.height===0)return{type:"error",error:"Parent element has no width or height"};let m={x:Math.min(Math.max(1,d.left-p.left),p.width-1),y:Math.min(Math.max(1,d.top-p.top),p.height-1)},h=l._MOMENTIC_FEATURE_FLAGS?.[hp],g=c.getAttribute(to),f=!h&&g?cn(g):l.getMPath?.(c)?.join(" >");return f?{type:"result",selector:f,relativePoint:m,serializedForm:u.outerHTML.slice(0,500)}:{type:"error",error:"Could not generate selector for parent element"}},{timeout:ce});if(a.type==="error")throw new Error(a.error);let s=r.page().locator(a.selector);return await s.waitFor({state:"visible",timeout:ce}),e.info({parentElementResult:a,originalElementDisplayString:o},`Redirected click to parent element with selector: ${a.selector}`),{locator:s,relativePoint:a.relativePoint}}var AM=["date","datetime-local","month","time","week"],RM={date:/^\d{4}-\d{2}-\d{2}$/,"datetime-local":/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}$/,month:/^\d{4}-\d{2}$/,time:/^\d{2}:\d{2}$/,week:/^\d{4}-W\d{2}$/};async function wM(r){try{await j(vV(r),{milliseconds:le})}catch(e){r.logger.warn({err:e},"Failed to transform native datetime input, continuing...")}}async function vV({root:r,text:e,options:t,logger:n,callbacks:o}){let i=(await xt({root:r,fn:()=>document.activeElement?.getAttribute("type")??"",timeout:ce,arg:void 0,waitForPageLoad:o.waitForPageLoad,codePath:"transforming native datetime input"})).toLowerCase();if(!RM[i])return;RM[i].test(e)&&n.warn(`Detected datetime input (${e}) in normalized format - this may fail to fill correctly as it is not how the user would input the value`),t.clearContent=!1,n.info("Transforming datetime input to use sequential key presses")}import{z as hr}from"zod";var CM=hr.object({doubleClick:hr.boolean().optional(),rightClick:hr.boolean().optional(),force:hr.boolean().optional(),waitForDownload:hr.boolean().optional(),delayMs:hr.number().optional(),downloadTimeoutMs:hr.number().optional(),relativePosition:hr.object({x:hr.number(),y:hr.number()}).optional()}),lke=hr.object({repeat:hr.number().optional(),convertMeta:hr.boolean().optional().describe("misleading name due to backcompat. converts keyshortcuts + meta/control to platform-specific combos. defaults to true"),delayMs:hr.number().optional()});async function bp({locator:r,callbacks:e,logger:t,timeoutMs:n=ce}){try{await ES(e,n);let o=r.evaluate(i=>{let a=window;a.momenticIsEligible=d=>{let m=window.getComputedStyle(d,null).getPropertyValue("display");if(m==="none"||m==="contents")return!1;let h=d.getBoundingClientRect();return!(!h.height||!h.width)},a.removeHighlightTimers=a.removeHighlightTimers||[],a.removeHighlightFunctions=a.removeHighlightFunctions||{};let s=0;for(;!a.momenticIsEligible(i)&&s<3;){if(!i.parentElement)throw new Error("No eligible non-empty parent found for highlighting");i=i.parentElement,s++}let c=i.style.getPropertyValue("outline"),l=i.style.getPropertyPriority("outline");i.style.setProperty("outline","5px dashed rgb(255, 0, 153)","important");let u=`momentic${Math.floor(Math.random()*1e7)}`;a[u]=()=>{i.style.removeProperty("outline"),i.style.setProperty("outline",c,l),i.getAttribute("style")||i.removeAttribute("style")},a.removeHighlightTimers.push(setTimeout(()=>{a[u](),a.removeHighlightFunctions?.[u]&&delete a.removeHighlightFunctions[u]},5e3)),a.removeHighlightFunctions[u]=a[u]},void 0,{timeout:n});return await j(o,{milliseconds:n}),!0}catch(o){return t.debug({err:o},"Failed to add node highlight, a page navigation likely occurred. This is non-fatal for tests."),!1}}async function ES(r,e=ce){let t=await r.state.getRoot();await xt({root:t,fn:()=>{let o=window,i=o.removeHighlightTimers||[];for(;i.length;){let a=i.pop();clearTimeout(a)}Object.values(o.removeHighlightFunctions??{}).forEach(a=>{a()})},timeout:e,arg:void 0,waitForPageLoad:r.waitForPageLoad,codePath:"removing element highlights"})}async function bS(r){let e=!!r.browserCallbacks.state.userBrowserSettings.visualActions;return $i({action:"clicking element",targetingResult:r.targetingResult,logger:r.logger,retryTimeoutMs:r.retryTimeoutMs,callbacks:r.browserCallbacks,func:async t=>_M({...r,targetingResult:t,useVisualClick:e})})}async function CV(r,e){let{redirectionAttempts:t=0}=e;if(t>=2)throw r;try{return await xV(r,e)}catch(n){throw e.redirectionAttempts===0?(e.logger.error({redirectionAttemptError:n,originalError:r},"Error handling click error, rethrowing original error"),r):n}}async function xV(r,e){let{logger:t,redirectionAttempts:n=0}=e,o=e.targetingResult.locator;if(r.message.includes("label")&&r.message.includes("for=")&&r.message.includes("intercepts pointer events")){let i=await o.getAttribute("id",{timeout:ce});if(!i)throw r;let a=o.page().locator(`[for=${JSON.stringify(i)}]`);return await a.waitFor({state:"visible",timeout:ce}),t.warn({err:r},"Attempting locator redirection due to input being covered by label"),_M({...e,targetingResult:{locator:a},redirectionAttempts:n+1})}else throw t.error({err:r},"Click error does not match any known recoverable patterns, rethrowing"),r}async function _V(r){let{logger:e,targetingResult:t,position:n,options:o}=r,i=CM.safeParse(o),a=Date.now(),{clickX:s,clickY:c,reason:l}=await PV({targetingResult:t,position:n,options:o,logger:e,isAndroid:r.isAndroid});return e.info({position:n,options:i.success?i.data:void 0,clickLocation:{clickX:s,clickY:c,reason:l},duration:Date.now()-a},"Visual click"),{x:s,y:c}}async function MV(r){let{actionSource:e,targetingResult:t,options:n,logger:o}=r,i=r.targetingResult.locator,a=n?.relativePosition??r.position;if(e==="click"&&!a){let l=await vM({locator:i,logger:o});l&&(i=l.locator,a=l.relativePoint??a)}let s=n?.force||t.hints?.force||!1;s&&!a&&t.hints?.relativeXYToLocator&&(a=t.hints.relativeXYToLocator);let c=i.toString();o.info({locator:c},"Locator click");try{n?.doubleClick?await i.dblclick({button:n.rightClick?"right":"left",timeout:le,position:a,delay:n?.delayMs??25,force:s}):await i.click({button:n?.rightClick?"right":"left",timeout:le,position:a,delay:n?.delayMs??25,force:s})}catch(l){let u=l;if(LV(u))o.warn({err:u},"Click action timed out while waiting for navigation after completion, continuing...");else return o.error({err:u},"Error clicking on locator, attempting to recover..."),CV(u,{...r,targetingResult:{...i,locator:i}})}return{locatorSource:c}}async function _M(r){let{options:e,logger:t,browserCallbacks:n,controllerCallbacks:o,useVisualClick:i,targetingResult:a}=r,s;e?.waitForDownload&&(s=(async()=>{let u=e.downloadTimeoutMs??Qf;try{return await a.locator.page().waitForEvent("download",{timeout:u})}catch(d){return d instanceof wV.TimeoutError?new _("ActionFailureError",`Download did not complete in ${u}ms`):new _("ActionFailureError",`Download failed: ${d.message}`)}})());try{await bp({locator:a.locator,callbacks:n,logger:t,timeoutMs:ce})}catch(u){t.warn({err:u},"Error highlighting locator in click, continuing...")}let c,l;if(i?c=await _V(r):l=(await MV(r)).locatorSource,e?.waitForDownload)if(s){if(!o?.createIsolatedFolder)throw new _("InternalWebAgentError","Cannot wait for download without a callback to create an isolated folder");t.info("Waiting for download to start and complete");let u=await j(s,{milliseconds:e.downloadTimeoutMs??Qf});if(u instanceof Error)throw u;return{downloadedFile:await OV(u,o.createIsolatedFolder,t),coordinates:c,locatorSource:l}}else throw new Error("No download promise or error but the step requested to wait for a download");return{coordinates:c,locatorSource:l}}async function IV(r,e){let t=await r.locator.boundingBox({timeout:le});if(!t){let i=await un(r.locator,e,500);throw new _("ActionFailureError",`${Lm}${i?`: ${i}`:""}`)}if(r.hints?.relativeXYToLocator){let i=t.x+r.hints.relativeXYToLocator.x,a=t.y+r.hints.relativeXYToLocator.y;return[{x:i,y:a},"targeting hint"]}let n=t.x+t.width/2,o=t.y+t.height/2;return[{x:n,y:o},"halfway point"]}async function PV({options:r,targetingResult:e,position:t,logger:n}){let o,i,a;if(r?.relativePosition){let u=await e.locator.boundingBox({timeout:le}),d=r.relativePosition.x,p=r.relativePosition.y;u?.width&&(d=Math.max(0,Math.min(r.relativePosition.x,u.width))),u?.height&&(p=Math.max(0,Math.min(r.relativePosition.y,u.height))),o=(u?.x??0)+d,i=(u?.y??0)+p,a="relative position from user"}else if(t){let u=await e.locator.boundingBox({timeout:le});o=(u?.x??0)+t.x,i=(u?.y??0)+t.y,a="predefined position"}else{let[u,d]=await IV(e,n);o=u.x,i=u.y,a=d}let s=e.locator.page(),c=r?.rightClick?"right":"left",l=r?.delayMs??25;return r?.doubleClick?await s.mouse.dblclick(o,i,{button:c,delay:l}):await s.mouse.click(o,i,{button:c,delay:l}),{clickX:o,clickY:i,reason:a}}async function OV(r,e,t){t.info("Download detected, saving file to disk");let n=await r.path(),o=lS(r.suggestedFilename()),i=e();await r.saveAs(AV(i,o)),xM(n,{force:!0}),setTimeout(()=>{xM(i,{recursive:!0,force:!0})},5*60*1e3);let a=eM(RV(i),o);return t.info({uri:a,downloadFolder:i},"Saved download to isolated folder"),a}function LV(r){return r.message.includes("locator.click: Timeout")&&r.message.includes("click action done")}import{platform as NV}from"os";var DV={goToNextWord:{win32:"Control+ArrowRight",darwin:"Alt+ArrowRight",linux:"Control+ArrowRight"},goToPreviousWord:{win32:"Control+ArrowLeft",darwin:"Alt+ArrowLeft",linux:"Control+ArrowLeft"},selectNextWord:{win32:"Control+Shift+ArrowRight",darwin:"Alt+Shift+ArrowRight",linux:"Control+Shift+ArrowRight"},selectPreviousWord:{win32:"Control+Shift+ArrowLeft",darwin:"Alt+Shift+ArrowLeft",linux:"Control+Shift+ArrowLeft"},selectToStartOfLine:{win32:"Shift+Home",darwin:"Meta+Shift+LeftArrow",linux:"Shift+Home"},selectToEndOfLine:{win32:"Shift+End",darwin:"Meta+Shift+RightArrow",linux:"Shift+End"},deleteNextWord:{win32:"Control+Delete",darwin:"Alt+Fn+Delete",linux:"Control+Delete"},deletePreviousWord:{win32:"Control+Backspace",darwin:"Alt+Delete",linux:"Control+Backspace"}};function kV(){let r=NV();return r==="win32"?"win32":r==="darwin"?"darwin":"linux"}function MM(r){return JSON.stringify(r.split("+").sort())}function Tp(r,e){let t=kV(),n=MM(r);for(let o of Object.values(DV))if(Object.values(o).some(i=>MM(i)===n))return o[t];return process.platform==="darwin"&&!e?r=r.replaceAll("Control","Meta"):r=r.replaceAll("Meta","Control"),r}async function TS({frame:r,page:e,deltaX:t,directionX:n,deltaY:o,directionY:i,signal:a,callbacks:s,logger:c}){if(!t&&!o)return;let l=n==="left"?-1:1,u=i==="up"?-1:1;if(r)await xt({root:r,fn:([d,p,m,h])=>window.scrollTo(window.scrollX+(d??window.innerWidth)*m,window.scrollY+(p??window.innerHeight)*h),arg:[t,o,l,u],waitForPageLoad:s.waitForPageLoad,timeout:Oe,codePath:"scrolling page"});else{let d=e.viewportSize()||Kt,p=await xt({root:e,fn:()=>document.body.scrollHeight,arg:void 0,waitForPageLoad:s.waitForPageLoad,timeout:Oe,codePath:"computing page height"}),[m,h,g]=await xt({root:e,fn:()=>{let f=document.activeElement;if(!f)return[void 0,void 0,void 0];let y=f.getBoundingClientRect();return[f.scrollTop,y.x,y.y]},arg:void 0,waitForPageLoad:s.waitForPageLoad,timeout:Oe,codePath:"computing active element position"});await e.mouse.wheel((t??d.width)*l,(o??d.height)*u);try{let f=Date.now();for(;Date.now()-f<Oe;){a?.throwIfAborted();let y=await j(e.evaluate(()=>document.body.scrollHeight),{milliseconds:ce}),[S,T,A]=await j(e.evaluate(()=>{let b=document.activeElement;if(!b)return[void 0,void 0,void 0];let C=b.getBoundingClientRect();return[b.scrollTop,C.x,C.y]}),{milliseconds:ce});if(y===p&&S===m&&T===h&&A===g)break;p=y,m=S,h=T,g=A,await ae(It)}}catch(f){c.warn({err:f},"Failed to wait for scroll to complete, continuing...")}}}async function vS(r,e){let t,n;for(let o=0;o<4;o++)try{return t=r.pages(),await Promise.all(t.map(async i=>{let a="";try{a=e?.getTitles?await i.title():""}catch{a="Unknown page"}return{title:a,url:i.url()}}))}catch(i){n=i,await ae(It)}throw new Error(`Failed to get tab titles after all retries: ${n?.message}`)}async function IM(r){let{page:e,deltaX:t,deltaY:n,steps:o,visualTarget:i,isAndroid:a,delayMs:s}=r;if(a){await FV(e,t,n,o,s,i);return}await e.mouse.move(i.x,i.y),await e.mouse.down(),await e.mouse.move(t+i.x,n+i.y,{steps:o}),await ae(s??ji),await e.mouse.up()}async function PM(r,e,t,n){await r.mouse.move(e.x,e.y,{steps:3}),await r.mouse.down(),await r.mouse.move(t.x,t.y,{steps:3}),await ae(n.hoverSeconds?Math.min(n.hoverSeconds*1e3,gp):500),await r.mouse.up()}async function FV(r,e,t,n,o,i){let a=Math.max(1,n??1),s=i.x,c=i.y,l=i.x+e,u=i.y+t;await r.evaluate(async({startX:d,startY:p,endX:m,endY:h,stepCount:g,delayMs:f})=>{let y=document.elementFromPoint(d,p)??document.body??document.documentElement,T=window._momenticMobileUtilities.dispatchTouch;T(y,"touchstart",d,p);for(let A=1;A<=g;A+=1){let b=d+(m-d)*A/g,C=p+(h-p)*A/g;T(y,"touchmove",b,C),await new Promise(x=>setTimeout(x,Math.floor((f??500)/g)))}T(y,"touchend",m,h)},{startX:s,startY:c,endX:l,endY:u,stepCount:a,delayMs:o})}import{randomUUID as $V}from"crypto";import{cloneDeep as wS}from"lodash-es";function Vo(r,e){let t=r.findIndex(n=>n===e);if(!(t===-1||!r[t+1]))return r[t+1]}import{createHash as UV}from"crypto";var BV="v1";function RS(r,e){if(r.tagName.toLowerCase()==="svg"&&!zV(r))try{let t=OM(r,e),n=HV(JSON.stringify(t));return{version:BV,json:t,hash:n}}catch{return}}function HV(r){return UV("md5").update(r).digest("hex")}function OM(r,e){let t=r.tagName.toLowerCase(),n=GV(r);if(t==="image"&&n["xlink:href"])throw new Error("Image tags within SVGs are not supported");let o={type:t,props:n,children:[]};for(let i of r.childrenBackendIds){let a=e.backendIdToNode[i];if(a&&a.nodeType===1){let s=OM(a,e);s&&o.children.push(s)}}return o}function zV(r){let e=r.computedStyles.display,t=r.computedStyles.visibility,n=r.computedStyles.opacity;return e==="none"||t==="hidden"||n==="0"}function GV(r){let e={},t=r.attributes;for(let n of Object.keys(t))jr.visualAttributesForSvgSerialization.includes(n)&&(e[n]=t[n]);return t.id&&r.tagName.toLowerCase()!=="svg"&&(e.id=t.id),e}var Wi={r:147,g:196,b:125,a:.55},NM={showRulers:!1,showStyles:!1,showExtensionLines:!1,contrastAlgorithm:"aa",contentColor:Wi,paddingColor:Wi,borderColor:Wi,marginColor:Wi,eventTargetColor:Wi,shapeColor:Wi,shapeMarginColor:Wi,showInfo:!0,showAccessibilityInfo:!0};function DM({snapshot:r,devicePixelRatio:e,computedStylesToFetch:t,logger:n}){let o=r.strings,i=r.documents,a={},s={},c={roots:[],backendIdToNode:a,frameIndexToIframeNode:s};return i.forEach((l,u)=>{let d=jV({allDocuments:i,stringConstants:o,computedStylesToFetch:t,devicePixelRatio:e,frameIndex:u,backendIdToNode:a,frameIndexToIframeNode:s,logger:n});c.roots.push(d)}),c}function jV({allDocuments:r,stringConstants:e,computedStylesToFetch:t,devicePixelRatio:n,frameIndex:o,frameIndexToIframeNode:i,backendIdToNode:a,logger:s}){let c=r[o],l=c.layout,u={};l.nodeIndex.forEach((x,M)=>{u[x]=M});let d=l.styles,p=l.bounds??[],m=c.nodes,h=m.contentDocumentIndex??{index:[],value:[]},g=m.backendNodeId??[],f=m.attributes??[],y=m.parentIndex??[],S=m.nodeName??[],T=m.nodeType??[],A=m.pseudoType??{index:[],value:[]},b=m.inputChecked??{index:[]},C=e[c.frameId];for(let x=0;x<g.length;x++){let M=g[x],P=T[x],U=f[x]??[],V=y[x]!==void 0&&y[x]>=0?y[x]:void 0,k=V!==void 0?g[V]:void 0,z=k!==void 0?a[k]:void 0,Q=A.index.indexOf(x),Y=Q!==-1?e[A.value[Q]]:void 0,Te=u[x],q;Te?q=p[Te]??[]:q=[];let it=S[x]!==void 0?e[S[x]]?.toLowerCase():void 0;if(!it){s.warn({backendNodeId:M,frameId:C,frameIndex:o,nodeBounds:q},"DOM node has no tag name");continue}let Ge={backendNodeId:M,psuedoType:Y,nodeType:P,frameIndex:o,parentFrameId:C,ownedFrameId:void 0,bounds:{x:q[0]??null,y:q[1]??null,width:q[2]??null,height:q[3]??null},computedStyles:{},attributes:{},parentBackendNodeId:k??null,tagName:it,parent:z??void 0,childrenBackendIds:[],momenticIgnored:void 0,mPathSelector:void 0};z&&z.childrenBackendIds.push(M);let Ye=h.index.indexOf(x);if(Ye!==-1){let Ie=h.value[Ye];i[Ie]=Ge;let oe=r[Ie]?.frameId;Ge.ownedFrameId=oe!==void 0?e[oe]:void 0}for(let Ie of Object.keys(Ge.bounds)){let oe=Ie;Ge.bounds[oe]!==null&&(Ge.bounds[oe]/=n)}let Nt=Te!==void 0?d[Te]??[]:[];for(let Ie=0;Ie<Nt.length&&!(Ie>=t.length);Ie++){let oe=Nt[Ie];if(oe===void 0||isNaN(oe))continue;let jt=e[oe];if(jt===void 0)continue;let Fn=t[Ie];Ge.computedStyles[Fn]=jt}for(let Ie=0;Ie<U.length;Ie+=2){let oe=U[Ie],jt=U[Ie+1];if(!oe||!jt)continue;let Fn=e[oe],Un=e[jt];!Fn||!Un||(Ge.attributes[Fn]=Un)}b.index.includes(x)&&(Ge.attributes.checked="true"),a[Ge.backendNodeId]=Ge}return a[g[0]]}function AS(r,e){if(r.mPathSelector)return r.mPathSelector;let t=r.parent,n;if(!t)n=r.tagName;else if(r.tagName==="body")n="body";else{let i=t.childrenBackendIds.filter(c=>e.backendIdToNode[c]?.nodeType===1&&!e.backendIdToNode[c]?.psuedoType).indexOf(r.backendNodeId),a=` > ${r.tagName}:nth-child(${i+1})`;n=`${AS(t,e)}${a}`}return r.mPathSelector=n,n}function LM(r,e){return r.parentBackendNodeId!==null?e.backendIdToNode[r.parentBackendNodeId]:r.frameIndex===0?void 0:e.frameIndexToIframeNode[r.frameIndex]}var VV=["html","#document","#document-fragment"];function kM({node:r,domGraph:e}){let t=[],n=r,o=LM(r,e);if(!o)return[r.tagName];let i=()=>{if(n=o,o=LM(o,e),!o&&n.frameIndex!==0)throw new Error("No parent node but not in main frame")},a=0;for(;o&&a<1e6;){if(a++,VV.includes(n.tagName)){i();continue}if(n.tagName==="body")t.push("body");else{let c=!1,l=1;for(let u=0;u<o.childrenBackendIds.length;u++){let d=o.childrenBackendIds[u],p=e.backendIdToNode[d];if(d===n.backendNodeId){t.push(`${n.tagName}:nth-child(${l})`),c=!0;break}else p?.nodeType===1&&!p.psuedoType&&l++}if(!c)throw new Error(`Could not find child (${n.tagName}) in parent's children list (${o.tagName})`)}i()}return t.reverse()}function FM(r,e){let t=r.locator("html"),n=[];for(let o=0;o<e.length;o++){let i=e[o];if(n.push(i),i.startsWith("iframe")){let a=n.join(" > ");n=[],o<e.length-1?t=t.frameLocator(a):t=t.locator(a)}}if(n.length&&(t=t.locator(n.join(" > "))),"owner"in t)throw new Error("Final locator from mpath is a frame locator");return t}async function UM(r,e){await r.send({method:"DOM.getDocument",params:{depth:0},timeout:Oe});let t=await r.send({method:"DOM.requestNode",params:{objectId:e},timeout:Oe}),o=(await r.send({method:"DOM.getAttributes",params:{nodeId:t.nodeId},timeout:Oe})).attributes,i=Vo(o,to);if(!i)throw new Error(`Could not find attribute ${to} for object ${e}`);return i}var WV=["focusable","keyshortcuts","controls","live","relevant","orientation"],qV=["selected","readonly","modal","required","invalid"],KV=["id","name","role","content"],BM=["absolute","fixed","sticky"],YV=["i","label"],XV=["path"],JV=["statictext","textbox","checkbox","combobox","iframe","rootwebarea","table","caption","columnheader","rowheader","gridcell","grid","row","rowgroup","cell","image","graphics-symbol","graphics-document","graphics-object","svgroot","button","link","list","listitem","tablist","tabpanel","tab","searchbox","menu","menubar","form","dialog","alertdialog","banner","navigation","main","menuitem","menuitemcheckbox","menuitemradio","option","radio","progressbar","switch","tree","treeitem","separator","LabelText"],GM=["ariaHiddenElement","ariaHiddenSubtree","hiddenByChildTree","inertElement","inertSubtree","notRendered","notVisible"],jM=["activeAriaModalDialog","activeFullscreenElement","activeModalDialog"],QV=["menulistpopup","statictext","inlinetextbox"],ZV=80,HM=100,VM=50,_S=["StaticText","ListMarker","RootWebArea","LineBreak","emphasis","::before","::after"],e$=["cite"],t$={LabelText:["label"],listitem:["li"],image:["img","svg"],link:["a"],RootWebArea:["#document"],paragraph:["p"],LineBreak:["br"],separator:["hr"],"graphics-symbol":["svg","rect"],gridcell:["td","th"],SvgRoot:["svg"],navigation:["nav"],cell:["td","th"],row:["tr"],list:["ul"],heading:["h1","h2","h3","h4","h5","h6"]},r$={name:!0,value:!0,title:!0,alt:!0,placeholder:!0,checked:!0,selected:!0,contenteditable:!0},zM={indentLevel:0},CS=class r{id;role;name;nameSources;tagName;content;properties;internalProperties;ignoredReasons;dataMomenticId;importantProperties;pathFromRoot;mPathSelector;parent;children;parentFrame;domNode;backendNodeId;ignoredByCDP;flagNotActionableNodes;constructor(e){if(this.id=e.id,this.role=e.role,this.name=e.name,this.nameSources=e.nameSources,this.content=e.content,this.properties={},this.pathFromRoot=e.pathFromRoot,this.children=e.children,this.backendNodeId=e.backendNodeID,this.ignoredByCDP=e.ignoredByCDP,this.internalProperties=e.internalProperties??{},this.parentFrame=e.parentFrame,this.ignoredReasons=e.ignoredReasons,this.importantProperties=e.importantProperties,this.flagNotActionableNodes=e.flagNotActionableNodes,e.properties&&e.properties.forEach(t=>{t.name==="keyshortcuts"?this.dataMomenticId=parseInt(t.value.value):this.properties[t.name]=t.value.value}),e.domNode){this.domNode=e.domNode,this.tagName=e.domNode.tagName||void 0;let t=e.domNode.attributes.id;this.name=this.name||e.domNode.attributes.name||(t&&t.length<VM?t:""),this.role=this.role||(e.domNode.attributes.role??""),a$(this.properties,e.domNode,e.importantProperties)}l$(this)}getSerializedFormWithContext(){return this.serialize({noId:!0,maxLevel:1,neighbors:1})}getNodeOnlySerializedForm(){return this.serialize({noId:!0,noChildren:!0,noContent:!0})}getLogForm(){return JSON.stringify({id:this.id,name:this.name??"",role:this.role??"",backendNodeId:this.backendNodeId})}isInteresting(e){if(this.domNode&&XV.includes(this.domNode.tagName)&&!this.domNode.attributes["aria-label"]||this.ignoredReasons.some(n=>jM.includes(n)))return!1;if(e){if(Object.keys(this.domNode?.attributes??{}).some(o=>YM(o,e)))return!0;let n=this.domNode?.attributes.class?.split(" ");if(n&&n.length>0&&n.some(o=>XM(o,e))||e.styles?.some(o=>{let i=o.split(":");if(i.length!==2)return!1;let a=i[0]?.trim(),s=i[1]?.trim();if(a===void 0||s===void 0)return!1;let c=this.domNode?.computedStyles[a];return c!==void 0&&(c===s||s==="*")}))return!0}if(this.domNode&&YV.includes(this.domNode.tagName)||JV.includes(this.role.toLowerCase())||this.domNode?.computedStyles["background-image"]&&this.domNode?.computedStyles["background-image"]!=="none"&&this.children.length===0||this.role.toLowerCase()==="inlinetextbox"&&this.tagName||!this.properties.hidden&&(this.properties.focusable||this.properties.settable)||jr.alwaysInterestingTruthyPropertyNames.some(n=>!!this.properties[n]))return!0;let t=this.properties.class;return typeof t=="string"&&t.split(" ").some(n=>KM(n))?!0:this.children.every(n=>n.role==="StaticText")&&this.internalProperties?.inCodeMirrorEditor?!1:this.children.some(n=>n.role==="StaticText")||this.children.length>1&&this.children.some(n=>n.tagName==="input")||this.children.some(n=>n.isIneligible())?!0:this.domNode&&(this.domNode.bounds.x===null||this.domNode.bounds.y===null||!this.domNode.bounds.width||!this.domNode.bounds.height)?!1:!!this.name.trim()||!!this.content||Object.keys(this.properties).some(n=>n.startsWith("data"))}shouldSerializeBounds(){let e=this.domNode?.computedStyles.position;return!!(e&&(e==="absolute"||e==="fixed"||e==="sticky"))}isIneligible(){return!!(this.domNode?.computedStyles.display==="contents"||this.domNode&&(this.domNode.bounds.x===null||this.domNode.bounds.y===null||!this.domNode.bounds.width||!this.domNode.bounds.height))}serialize(e=zM){let t=Object.assign({},zM,e),{indentLevel:n,noChildren:o,noProperties:i,noId:a,noContent:s,condensedMode:c}=t,l=wS(this.properties),u=" ".repeat(n),d=this.role||"",p=this.tagName??"unknown",m=this.name;d==="heading"&&m==="heading"&&(m=""),this.nameSources?.find(b=>!b.superseded&&b.type==="contents")&&this.children.length>0&&(m="");let g=this.nameSources?.find(b=>!b.superseded);if(g&&!g.nativeSource&&g.type==="relatedElement"){let b=g.attributeValue?.relatedNodes??[];b.length===1&&b[0].text&&b[0].text===m&&(m="")}let f=_S.includes(this.role)||e$.includes(this.tagName||"");if(this.role==="StaticText"||this.role==="ListMarker")return`${u}${m}
4347
4347
  `;let y=`${u}<${p}`;!a&&!f&&(y+=` id="${this.id}"`);let S=s??!1;if((l.multiline||l.contenteditable)&&this.children.length>0&&(S=!0),d&&d!=="generic"&&d!==p&&!(t$[d]??[]).includes(p)&&(y+=` role=${JSON.stringify(d)}`),m&&(y+=` name=${JSON.stringify(m)}`),this.content&&!S&&(y+=` content=${JSON.stringify(this.content)}`),this.flagNotActionableNodes&&this.tagName!=="#document"&&this.isIneligible()&&(y+=` ${jr.ineligibleElementAttribute}`),this.shouldSerializeBounds()&&this.domNode?.bounds){let b=this.domNode.bounds,C=Math.round(b.x??0),x=Math.round(b.y??0),M=Math.round((b.x??0)+(b.width??0)),P=Math.round((b.y??0)+(b.height??0));y+=` bounds=[${C} ${x} ${M} ${P}]`}let T=Date.now();if(Object.keys(l).length>0&&!i){if(Date.now()-T>1e3)throw new Error(`Serialization for the HTML element with tag ${p} and internal ID ${this.id} took too long. Please ensure your machine has enough resources to run Momentic.`);Object.entries(l).forEach(([b,C])=>{if(!WV.includes(b)){{if(qV.includes(b)&&(!C||C==="false"))return;if(b==="value"&&S&&(l.type==="text"||this.role==="textbox"))return;if(b==="level"&&`${C}`=="1")return;if(b==="url"&&l.src&&p==="img")return;if(b==="url"&&l.href&&p==="a")return;if(b==="editable"&&C==="plaintext")return;if(b==="type"&&C===p)return;if(c&&!r$[b])return}typeof C=="string"?y+=` ${b}="${mt(C,HM,!0)}"`:typeof C=="boolean"?C?y+=` ${b}`:y+=` ${b}={false}`:typeof C<"u"&&(y+=` ${b}={${mt(JSON.stringify(C),HM,!0)}}`)}})}if(p==="::before"||p==="::after"){let b="";for(let C of this.children)b+=C.serialize({...e,indentLevel:n,neighbors:0});return b}let A=e.maxLevel!==void 0&&n/2>=e.maxLevel;if(this.children.length===0||o||A)y+=` />
4348
4348
  `;else{let b="";for(let x of this.children)b+=x.serialize({...e,indentLevel:n+2,neighbors:0});let C=b.trim();C.length<=ZV&&!C.includes(`
4349
4349
  `)?y+=`>${C}</${p}>
@@ -4360,7 +4360,7 @@ Available pages:${JSON.stringify(n.map(i=>i.url))}`);if(!_i(o.url,this.logger)){
4360
4360
  `),tokenLength:d}),u=[],d=0,p=m.length?[m[m.length-1].id]:[],h=!1);let g=c[l],f=Pe(g);d+=f,g.length>a&&(g=g.slice(0,a));let T=Array.from(g.matchAll(mI)).map(Q=>Q&&Q.length>=3?{tagName:Q[1],id:Q[2]}:void 0).filter(Q=>!!Q),b=Array.from(g.matchAll(I$)).map(Q=>Q&&(Q[2]||Q[4])).filter(Q=>!!Q);b.reverse();let C=g.replace(/ id="[0-9]+"/g,"");u.push(C);for(let Q of T)p.push(Q.id),m.push(Q);for(let Q of b){let Y=m[m.length-1];Y&&Y.tagName===Q&&m.pop()}let x=m.some(Q=>O$.includes(Q.tagName)),M=c[l+1]??"",P=Pe(M),V=Array.from(M.matchAll(mI)).map(Q=>Q&&Q.length>2?Q[1]:void 0).filter(Q=>!!Q),k=V.some(Q=>fI.includes(Q)),z=V.some(Q=>P$.includes(Q));d+P>=i&&(h=!0),d>=n&&(k&&!x||b.some(Q=>L$.includes(Q)))&&(h=!0),d>=o&&z&&!x&&(h=!0),l++}return u.length&&s.push({ids:p,content:u.join(`
4361
4361
  `),tokenLength:d}),s.forEach((g,f)=>{let y=g.ids[0],S=g.ids[g.ids.length-1];r.debug({tokenLength:g.tokenLength,minId:y,maxId:S},`Chunk for page filtering (index ${f+1}/${s.length})`)}),{chunks:s}}var k$=75e4,_p=3e5;async function qi(r){let{options:e,fixtures:t,screenshot:n}=r,{aiPageFiltering:o}=e,{logger:i,generator:a,orgId:s,signal:c}=t,l=r.tree,u=r.serializedTree,d=Pe(u);if(d>k$)try{let p=xp({serializedTree:u,options:{minChunkTokenCount:1e4,maxChunkTokenCount:1e5,acceptableChunkTokenCount:5e4,maxLineLength:4e3},logger:i});l=await U$({...r,tokenLimit:_p-1e4,chunks:p.chunks}),u=l.serialize();let m=Pe(u);i.info({oldTokens:d,newTokens:m},"Filtered page using keywords"),d=m}catch(p){i.warn({err:p},"Error filtering page using keyword matching, using naive truncation"),l=l.pruneToSerializedCharLimit(_p*wo),u=l.serialize();let m=Pe(u);i.info({oldTokens:d,newTokens:m},"Filtered page using naive truncation"),d=m}if(d>_p)try{if(o){let p=xp({serializedTree:u,options:gI,logger:i}),m=D$();l=await j(F$({...r,chunks:p.chunks,callId:m}),{milliseconds:12e3,signal:c}),u=l.serialize();let h=Pe(u);i.info({oldTokens:d,newTokens:h,langfuseCallId:m},"Filtered page using AI chunk ranking"),d=h}else{let p=xp({serializedTree:u,options:hI,logger:i});l=await j(B$({...r,chunkResult:p,tokenLimit:4e4}),{milliseconds:12e3,signal:c}),u=l.serialize();let m=Pe(u);i.info({oldTokens:d,newTokens:m},"Filtered page using RAG"),d=m}}catch(p){i.warn({err:p},"Error filtering page using RAG/AI, using naive truncation"),l=l.pruneToSerializedCharLimit(_p*wo),u=l.serialize(),i.info("Filtered page using naive truncation")}return u}async function F$({type:r,callId:e,chunks:t,description:n,fixtures:o,tree:i}){let{generator:a,signal:s,logger:c}=o,l=await a.rankChunksWithAi({chunks:t,description:n,type:r,softTokenLimit:4e4,hardTokenLimit:8e4,callId:e},{abortSignal:s,logger:c,loggerTags:He(c)}),u=[];return t.forEach((p,m)=>{l.indices.includes(m)&&(u=u.concat(p.ids))}),i.pruneUsingRelevantIds(new Set(u))}async function U$(r){let{description:e,fixtures:t,tree:n}=r,{generator:o,logger:i,signal:a}=t;if(!e.trim())throw new Error("Empty description passed to page filtering");let s=await o.getExtractedKeywords({goal:e},{logger:i,loggerTags:He(i),abortSignal:a});i.info({keywordsResult:s},"Got keywords for page filtering");for(let c of s.keywords){let l=r.chunks.filter(m=>m.content.toLowerCase().includes(c.toLowerCase()));if(!l.length||l.reduce((m,h)=>m+h.tokenLength,0)>r.tokenLimit&&l.length>1)continue;let d=l.flatMap(m=>m.ids);return n.pruneUsingRelevantIds(new Set(d))}throw new Error("No keywords were unique enough for page filtering")}async function B$(r){let{description:e,fixtures:t,chunkResult:n,tokenLimit:o,tree:i}=r,{generator:a,logger:s,signal:c}=t,l=await a.rankChunksWithRag({description:e,chunks:n.chunks,tokenLimit:o},{abortSignal:c,logger:s,loggerTags:He(s)});if(l.ids.length===0)throw new Error("RAG returned no important ids");return i.pruneUsingRelevantIds(new Set(l.ids.map(d=>`${d}`)))}async function kS(r,e){if(!r.description)throw new _("UserConfigurationError","Cannot locate element with empty description");return Gr({action:async()=>H$(r,e),frameConfig:r.iframeUrl?{type:"url",url:r.iframeUrl}:void 0,browser:e.browser,logger:r.logger})}async function H$(r,e){let{disableCache:t,testContext:n,filterByViewport:o,skipWait:i,source:a,memory:s,aiPageFiltering:c,logger:l,allowNotActionableNodesOverride:u}=r,{ctx:d,orgId:p,browser:m,localCodeEvalTools:h,generator:g,abortSignal:f}=e,y=r.description,S=r.useMemory&&!t;n&&(y=await sr({orgId:p,s:y,context:n,localTools:h,signal:f,logger:l})),a&&(y=G$(y,a));let{serializedTree:T,tree:A}=await In(m,{allowNotActionableNodesOverride:u,filterByViewport:o,abortSignal:f,skipWait:i,logger:l}),b,C=Date.now(),x;for(;!b&&Date.now()-C<3e3;){f.throwIfAborted();try{b=await m.screenshot({clearHighlights:!0,respectActiveFrame:!0,retries:2})}catch(q){x=q}}if(!b)throw new _("ActionFailureError",`Failed to take screenshot of page to locate element. The page may be unresponsive, or your machine might be severely resource constrained. Error: ${x?.message}`);let M=T,P=!1,V=`data:image/jpeg;base64,${b.toString("base64")}`;M=await qi({type:"locator",description:y,screenshot:V,serializedTree:T,options:{aiPageFiltering:c},tree:A,fixtures:{generator:g,signal:f,logger:l,orgId:p}}),M!==T&&(P=!0);let k=await g.getElementLocation({browserState:M,goal:y,screenshot:V,source:a,memory:S?s:void 0},{disableCache:t,abortSignal:f,loggerTags:He(l),useMemory:S});l.debug({usedRag:P,result:k},"Got locator result");let z=k.id>0;if(d?.details?.push({type:"AI_LOCATION",matched:z,pageState:M,ragUsed:P,thoughts:k.thoughts}),!z)throw new pa(`Could not find any relevant element: ${k.thoughts}`,k.updatedMemory?{type:"GCS_TRACES",traces:k.updatedMemory}:void 0);let{resolution:Q,target:Y,frameConfig:Te}=await m.createTargetFromA11yId({id:k.id,requirements:k.requirements,additionalElements:k.additionalElements,description:y,targetSource:"AI",logger:l});if(Q.a11yNode?.properties?.hidden&&Q.a11yNode?.properties?.hidden!=="false")throw new _("ActionFailureError",`Momentic's AI found a relevant element to interact with, but it is explicitly marked with an 'aria-hidden' attribute. Please remove this attribute or adjust the element description to locate a different element. Element chosen: ${Q.displayString}`);return S&&(k.updatedMemory?Y.memory={type:"GCS_TRACES",traces:k.updatedMemory}:s&&(Y.memory=s)),{thoughts:k.thoughts,target:Y,resolution:Q,frameConfig:Te,screenshot:V}}var z$=["Element exactly matching the description below. Interpret the description narrowly and do not assume there are any typos or errors. Err on the side of returning -1 unless there is a perfect match. Description:","Element closely matching the description below. Interpret the description narrowly and do not return elements that are merely loosely related. Description:","Element matching the description below. This element is being located as part of a negative check step (i.e. we are trying to verify the element does not exist). Therefore, interpret the description narrowly, do not assume there are typos, and err on the side of returning -1 unless there is a perfect match. Description:"],SI="<select> element:",yI="text input or contenteditable element:",EI="Element matching the description below. It is possible the element is hidden or doesn't exist. Interpret the description narrowly and do not assume there are typos. Return -1 unless there is an straightforward match. Description:",bI="Element matching the description below. This element is being located as part of a check step (i.e. we are trying to verify certain properties about the element). Interpret the description narrowly and do not return elements that are merely loosely related. Description:",DS=[SI,yI,EI,bI,...z$];function TI(r,e){if(r===e)return!0;for(let t of DS){if(!r.startsWith(t))continue;let n=r.slice(t.length).trim();if(DS.some(o=>e.startsWith(o)&&e.slice(o.length).trim()===n)||n===e.trim())return!0}return!!DS.some(t=>e.startsWith(t)&&e.slice(t.length).trim()===r.trim())}function G$(r,e){if(!r||!e)return r;switch(e){case"SELECT_OPTION":return`${SI} ${r}`;case"TYPE":return`${yI} ${r}`;case"NEGATED_ELEMENT_VISIBLE_CHECK":return`${EI}
4362
4362
  ${r}`;case"ELEMENT_CHECK":return`${bI}
4363
- ${r}`;default:return r}}var j$=15;async function Mp({command:r,aiPageFiltering:e,logger:t,fixtures:n,source:o,useMemory:i,maxRetries:a=j$}){if(!r.assertion.trim())throw new _("ActionFailureError","Assertion command is missing the assertion content");let{browser:s}=n,c=r.timeout?r.timeout*1e3:s.smartWaitingTimeout,l=EA(c),u=0,d=Date.now(),p,m,h;try{await Gr({action:()=>s.clearHighlights(),frameConfig:r.iframeUrl?{type:"url",url:r.iframeUrl}:void 0,browser:s,logger:t})}catch(f){t.warn({err:f},"Failed to clear highlights before AI check, continuing...")}let g;for(;u<a&&(!g||g-d<c);){n.abortSignal.throwIfAborted(),u!==0&&await ae(l,n.abortSignal),g=Date.now();let f=!1;try{if(p=await Gr({action:async()=>{let S=await vI(s,t,n.abortSignal);return m&&m.serializedTree===S.serializedTree&&m.screenshotBuff.equals(S.screenshotBuff)?(f=!0,p):(m=S,RI({command:r,state:S,fixtures:n,useMemory:i,useConsensus:!1,highlightElementsOnFailure:!1,attemptNumber:u,aiPageFiltering:e,logger:t,source:o}))},frameConfig:r.iframeUrl?{type:"url",url:r.iframeUrl}:void 0,logger:t,browser:s}),p?.success){p?.updatedMemory&&yl(r,p.updatedMemory,t);break}else throw p?.thoughts?new _("AssertionFailureError",p.thoughts):new _("InternalPlatformError","No thoughts were provided for AI assertion failure")}catch(y){n.abortSignal.throwIfAborted(),h=y instanceof Error?y:new Error(`${y}`),f?t.info(`AI check attempt ${u} failed (re-used previous result)`):t.info({err:y},`AI check assert attempt ${u} failed, retrying...`)}finally{u++}}if(!p?.success)try{p=await Gr({action:async()=>RI({command:r,state:await vI(s,t,n.abortSignal),fixtures:n,useMemory:i,useConsensus:!0,highlightElementsOnFailure:!0,attemptNumber:u,aiPageFiltering:e,logger:t}),frameConfig:r.iframeUrl?{type:"url",url:r.iframeUrl}:void 0,logger:t,browser:s})}catch(f){n.abortSignal.throwIfAborted(),h=f instanceof Error?f:new Error(`${f}`)}finally{u++}if(p?.updatedMemory&&yl(r,p.updatedMemory,t),!p?.success){let f=`AI check still failing after ${u} attempts.`;throw h&&(f+=` Latest result: ${h.message}`),new _("AssertionFailureError",f)}return{...p,succeedImmediately:!1,urlAfterCommand:s.url()}}async function vI(r,e,t){let[n,o]=await Promise.all([In(r,{abortSignal:t,skipWait:!0,skipWaitForPageLoad:!0,logger:e}),r.screenshot({retries:1,respectActiveFrame:!0})]);return{...n,screenshotBuff:o}}async function RI({command:r,state:e,fixtures:t,useConsensus:n,useMemory:o,highlightElementsOnFailure:i,aiPageFiltering:a,attemptNumber:s,source:c,logger:l}){let{browser:u,generator:d,abortSignal:p}=t,m={type:"ASSERTION"},{serializedTree:h,tree:g}=e,f=e.screenshotBuff,y=f.toString("base64"),S=u.url(),T=r.contextChoice??"MULTIMODAL",A=h;T!=="VISION_ONLY"&&(A=await qi({type:"assertion",serializedTree:h,tree:g,description:r.assertion,screenshot:y,options:{aiPageFiltering:a},fixtures:{generator:d,signal:p,logger:l,orgId:t.orgId}}),A!==h&&(m.ragUsed=!0),m.pageState=A);let b={goal:r.assertion,url:S,memory:o?r.cache?.memory:void 0,browserState:A,screenshot:y,contextChoice:T,source:c},x=await(T==="VISION_ONLY"?(M,P)=>d.getVisualAssertionResult(M,P):(M,P)=>d.getAssertionResult(M,P))(b,{useConsensus:n,attemptNumber:s,useMemory:o,disableCache:!!r.disableCache,abortSignal:p,logger:l,loggerTags:He(l)});return(x.result||i)&&x.relevantElements&&(m.relevantElementsSerialized=x.relevantElements.map(M=>u.getSerializedFormFromA11yId(M)).filter(M=>!!M),await V$(x.relevantElements,u,l)),{success:x.result,thoughts:x.thoughts,afterScreenshotOverride:f,updatedMemory:o?x.updatedMemory:void 0}}async function V$(r,e,t){let n=Date.now();for(let o of r){if(Date.now()-n>2e3){t.debug("Highlighting relevant elements took over 2s, aborting...");return}try{let i=new AbortController;await j(e.highlightA11yId(o),{milliseconds:1e3,fallback:()=>{throw i.abort(),new Error("Timed out waiting for highlighting to complete")}})}catch(i){t.debug({err:i},"Failed to highlight relevant element after assertion, continuing...");return}}}var $$=75e4,Ip=class extends Error{constructor(){super("The page content exceeds the maximum token limit for AI smart waiting."),this.name="ExceededMaxAISmartWaitingTokensError"}};async function AI(r,e){let{logger:t}=r,{abortSignal:n,browser:o}=e,i=Date.now();try{await W$(i,r,e)}catch(a){if(a instanceof Error&&(a.name==="AbortError"||a.name==="TimeoutError")||n.aborted)return;a instanceof Ip?t.warn("Skipping AI smart waiting due to excessive page size - falling back to naive waiting"):t.warn({err:a},"Unexpected error occurred during AI smart waiting");let s=o.smartWaitingTimeout-(Date.now()-i);s>0&&await ae(s,n)}finally{t.debug({durationMs:Date.now()-i},"AI smart waiting complete")}}async function W$(r,e,t){let{abortSignal:n,browser:o}=t;if(o.smartWaitingTimeout<3e3){await ae(o.smartWaitingTimeout,n);return}if(!e.description)throw new _("UserConfigurationError","Cannot locate element with empty description");await j(q$(r,e,t),{milliseconds:o.smartWaitingTimeout})}async function q$(r,e,t){let{logger:n,iframeUrl:o}=e,{browser:i}=t;for(;Date.now()-r<i.smartWaitingTimeout;)if(await Gr({action:async()=>K$(e,t),frameConfig:o?{type:"url",url:o}:void 0,browser:i,logger:n}))return}async function K$(r,e){let{testContext:t,logger:n,filterByViewport:o,allowNotActionableNodesOverride:i}=r,{browser:a,abortSignal:s,localCodeEvalTools:c,orgId:l,generator:u}=e,d=r.description;t&&(d=await sr({orgId:l,s:d,context:t,localTools:c,signal:s,logger:n}));let{serializedTree:p}=await In(a,{allowNotActionableNodesOverride:i,filterByViewport:o,abortSignal:s,logger:n});if(Pe(p)>$$)throw new Ip;s.throwIfAborted();let h;try{h=await a.screenshot({clearHighlights:!0,respectActiveFrame:!0,retries:2})}catch(S){throw new _("ActionFailureError",`Failed to take screenshot of page to perform smart waiting. The page may be unresponsive, or your machine might be severely resource constrained. Error: ${S instanceof Error?S.message:S}`)}let f=`data:image/jpeg;base64,${h.toString("base64")}`;s.throwIfAborted();let y=await u.getSmartWaitingDecision({browserState:p,description:d,screenshot:f},{abortSignal:s,loggerTags:He(n)});return n.debug({result:y},"Got smart waiting result"),y.isPageReady}var Y$=3e4;async function wI({command:r,logger:e,baseUrl:t,fetchImplementation:n=fetch}){let o=r.timeout??Y$/1e3,i=new AbortController,a=Object.fromEntries(Object.entries(r.headers||{}).filter(([d,p])=>d&&p));a["Content-Type"]="application/json";let s;if(Ba(r.url)&&(s=r.url),t&&Ha(r.url,t)&&(s=new URL(r.url,t).toString()),!s)throw new _("ActionFailureError",`Invalid URL: ${r.url}`);let l=await j((async()=>{try{return await n(s,{headers:a,method:"POST",body:JSON.stringify({query:r.query,variables:r.variables?JSON.parse(r.variables):void 0}),signal:i.signal})}catch(d){e.error({err:d},"Failed to make HTTP request")}})(),{milliseconds:o*1e3});if(!l)throw new _("ActionFailureError",`GraphQL request timed out after ${o} seconds`);if(!l.ok){let d,p=await l.text();try{d=JSON.parse(p)}catch{throw new _("ActionFailureError",`GraphQL request failed with status ${l.status}: ${p}`)}throw d?.errors?.length&&d?.errors[0]?.message?new _("ActionFailureError",`GraphQL request failed with status ${l.status}: ${d.errors[0].message}`):new _("ActionFailureError",`GraphQL request failed with status ${l.status}: ${p}`)}let u={};return l.headers.forEach((d,p)=>{u[p]=d}),{status:l.status,headers:u,json:await l.json()}}var $o=class{orgId;options;storage;localCodeEvalTools;uploadedFileStorage;visualDiffScreenshotStorage;browser;generator;executeAbortController=new AbortController;logger;recordAbortController=null;registeredListeners={};recordedRequests={};constructor({browser:e,generator:t,logger:n,storage:o,orgId:i,localCodeEvalTools:a,uploadedFileStorage:s,visualDiffScreenshotStorage:c,options:l}){this.orgId=i,this.options=l,this.browser=e,this.browser.registerAbortSignal(this.executeAbortController.signal),this.storage=o,this.uploadedFileStorage=s,this.visualDiffScreenshotStorage=c,this.localCodeEvalTools=a,this.generator=t,this.logger=n}setOpen(){this.executeAbortController=new AbortController,this.browser.registerAbortSignal(this.executeAbortController.signal)}setClosed(){this.executeAbortController.abort()}throwIfClosed(){this.executeAbortController.signal.throwIfAborted()}get closed(){return this.executeAbortController.signal.aborted}async evaluateAiAction({goal:e,startingScreenshot:t,history:n,disableCache:o,langfuseSessionId:i,lastError:a,logger:s=this.logger}){let[c,l]=await Promise.all([In(this.browser,{abortSignal:this.executeAbortController.signal,skipWait:!0,skipWaitForPageLoad:!0,logger:s}),this.browser.screenshot({retries:1,clearHighlights:!0})]),u=`data:image/jpeg;base64,${l.toString("base64")}`,d=await qi({type:"ai-action",description:e,screenshot:u,serializedTree:c.serializedTree,tree:c.tree,options:{aiPageFiltering:!!this.options?.aiPageFiltering},fixtures:{generator:this.generator,signal:this.executeAbortController.signal,logger:s,orgId:this.orgId}}),p={url:this.browser.url(),browserState:d,startingScreenshot:t,history:n,goal:e,screenshot:u,lastError:a};return await this.generator.getMultiturnAiActionEvaluation(p,{disableCache:o,abortSignal:this.executeAbortController.signal,loggerTags:{...He(s)},langfuseSessionId:i})}async promptToCommand({goal:e,startingScreenshot:t,history:n,actionHint:o,disableCache:i,logger:a=this.logger,langfuseSessionId:s}){let c=this.browser.url(),[l,u]=await Promise.all([In(this.browser,{abortSignal:this.executeAbortController.signal,skipWait:!0,skipWaitForPageLoad:!0,logger:a}),this.browser.screenshot({retries:1,clearHighlights:!0})]),d=`data:image/jpeg;base64,${u.toString("base64")}`,p=await qi({type:"ai-action",description:e,screenshot:d,serializedTree:l.serializedTree,tree:l.tree,options:{aiPageFiltering:!!this.options?.aiPageFiltering},fixtures:{generator:this.generator,signal:this.executeAbortController.signal,logger:a,orgId:this.orgId}}),m={url:c,browserState:p,startingScreenshot:t,history:n,goal:e,actionHint:o,screenshot:d};try{return await this.generator.getMultiturnAiActionCommand(m,{disableCache:i,abortSignal:this.executeAbortController.signal,loggerTags:{...He(a)},langfuseSessionId:s})}catch(h){throw new _("InternalWebAgentError",`Error generating command: ${h instanceof Error?h.message:h}`,{errOptions:{cause:h}})}}async getBrowserState(e){return In(this.browser,e)}async locateElement(e){return await kS({...e,aiPageFiltering:!!this.options?.aiPageFiltering},this.getControllerFixtures())}async locateElementWithSelector(e,t){return Gr({action:async()=>{let n=await this.browser.resolveHardcodedCssSelector({ctx:null,selector:e,timeoutMs:2e3,logger:this.logger});return{thoughts:"Located element with selector",target:{id:-1,selector:e,targetSource:"USER_CSS_SELECTOR",targetUpdateTime:new Date().toUTCString()},resolution:n}},frameConfig:t?{type:"url",url:t}:void 0,browser:this.browser,logger:this.logger})}getControllerFixtures(e){return{ctx:e??null,browser:this.browser,generator:this.generator,logger:this.logger,orgId:this.orgId,storage:this.storage,localCodeEvalTools:this.localCodeEvalTools,abortSignal:this.executeAbortController.signal}}shouldUseMemory(){return this.options?.useMemory??(this.orgId==="org_01HMSCJQBCCG51M2ZF65YC5B8W"||this.orgId==="org_01HMJTX4GT1KG94KZRCT8MZ6YB")}async wrapMultiElementTargetingCommand({ctx:e,tracer:t,command:n,targetNames:o,descriptions:i,caches:a,action:s,options:c,retriesWithAI:l=1}){let u=[];for(let d=0;d<i.length;d++){let p=i[d],m=await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:p,cache:a[d],action:async h=>h,options:{...c,targetName:o[d]}});u.push(m)}try{let d=await s(...u.map(h=>h.result)),p=h=>h==="fromTarget"?"From Target":h==="toTarget"?"To Target":"Target",m=u.map((h,g)=>h.thoughts?`${p(o[g])}: ${h.thoughts}`:void 0).filter(h=>!!h).join(" -------------- ")||void 0;return{result:d,elementInteractedDisplayStrings:u.map(h=>h.elementInteractedDisplayString),thoughts:m}}catch(d){if(this.throwIfClosed(),l>0)return this.logger.warn({err:d},"Failed to execute action with multiple cached targets, retrying with AI"),this.wrapMultiElementTargetingCommand({ctx:e,tracer:t,command:n,targetNames:o,descriptions:i,caches:i.map(()=>{}),action:s,options:c,retriesWithAI:l-1});throw new _("ActionFailureError",d.message,{errOptions:{cause:d}})}}async wrapElementTargetingCommand(e){let t=this.logger.child({commandId:e.command.id}),n;for(let o=0;o<2;o++)try{return await Gr({action:()=>this.wrapElementTargetingCommandHelper({...e,originalCache:e.originalCache??e.cache}),frameConfig:e.options.iframeUrl?{type:"url",url:e.options.iframeUrl}:void 0,browser:this.browser,logger:t})}catch(i){if(n=i,this.browser.userBrowserSettings.visualActions&&Pm(i)){t.warn({err:i},"Invalid mpath error, retrying element targeting command");continue}if(!this.browser.userBrowserSettings.visualActions&&(Nm(i)||Om(i))){t.warn({err:i},"Invalid momentic id error, retrying element targeting command");continue}if(Dm(i)){t.warn({err:i},"Invalid backend node id error, retrying element targeting command");continue}if(i instanceof fn&&i.retryableWithAI){t.warn({err:i},"Element cache disqualification error, retrying element targeting command");continue}throw i}throw n instanceof _?n:new _("ActionFailureError",n?.message??"An unknown error occurred during element targeting")}async wrapHardcodedCssTargetingCommandHelper({ctx:e,target:t,action:n,options:o,command:i}){let a=this.logger.child({commandId:i.id}),{targetName:s}=o;if(t.type!=="description")throw new _("ActionFailureError","Cannot use selector with non-description target");let c,l=Date.now(),u=Date.now();for(;Date.now()-u<this.browser.smartWaitingTimeout;){l=Date.now();try{let d=await this.browser.resolveHardcodedCssSelector({ctx:e,selector:t.elementDescriptor,targetName:s,logger:a});return{result:await n({locator:d.locator}),elementInteractedDisplayString:d.displayString}}catch(d){if(d.name==="AbortError")throw d;c=d,a.warn({err:d},"Failed to action on hardcoded css selector"),Date.now()-l<500&&await ae(500)}}throw c}async wrapElementTargetingCommandHelper(e){let{ctx:t,tracer:n,target:o,originalCache:i,action:a,options:s,command:c}=e,{disableCache:l,useSelector:u,targetName:d,targetHealingInProgress:p,source:m}=s,h=this.logger.child({commandId:c.id}),g=this.shouldUseMemory(),f=s.retriesWithAI??1,y=!1,S=CI(e.cache);if((!S||l)&&!fm(o))throw new _("ActionFailureError","Cannot target element with no cached data or element descriptor");if(u)return this.wrapHardcodedCssTargetingCommandHelper(e);l&&(h.info("Cache explicitly disabled for this step"),y=!0,S=void 0),S&&this.browser.userBrowserSettings.disableSecondaryCacheResolution&&S.targetSource==="HEURISTIC_HEALED"&&(y=!0,S=void 0),S?.inputDescription&&!TI(o.elementDescriptor,S.inputDescription)&&(h.warn({old:S.inputDescription,new:o.elementDescriptor},"Target cache was generated with a different description, clearing it automatically"),y=!0,S=void 0);let T=b=>!!b&&Ac(b),A=!0;if(!T(S)){A=!1,h.info({description:o.elementDescriptor,targetHealingInProgress:p,cacheBustedBeforeAction:y,memory:s.memory,useMemory:g},"Prompting AI for an updated element location"),(y||!i)&&await AI({description:o.elementDescriptor,iframeUrl:s.iframeUrl,source:m,logger:h,allowNotActionableNodesOverride:s.allowNotActionableNodesOverride},this.getControllerFixtures(t)),f--;let b;try{b=await kS({description:o.elementDescriptor,disableCache:!!s.disableCache,iframeUrl:s.iframeUrl,source:m,useMemory:g,memory:g?s.memory:void 0,aiPageFiltering:!!this.options?.aiPageFiltering,allowNotActionableNodesOverride:s.allowNotActionableNodesOverride,logger:h},this.getControllerFixtures(t))}catch(M){if(M instanceof pa&&M.updatedLocatorMemory){let P={id:-1,...i,memory:M.updatedLocatorMemory};zu({cmd:c,key:d,newTarget:P,logger:h,updatedWithAI:!0})}throw new _("ActionFailureError",M.message)}b.frameConfig&&this.browser.setActiveFrameConfig(b.frameConfig);let C=s.disableGlobalLocatorRedirect?{locator:b.resolution.locator}:await this.attemptLocatorRedirect(b.resolution.locator,h),x=await a(C);return zu({cmd:c,key:d,newTarget:b.target,logger:h,updatedWithAI:!0}),p&&(n.recordTargetAutoHeal({healType:"AI"}),b.target.targetSource="AI_HEALED",b.target.targetUpdateTime=new Date().toUTCString(),b.target.targetUpdateLoggerTags=He(h)),{result:x,elementInteractedDisplayString:b.resolution.displayString,thoughts:b.thoughts}}try{let b=await this.browser.resolveTarget(t,S,{allowNotActionableNodesOverride:s.allowNotActionableNodesOverride,targetName:d,logger:h,signal:this.executeAbortController.signal});(this.browser.userBrowserSettings.visualActions||this.browser.userBrowserSettings.globalLocatorRedirect!==!1)&&await this.browser.scrollIntoViewIfNeeded(b.locator);let C=s.disableGlobalLocatorRedirect?{locator:b.locator}:await this.attemptLocatorRedirect(b.locator,h),x=await a(C);if(Lt.increment("cache_target_resolution_v2",1,["outcome:hit","platform:web",`hasRequirements:${!!S.requirements}`,`hasAdditionalElements:${!!S.additionalElements}`,`orgId:${this.orgId}`,"cliVersion:2.27.2"]),zu({cmd:c,key:d,newTarget:S,logger:h,updatedWithAI:!1}),A){let M=b.decisions.filter(P=>P.matched);if(M.length!==1)h.warn({decisions:b.decisions},"Expected exactly 1 matching method for element location, got more or less");else{let P=M[0].type;n.recordTargetAutoHeal({healType:P})}}return{result:x,elementInteractedDisplayString:b.displayString}}catch(b){this.throwIfClosed();let C="unknown";b instanceof _r&&b.cacheMissReason&&(C=b.cacheMissReason),Lt.increment("cache_target_resolution_v2",1,["outcome:miss","platform:web",`hasRequirements:${!!S.requirements}`,`hasAdditionalElements:${!!S.additionalElements}`,`orgId:${this.orgId}`,"cliVersion:2.27.2",`missReason:${C}`]);let x=!1;if((b instanceof fn||Pm(b)||Nm(b)||Dm(b)||zE(b)||Om(b)||GE(b))&&(x=!0),b instanceof _&&!x)throw h.error({err:b},"Failed to execute action with cached target (fatal)"),b;if(f>0&&o){h.info({err:b},"Failed to execute action with cached target, retrying with AI");let M;return S.memory&&wc(S.memory)&&(M=S.memory),this.wrapElementTargetingCommand({ctx:t,tracer:n,command:c,target:o,cache:void 0,originalCache:i,action:a,options:{...s,memory:M,retriesWithAI:f,targetHealingInProgress:!0}})}throw new _("ActionFailureError",b.message,{errOptions:{cause:b}})}}async attemptLocatorRedirect(e,t){return this.browser.userBrowserSettings.globalLocatorRedirect!==!1?this.browser.performTargetRedirection(e,t):{locator:e}}async screenshotWithDimensions(e){return Il(this.browser,e)}async executePresetCommand(e,t,n,o,i){this.options?.slowMoMs&&await ae(this.options.slowMoMs);let a=await this.browser.getOpenPages(),s=this.browser.url(),c;try{c=await this.resolveCommandTemplateStrings(n,o)}catch(l){throw this.throwIfClosed(),new _("ActionFailureError",`Failed to substitute template strings in command: ${l.message}`,{errOptions:{cause:l}})}try{let l=await this.executePresetCommandHelper(e,t,n,o,i);return this.browser.userBrowserSettings.visualActions&&nE(n)?await this.browser.waitForDOMStability({timeout:Oe}):!this.browser.userBrowserSettings.visualActions&&["PRESS","TYPE"].includes(n.type)&&await this.browser.waitForDOMStability({timeout:ce}),this.options?.autoFollowNewTabs&&await F_({beforeUrl:s,command:n,beforePages:a.map(u=>u.url),browser:this.browser,logger:this.logger}),l}catch(l){throw l.name!=="AbortError"&&this.logger.error({err:l},"Error thrown in action controller"),l}finally{aw(n,c)}}createCallbacksForBrowser(e){return{createIsolatedFolder:()=>sS(e)}}async resolveCommandTemplateStrings(e,t){return pd({obj:e,context:t,bannedKeys:["type","a11yData","thoughts","cache","code"],orgId:this.orgId,logger:this.logger,signal:this.executeAbortController.signal,localTools:this.localCodeEvalTools})}async executePresetCommandHelper(e,t,n,o,i){i=i||"disableCache"in n&&!!n.disableCache;let a=this.logger.child({commandId:n.id});switch(n.type){case"SUCCESS":let s=n.condition;return s?.assertion.trim()?Mp({command:s,fixtures:this.getControllerFixtures(e),useMemory:this.shouldUseMemory(),aiPageFiltering:!!this.options?.aiPageFiltering,logger:a}):{succeedImmediately:!1,urlAfterCommand:this.browser.url()};case"AI_ASSERTION":{if(!n.assertion.trim())throw new _("ActionFailureError","Missing assertion");if(n.timeout&&n.timeout>1800)throw new _("AssertionFailureError",`AI check timeout of ${n.timeout} exceeds the maximum allowed value of 30 minutes.`);return Mp({command:n,fixtures:this.getControllerFixtures(e),useMemory:this.shouldUseMemory(),aiPageFiltering:!!this.options?.aiPageFiltering,logger:a})}case"AI_EXTRACT":{if(!n.goal.trim())throw new _("ActionFailureError","Cannot perform AI extraction without goal");if(n.schema){let f=qv(n.schema);if(f)throw new _("UserConfigurationError",f)}let h=await this.browser.getCondensedHtml(),g=await this.browser.screenshot({retries:2});try{let f=await this.generator.getTextExtraction({goal:n.goal,browserState:h,returnSchema:n.schema,screenshot:`data:image/jpeg;base64,${g.toString("base64")}`},{disableCache:i,abortSignal:this.executeAbortController.signal,loggerTags:He(a)});if(f.result==="NOT_FOUND")throw new _("ActionFailureError","No relevant data found for extraction goal on this page");if(f.thoughts?.includes("MaxGenerationLengthExceededError"))throw new _("UserConfigurationError",f.thoughts);return{thoughts:f.thoughts||void 0,data:f.result,succeedImmediately:!1,urlAfterCommand:this.browser.url()}}catch(f){let y=f.message;throw y.includes("MaxGenerationLengthExceededError")?new _("UserConfigurationError","You tried to extract too much data. Please rephrase your query to limit the results returned or use a JavaScript step in the browser instead."):y.includes("AIProviderError")&&y.includes("time")?new _("AIProviderError","The AI provider responded with an error. This may be because you tried to extract too much data. Please limit extraction results to 2000 characters.",{errOptions:{cause:f}}):f}}case"NAVIGATE":if(!Ba(n.url)&&!Ha(n.url,this.browser.baseUrl))throw new _("ActionFailureError",`Invalid URL provided to navigate command: ${n.url}`);await this.browser.navigate({url:n.url,loadTimeoutMs:n.loadTimeout?n.loadTimeout*1e3:void 0});break;case"DIALOG":this.browser.registerDialogHandler(n.action);break;case"CAPTCHA":if(!this.browser.canSolveCaptchas())break;let c=await this.browser.solveCaptcha();c&&(await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:{type:"description",elementDescriptor:"the captcha image solution input"},cache:void 0,action:h=>this.browser.click(h,this.createCallbacksForBrowser(this.orgId),{}),options:{...n,targetName:"target",disableCache:i}}),await this.browser.type(c,{clearContent:!0,pressEnter:!0},!0));break;case"GO_BACK":await this.browser.goBack();break;case"GO_FORWARD":await this.browser.goForward();break;case"SCROLL_LEFT":case"SCROLL_RIGHT":case"SCROLL_DOWN":case"SCROLL_UP":{let h,g;if(n.target&&mn(n.target))await this.browser.hoverUsingVisualCoordinates(n.target.pixels);else if(n.target&&n.target.elementDescriptor.trim()){let{elementInteractedDisplayString:S,thoughts:T}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:n.target,cache:n.cache?.target,action:A=>this.browser.hover(A),options:{...n,targetName:"target",disableGlobalLocatorRedirect:!0,disableCache:i}});h=S,g=T}let f=this.browser.getViewport()?.height??Kt.height,y=this.browser.getViewport()?.width??Kt.width;switch(n.type){case"SCROLL_UP":await this.browser.scrollVertical(-(n.deltaY??f));break;case"SCROLL_DOWN":await this.browser.scrollVertical(n.deltaY??f);break;case"SCROLL_LEFT":await this.browser.scrollHorizontal(-(n.deltaX??y));break;case"SCROLL_RIGHT":await this.browser.scrollHorizontal(n.deltaX??y);break}return{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:h,thoughts:g}}case"WAIT_FOR_URL":{if(n.timeout&&n.timeout>1800)throw new _("UserConfigurationError",`Wait for URL timeout of ${n.timeout} exceeds the maximum allowed value of 30 minutes.`);let h=n.matcher;await this.browser.waitForUrl({beforeUrl:this.browser.url(),matcher:h},{timeout:n.timeout?n.timeout*1e3:void 0,negated:n.negated,caseInsensitive:n.caseInsensitive});break}case"WAIT":if(n.delay>1800)throw new _("UserConfigurationError",`Wait timeout of ${n.delay} seconds exceeds the maximum allowed value of 30 minutes`);let l=n.delay*1e3;await ae(l,this.executeAbortController.signal);break;case"REFRESH":await this.browser.refresh({loadTimeoutMs:n.loadTimeout?n.loadTimeout*1e3:void 0});break;case"CLICK":{if(mn(n.target)){await this.browser.clickUsingVisualCoordinates(n.target.pixels,n);break}let h=this.browser.url(),{elementInteractedDisplayString:g,result:f,thoughts:y}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,target:n.target,command:n,cache:n.cache?.target,action:T=>this.browser.click(T,this.createCallbacksForBrowser(this.orgId),n),options:{disableCache:i,targetName:"target",...n}}),S={urlAfterCommand:this.browser.url(),succeedImmediately:!1,elementInteracted:g,thoughts:y,data:f.downloadedFile?{downloadedFile:f.downloadedFile}:void 0};return ed(h,S.urlAfterCommand)&&(S.succeedImmediately=!0,S.succeedImmediatelyReason="URL changed"),S}case"COPY":return await this.browser.copy(n.value),{succeedImmediately:!1,data:n.value,urlAfterCommand:this.browser.url()};case"PASTE":{await this.browser.paste();break}case"DRAG":{if(mn(n.fromTarget)&&mn(n.toTarget)){await this.browser.dragAndDropUsingVisualCoordinates(n.fromTarget.pixels,n.toTarget.pixels,{hoverSeconds:n.hoverSeconds});break}if(mn(n.fromTarget)||mn(n.toTarget))throw new Error("Drag and drop targets must be both coordinates or both descriptions");let{elementInteractedDisplayStrings:h,thoughts:g}=await this.wrapMultiElementTargetingCommand({ctx:e,tracer:t,command:n,targetNames:["fromTarget","toTarget"],descriptions:[n.fromTarget,n.toTarget],caches:[n.cache?.fromTarget,n.cache?.toTarget],action:(f,y)=>this.browser.dragAndDrop(f.locator,y.locator,{hoverSeconds:n.hoverSeconds,steps:n.steps}),options:{useSelector:!!n.useSelector,disableCache:i}});return{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:h[0],thoughts:g}}case"MOUSE_DRAG":{let h=parseInt(n.deltaX),g=parseInt(n.deltaY),f=n.steps??5;if(isNaN(h)||isNaN(g))throw new _("ActionFailureError",`Invalid pixel values passed to mouse drag command: (${n.deltaX}, ${n.deltaY})`);if(n.target&&mn(n.target)){await this.browser.mouseDragUsingVisualCoordinates(h,g,f,void 0,n.target.pixels);break}let y,S;if(n.target?.elementDescriptor){let{elementInteractedDisplayString:T,thoughts:A}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:n.target,cache:n.cache?.target,action:async b=>this.browser.mouseDrag(h,g,f,b.locator,{force:n.force}),options:{disableCache:i,targetName:"target",...n}});y=T,S=A}else await this.browser.mouseDrag(h,g,f,void 0,{force:n.force});return{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:y,thoughts:S}}case"SELECT_OPTION":{if(!po(n.target))throw new Error("Select with x/y is not supported yet");let h=n.target.elementDescriptor,g=n.choice,{elementInteractedDisplayString:f,thoughts:y}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:{type:"description",elementDescriptor:h},cache:n.cache?.target,action:S=>this.browser.selectOption(S,g,n.force),options:{...n,targetName:"target",disableCache:i,source:di(n)}});return{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:f,thoughts:y}}case"TAB":{let h={loadTimeoutMs:n.loadTimeout?n.loadTimeout*1e3:void 0,retry:!0};await this.browser.switchToPage(n.action,h);break}case"NEW_TAB":await this.browser.createNewTab(n.url,{loadTimeoutMs:n.loadTimeout?n.loadTimeout*1e3:void 0});break;case"COOKIE":if(!n.value)break;let u=await this.browser.setCookie(n.value);a.debug({results:u},"Set cookies");break;case"LOCAL_STORAGE":if(!n.value||!n.key)break;await this.browser.setLocalStorage(n.key,n.value);break;case"JAVASCRIPT":{let h;try{n.environment==="BROWSER"?(h=await this.browser.evaluateCodeInPage({code:n.code,fragment:n.fragment??!1,context:o.toObjectCopy(),timeoutMs:n.timeout?n.timeout*1e3:void 0}),a.info({result:h},"Executed JavaScript in browser")):h=await No({orgId:this.orgId,code:n.code,fragment:!!n.fragment,context:o,timeoutMs:n.timeout?n.timeout*1e3:void 0,logger:a,localTools:this.localCodeEvalTools,signal:this.executeAbortController.signal,callbacks:{onPersistentVariableUpdates:async g=>{if(!this.options?.scratchPadId){a.warn({updates:g},"Got persistent variable updates but scratch pad is not available");return}await this.storage.savePersistentVariables?.({scratchPadId:this.options?.scratchPadId,orgId:this.orgId,updates:g,logger:a})}}})}catch(g){throw this.throwIfClosed(),new _("ActionFailureError",g instanceof Error?g.message:`${g}`,{errOptions:{cause:g}})}try{JSON.stringify(h)}catch(g){throw new _("ActionFailureError",`Return value is not serializable: ${g instanceof Error?g.message:`${g}`}`,{errOptions:{cause:g}})}return{urlAfterCommand:this.browser.url(),succeedImmediately:!1,data:h}}case"TYPE":{if(n.target&&mn(n.target)){await this.browser.clickUsingVisualCoordinates(n.target.pixels,n),await this.browser.type(n.value,{force:n.force,clearContent:n.clearContent,forceClearContent:n.forceClearContent,delay:n.delay,pressEnter:n.pressEnter},!0);break}let h=this.browser.url(),g,f,y=CI(n.target),S=this.browser.userBrowserSettings.globalLocatorRedirect===void 0||this.browser.userBrowserSettings.globalLocatorRedirect==="always";if(y){let{elementInteractedDisplayString:A,thoughts:b}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:y,cache:n.cache?.target,action:C=>this.browser.typeIntoTarget(n.value,C,{force:n.force,clearContent:n.clearContent,forceClearContent:n.forceClearContent,delay:n.delay,pressEnter:n.pressEnter,relativePosition:n.relativePosition}),options:{...n,targetName:"target",disableCache:i,disableGlobalLocatorRedirect:!S,source:di(n)}});g=A,f=b}else await this.browser.type(n.value,{force:n.force,clearContent:n.clearContent,forceClearContent:n.forceClearContent,delay:n.delay,pressEnter:n.pressEnter},!0);let T={urlAfterCommand:this.browser.url(),succeedImmediately:!1,elementInteracted:g,thoughts:f};return ed(h,T.urlAfterCommand)&&(T.succeedImmediately=!0,T.succeedImmediatelyReason="URL changed"),T}case"HOVER":{if(mn(n.target)){await this.browser.hoverUsingVisualCoordinates(n.target.pixels);break}let{elementInteractedDisplayString:h,thoughts:g}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:n.target,cache:n.cache?.target,action:f=>this.browser.hover(f),options:{...n,targetName:"target",disableCache:i}});return{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:h,thoughts:g}}case"FOCUS":{if(!po(n.target))throw new Error("Focus with x/y is not supported yet");let{elementInteractedDisplayString:h,thoughts:g}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:n.target,cache:n.cache?.target,action:f=>this.browser.focus(f),options:{...n,targetName:"target",disableCache:i}});return{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:h,thoughts:g}}case"BLUR":{if(n.target&&!po(n.target))throw new Error("Blur with x/y is not supported yet");if(!n.target||!n.target.elementDescriptor)return await this.browser.blur(null),{succeedImmediately:!1,urlAfterCommand:this.browser.url()};let{elementInteractedDisplayString:h,thoughts:g}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,target:n.target,command:n,cache:n.cache?.target,action:f=>this.browser.blur(f),options:{...n,targetName:"target",disableCache:i}});return{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:h,thoughts:g}}case"PRESS":let d=this.browser.url();await this.browser.press(n.value,{repeat:n.repeat,convertMeta:n.convertMeta??!0,delayMs:n.delayMs});let p={urlAfterCommand:this.browser.url(),succeedImmediately:!1};return ed(d,p.urlAfterCommand)&&(p.succeedImmediately=!0,p.succeedImmediatelyReason="URL changed"),p;case"KEY_DOWN":return await this.browser.keyDown(n.value,{convertMeta:n.convertMeta??!0}),{urlAfterCommand:this.browser.url(),succeedImmediately:!1};case"KEY_UP":return await this.browser.keyUp(n.value,{convertMeta:n.convertMeta??!0}),{urlAfterCommand:this.browser.url(),succeedImmediately:!1};case"REQUEST":{let h=new J$,g=X$(fetch,h),f;try{f=new URL(n.url).hostname}catch{}return{data:{...await mw({command:n,baseUrl:this.browser.baseUrl,logger:a,fetchImplementation:g}),cookies:sT(h,f)},succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"GRAPHQL_REQUEST":return{data:await wI({command:n,baseUrl:this.browser.baseUrl,logger:a}),succeedImmediately:!1,urlAfterCommand:this.browser.url()};case"VISUAL_DIFF":return pw({ctx:e,tracer:t,command:n,disableCache:i,browser:this.browser,logger:a,storage:this.storage,screenshotStorage:this.visualDiffScreenshotStorage,targetingWrapper:h=>this.wrapElementTargetingCommand(h)});case"FILE_UPLOAD":{let h,g;if(n.fileSource.type==="URL"?(g=n.fileSource.url,h=await Z_({uri:n.fileSource.url,logger:a,orgId:this.orgId})):n.fileSource.type==="USER_FILE"&&(g=n.fileSource.name,h=await this.uploadedFileStorage?.getFileForUpload(n.fileSource.name,this.orgId)),!h)throw new _("UserConfigurationError",`Attempted to use non-existent file for upload step: ${g}`);await this.browser.setFileChooserHandler({...h,filename:n.filename});break}case"AUTH_SAVE":return{data:await this.browser.saveAuthState(),succeedImmediately:!1,urlAfterCommand:this.browser.url()};case"AUTH_LOAD":{let h;if(!n.storageState.trim())h=void 0;else if(h=await No({orgId:this.orgId,code:n.storageState,fragment:!1,context:o,logger:a,localTools:this.localCodeEvalTools,signal:this.executeAbortController.signal}),typeof h!="object")throw new _("ActionFailureError",`Credentials must evaluate to an object (received ${typeof h} instead)`);let g;try{g=uu.optional().parse(h)}catch(f){throw new _("ActionFailureError",`Credentials provided do not follow the required format: ${f}`)}await this.browser.loadAuthState(g);break}case"ELEMENT_CHECK":{let h=(n.timeout??hn)*1e3,g=this.generator.getAgentConfig()?.assertion;if(uw(n.assertion)&&!n.useSelector&&n.target.type==="description"&&g&&g!=="v1"){let y={id:n.id,type:"AI_ASSERTION",assertion:`There is no element on the page closely matches the following description. If the description has single quotes, remember that requires an exact text substring match. Description: ${n.target.elementDescriptor}`,iframeUrl:n.iframeUrl,timeout:n.timeout,cache:n.cache&&"memory"in n.cache?{memory:n.cache?.memory}:void 0};try{let S=await Mp({command:y,logger:a,aiPageFiltering:!!this.options?.aiPageFiltering,fixtures:this.getControllerFixtures(e),useMemory:this.shouldUseMemory(),source:"NEGATED_CHECK"});return{succeedImmediately:!1,thoughts:`The element described does not exist on the page: ${S.thoughts}`,urlAfterCommand:this.browser.url(),afterScreenshotOverride:S.afterScreenshotOverride}}finally{y.cache?.memory&&yl(n,y.cache?.memory.traces,a)}}let f=await cw({command:n,tracer:t,timeoutMs:h,targetingWrapper:y=>this.wrapElementTargetingCommand(y),fixtures:this.getControllerFixtures(e),disableCache:i});return{fail:!f.success,data:f.data,elementInteracted:f.elementInteractedDisplayString,thoughts:f.err?.message??f.thoughts??`Element assertion ${f.success?"succeeded":"failed"}.`,succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"PAGE_CHECK":{let h=await Gr({action:async()=>md({assertion:n.assertion,browser:this.browser,logger:a,timeout:n.timeout,signal:this.executeAbortController.signal,autoExpandIframes:!!this.browser.userBrowserSettings.autoExpandIframes}),frameConfig:n.iframeUrl?{type:"url",url:n.iframeUrl}:void 0,browser:this.browser,logger:a});return{fail:!h.success,data:h.data,thoughts:h.success?"Page assertion passed.":h.err?.message??`Page assertion still failing after ${n.timeout} seconds.`,urlAfterCommand:this.browser.url(),succeedImmediately:!1}}case"REGISTER_REQUEST_LISTENER":{let h=new Go(n.requestMatcher),g=this.browser.registerRequestListener(h);return this.registeredListeners[n.key]=g.then(async f=>await pS(f)).catch(f=>{a.error({err:f},"Failed to get request listener response")}),{succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"AWAIT_LISTENER":{let h=this.registeredListeners[n.key];if(!h)throw new _("ActionFailureError",`No listener registered with key: ${n.key}`);let g=n.timeout??10;return{data:await j(h,{milliseconds:g*1e3,message:`Request listener timed out after ${g} seconds`}),succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"RECORD_REQUESTS":{let h=new Go(n.requestMatcher);return this.recordedRequests[n.key]={},this.browser.registerRequestRecorder(n.key,{matches:g=>h.matches({url:g.request.url,method:g.request.method}),onRequestStart:(g,f)=>{this.recordedRequests[n.key][g]=yp(f)},onRequestComplete:(g,f)=>{this.recordedRequests[n.key][g]=yp(f)}}),{succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"GET_RECORDED_REQUESTS":{let h=this.recordedRequests[n.key];if(!h)throw new _("ActionFailureError",`No recorder registered with key: ${n.key}`);return delete this.recordedRequests[n.key],{data:Object.values(h),succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"SET_HEADER":{let h;return n.requestMatcher&&(h=new Go(n.requestMatcher)),this.browser.setHeader(n.name,n.value,h),{succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"MOCK_ROUTE":return{data:{key:this.browser.registerMock(n.key,new Go(n.requestMatcher),async(g,f)=>{let y=await No({orgId:this.orgId,code:n.responseGenerator,fragment:!1,context:o,timeoutMs:void 0,logger:a,localTools:this.localCodeEvalTools,mock:{request:g,response:f},disallowVariableUpdates:!0,responseSerialization:"RESPONSE"}),S=AT.parse(y);return new Response(S.body,{status:S.status,headers:S.headers})},n.fetchOriginalResponse??!1)},succeedImmediately:!1,urlAfterCommand:this.browser.url()};case"REMOVE_ROUTE_MOCK":return this.browser.removeMock(n.key),{succeedImmediately:!1,urlAfterCommand:this.browser.url()};case"OFFLINE_MODE":return await this.browser.setOfflineMode(n.enable),{succeedImmediately:!1,urlAfterCommand:this.browser.url()};default:return(h=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(n)}return{succeedImmediately:!1,urlAfterCommand:this.browser.url()}}async getReverseMappedDescription({browserState:e,targetId:t,disableCache:n,screenshot:o}){return(await this.generator.getReverseMappedDescription({browserState:e,target:t,screenshot:o},{disableCache:n,abortSignal:this.executeAbortController.signal,loggerTags:He(this.logger)})).phrase}async stopRecordMode(){this.recordAbortController?.abort(),await this.browser.clearAllCdpHighlights()}async startRecordMode({params:e,abortController:t,isClickToRecord:n}){this.recordAbortController=t;let o=new Ap({signal:t.signal,...e});return await this.browser.startRecording(this.recordAbortController.signal,o,n),o}async runSectionAutohealing(e){return this.generator.getAutohealingProposal(e,{disableCache:!0,abortSignal:this.executeAbortController.signal,loggerTags:He(this.logger)})}async getFailureRecoveryPlan(e){return this.generator.getFailureRecoveryPlan(e,{disableCache:!0,abortSignal:this.executeAbortController.signal,loggerTags:He(this.logger)})}};import{cloneDeep as Q$}from"lodash-es";var Z$={showOverlay:!1},Pp=class{sessions=new Map;sessionCountByIp=new Map;getCurrentConnectionsByIp(e){return this.sessionCountByIp.get(e)??0}getCurrentSessionsByIp(){return Object.fromEntries(this.sessionCountByIp)}reserveCapacityByIp(e){e&&this.sessionCountByIp.set(e,(this.sessionCountByIp.get(e)??0)+1)}releaseCapacityByIp(e){e&&this.sessionCountByIp.set(e,Math.max(this.getCurrentConnectionsByIp(e)-1,0))}registerSession({controller:e,context:t,cleanup:n,clientIp:o,sessionId:i,socket:a}){return this.sessions.set(i,{controller:e,context:t,cleanup:n,clientIp:o,browserBehavior:Q$(Z$),socket:a}),i}removeSession(e,t){(async()=>{let o=this.sessions.get(e);if(!o)return;this.releaseCapacityByIp(o.clientIp);let{controller:i}=o;try{i.setClosed(),await i.browser.cleanup()}catch(a){t.error({err:a},"Error cleaning up browser in global state manager")}try{await o.cleanup?.()}catch(a){t.error({err:a},"Error running cleanup function in global state manager")}this.sessions.delete(e)})()}getSession(e){return this.sessions.get(e)}};function xI(r,e,t,n){let o=Date.now(),i=Date.now(),a,s,c,l,u=!1,d=async(g,f)=>{if(!g.closed&&!g.isInPageLoad)try{let y=c;c=void 0;let S=g.url(),T=f.toEditorDisplayCopy();JSON.stringify(T)===JSON.stringify(a)&&S===l&&o>i||(r.emit("browserState",{logsPerPage:y?.logsPerPage,viewport:g.getViewport(),url:S,iframeSrcUrls:s??[],context:T,isInPageLoad:g.isInPageLoad}),o=Date.now()),l=S,a=T}catch(y){if(!r.connected)return;let S=y instanceof Error?y.message:`${y}`;if(S.includes("Frame was detached")||S.includes("Not attached to an active page")||S.includes("browser has been closed")||S.includes("UserInfrastructureError"))return;t.error({err:y,sessionId:e},"Error grabbing browser state")}},p=setInterval(()=>{let g=n.getSession(e),f=g?.controller?.browser;if(!f||f.closed){t.debug("Clearing browser state socket cron due to the browser being closed"),clearInterval(p);return}d(f,g.context)},1e3),m=(g,f)=>!!(JSON.stringify(g)!==JSON.stringify(s)||f.logsPerPage.some(y=>y.length>0)),h=setInterval(async()=>{let f=n.getSession(e)?.controller?.browser;if(!f||f.closed){clearInterval(h);return}else if(u)return;u=!0;try{let y=await f.getAllFrameUrls(),S=f.retrieveAndClearDebugData();m(y,S)&&(s=y,c=S,i=Date.now())}catch(y){t.warn({err:y},"Failed to fetch extended details")}finally{u=!1}},2500);return{timers:[p,h]}}var eW=3;async function _I({socket:r,logger:e,storageFactory:t,uploadedFileStorage:n,visualDiffScreenshotStorage:o,devicePixelRatio:i,generatorFactory:a,enricherFactory:s,authorization:c,settingsFactory:l,getOrgId:u,branchGetter:d,globalE2eStateManager:p}){let m=r.id,h=r.handshake.query.testId;if(!h)throw new Error("Socket connection request is missing testId");let g=await u({type:"e2e",testId:h}),f=await d?.();e=e.child({testId:h,orgId:g,sessionId:m,branch:f});let y=await a(g,e),S=await s(g,e),T=await l(g,e),A=await t(g),{testMetadata:b,baseUrl:C,envName:x,browserConfig:M,aiSettings:P,environmentVariables:U,localCodeEvalTools:V}=await Ki({testId:h,orgId:g,logger:e,storage:A,authorization:c,settings:T}),k=p.getSession(m);if(k)return e.info("Associating connection with existing session (likely reconnect)"),await k.controller.browser.clearAllCdpHighlights(),{type:"e2e",sessionId:m,orgId:g,testId:h};let z=r.handshake.headers["x-forwarded-for"]?.split(",")[0];if(e.info({clientIp:z,event:"connect",args:r.handshake.query},"Websocket event (connect)"),z&&p.getCurrentConnectionsByIp(z)>=eW)throw e.error({clientIp:z,sessions:p.getCurrentSessionsByIp(),...r.handshake.query},"Socket connection browser creation rate limit triggered"),new Error("You have exceeded the maximum number of connections allowed. Momentic limits the number of simultaneously open tabs to uphold browser reliability. Please close duplicate tabs and try again later.");p.reserveCapacityByIp(z);try{await tW({socket:r,baseUrl:C,envName:x,testMetadata:b,orgId:g,sessionId:m,logger:e,environmentVariables:U,clientIp:z,devicePixelRatio:i,storage:A,uploadedFileStorage:n,visualDiffScreenshotStorage:o,localCodeEvalTools:V,generator:y,enricher:S,browserConfig:M,aiSettings:P,globalE2eStateManager:p})}catch(Q){throw e.warn({err:Q},"Error setting up socket session, possibly due to client closing the connection"),p.releaseCapacityByIp(z),Q}return{type:"e2e",sessionId:m,testId:h,orgId:g}}async function tW({socket:r,baseUrl:e,envName:t,devicePixelRatio:n,testMetadata:o,orgId:i,sessionId:a,logger:s,storage:c,uploadedFileStorage:l,visualDiffScreenshotStorage:u,localCodeEvalTools:d,generator:p,environmentVariables:m,browserConfig:h,aiSettings:g,clientIp:f,enricher:y,globalE2eStateManager:S}){let T={viewport:o.advanced?.viewport??Kt,locale:o.advanced?.locale??So,timezoneId:o.advanced?.timezone??yo,geolocation:o.advanced?.geolocation??Eo,colorScheme:o.advanced?.colorScheme};n&&(T.deviceScaleFactor=n);let A=o.id,b=await pp({settings:h,orgId:i,baseUrl:e,envName:t,testName:o.name,localTools:d,envVariables:m,logger:s,customHeaders:void 0});s=s.child({orgId:i,sessionId:a,testId:A});let C=await $r.init({baseUrl:e,userBrowserSettings:b,enricher:y,storage:c,logger:s,contextArgs:T,iconKnowledgeBase:null,callbacks:{onTabsChange:(V,k)=>{r.emit("tabs",{tabs:V,activeTab:k})},onScreencastFrame:(V,k)=>{let z=r;kr&&(z=r.compress(!0)),z.emit("screenshot",{buffer:V},()=>{k()})},onSvgsCollected:V=>{r.emit("newIconDetected",{numIcons:V.newSvgs.length}),c.saveNewIcons(V,s)},onNetworkLogs:V=>{r.emit("networkLogs",{harEntries:V})}}});await C.navigate({url:e,initialNavigation:!0});let x=new $o({browser:C,generator:p,logger:s,orgId:i,options:{scratchPadId:void 0,slowMoMs:b.slowMoMs,autoFollowNewTabs:b.autoFollowNewTabs,useMemory:g.useMemory,aiPageFiltering:g.aiPageFiltering},storage:c,localCodeEvalTools:d,uploadedFileStorage:l,visualDiffScreenshotStorage:u}),M=xI(r,a,s,S),P=async()=>{M.timers.forEach(V=>clearInterval(V))},U=new or({baseUrl:e,testName:o.name,currentUrl:x.browser.url(),variablesFromEnvironment:m,envName:t});if(!r.connected)throw await C.cleanup(),new Error("Socket not connected anymore, not proceeding with session setup");r.emit("session",{url:e,userAgent:$r.USER_AGENT,viewport:x.browser.getViewport(),sessionId:a}),S.registerSession({controller:x,context:U,sessionId:a,cleanup:P,clientIp:f,socket:r})}async function Ki({testId:r,orgId:e,logger:t,storage:n,authorization:o,settings:i}){let a=await n.fetchTestMetadata(r,t);if(!a)throw new Error(`Test metadata could not found for test ${r}`);let s;o?.type==="API_KEY"&&(s=new vn({httpClient:new Bt({...o,logger:t,mode:"interactive"}),fakerSeed:void 0}));let c=a.envs?.find(g=>g.default),l;c&&(l=await n.fetchEnvironment(c.name,t));let u=l&&"browser"in l?l.browser:void 0,d={...i.browser,...u,...a.advanced},p=a.baseUrl||l?.variables?.[Tt];if(!p)throw new Error("Base URL is empty in both test options and the configured environment");let m={...l?.variables};m=await mp({orgId:e,testName:a.name,envName:l?.name,baseEnvVariables:m,parameters:a.parameters,logger:t,localTools:s});let h={...i.ai,...a.advanced};return{localCodeEvalTools:s,baseUrl:p,envName:l?.name,testName:a.name,browserConfig:d,environmentVariables:m,testMetadata:a,aiSettings:h}}var FS=class{parentTracer=null;socket;step;orgId;constructor({step:e,socket:t,parentTracer:n,orgId:o}){this.socket=t,this.parentTracer=n,this.step=e,this.orgId=o}getParentStepIdChain(){return this.parentTracer?this.parentTracer?.getParentStepIdChain()??[]:[]}recordStepDuration(e){let t=e.step.type!=="PRESET_ACTION"?e.step.type:e.step.command.type;Lt.distribution("test_step_duration",e.durationMs,[`type:${t}`,"platform:browser","executor:editor",`orgId:${this.orgId}`])}attachBeforeScreenshot(){}attachAfterScreenshot(){}attachBeforeHtmlSnapshot(){}attachAfterHtmlSnapshot(){}recordTargetAutoHeal(){}async finish(e){switch(e.step.status){case"SUCCESS":this.socket.emit("success",{...e,parentStepIdChain:this.getParentStepIdChain()});return;case"FAILED":this.socket.emit("failure",{...e,parentStepIdChain:this.getParentStepIdChain()});return;case"CANCELLED":this.socket.emit("cancelled",{...e,parentStepIdChain:this.getParentStepIdChain()});return}}async startSubSteps(){return new ro({parentStep:this.step,socket:this.socket,parentTracer:this,orgId:this.orgId})}},ro=class{stepFrequenciesByType={};parentTracer;parentStep;socket;orgId;recordStepStat(e){e.type!=="PRESET_ACTION"?this.stepFrequenciesByType[e.type]=(this.stepFrequenciesByType[e.type]||0)+1:this.stepFrequenciesByType[e.command.type]=(this.stepFrequenciesByType[e.command.type]||0)+1}sendFinalizedStepStats(){for(let[e,t]of Object.entries(this.stepFrequenciesByType))Lt.increment("test_step_execution",t,[`type:${e}`,"platform:browser","executor:editor",`orgId:${this.orgId}`])}constructor({parentStep:e,socket:t,parentTracer:n,orgId:o}){this.parentTracer=n,this.parentStep=e,this.socket=t,this.orgId=o}async getScreenshot(){throw new Error("getScreenshot is not supported in the editor")}async getHtmlSnapshot(){throw new Error("getHtmlSnapshot is not supported in the editor")}getParentStepIdChain(){return this.parentStep?[...this.parentTracer?.getParentStepIdChain()??[],this.parentStep.id]:[]}async startStep(e){return this.recordStepStat(e.step),this.socket.emit("started",{stepId:e.step.id,parentStepIdChain:this.getParentStepIdChain(),attempt:e.attempt}),new FS({step:e.step,parentTracer:this,socket:this.socket,orgId:this.orgId})}async finish(){this.sendFinalizedStepStats()}},Op=class{constructor(e,t,n,o){this.socket=e;this.storage=t;this.orgId=n;this.testId=o}children=[];loggerBindings;setActiveVideo(){}async getScreenshot(){throw new Error("getScreenshot is not supported in the editor")}async getHtmlSnapshot(){throw new Error("getHtmlSnapshot is not supported in the editor")}onNetworkPage(){}onNetworkLogs(){}attachConsoleLogs(){}attachBrowserCrashDump(){}async finish(){this.socket.emit("finished"),await Promise.all(this.children.map(e=>e.finish()))}async startBeforeStepList(){let e=new ro({orgId:this.orgId,parentStep:null,parentTracer:null,socket:this.socket});return this.children.push(e),e}async startMainStepList(){let e=new ro({orgId:this.orgId,parentStep:null,parentTracer:null,socket:this.socket});return this.children.push(e),e}async startAfterStepList(){let e=new ro({orgId:this.orgId,parentStep:null,parentTracer:null,socket:this.socket});return this.children.push(e),e}};var US={currentlyExecutingRequests:{}},nW=r=>async(e,t)=>{let{testId:n,orgId:o}=r.metadata,i=await r.settingsFactory(o,r.logger),a=await r.storageFactory(o),s,c=await Ki({testId:n,orgId:o,logger:r.logger,storage:a,authorization:r.authorization,settings:i}),l=`${n}|${c.baseUrl}`;try{let u=US.currentlyExecutingRequests[l]??0;US.currentlyExecutingRequests[l]=u+1,s=await oW({...r,...e,...c,done:t})}finally{r.logger.info({result:s,sessionId:r.metadata.sessionId},"Test execution complete"),US.currentlyExecutingRequests[l]--}},oW=async({socket:r,steps:e,baseUrl:t,testMetadata:n,reInitialize:o,toStep:i,fromStep:a,storageFactory:s,aiSettings:c,browserConfig:l,metadata:u,logger:d,envName:p,testName:m,environmentVariables:h,localCodeEvalTools:g,done:f,cacheStorageFactory:y,globalE2eStateManager:S})=>{let{testId:T,sessionId:A,orgId:b}=u,C=A,x=S.getSession(A);if(!x)throw new Error("No active session found");let{controller:M,context:P}=x;M.setOpen(),d=d.child({testId:T,orgId:b,sessionId:A,runId:C}),d.info({steps:e.map(oe=>`${oe.type}${"command"in oe?` - ${oe.command.type}`:""}`),toStep:i,fromStep:a,reInitialize:o,envName:p,testName:m,baseUrl:t,context:P,browserConfig:l,aiSettings:c},"Socket execution parameters");let U=h??{},V=async()=>{o&&(await M.browser.reset({newUrl:t}),P.reset({baseUrl:t,currentUrl:M.browser.url(),variablesFromEnvironment:U,envName:p,testName:m}))},k=await s(b),z=await y(b),Q=async()=>{let oe=Date.now();try{await z.resolveStepCacheEntries({schemaVersion:n.schemaVersion,testId:T,stepLists:{steps:e},logger:d})}catch(jt){d.error({err:jt},"Failed to fetch step cache entries from Momentic server. This can drastically reduce test reliability and performance.")}finally{Lt.distribution("cache-resolution",Date.now()-oe,["executor:editor"])}};try{await bl({promiseGenerator:async()=>Promise.all([V(),Q()]),signal:M.executeAbortController.signal,codePath:"resolveStepCacheAndInitBrowser"}),M.setOpen()}catch(oe){if(r.emit("finished"),oe.name!=="AbortError")throw new Error(`Failed to setup browser for execution: ${oe}`)}let Y=rW(e),Te={collectDebugData:!1,reinitializeBrowser:!1,disableHealing:!0},q={orgId:b,runId:C,testMetadata:n,steps:e,fromStep:a,toStep:i,orgSettings:{ai:c,browser:l}},it={controller:M,context:P,storage:k,codeEvalTools:g,usageTracker:new Ta,logger:d},Ge={test:{},step:{onDynamicAIActionStatusUpdateEvent:oe=>{r.emit("dynamicCommandStatusUpdate",oe)},onDynamicAIActionEvaluatingEvent:oe=>{r.emit("dynamicCommandEvaluating",oe)},onDynamicCommandGenerated:oe=>{r.emit("dynamicCommandGenerated",oe)},onDynamicCommandExecuted:oe=>{r.emit("dynamicCommandExecuted",oe)}}},Ye=new Op(r,k,b,T),Nt=await dp({fixtures:it,options:Te,callbacks:Ge,inputs:q,testParams:{tracer:Ye}}),Ie={logger:d,cacheStorage:z,orgId:b,testId:T,originalStepsWithCaches:{steps:Y},updatedStepsWithCaches:{steps:e}};return Nt?.status==="PASSED"?await Ku(Ie):Nt?.status==="FAILED"&&await Yu(Ie),await Ye.finish(),f?.(Nt),Nt.status};var MI={event:"execute",createHandler:nW};import{cloneDeep as iW}from"lodash-es";var aW=r=>async({command:e},t)=>{let{logger:n,generatorFactory:o,metadata:i}=r,a=iW(e),s=cA(a);if(s.category!=="NO_DESCRIPTION_PROVIDED"){if(s.category!=="NONE"){t?.({result:s});return}"cache"in a&&(a.cache=void 0);try{let l=await(await o(i.orgId,n)).getLintStepResult({command:a},{logger:n});t?.({result:l})}catch(c){n.error({event:"lint",err:c},"Failed to lint step"),t?.({result:void 0})}}},II={event:"lintStep",createHandler:aW};var sW=({metadata:r,logger:e,storageFactory:t,globalE2eStateManager:n})=>{let{sessionId:o,orgId:i}=r;return async(a,s)=>{let{description:c,command:l,testMetadata:u,returnScreenshot:d}=a;e.info({params:a},`Locate handler called - ${c}`);let p=n.getSession(o);if(!p)throw new Error("No active session found");let{controller:m,context:h}=p;m.setOpen();let g=await t(i),f=fi.parse(u.advanced??{}),y={},S;if(c){if("useSelector"in l&&l.useSelector)try{let T=await m.locateElementWithSelector(c,"iframeUrl"in l?l.iframeUrl:void 0);S=T.resolution.locator,y={target:T.target,thoughts:T.thoughts}}catch(T){e.warn({err:T},"Failed resolving target with selector"),s({err:`Failed locating element: ${T.message}`,decisions:T instanceof _r?T.decisions:void 0});return}else try{let T=await m.locateElement({description:c,disableCache:f.disableAICaching??!1,skipWait:!0,testContext:h,source:di(l),iframeUrl:"iframeUrl"in l?l.iframeUrl:void 0,memory:"cache"in l&&l.cache&&"target"in l.cache&&wc(l.cache.target.memory)?l.cache.target.memory:void 0,logger:e});y={target:T.target,thoughts:T.thoughts},S=T.resolution.locator}catch(T){(async()=>{try{let A=await m.browser.getCondensedHtml({skipWait:!0});e.warn({err:T,html:A.slice(0,1e5)},"Failed locating element with AI")}catch(A){e.warn({err:A},"Failed grabbing HTML after trying to locate element with AI")}})(),s({err:`${T.message}`});return}if(l.type==="SELECT_OPTION"&&S)try{y.options=await m.browser.getSelectOptions(S)}catch(T){e.warn({err:T},"Failed getting select options"),s({err:`Failed getting select options: ${T.message}`});return}e.info({result:y},"Locate handler result")}if(d)try{let{buffer:T,width:A,height:b}=await m.screenshotWithDimensions({clearHighlights:!0,locator:S}),C=await g.uploadScreenshot(T);y.screenshot={data:C,width:A,height:b},e.info({width:A,height:b},"Captured screenshot during locate")}catch(T){e.error({err:T},"Error capturing screenshot during locate"),s({err:`Error taking screenshot: ${T.message}`});return}if(s({result:y}),S)try{await Promise.all([m.browser.scrollIntoViewIfNeeded(S),m.browser.highlight(S)])}catch(T){e.warn({err:T},"Error highlighting element, continuing...")}}},PI={event:"locate",createHandler:sW};var lW=({metadata:r,logger:e,globalE2eStateManager:t})=>{let{sessionId:n}=r;return async({event:o,percentX:i,percentY:a})=>{let s=t.getSession(n);if(!s)throw new Error("No active session found");let c=s.controller.browser;if(c.closed||c.getActivePage().isClosed()){e.warn("Ignoring mouse move because the browser is closed");return}try{await c.clickMouseFromPositionPercentages(o,i,a)}catch(l){e.error({err:l},"Error performing click during cloud recording in control mode")}}},OI={event:"mouseClickEvent",createHandler:lW};var cW=({metadata:r,generatorFactory:e,logger:t,socket:n,globalE2eStateManager:o})=>{let{sessionId:i,orgId:a,testId:s}=r;return async({stepId:c,parentStepIdChain:l,attribute:u})=>{let d=o.getSession(i);if(!d)throw new Error("No active session found");let{controller:p}=d,m=await e(a,t);p.setOpen(),d.browserBehavior.showOverlay=!0;let h=new AbortController;h.signal.addEventListener("abort",async()=>{try{d.browserBehavior.showOverlay=!1,await p.stopRecordMode()}catch(y){t.warn({err:y},"Failed to stop record mode in target click socket handler")}},{once:!0});let g=!1,f=(y,S)=>{S.type!=="PRESET_ACTION"||S.command.type!=="CLICK"||(n.emit("targetRecordingUpdate",{type:y,stepId:c,parentStepIdChain:l,command:S.command,attribute:u}),h.abort(),g=!0)};setTimeout(()=>{g||(h.abort(),n.emit("targetRecordingUpdate",{type:"error",err:"Timed out waiting for click event",stepId:c,parentStepIdChain:l,attribute:u}))},1e4),await p.startRecordMode({params:{generator:m,logger:t,testId:s,orgId:a,callbacks:{onActionReceived:y=>f("clickReceived",y),onStepRecorded:y=>f("descriptionGenerated",y)}},abortController:h,isClickToRecord:!0}),n.emit("targetRecordingUpdate",{type:"listenersInitialized",stepId:c,parentStepIdChain:l,attribute:u})}},LI={event:"recordTargetClick",createHandler:cW};var uW=({metadata:r,logger:e,globalE2eStateManager:t})=>{let{sessionId:n}=r;return async({key:o})=>{let i=t.getSession(n);if(!i)throw new Error("No active session found");if(o==="Dead")return;let{controller:a}=i;if(a.browser.closed||a.browser.getActivePage().isClosed()){e.debug({sessionId:n},"Browser is closed, ignoring keyboard press socket event");return}try{a.setOpen(),await a.browser.keyDown(o,{})}catch(s){if(s.message.includes("has been closed")){e.debug({sessionId:n,err:s},"Browser is closed, ignoring key down socket event error");return}throw s}}},NI={event:"keyDownEvent",createHandler:uW};var dW=({metadata:r,logger:e,globalE2eStateManager:t})=>{let{sessionId:n}=r;return async({key:o})=>{let i=t.getSession(n);if(!i)throw new Error("No active session found");if(o==="Dead")return;let{controller:a}=i;if(a.browser.closed||a.browser.getActivePage().isClosed()){e.debug({sessionId:n},"Browser is closed, ignoring keyboard press socket event");return}try{a.setOpen(),await a.browser.keyUp(o,{})}catch(s){if(s.message.includes("has been closed")){e.debug({sessionId:n,err:s},"Browser is closed, ignoring key up socket event error");return}throw s}}},DI={event:"keyUpEvent",createHandler:dW};var pW=({metadata:r,logger:e,globalE2eStateManager:t})=>{let{sessionId:n}=r,o,i=0,a=(l,u)=>{let d=async()=>{o=void 0};clearTimeout(o),o=setTimeout(d,Math.min(1e3,250*(i+1)))},s,c=0;return async l=>{let u=t.getSession(n);if(!u)throw new Error("No active session found");let{controller:d,browserBehavior:p}=u,m=d.browser;if(m.closed||m.getActivePage().isClosed()){e.warn("Ignoring mouse move because the page is closed");return}if(l.event==="scroll"){let h=await m.scrollFromPositionPercentages(l.percentX,l.percentY,s?.x??0,s?.y??0),g=u.browserBehavior.recordingState?.transformer;g&&h&&g.recordScroll(h);return}p.showOverlay&&a(m,l);try{let h=await m.moveMouseFromPositionPercentages(l.percentX,l.percentY);c=0,s=h}catch(h){c++,c%5===0&&e.warn({err:h,mouseErrors:c},"Error in socket mouse move handler")}}},kI={event:"mouseMoveEvent",createHandler:pW};var mW=({metadata:r,generatorFactory:e,socket:t,logger:n,globalE2eStateManager:o})=>{let{sessionId:i,orgId:a,testId:s}=r;return async({stepId:c})=>{let l=o.getSession(i);if(!l)throw new Error("No active session found");let{controller:u,browserBehavior:d}=l,p=await e(a,n);n.info("Starting cloud recording");let m=new AbortController,h=await u.startRecordMode({params:{generator:p,logger:n,testId:s,orgId:a,callbacks:{onActionReceived:(g,f)=>{t.emit("stepRecorded",{stepId:c,step:g,offset:f})},onStepRecorded:(g,f)=>{t.emit("stepRecorded",{stepId:c,step:g,offset:f})}}},abortController:m,isClickToRecord:!1});d.recordingState={transformer:h}}},FI={event:"recordingStart",createHandler:mW};var hW=({metadata:r,logger:e,globalE2eStateManager:t})=>{let{sessionId:n}=r;return async()=>{let o=t.getSession(n);if(!o)throw new Error("No active session found");e.info("Stopping cloud recording"),await o.controller.stopRecordMode(),o.browserBehavior.recordingState=void 0,o.browserBehavior.showOverlay=!1}},UI={event:"recordingStop",createHandler:hW};var gW=({socket:r,metadata:e,logger:t,storageFactory:n,authorization:o,settingsFactory:i,globalE2eStateManager:a})=>async(s,c)=>{let{testId:l,sessionId:u,orgId:d}=e;t.info({testId:l,sessionId:u},"Refresh event received");let p=await i(d,t),m=await n(d),{baseUrl:h}=await Ki({testId:l,orgId:d,logger:t,storage:m,authorization:o,settings:p}),g=a.getSession(u);if(!g){r.emit("error",{message:"No session to refresh"});return}let{controller:f}=g;f.setOpen(),await f.browser.refresh();let y=f.browser.getViewport();t.info({baseUrl:h,viewport:y},`Session refreshed for test ${l} at ${h}`),c()},BI={event:"refresh",createHandler:gW};var fW=({socket:r,metadata:e,logger:t,storageFactory:n,authorization:o,settingsFactory:i,globalE2eStateManager:a})=>async()=>{let{testId:s,sessionId:c,orgId:l}=e;t.info({testId:s,sessionId:c},"Reset event received");let u=await i(l,t),d=await n(l),{baseUrl:p,envName:m,testName:h,environmentVariables:g}=await Ki({testId:s,orgId:l,logger:t,storage:d,authorization:o,settings:u}),f=a.getSession(c);if(!f){r.emit("error",{message:"No session to reset"});return}let{controller:y,context:S}=f;await y.browser.reset({newUrl:p});let T=y.browser.baseUrl;S.reset({baseUrl:T,currentUrl:y.browser.url(),variablesFromEnvironment:g,envName:m,testName:h});let A=y.browser.getViewport(),b=$r.USER_AGENT;t.info({baseUrl:p,viewport:A},`Session reset for test ${s} at ${T}`),r.emit("session",{url:T,userAgent:b,viewport:A,sessionId:c})},HI={event:"reset",createHandler:fW};var SW=({metadata:r,globalE2eStateManager:e})=>{let{sessionId:t}=r;return async({url:n})=>{let o=e.getSession(t);if(!o)throw new Error("No active session found");await o.controller.browser.switchToPage({type:"SUBSTRING",substring:n})}},zI={event:"switchTab",createHandler:SW};async function GI(r){return _I(r)}var jI=[QA,MI,PI,HI,BI,YA,zI,II,LI,FI,UI,kI,OI,NI,DI,JA,XA];var VI=r=>{let{logger:e}=r,t=new yW(r.baseServer,{cors:{origin:"*",methods:["GET","POST"]},pingTimeout:15*60*1e3,pingInterval:15*60*1e3,maxHttpBufferSize:1e7,perMessageDeflate:!0});return t.on("connection",async n=>{let o;try{e.info({event:"connection",transport:n.conn.transport.name},"Websocket connection established"),o=await GI({...r,socket:n,logger:e}),e=e.child(o)}catch(i){e.error({event:"connection",type:"websocket",err:i},"Failed to setup connection"),n.emit("error",{message:i instanceof Error?i.message:`${i}`}),n.disconnect(!0);return}jI.forEach(i=>EW(i,{...r,socket:n,metadata:o,logger:e}))}),t},EW=(r,e)=>{let t=r.createHandler(e),n=(...o)=>{["mouseMoveEvent","keyDownEvent","keyUpEvent","mouseClickEvent","lintStep"].includes(r.event)||e.logger.debug({...e.metadata,event:r.event},`Websocket event (${r.event})`);let i=a=>{e.logger.error({event:r.event,type:"websocket",err:a instanceof Error?a:new Error(`${a}`)},"Unhandled exception in socket handler"),e.socket.emit("error",{message:a instanceof Error?a.message:`${a}`})};try{let a=t.apply(void 0,o);a&&typeof a.catch=="function"&&a.catch(i)}catch(a){i(a)}};e.socket.on(r.event,n)};import{Router as AW}from"express";import{Router as TW}from"express";import ac from"fs";import ic from"path";import{v4 as vW}from"uuid";import RW from"yaml";import{hostname as bW}from"os";var oc="2.27.2",et=Ma({app:"desktop-server",hostname:bW(),disableConsoleLogs:!0}).child({cliVersion:oc});(async()=>{try{let r=await Qn(et);r.gitBranchName&&et.addBinding("branch",r.gitBranchName)}catch{}})();var hs=TW();async function BS(r){return(await sd(r,et)).map(n=>{let o=r.modules[n.moduleId];if(!o){E.warn(`Found a dangling module with ID ${n.moduleId} that could not be found on disk.`);return}return{...o,content:n}}).filter(n=>n!==void 0)}hs.get("/",Me(async(r,e)=>{let t=se(),n=await Z(t),o=await BS(n);e.status(200).json(o)}));hs.post("/",Me(async(r,e)=>{let t;try{t=UT.parse(r.body)}catch(s){e.status(400).json({error:`Invalid request body: ${s}`});return}try{go(t.name)}catch(s){e.status(400).json({error:`Invalid module name: ${s}`});return}let n=se(),o=(await Z(n)).modules;if(Object.values(o).find(s=>s.name===t.name)){e.status(400).send(`A module with the name "${t.name}" already exists. Please choose a different name.`);return}let i=ic.join(n.rootDir,t.folderPath??"");if(!ac.existsSync(i)||!ac.statSync(i).isDirectory()){e.status(400).json({error:`The folder configured for module creation '${i}' does not exist.`});return}let a=await ad({...t,folder:i,project:n});e.status(201).json(a)}));hs.get("/:moduleId",Me(async(r,e)=>{if(!r.params.moduleId){e.status(400).json({error:"Missing moduleId in url path."});return}let t=await Z(se()),n=t.modules[r.params.moduleId];if(!n){e.status(404).json({error:"Module not found."});return}try{let o=await nn(n,t,E);e.json(o)}catch(o){e.status(400).json({err:o})}}));hs.post("/:moduleId/duplicate",Me(async(r,e)=>{if(!r.params.moduleId){e.status(400).json({error:"Missing moduleId in url path."});return}let t;try{t=FT.parse(r.body)}catch(g){e.status(400).json({error:`Invalid request body: ${g}`});return}try{go(t.name)}catch(g){e.status(400).json({error:g.message});return}let n=se(),o=await Z(n),i=o.modules[r.params.moduleId];if(!i){e.status(404).json({error:"Module not found."});return}if(Object.values(o.modules).find(g=>g.name===t.name)){e.status(400).send(`A module with the name "${t.name}" already exists. Please choose a different name.`);return}let a=await nn(i,o,E),s=ic.join(n.rootDir,ic.dirname(i.relativePath));if(!ac.existsSync(s)||!ac.statSync(s).isDirectory()){e.status(400).json({error:`The folder configured for module creation '${s}' does not exist.`});return}let c=Ue(t.name),l=ic.join(s,`${c}.module.yaml`),u=vW(),{stepsToSave:d}=await nt({stepLists:{steps:a.steps},createNewCacheIds:!0,cacheCreationParams:{orgId:wt()}}),p={fileType:he.MODULE,schemaVersion:Ce,moduleId:u,name:t.name,description:"",enabled:!0,steps:d.steps,parameters:a.parameters,defaultParameters:a.defaultParameters,parameterEnums:a.parameterEnums,defaultCacheKey:a.defaultCacheKey,defaultCacheTtl:a.defaultCacheTtl,defaultCacheAllInvocations:a.defaultCacheAllInvocations,autoAuth:a.autoAuth,advanced:a.advanced},m=RW.stringify(p);ac.writeFileSync(l,m,"utf-8");let h={relativeFilePath:ic.relative(n.rootDir,l)};e.status(201).json(h)}));hs.patch("/:moduleId/metadata",Me(async(r,e)=>{if(!r.params.moduleId){e.status(400).json({error:"Missing moduleId in url path."});return}let t;try{t=BT.parse(r.body)}catch(i){e.status(400).json({error:`Invalid request body: ${i}`});return}let n=se(),o=await Z(n);_A({moduleId:r.params.moduleId,content:t,momenticFiles:o,logger:E,project:n}),e.status(201).json({message:"ok"})}));var $I=hs;var WI=AW();WI.get("/",Me(async(r,e)=>{let t=se(),n=await Z(t),o=new Set;n?.tests&&Object.values(n.tests).forEach(l=>{l.labels?.forEach(u=>o.add(u))});let i=Array.from(o).sort(),a=Object.values(n.tests),s=await BS(n),c={labels:i,tests:a,modules:s};e.status(200).json(c)}));var qI=WI;import{Router as wW}from"express";var HS=wW();HS.get("/",Me((r,e)=>{let t=ld(se(),et);e.status(200).json(t)}));HS.get("/names",Me((r,e)=>{let n=se().config.environments?.map(o=>o.name)??[];e.status(200).json(n)}));var KI=HS;import{Router as CW}from"express";var YI=CW();YI.get("/",Me((r,e)=>{let t={userId:Po(),orgId:wt(),cliVersion:oc??"0.0.0"};e.status(200).json(t)}));var XI=YI;import{StreamableHTTPServerTransport as kq}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{isInitializeRequest as Fq}from"@modelcontextprotocol/sdk/types.js";import{randomUUID as Uq}from"crypto";import{Router as Bq}from"express";import{McpServer as Nq}from"@modelcontextprotocol/sdk/server/mcp.js";import{SSEServerTransport as Dq}from"@modelcontextprotocol/sdk/server/sse.js";import{streamObject as PW}from"ai";import Dp from"dedent";import{z as Wo}from"zod";import{tool as xW}from"ai";import{z as _W}from"zod";var JI=(r,e)=>({builder:n=>xW({description:r.schema.description,inputSchema:_W.object(r.schema.inputSchema),execute:async o=>{let i=e(n);n.logger.info({input:o},`Executing tool ${r.schema.name}`);try{await r.handle(n,o,i,void 0)}catch(s){i.addError(String(s))}let a=await i.serialize();return a.isError?n.logger.error({toolName:r.schema.name,input:o,err:a.content.map(s=>s.text).join(`
4363
+ ${r}`;default:return r}}var j$=15;async function Mp({command:r,aiPageFiltering:e,logger:t,fixtures:n,source:o,useMemory:i,maxRetries:a=j$}){if(!r.assertion.trim())throw new _("ActionFailureError","Assertion command is missing the assertion content");let{browser:s}=n,c=r.timeout?r.timeout*1e3:s.smartWaitingTimeout,l=EA(c),u=0,d=Date.now(),p,m,h;try{await Gr({action:()=>s.clearHighlights(),frameConfig:r.iframeUrl?{type:"url",url:r.iframeUrl}:void 0,browser:s,logger:t})}catch(f){t.warn({err:f},"Failed to clear highlights before AI check, continuing...")}let g;for(;u<a&&(!g||g-d<c);){n.abortSignal.throwIfAborted(),u!==0&&await ae(l,n.abortSignal),g=Date.now();let f=!1;try{if(p=await Gr({action:async()=>{let S=await vI(s,t,n.abortSignal);return m&&m.serializedTree===S.serializedTree&&m.screenshotBuff.equals(S.screenshotBuff)?(f=!0,p):(m=S,RI({command:r,state:S,fixtures:n,useMemory:i,useConsensus:!1,highlightElementsOnFailure:!1,attemptNumber:u,aiPageFiltering:e,logger:t,source:o}))},frameConfig:r.iframeUrl?{type:"url",url:r.iframeUrl}:void 0,logger:t,browser:s}),p?.success){p?.updatedMemory&&yl(r,p.updatedMemory,t);break}else throw p?.thoughts?new _("AssertionFailureError",p.thoughts):new _("InternalPlatformError","No thoughts were provided for AI assertion failure")}catch(y){n.abortSignal.throwIfAborted(),h=y instanceof Error?y:new Error(`${y}`),f?t.info(`AI check attempt ${u} failed (re-used previous result)`):t.info({err:y},`AI check assert attempt ${u} failed, retrying...`)}finally{u++}}if(!p?.success)try{p=await Gr({action:async()=>RI({command:r,state:await vI(s,t,n.abortSignal),fixtures:n,useMemory:i,useConsensus:!0,highlightElementsOnFailure:!0,attemptNumber:u,aiPageFiltering:e,logger:t}),frameConfig:r.iframeUrl?{type:"url",url:r.iframeUrl}:void 0,logger:t,browser:s})}catch(f){n.abortSignal.throwIfAborted(),h=f instanceof Error?f:new Error(`${f}`)}finally{u++}if(p?.updatedMemory&&yl(r,p.updatedMemory,t),!p?.success){let f=`AI check still failing after ${u} attempts.`;throw h&&(f+=` Latest result: ${h.message}`),new _("AssertionFailureError",f)}return{...p,succeedImmediately:!1,urlAfterCommand:s.url()}}async function vI(r,e,t){let[n,o]=await Promise.all([In(r,{abortSignal:t,skipWait:!0,skipWaitForPageLoad:!0,logger:e}),r.screenshot({retries:1,respectActiveFrame:!0})]);return{...n,screenshotBuff:o}}async function RI({command:r,state:e,fixtures:t,useConsensus:n,useMemory:o,highlightElementsOnFailure:i,aiPageFiltering:a,attemptNumber:s,source:c,logger:l}){let{browser:u,generator:d,abortSignal:p}=t,m={type:"ASSERTION"},{serializedTree:h,tree:g}=e,f=e.screenshotBuff,y=f.toString("base64"),S=u.url(),T=r.contextChoice??"MULTIMODAL",A=h;T!=="VISION_ONLY"&&(A=await qi({type:"assertion",serializedTree:h,tree:g,description:r.assertion,screenshot:y,options:{aiPageFiltering:a},fixtures:{generator:d,signal:p,logger:l,orgId:t.orgId}}),A!==h&&(m.ragUsed=!0),m.pageState=A);let b={goal:r.assertion,url:S,memory:o?r.cache?.memory:void 0,browserState:A,screenshot:y,contextChoice:T,source:c},x=await(T==="VISION_ONLY"?(M,P)=>d.getVisualAssertionResult(M,P):(M,P)=>d.getAssertionResult(M,P))(b,{useConsensus:n,attemptNumber:s,useMemory:o,disableCache:!!r.disableCache,abortSignal:p,logger:l,loggerTags:He(l)});return(x.result||i)&&x.relevantElements&&(m.relevantElementsSerialized=x.relevantElements.map(M=>u.getSerializedFormFromA11yId(M)).filter(M=>!!M),await V$(x.relevantElements,u,l)),{success:x.result,thoughts:x.thoughts,afterScreenshotOverride:f,updatedMemory:o?x.updatedMemory:void 0}}async function V$(r,e,t){let n=Date.now();for(let o of r){if(Date.now()-n>2e3){t.debug("Highlighting relevant elements took over 2s, aborting...");return}try{let i=new AbortController;await j(e.highlightA11yId(o),{milliseconds:1e3,fallback:()=>{throw i.abort(),new Error("Timed out waiting for highlighting to complete")}})}catch(i){t.debug({err:i},"Failed to highlight relevant element after assertion, continuing...");return}}}var $$=75e4,Ip=class extends Error{constructor(){super("The page content exceeds the maximum token limit for AI smart waiting."),this.name="ExceededMaxAISmartWaitingTokensError"}};async function AI(r,e){let{logger:t}=r,{abortSignal:n,browser:o}=e,i=Date.now();try{await W$(i,r,e)}catch(a){if(a instanceof Error&&(a.name==="AbortError"||a.name==="TimeoutError")||n.aborted)return;a instanceof Ip?t.warn("Skipping AI smart waiting due to excessive page size - falling back to naive waiting"):t.warn({err:a},"Unexpected error occurred during AI smart waiting");let s=o.smartWaitingTimeout-(Date.now()-i);s>0&&await ae(s,n)}finally{t.debug({durationMs:Date.now()-i},"AI smart waiting complete")}}async function W$(r,e,t){let{abortSignal:n,browser:o}=t;if(o.smartWaitingTimeout<3e3){await ae(o.smartWaitingTimeout,n);return}if(!e.description)throw new _("UserConfigurationError","Cannot locate element with empty description");await j(q$(r,e,t),{milliseconds:o.smartWaitingTimeout})}async function q$(r,e,t){let{logger:n,iframeUrl:o}=e,{browser:i}=t;for(;Date.now()-r<i.smartWaitingTimeout;)if(await Gr({action:async()=>K$(e,t),frameConfig:o?{type:"url",url:o}:void 0,browser:i,logger:n}))return}async function K$(r,e){let{testContext:t,logger:n,filterByViewport:o,allowNotActionableNodesOverride:i}=r,{browser:a,abortSignal:s,localCodeEvalTools:c,orgId:l,generator:u}=e,d=r.description;t&&(d=await sr({orgId:l,s:d,context:t,localTools:c,signal:s,logger:n}));let{serializedTree:p}=await In(a,{allowNotActionableNodesOverride:i,filterByViewport:o,abortSignal:s,logger:n});if(Pe(p)>$$)throw new Ip;s.throwIfAborted();let h;try{h=await a.screenshot({clearHighlights:!0,respectActiveFrame:!0,retries:2})}catch(S){throw new _("ActionFailureError",`Failed to take screenshot of page to perform smart waiting. The page may be unresponsive, or your machine might be severely resource constrained. Error: ${S instanceof Error?S.message:S}`)}let f=`data:image/jpeg;base64,${h.toString("base64")}`;s.throwIfAborted();let y=await u.getSmartWaitingDecision({browserState:p,description:d,screenshot:f},{abortSignal:s,loggerTags:He(n)});return n.debug({result:y},"Got smart waiting result"),y.isPageReady}var Y$=3e4;async function wI({command:r,logger:e,baseUrl:t,fetchImplementation:n=fetch}){let o=r.timeout??Y$/1e3,i=new AbortController,a=Object.fromEntries(Object.entries(r.headers||{}).filter(([d,p])=>d&&p));a["Content-Type"]="application/json";let s;if(Ba(r.url)&&(s=r.url),t&&Ha(r.url,t)&&(s=new URL(r.url,t).toString()),!s)throw new _("ActionFailureError",`Invalid URL: ${r.url}`);let l=await j((async()=>{try{return await n(s,{headers:a,method:"POST",body:JSON.stringify({query:r.query,variables:r.variables?JSON.parse(r.variables):void 0}),signal:i.signal})}catch(d){e.error({err:d},"Failed to make HTTP request")}})(),{milliseconds:o*1e3});if(!l)throw new _("ActionFailureError",`GraphQL request timed out after ${o} seconds`);if(!l.ok){let d,p=await l.text();try{d=JSON.parse(p)}catch{throw new _("ActionFailureError",`GraphQL request failed with status ${l.status}: ${p}`)}throw d?.errors?.length&&d?.errors[0]?.message?new _("ActionFailureError",`GraphQL request failed with status ${l.status}: ${d.errors[0].message}`):new _("ActionFailureError",`GraphQL request failed with status ${l.status}: ${p}`)}let u={};return l.headers.forEach((d,p)=>{u[p]=d}),{status:l.status,headers:u,json:await l.json()}}var $o=class{orgId;options;storage;localCodeEvalTools;uploadedFileStorage;visualDiffScreenshotStorage;browser;generator;executeAbortController=new AbortController;logger;recordAbortController=null;registeredListeners={};recordedRequests={};constructor({browser:e,generator:t,logger:n,storage:o,orgId:i,localCodeEvalTools:a,uploadedFileStorage:s,visualDiffScreenshotStorage:c,options:l}){this.orgId=i,this.options=l,this.browser=e,this.browser.registerAbortSignal(this.executeAbortController.signal),this.storage=o,this.uploadedFileStorage=s,this.visualDiffScreenshotStorage=c,this.localCodeEvalTools=a,this.generator=t,this.logger=n}setOpen(){this.executeAbortController=new AbortController,this.browser.registerAbortSignal(this.executeAbortController.signal)}setClosed(){this.executeAbortController.abort()}throwIfClosed(){this.executeAbortController.signal.throwIfAborted()}get closed(){return this.executeAbortController.signal.aborted}async evaluateAiAction({goal:e,startingScreenshot:t,history:n,disableCache:o,langfuseSessionId:i,lastError:a,logger:s=this.logger}){let[c,l]=await Promise.all([In(this.browser,{abortSignal:this.executeAbortController.signal,skipWait:!0,skipWaitForPageLoad:!0,logger:s}),this.browser.screenshot({retries:1,clearHighlights:!0})]),u=`data:image/jpeg;base64,${l.toString("base64")}`,d=await qi({type:"ai-action",description:e,screenshot:u,serializedTree:c.serializedTree,tree:c.tree,options:{aiPageFiltering:!!this.options?.aiPageFiltering},fixtures:{generator:this.generator,signal:this.executeAbortController.signal,logger:s,orgId:this.orgId}}),p={url:this.browser.url(),browserState:d,startingScreenshot:t,history:n,goal:e,screenshot:u,lastError:a};return await this.generator.getMultiturnAiActionEvaluation(p,{disableCache:o,abortSignal:this.executeAbortController.signal,loggerTags:{...He(s)},langfuseSessionId:i})}async promptToCommand({goal:e,startingScreenshot:t,history:n,actionHint:o,disableCache:i,logger:a=this.logger,langfuseSessionId:s}){let c=this.browser.url(),[l,u]=await Promise.all([In(this.browser,{abortSignal:this.executeAbortController.signal,skipWait:!0,skipWaitForPageLoad:!0,logger:a}),this.browser.screenshot({retries:1,clearHighlights:!0})]),d=`data:image/jpeg;base64,${u.toString("base64")}`,p=await qi({type:"ai-action",description:e,screenshot:d,serializedTree:l.serializedTree,tree:l.tree,options:{aiPageFiltering:!!this.options?.aiPageFiltering},fixtures:{generator:this.generator,signal:this.executeAbortController.signal,logger:a,orgId:this.orgId}}),m={url:c,browserState:p,startingScreenshot:t,history:n,goal:e,actionHint:o,screenshot:d};try{return await this.generator.getMultiturnAiActionCommand(m,{disableCache:i,abortSignal:this.executeAbortController.signal,loggerTags:{...He(a)},langfuseSessionId:s})}catch(h){throw new _("InternalWebAgentError",`Error generating command: ${h instanceof Error?h.message:h}`,{errOptions:{cause:h}})}}async getBrowserState(e){return In(this.browser,e)}async locateElement(e){return await kS({...e,aiPageFiltering:!!this.options?.aiPageFiltering},this.getControllerFixtures())}async locateElementWithSelector(e,t){return Gr({action:async()=>{let n=await this.browser.resolveHardcodedCssSelector({ctx:null,selector:e,timeoutMs:2e3,logger:this.logger});return{thoughts:"Located element with selector",target:{id:-1,selector:e,targetSource:"USER_CSS_SELECTOR",targetUpdateTime:new Date().toUTCString()},resolution:n}},frameConfig:t?{type:"url",url:t}:void 0,browser:this.browser,logger:this.logger})}getControllerFixtures(e){return{ctx:e??null,browser:this.browser,generator:this.generator,logger:this.logger,orgId:this.orgId,storage:this.storage,localCodeEvalTools:this.localCodeEvalTools,abortSignal:this.executeAbortController.signal}}shouldUseMemory(){return this.options?.useMemory??(this.orgId==="org_01HMSCJQBCCG51M2ZF65YC5B8W"||this.orgId==="org_01HMJTX4GT1KG94KZRCT8MZ6YB")}async wrapMultiElementTargetingCommand({ctx:e,tracer:t,command:n,targetNames:o,descriptions:i,caches:a,action:s,options:c,retriesWithAI:l=1}){let u=[];for(let d=0;d<i.length;d++){let p=i[d],m=await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:p,cache:a[d],action:async h=>h,options:{...c,targetName:o[d]}});u.push(m)}try{let d=await s(...u.map(h=>h.result)),p=h=>h==="fromTarget"?"From Target":h==="toTarget"?"To Target":"Target",m=u.map((h,g)=>h.thoughts?`${p(o[g])}: ${h.thoughts}`:void 0).filter(h=>!!h).join(" -------------- ")||void 0;return{result:d,elementInteractedDisplayStrings:u.map(h=>h.elementInteractedDisplayString),thoughts:m}}catch(d){if(this.throwIfClosed(),l>0)return this.logger.warn({err:d},"Failed to execute action with multiple cached targets, retrying with AI"),this.wrapMultiElementTargetingCommand({ctx:e,tracer:t,command:n,targetNames:o,descriptions:i,caches:i.map(()=>{}),action:s,options:c,retriesWithAI:l-1});throw new _("ActionFailureError",d.message,{errOptions:{cause:d}})}}async wrapElementTargetingCommand(e){let t=this.logger.child({commandId:e.command.id}),n;for(let o=0;o<2;o++)try{return await Gr({action:()=>this.wrapElementTargetingCommandHelper({...e,originalCache:e.originalCache??e.cache}),frameConfig:e.options.iframeUrl?{type:"url",url:e.options.iframeUrl}:void 0,browser:this.browser,logger:t})}catch(i){if(n=i,this.browser.userBrowserSettings.visualActions&&Pm(i)){t.warn({err:i},"Invalid mpath error, retrying element targeting command");continue}if(!this.browser.userBrowserSettings.visualActions&&(Nm(i)||Om(i))){t.warn({err:i},"Invalid momentic id error, retrying element targeting command");continue}if(Dm(i)){t.warn({err:i},"Invalid backend node id error, retrying element targeting command");continue}if(i instanceof fn&&i.retryableWithAI){t.warn({err:i},"Element cache disqualification error, retrying element targeting command");continue}throw i}throw n instanceof _?n:new _("ActionFailureError",n?.message??"An unknown error occurred during element targeting")}async wrapHardcodedCssTargetingCommandHelper({ctx:e,target:t,action:n,options:o,command:i}){let a=this.logger.child({commandId:i.id}),{targetName:s}=o;if(t.type!=="description")throw new _("ActionFailureError","Cannot use selector with non-description target");let c,l=Date.now(),u=Date.now();for(;Date.now()-u<this.browser.smartWaitingTimeout;){l=Date.now();try{let d=await this.browser.resolveHardcodedCssSelector({ctx:e,selector:t.elementDescriptor,targetName:s,logger:a});return{result:await n({locator:d.locator}),elementInteractedDisplayString:d.displayString}}catch(d){if(d.name==="AbortError")throw d;c=d,a.warn({err:d},"Failed to action on hardcoded css selector"),Date.now()-l<500&&await ae(500)}}throw c}async wrapElementTargetingCommandHelper(e){let{ctx:t,tracer:n,target:o,originalCache:i,action:a,options:s,command:c}=e,{disableCache:l,useSelector:u,targetName:d,targetHealingInProgress:p,source:m}=s,h=this.logger.child({commandId:c.id}),g=this.shouldUseMemory(),f=s.retriesWithAI??1,y=!1,S=CI(e.cache);if((!S||l)&&!fm(o))throw new _("ActionFailureError","Cannot target element with no cached data or element descriptor");if(u)return this.wrapHardcodedCssTargetingCommandHelper(e);l&&(h.info("Cache explicitly disabled for this step"),y=!0,S=void 0),S&&this.browser.userBrowserSettings.disableSecondaryCacheResolution&&S.targetSource==="HEURISTIC_HEALED"&&(y=!0,S=void 0),S?.inputDescription&&!TI(o.elementDescriptor,S.inputDescription)&&(h.warn({old:S.inputDescription,new:o.elementDescriptor},"Target cache was generated with a different description, clearing it automatically"),y=!0,S=void 0);let T=b=>!!b&&Ac(b),A=!0;if(!T(S)){A=!1,h.info({description:o.elementDescriptor,targetHealingInProgress:p,cacheBustedBeforeAction:y,memory:s.memory,useMemory:g},"Prompting AI for an updated element location"),(y||!i)&&await AI({description:o.elementDescriptor,iframeUrl:s.iframeUrl,source:m,logger:h,allowNotActionableNodesOverride:s.allowNotActionableNodesOverride},this.getControllerFixtures(t)),f--;let b;try{b=await kS({description:o.elementDescriptor,disableCache:!!s.disableCache,iframeUrl:s.iframeUrl,source:m,useMemory:g,memory:g?s.memory:void 0,aiPageFiltering:!!this.options?.aiPageFiltering,allowNotActionableNodesOverride:s.allowNotActionableNodesOverride,logger:h},this.getControllerFixtures(t))}catch(M){if(M instanceof pa&&M.updatedLocatorMemory){let P={id:-1,...i,memory:M.updatedLocatorMemory};zu({cmd:c,key:d,newTarget:P,logger:h,updatedWithAI:!0})}throw new _("ActionFailureError",M.message)}b.frameConfig&&this.browser.setActiveFrameConfig(b.frameConfig);let C=s.disableGlobalLocatorRedirect?{locator:b.resolution.locator}:await this.attemptLocatorRedirect(b.resolution.locator,h),x=await a(C);return zu({cmd:c,key:d,newTarget:b.target,logger:h,updatedWithAI:!0}),p&&(n.recordTargetAutoHeal({healType:"AI"}),b.target.targetSource="AI_HEALED",b.target.targetUpdateTime=new Date().toUTCString(),b.target.targetUpdateLoggerTags=He(h)),{result:x,elementInteractedDisplayString:b.resolution.displayString,thoughts:b.thoughts}}try{let b=await this.browser.resolveTarget(t,S,{allowNotActionableNodesOverride:s.allowNotActionableNodesOverride,targetName:d,logger:h,signal:this.executeAbortController.signal});(this.browser.userBrowserSettings.visualActions||this.browser.userBrowserSettings.globalLocatorRedirect!==!1)&&await this.browser.scrollIntoViewIfNeeded(b.locator);let C=s.disableGlobalLocatorRedirect?{locator:b.locator}:await this.attemptLocatorRedirect(b.locator,h),x=await a(C);if(Lt.increment("cache_target_resolution_v2",1,["outcome:hit","platform:web",`hasRequirements:${!!S.requirements}`,`hasAdditionalElements:${!!S.additionalElements}`,`orgId:${this.orgId}`,"cliVersion:2.28.1"]),zu({cmd:c,key:d,newTarget:S,logger:h,updatedWithAI:!1}),A){let M=b.decisions.filter(P=>P.matched);if(M.length!==1)h.warn({decisions:b.decisions},"Expected exactly 1 matching method for element location, got more or less");else{let P=M[0].type;n.recordTargetAutoHeal({healType:P})}}return{result:x,elementInteractedDisplayString:b.displayString}}catch(b){this.throwIfClosed();let C="unknown";b instanceof _r&&b.cacheMissReason&&(C=b.cacheMissReason),Lt.increment("cache_target_resolution_v2",1,["outcome:miss","platform:web",`hasRequirements:${!!S.requirements}`,`hasAdditionalElements:${!!S.additionalElements}`,`orgId:${this.orgId}`,"cliVersion:2.28.1",`missReason:${C}`]);let x=!1;if((b instanceof fn||Pm(b)||Nm(b)||Dm(b)||zE(b)||Om(b)||GE(b))&&(x=!0),b instanceof _&&!x)throw h.error({err:b},"Failed to execute action with cached target (fatal)"),b;if(f>0&&o){h.info({err:b},"Failed to execute action with cached target, retrying with AI");let M;return S.memory&&wc(S.memory)&&(M=S.memory),this.wrapElementTargetingCommand({ctx:t,tracer:n,command:c,target:o,cache:void 0,originalCache:i,action:a,options:{...s,memory:M,retriesWithAI:f,targetHealingInProgress:!0}})}throw new _("ActionFailureError",b.message,{errOptions:{cause:b}})}}async attemptLocatorRedirect(e,t){return this.browser.userBrowserSettings.globalLocatorRedirect!==!1?this.browser.performTargetRedirection(e,t):{locator:e}}async screenshotWithDimensions(e){return Il(this.browser,e)}async executePresetCommand(e,t,n,o,i){this.options?.slowMoMs&&await ae(this.options.slowMoMs);let a=await this.browser.getOpenPages(),s=this.browser.url(),c;try{c=await this.resolveCommandTemplateStrings(n,o)}catch(l){throw this.throwIfClosed(),new _("ActionFailureError",`Failed to substitute template strings in command: ${l.message}`,{errOptions:{cause:l}})}try{let l=await this.executePresetCommandHelper(e,t,n,o,i);return this.browser.userBrowserSettings.visualActions&&nE(n)?await this.browser.waitForDOMStability({timeout:Oe}):!this.browser.userBrowserSettings.visualActions&&["PRESS","TYPE"].includes(n.type)&&await this.browser.waitForDOMStability({timeout:ce}),this.options?.autoFollowNewTabs&&await F_({beforeUrl:s,command:n,beforePages:a.map(u=>u.url),browser:this.browser,logger:this.logger}),l}catch(l){throw l.name!=="AbortError"&&this.logger.error({err:l},"Error thrown in action controller"),l}finally{aw(n,c)}}createCallbacksForBrowser(e){return{createIsolatedFolder:()=>sS(e)}}async resolveCommandTemplateStrings(e,t){return pd({obj:e,context:t,bannedKeys:["type","a11yData","thoughts","cache","code"],orgId:this.orgId,logger:this.logger,signal:this.executeAbortController.signal,localTools:this.localCodeEvalTools})}async executePresetCommandHelper(e,t,n,o,i){i=i||"disableCache"in n&&!!n.disableCache;let a=this.logger.child({commandId:n.id});switch(n.type){case"SUCCESS":let s=n.condition;return s?.assertion.trim()?Mp({command:s,fixtures:this.getControllerFixtures(e),useMemory:this.shouldUseMemory(),aiPageFiltering:!!this.options?.aiPageFiltering,logger:a}):{succeedImmediately:!1,urlAfterCommand:this.browser.url()};case"AI_ASSERTION":{if(!n.assertion.trim())throw new _("ActionFailureError","Missing assertion");if(n.timeout&&n.timeout>1800)throw new _("AssertionFailureError",`AI check timeout of ${n.timeout} exceeds the maximum allowed value of 30 minutes.`);return Mp({command:n,fixtures:this.getControllerFixtures(e),useMemory:this.shouldUseMemory(),aiPageFiltering:!!this.options?.aiPageFiltering,logger:a})}case"AI_EXTRACT":{if(!n.goal.trim())throw new _("ActionFailureError","Cannot perform AI extraction without goal");if(n.schema){let f=qv(n.schema);if(f)throw new _("UserConfigurationError",f)}let h=await this.browser.getCondensedHtml(),g=await this.browser.screenshot({retries:2});try{let f=await this.generator.getTextExtraction({goal:n.goal,browserState:h,returnSchema:n.schema,screenshot:`data:image/jpeg;base64,${g.toString("base64")}`},{disableCache:i,abortSignal:this.executeAbortController.signal,loggerTags:He(a)});if(f.result==="NOT_FOUND")throw new _("ActionFailureError","No relevant data found for extraction goal on this page");if(f.thoughts?.includes("MaxGenerationLengthExceededError"))throw new _("UserConfigurationError",f.thoughts);return{thoughts:f.thoughts||void 0,data:f.result,succeedImmediately:!1,urlAfterCommand:this.browser.url()}}catch(f){let y=f.message;throw y.includes("MaxGenerationLengthExceededError")?new _("UserConfigurationError","You tried to extract too much data. Please rephrase your query to limit the results returned or use a JavaScript step in the browser instead."):y.includes("AIProviderError")&&y.includes("time")?new _("AIProviderError","The AI provider responded with an error. This may be because you tried to extract too much data. Please limit extraction results to 2000 characters.",{errOptions:{cause:f}}):f}}case"NAVIGATE":if(!Ba(n.url)&&!Ha(n.url,this.browser.baseUrl))throw new _("ActionFailureError",`Invalid URL provided to navigate command: ${n.url}`);await this.browser.navigate({url:n.url,loadTimeoutMs:n.loadTimeout?n.loadTimeout*1e3:void 0});break;case"DIALOG":this.browser.registerDialogHandler(n.action);break;case"CAPTCHA":if(!this.browser.canSolveCaptchas())break;let c=await this.browser.solveCaptcha();c&&(await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:{type:"description",elementDescriptor:"the captcha image solution input"},cache:void 0,action:h=>this.browser.click(h,this.createCallbacksForBrowser(this.orgId),{}),options:{...n,targetName:"target",disableCache:i}}),await this.browser.type(c,{clearContent:!0,pressEnter:!0},!0));break;case"GO_BACK":await this.browser.goBack();break;case"GO_FORWARD":await this.browser.goForward();break;case"SCROLL_LEFT":case"SCROLL_RIGHT":case"SCROLL_DOWN":case"SCROLL_UP":{let h,g;if(n.target&&mn(n.target))await this.browser.hoverUsingVisualCoordinates(n.target.pixels);else if(n.target&&n.target.elementDescriptor.trim()){let{elementInteractedDisplayString:S,thoughts:T}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:n.target,cache:n.cache?.target,action:A=>this.browser.hover(A),options:{...n,targetName:"target",disableGlobalLocatorRedirect:!0,disableCache:i}});h=S,g=T}let f=this.browser.getViewport()?.height??Kt.height,y=this.browser.getViewport()?.width??Kt.width;switch(n.type){case"SCROLL_UP":await this.browser.scrollVertical(-(n.deltaY??f));break;case"SCROLL_DOWN":await this.browser.scrollVertical(n.deltaY??f);break;case"SCROLL_LEFT":await this.browser.scrollHorizontal(-(n.deltaX??y));break;case"SCROLL_RIGHT":await this.browser.scrollHorizontal(n.deltaX??y);break}return{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:h,thoughts:g}}case"WAIT_FOR_URL":{if(n.timeout&&n.timeout>1800)throw new _("UserConfigurationError",`Wait for URL timeout of ${n.timeout} exceeds the maximum allowed value of 30 minutes.`);let h=n.matcher;await this.browser.waitForUrl({beforeUrl:this.browser.url(),matcher:h},{timeout:n.timeout?n.timeout*1e3:void 0,negated:n.negated,caseInsensitive:n.caseInsensitive});break}case"WAIT":if(n.delay>1800)throw new _("UserConfigurationError",`Wait timeout of ${n.delay} seconds exceeds the maximum allowed value of 30 minutes`);let l=n.delay*1e3;await ae(l,this.executeAbortController.signal);break;case"REFRESH":await this.browser.refresh({loadTimeoutMs:n.loadTimeout?n.loadTimeout*1e3:void 0});break;case"CLICK":{if(mn(n.target)){await this.browser.clickUsingVisualCoordinates(n.target.pixels,n);break}let h=this.browser.url(),{elementInteractedDisplayString:g,result:f,thoughts:y}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,target:n.target,command:n,cache:n.cache?.target,action:T=>this.browser.click(T,this.createCallbacksForBrowser(this.orgId),n),options:{disableCache:i,targetName:"target",...n}}),S={urlAfterCommand:this.browser.url(),succeedImmediately:!1,elementInteracted:g,thoughts:y,data:f.downloadedFile?{downloadedFile:f.downloadedFile}:void 0};return ed(h,S.urlAfterCommand)&&(S.succeedImmediately=!0,S.succeedImmediatelyReason="URL changed"),S}case"COPY":return await this.browser.copy(n.value),{succeedImmediately:!1,data:n.value,urlAfterCommand:this.browser.url()};case"PASTE":{await this.browser.paste();break}case"DRAG":{if(mn(n.fromTarget)&&mn(n.toTarget)){await this.browser.dragAndDropUsingVisualCoordinates(n.fromTarget.pixels,n.toTarget.pixels,{hoverSeconds:n.hoverSeconds});break}if(mn(n.fromTarget)||mn(n.toTarget))throw new Error("Drag and drop targets must be both coordinates or both descriptions");let{elementInteractedDisplayStrings:h,thoughts:g}=await this.wrapMultiElementTargetingCommand({ctx:e,tracer:t,command:n,targetNames:["fromTarget","toTarget"],descriptions:[n.fromTarget,n.toTarget],caches:[n.cache?.fromTarget,n.cache?.toTarget],action:(f,y)=>this.browser.dragAndDrop(f.locator,y.locator,{hoverSeconds:n.hoverSeconds,steps:n.steps}),options:{useSelector:!!n.useSelector,disableCache:i}});return{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:h[0],thoughts:g}}case"MOUSE_DRAG":{let h=parseInt(n.deltaX),g=parseInt(n.deltaY),f=n.steps??5;if(isNaN(h)||isNaN(g))throw new _("ActionFailureError",`Invalid pixel values passed to mouse drag command: (${n.deltaX}, ${n.deltaY})`);if(n.target&&mn(n.target)){await this.browser.mouseDragUsingVisualCoordinates(h,g,f,void 0,n.target.pixels);break}let y,S;if(n.target?.elementDescriptor){let{elementInteractedDisplayString:T,thoughts:A}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:n.target,cache:n.cache?.target,action:async b=>this.browser.mouseDrag(h,g,f,b.locator,{force:n.force}),options:{disableCache:i,targetName:"target",...n}});y=T,S=A}else await this.browser.mouseDrag(h,g,f,void 0,{force:n.force});return{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:y,thoughts:S}}case"SELECT_OPTION":{if(!po(n.target))throw new Error("Select with x/y is not supported yet");let h=n.target.elementDescriptor,g=n.choice,{elementInteractedDisplayString:f,thoughts:y}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:{type:"description",elementDescriptor:h},cache:n.cache?.target,action:S=>this.browser.selectOption(S,g,n.force),options:{...n,targetName:"target",disableCache:i,source:di(n)}});return{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:f,thoughts:y}}case"TAB":{let h={loadTimeoutMs:n.loadTimeout?n.loadTimeout*1e3:void 0,retry:!0};await this.browser.switchToPage(n.action,h);break}case"NEW_TAB":await this.browser.createNewTab(n.url,{loadTimeoutMs:n.loadTimeout?n.loadTimeout*1e3:void 0});break;case"COOKIE":if(!n.value)break;let u=await this.browser.setCookie(n.value);a.debug({results:u},"Set cookies");break;case"LOCAL_STORAGE":if(!n.value||!n.key)break;await this.browser.setLocalStorage(n.key,n.value);break;case"JAVASCRIPT":{let h;try{n.environment==="BROWSER"?(h=await this.browser.evaluateCodeInPage({code:n.code,fragment:n.fragment??!1,context:o.toObjectCopy(),timeoutMs:n.timeout?n.timeout*1e3:void 0}),a.info({result:h},"Executed JavaScript in browser")):h=await No({orgId:this.orgId,code:n.code,fragment:!!n.fragment,context:o,timeoutMs:n.timeout?n.timeout*1e3:void 0,logger:a,localTools:this.localCodeEvalTools,signal:this.executeAbortController.signal,callbacks:{onPersistentVariableUpdates:async g=>{if(!this.options?.scratchPadId){a.warn({updates:g},"Got persistent variable updates but scratch pad is not available");return}await this.storage.savePersistentVariables?.({scratchPadId:this.options?.scratchPadId,orgId:this.orgId,updates:g,logger:a})}}})}catch(g){throw this.throwIfClosed(),new _("ActionFailureError",g instanceof Error?g.message:`${g}`,{errOptions:{cause:g}})}try{JSON.stringify(h)}catch(g){throw new _("ActionFailureError",`Return value is not serializable: ${g instanceof Error?g.message:`${g}`}`,{errOptions:{cause:g}})}return{urlAfterCommand:this.browser.url(),succeedImmediately:!1,data:h}}case"TYPE":{if(n.target&&mn(n.target)){await this.browser.clickUsingVisualCoordinates(n.target.pixels,n),await this.browser.type(n.value,{force:n.force,clearContent:n.clearContent,forceClearContent:n.forceClearContent,delay:n.delay,pressEnter:n.pressEnter},!0);break}let h=this.browser.url(),g,f,y=CI(n.target),S=this.browser.userBrowserSettings.globalLocatorRedirect===void 0||this.browser.userBrowserSettings.globalLocatorRedirect==="always";if(y){let{elementInteractedDisplayString:A,thoughts:b}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:y,cache:n.cache?.target,action:C=>this.browser.typeIntoTarget(n.value,C,{force:n.force,clearContent:n.clearContent,forceClearContent:n.forceClearContent,delay:n.delay,pressEnter:n.pressEnter,relativePosition:n.relativePosition}),options:{...n,targetName:"target",disableCache:i,disableGlobalLocatorRedirect:!S,source:di(n)}});g=A,f=b}else await this.browser.type(n.value,{force:n.force,clearContent:n.clearContent,forceClearContent:n.forceClearContent,delay:n.delay,pressEnter:n.pressEnter},!0);let T={urlAfterCommand:this.browser.url(),succeedImmediately:!1,elementInteracted:g,thoughts:f};return ed(h,T.urlAfterCommand)&&(T.succeedImmediately=!0,T.succeedImmediatelyReason="URL changed"),T}case"HOVER":{if(mn(n.target)){await this.browser.hoverUsingVisualCoordinates(n.target.pixels);break}let{elementInteractedDisplayString:h,thoughts:g}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:n.target,cache:n.cache?.target,action:f=>this.browser.hover(f),options:{...n,targetName:"target",disableCache:i}});return{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:h,thoughts:g}}case"FOCUS":{if(!po(n.target))throw new Error("Focus with x/y is not supported yet");let{elementInteractedDisplayString:h,thoughts:g}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:n.target,cache:n.cache?.target,action:f=>this.browser.focus(f),options:{...n,targetName:"target",disableCache:i}});return{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:h,thoughts:g}}case"BLUR":{if(n.target&&!po(n.target))throw new Error("Blur with x/y is not supported yet");if(!n.target||!n.target.elementDescriptor)return await this.browser.blur(null),{succeedImmediately:!1,urlAfterCommand:this.browser.url()};let{elementInteractedDisplayString:h,thoughts:g}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,target:n.target,command:n,cache:n.cache?.target,action:f=>this.browser.blur(f),options:{...n,targetName:"target",disableCache:i}});return{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:h,thoughts:g}}case"PRESS":let d=this.browser.url();await this.browser.press(n.value,{repeat:n.repeat,convertMeta:n.convertMeta??!0,delayMs:n.delayMs});let p={urlAfterCommand:this.browser.url(),succeedImmediately:!1};return ed(d,p.urlAfterCommand)&&(p.succeedImmediately=!0,p.succeedImmediatelyReason="URL changed"),p;case"KEY_DOWN":return await this.browser.keyDown(n.value,{convertMeta:n.convertMeta??!0}),{urlAfterCommand:this.browser.url(),succeedImmediately:!1};case"KEY_UP":return await this.browser.keyUp(n.value,{convertMeta:n.convertMeta??!0}),{urlAfterCommand:this.browser.url(),succeedImmediately:!1};case"REQUEST":{let h=new J$,g=X$(fetch,h),f;try{f=new URL(n.url).hostname}catch{}return{data:{...await mw({command:n,baseUrl:this.browser.baseUrl,logger:a,fetchImplementation:g}),cookies:sT(h,f)},succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"GRAPHQL_REQUEST":return{data:await wI({command:n,baseUrl:this.browser.baseUrl,logger:a}),succeedImmediately:!1,urlAfterCommand:this.browser.url()};case"VISUAL_DIFF":return pw({ctx:e,tracer:t,command:n,disableCache:i,browser:this.browser,logger:a,storage:this.storage,screenshotStorage:this.visualDiffScreenshotStorage,targetingWrapper:h=>this.wrapElementTargetingCommand(h)});case"FILE_UPLOAD":{let h,g;if(n.fileSource.type==="URL"?(g=n.fileSource.url,h=await Z_({uri:n.fileSource.url,logger:a,orgId:this.orgId})):n.fileSource.type==="USER_FILE"&&(g=n.fileSource.name,h=await this.uploadedFileStorage?.getFileForUpload(n.fileSource.name,this.orgId)),!h)throw new _("UserConfigurationError",`Attempted to use non-existent file for upload step: ${g}`);await this.browser.setFileChooserHandler({...h,filename:n.filename});break}case"AUTH_SAVE":return{data:await this.browser.saveAuthState(),succeedImmediately:!1,urlAfterCommand:this.browser.url()};case"AUTH_LOAD":{let h;if(!n.storageState.trim())h=void 0;else if(h=await No({orgId:this.orgId,code:n.storageState,fragment:!1,context:o,logger:a,localTools:this.localCodeEvalTools,signal:this.executeAbortController.signal}),typeof h!="object")throw new _("ActionFailureError",`Credentials must evaluate to an object (received ${typeof h} instead)`);let g;try{g=uu.optional().parse(h)}catch(f){throw new _("ActionFailureError",`Credentials provided do not follow the required format: ${f}`)}await this.browser.loadAuthState(g);break}case"ELEMENT_CHECK":{let h=(n.timeout??hn)*1e3,g=this.generator.getAgentConfig()?.assertion;if(uw(n.assertion)&&!n.useSelector&&n.target.type==="description"&&g&&g!=="v1"){let y={id:n.id,type:"AI_ASSERTION",assertion:`There is no element on the page closely matches the following description. If the description has single quotes, remember that requires an exact text substring match. Description: ${n.target.elementDescriptor}`,iframeUrl:n.iframeUrl,timeout:n.timeout,cache:n.cache&&"memory"in n.cache?{memory:n.cache?.memory}:void 0};try{let S=await Mp({command:y,logger:a,aiPageFiltering:!!this.options?.aiPageFiltering,fixtures:this.getControllerFixtures(e),useMemory:this.shouldUseMemory(),source:"NEGATED_CHECK"});return{succeedImmediately:!1,thoughts:`The element described does not exist on the page: ${S.thoughts}`,urlAfterCommand:this.browser.url(),afterScreenshotOverride:S.afterScreenshotOverride}}finally{y.cache?.memory&&yl(n,y.cache?.memory.traces,a)}}let f=await cw({command:n,tracer:t,timeoutMs:h,targetingWrapper:y=>this.wrapElementTargetingCommand(y),fixtures:this.getControllerFixtures(e),disableCache:i});return{fail:!f.success,data:f.data,elementInteracted:f.elementInteractedDisplayString,thoughts:f.err?.message??f.thoughts??`Element assertion ${f.success?"succeeded":"failed"}.`,succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"PAGE_CHECK":{let h=await Gr({action:async()=>md({assertion:n.assertion,browser:this.browser,logger:a,timeout:n.timeout,signal:this.executeAbortController.signal,autoExpandIframes:!!this.browser.userBrowserSettings.autoExpandIframes}),frameConfig:n.iframeUrl?{type:"url",url:n.iframeUrl}:void 0,browser:this.browser,logger:a});return{fail:!h.success,data:h.data,thoughts:h.success?"Page assertion passed.":h.err?.message??`Page assertion still failing after ${n.timeout} seconds.`,urlAfterCommand:this.browser.url(),succeedImmediately:!1}}case"REGISTER_REQUEST_LISTENER":{let h=new Go(n.requestMatcher),g=this.browser.registerRequestListener(h);return this.registeredListeners[n.key]=g.then(async f=>await pS(f)).catch(f=>{a.error({err:f},"Failed to get request listener response")}),{succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"AWAIT_LISTENER":{let h=this.registeredListeners[n.key];if(!h)throw new _("ActionFailureError",`No listener registered with key: ${n.key}`);let g=n.timeout??10;return{data:await j(h,{milliseconds:g*1e3,message:`Request listener timed out after ${g} seconds`}),succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"RECORD_REQUESTS":{let h=new Go(n.requestMatcher);return this.recordedRequests[n.key]={},this.browser.registerRequestRecorder(n.key,{matches:g=>h.matches({url:g.request.url,method:g.request.method}),onRequestStart:(g,f)=>{this.recordedRequests[n.key][g]=yp(f)},onRequestComplete:(g,f)=>{this.recordedRequests[n.key][g]=yp(f)}}),{succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"GET_RECORDED_REQUESTS":{let h=this.recordedRequests[n.key];if(!h)throw new _("ActionFailureError",`No recorder registered with key: ${n.key}`);return delete this.recordedRequests[n.key],{data:Object.values(h),succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"SET_HEADER":{let h;return n.requestMatcher&&(h=new Go(n.requestMatcher)),this.browser.setHeader(n.name,n.value,h),{succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"MOCK_ROUTE":return{data:{key:this.browser.registerMock(n.key,new Go(n.requestMatcher),async(g,f)=>{let y=await No({orgId:this.orgId,code:n.responseGenerator,fragment:!1,context:o,timeoutMs:void 0,logger:a,localTools:this.localCodeEvalTools,mock:{request:g,response:f},disallowVariableUpdates:!0,responseSerialization:"RESPONSE"}),S=AT.parse(y);return new Response(S.body,{status:S.status,headers:S.headers})},n.fetchOriginalResponse??!1)},succeedImmediately:!1,urlAfterCommand:this.browser.url()};case"REMOVE_ROUTE_MOCK":return this.browser.removeMock(n.key),{succeedImmediately:!1,urlAfterCommand:this.browser.url()};case"OFFLINE_MODE":return await this.browser.setOfflineMode(n.enable),{succeedImmediately:!1,urlAfterCommand:this.browser.url()};default:return(h=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(n)}return{succeedImmediately:!1,urlAfterCommand:this.browser.url()}}async getReverseMappedDescription({browserState:e,targetId:t,disableCache:n,screenshot:o}){return(await this.generator.getReverseMappedDescription({browserState:e,target:t,screenshot:o},{disableCache:n,abortSignal:this.executeAbortController.signal,loggerTags:He(this.logger)})).phrase}async stopRecordMode(){this.recordAbortController?.abort(),await this.browser.clearAllCdpHighlights()}async startRecordMode({params:e,abortController:t,isClickToRecord:n}){this.recordAbortController=t;let o=new Ap({signal:t.signal,...e});return await this.browser.startRecording(this.recordAbortController.signal,o,n),o}async runSectionAutohealing(e){return this.generator.getAutohealingProposal(e,{disableCache:!0,abortSignal:this.executeAbortController.signal,loggerTags:He(this.logger)})}async getFailureRecoveryPlan(e){return this.generator.getFailureRecoveryPlan(e,{disableCache:!0,abortSignal:this.executeAbortController.signal,loggerTags:He(this.logger)})}};import{cloneDeep as Q$}from"lodash-es";var Z$={showOverlay:!1},Pp=class{sessions=new Map;sessionCountByIp=new Map;getCurrentConnectionsByIp(e){return this.sessionCountByIp.get(e)??0}getCurrentSessionsByIp(){return Object.fromEntries(this.sessionCountByIp)}reserveCapacityByIp(e){e&&this.sessionCountByIp.set(e,(this.sessionCountByIp.get(e)??0)+1)}releaseCapacityByIp(e){e&&this.sessionCountByIp.set(e,Math.max(this.getCurrentConnectionsByIp(e)-1,0))}registerSession({controller:e,context:t,cleanup:n,clientIp:o,sessionId:i,socket:a}){return this.sessions.set(i,{controller:e,context:t,cleanup:n,clientIp:o,browserBehavior:Q$(Z$),socket:a}),i}removeSession(e,t){(async()=>{let o=this.sessions.get(e);if(!o)return;this.releaseCapacityByIp(o.clientIp);let{controller:i}=o;try{i.setClosed(),await i.browser.cleanup()}catch(a){t.error({err:a},"Error cleaning up browser in global state manager")}try{await o.cleanup?.()}catch(a){t.error({err:a},"Error running cleanup function in global state manager")}this.sessions.delete(e)})()}getSession(e){return this.sessions.get(e)}};function xI(r,e,t,n){let o=Date.now(),i=Date.now(),a,s,c,l,u=!1,d=async(g,f)=>{if(!g.closed&&!g.isInPageLoad)try{let y=c;c=void 0;let S=g.url(),T=f.toEditorDisplayCopy();JSON.stringify(T)===JSON.stringify(a)&&S===l&&o>i||(r.emit("browserState",{logsPerPage:y?.logsPerPage,viewport:g.getViewport(),url:S,iframeSrcUrls:s??[],context:T,isInPageLoad:g.isInPageLoad}),o=Date.now()),l=S,a=T}catch(y){if(!r.connected)return;let S=y instanceof Error?y.message:`${y}`;if(S.includes("Frame was detached")||S.includes("Not attached to an active page")||S.includes("browser has been closed")||S.includes("UserInfrastructureError"))return;t.error({err:y,sessionId:e},"Error grabbing browser state")}},p=setInterval(()=>{let g=n.getSession(e),f=g?.controller?.browser;if(!f||f.closed){t.debug("Clearing browser state socket cron due to the browser being closed"),clearInterval(p);return}d(f,g.context)},1e3),m=(g,f)=>!!(JSON.stringify(g)!==JSON.stringify(s)||f.logsPerPage.some(y=>y.length>0)),h=setInterval(async()=>{let f=n.getSession(e)?.controller?.browser;if(!f||f.closed){clearInterval(h);return}else if(u)return;u=!0;try{let y=await f.getAllFrameUrls(),S=f.retrieveAndClearDebugData();m(y,S)&&(s=y,c=S,i=Date.now())}catch(y){t.warn({err:y},"Failed to fetch extended details")}finally{u=!1}},2500);return{timers:[p,h]}}var eW=3;async function _I({socket:r,logger:e,storageFactory:t,uploadedFileStorage:n,visualDiffScreenshotStorage:o,devicePixelRatio:i,generatorFactory:a,enricherFactory:s,authorization:c,settingsFactory:l,getOrgId:u,branchGetter:d,globalE2eStateManager:p}){let m=r.id,h=r.handshake.query.testId;if(!h)throw new Error("Socket connection request is missing testId");let g=await u({type:"e2e",testId:h}),f=await d?.();e=e.child({testId:h,orgId:g,sessionId:m,branch:f});let y=await a(g,e),S=await s(g,e),T=await l(g,e),A=await t(g),{testMetadata:b,baseUrl:C,envName:x,browserConfig:M,aiSettings:P,environmentVariables:U,localCodeEvalTools:V}=await Ki({testId:h,orgId:g,logger:e,storage:A,authorization:c,settings:T}),k=p.getSession(m);if(k)return e.info("Associating connection with existing session (likely reconnect)"),await k.controller.browser.clearAllCdpHighlights(),{type:"e2e",sessionId:m,orgId:g,testId:h};let z=r.handshake.headers["x-forwarded-for"]?.split(",")[0];if(e.info({clientIp:z,event:"connect",args:r.handshake.query},"Websocket event (connect)"),z&&p.getCurrentConnectionsByIp(z)>=eW)throw e.error({clientIp:z,sessions:p.getCurrentSessionsByIp(),...r.handshake.query},"Socket connection browser creation rate limit triggered"),new Error("You have exceeded the maximum number of connections allowed. Momentic limits the number of simultaneously open tabs to uphold browser reliability. Please close duplicate tabs and try again later.");p.reserveCapacityByIp(z);try{await tW({socket:r,baseUrl:C,envName:x,testMetadata:b,orgId:g,sessionId:m,logger:e,environmentVariables:U,clientIp:z,devicePixelRatio:i,storage:A,uploadedFileStorage:n,visualDiffScreenshotStorage:o,localCodeEvalTools:V,generator:y,enricher:S,browserConfig:M,aiSettings:P,globalE2eStateManager:p})}catch(Q){throw e.warn({err:Q},"Error setting up socket session, possibly due to client closing the connection"),p.releaseCapacityByIp(z),Q}return{type:"e2e",sessionId:m,testId:h,orgId:g}}async function tW({socket:r,baseUrl:e,envName:t,devicePixelRatio:n,testMetadata:o,orgId:i,sessionId:a,logger:s,storage:c,uploadedFileStorage:l,visualDiffScreenshotStorage:u,localCodeEvalTools:d,generator:p,environmentVariables:m,browserConfig:h,aiSettings:g,clientIp:f,enricher:y,globalE2eStateManager:S}){let T={viewport:o.advanced?.viewport??Kt,locale:o.advanced?.locale??So,timezoneId:o.advanced?.timezone??yo,geolocation:o.advanced?.geolocation??Eo,colorScheme:o.advanced?.colorScheme};n&&(T.deviceScaleFactor=n);let A=o.id,b=await pp({settings:h,orgId:i,baseUrl:e,envName:t,testName:o.name,localTools:d,envVariables:m,logger:s,customHeaders:void 0});s=s.child({orgId:i,sessionId:a,testId:A});let C=await $r.init({baseUrl:e,userBrowserSettings:b,enricher:y,storage:c,logger:s,contextArgs:T,iconKnowledgeBase:null,callbacks:{onTabsChange:(V,k)=>{r.emit("tabs",{tabs:V,activeTab:k})},onScreencastFrame:(V,k)=>{let z=r;kr&&(z=r.compress(!0)),z.emit("screenshot",{buffer:V},()=>{k()})},onSvgsCollected:V=>{r.emit("newIconDetected",{numIcons:V.newSvgs.length}),c.saveNewIcons(V,s)},onNetworkLogs:V=>{r.emit("networkLogs",{harEntries:V})}}});await C.navigate({url:e,initialNavigation:!0});let x=new $o({browser:C,generator:p,logger:s,orgId:i,options:{scratchPadId:void 0,slowMoMs:b.slowMoMs,autoFollowNewTabs:b.autoFollowNewTabs,useMemory:g.useMemory,aiPageFiltering:g.aiPageFiltering},storage:c,localCodeEvalTools:d,uploadedFileStorage:l,visualDiffScreenshotStorage:u}),M=xI(r,a,s,S),P=async()=>{M.timers.forEach(V=>clearInterval(V))},U=new or({baseUrl:e,testName:o.name,currentUrl:x.browser.url(),variablesFromEnvironment:m,envName:t});if(!r.connected)throw await C.cleanup(),new Error("Socket not connected anymore, not proceeding with session setup");r.emit("session",{url:e,userAgent:$r.USER_AGENT,viewport:x.browser.getViewport(),sessionId:a}),S.registerSession({controller:x,context:U,sessionId:a,cleanup:P,clientIp:f,socket:r})}async function Ki({testId:r,orgId:e,logger:t,storage:n,authorization:o,settings:i}){let a=await n.fetchTestMetadata(r,t);if(!a)throw new Error(`Test metadata could not found for test ${r}`);let s;o?.type==="API_KEY"&&(s=new vn({httpClient:new Bt({...o,logger:t,mode:"interactive"}),fakerSeed:void 0}));let c=a.envs?.find(g=>g.default),l;c&&(l=await n.fetchEnvironment(c.name,t));let u=l&&"browser"in l?l.browser:void 0,d={...i.browser,...u,...a.advanced},p=a.baseUrl||l?.variables?.[Tt];if(!p)throw new Error("Base URL is empty in both test options and the configured environment");let m={...l?.variables};m=await mp({orgId:e,testName:a.name,envName:l?.name,baseEnvVariables:m,parameters:a.parameters,logger:t,localTools:s});let h={...i.ai,...a.advanced};return{localCodeEvalTools:s,baseUrl:p,envName:l?.name,testName:a.name,browserConfig:d,environmentVariables:m,testMetadata:a,aiSettings:h}}var FS=class{parentTracer=null;socket;step;orgId;constructor({step:e,socket:t,parentTracer:n,orgId:o}){this.socket=t,this.parentTracer=n,this.step=e,this.orgId=o}getParentStepIdChain(){return this.parentTracer?this.parentTracer?.getParentStepIdChain()??[]:[]}recordStepDuration(e){let t=e.step.type!=="PRESET_ACTION"?e.step.type:e.step.command.type;Lt.distribution("test_step_duration",e.durationMs,[`type:${t}`,"platform:browser","executor:editor",`orgId:${this.orgId}`])}attachBeforeScreenshot(){}attachAfterScreenshot(){}attachBeforeHtmlSnapshot(){}attachAfterHtmlSnapshot(){}recordTargetAutoHeal(){}async finish(e){switch(e.step.status){case"SUCCESS":this.socket.emit("success",{...e,parentStepIdChain:this.getParentStepIdChain()});return;case"FAILED":this.socket.emit("failure",{...e,parentStepIdChain:this.getParentStepIdChain()});return;case"CANCELLED":this.socket.emit("cancelled",{...e,parentStepIdChain:this.getParentStepIdChain()});return}}async startSubSteps(){return new ro({parentStep:this.step,socket:this.socket,parentTracer:this,orgId:this.orgId})}},ro=class{stepFrequenciesByType={};parentTracer;parentStep;socket;orgId;recordStepStat(e){e.type!=="PRESET_ACTION"?this.stepFrequenciesByType[e.type]=(this.stepFrequenciesByType[e.type]||0)+1:this.stepFrequenciesByType[e.command.type]=(this.stepFrequenciesByType[e.command.type]||0)+1}sendFinalizedStepStats(){for(let[e,t]of Object.entries(this.stepFrequenciesByType))Lt.increment("test_step_execution",t,[`type:${e}`,"platform:browser","executor:editor",`orgId:${this.orgId}`])}constructor({parentStep:e,socket:t,parentTracer:n,orgId:o}){this.parentTracer=n,this.parentStep=e,this.socket=t,this.orgId=o}async getScreenshot(){throw new Error("getScreenshot is not supported in the editor")}async getHtmlSnapshot(){throw new Error("getHtmlSnapshot is not supported in the editor")}getParentStepIdChain(){return this.parentStep?[...this.parentTracer?.getParentStepIdChain()??[],this.parentStep.id]:[]}async startStep(e){return this.recordStepStat(e.step),this.socket.emit("started",{stepId:e.step.id,parentStepIdChain:this.getParentStepIdChain(),attempt:e.attempt}),new FS({step:e.step,parentTracer:this,socket:this.socket,orgId:this.orgId})}async finish(){this.sendFinalizedStepStats()}},Op=class{constructor(e,t,n,o){this.socket=e;this.storage=t;this.orgId=n;this.testId=o}children=[];loggerBindings;setActiveVideo(){}async getScreenshot(){throw new Error("getScreenshot is not supported in the editor")}async getHtmlSnapshot(){throw new Error("getHtmlSnapshot is not supported in the editor")}onNetworkPage(){}onNetworkLogs(){}attachConsoleLogs(){}attachBrowserCrashDump(){}async finish(){this.socket.emit("finished"),await Promise.all(this.children.map(e=>e.finish()))}async startBeforeStepList(){let e=new ro({orgId:this.orgId,parentStep:null,parentTracer:null,socket:this.socket});return this.children.push(e),e}async startMainStepList(){let e=new ro({orgId:this.orgId,parentStep:null,parentTracer:null,socket:this.socket});return this.children.push(e),e}async startAfterStepList(){let e=new ro({orgId:this.orgId,parentStep:null,parentTracer:null,socket:this.socket});return this.children.push(e),e}};var US={currentlyExecutingRequests:{}},nW=r=>async(e,t)=>{let{testId:n,orgId:o}=r.metadata,i=await r.settingsFactory(o,r.logger),a=await r.storageFactory(o),s,c=await Ki({testId:n,orgId:o,logger:r.logger,storage:a,authorization:r.authorization,settings:i}),l=`${n}|${c.baseUrl}`;try{let u=US.currentlyExecutingRequests[l]??0;US.currentlyExecutingRequests[l]=u+1,s=await oW({...r,...e,...c,done:t})}finally{r.logger.info({result:s,sessionId:r.metadata.sessionId},"Test execution complete"),US.currentlyExecutingRequests[l]--}},oW=async({socket:r,steps:e,baseUrl:t,testMetadata:n,reInitialize:o,toStep:i,fromStep:a,storageFactory:s,aiSettings:c,browserConfig:l,metadata:u,logger:d,envName:p,testName:m,environmentVariables:h,localCodeEvalTools:g,done:f,cacheStorageFactory:y,globalE2eStateManager:S})=>{let{testId:T,sessionId:A,orgId:b}=u,C=A,x=S.getSession(A);if(!x)throw new Error("No active session found");let{controller:M,context:P}=x;M.setOpen(),d=d.child({testId:T,orgId:b,sessionId:A,runId:C}),d.info({steps:e.map(oe=>`${oe.type}${"command"in oe?` - ${oe.command.type}`:""}`),toStep:i,fromStep:a,reInitialize:o,envName:p,testName:m,baseUrl:t,context:P,browserConfig:l,aiSettings:c},"Socket execution parameters");let U=h??{},V=async()=>{o&&(await M.browser.reset({newUrl:t}),P.reset({baseUrl:t,currentUrl:M.browser.url(),variablesFromEnvironment:U,envName:p,testName:m}))},k=await s(b),z=await y(b),Q=async()=>{let oe=Date.now();try{await z.resolveStepCacheEntries({schemaVersion:n.schemaVersion,testId:T,stepLists:{steps:e},logger:d})}catch(jt){d.error({err:jt},"Failed to fetch step cache entries from Momentic server. This can drastically reduce test reliability and performance.")}finally{Lt.distribution("cache-resolution",Date.now()-oe,["executor:editor"])}};try{await bl({promiseGenerator:async()=>Promise.all([V(),Q()]),signal:M.executeAbortController.signal,codePath:"resolveStepCacheAndInitBrowser"}),M.setOpen()}catch(oe){if(r.emit("finished"),oe.name!=="AbortError")throw new Error(`Failed to setup browser for execution: ${oe}`)}let Y=rW(e),Te={collectDebugData:!1,reinitializeBrowser:!1,disableHealing:!0},q={orgId:b,runId:C,testMetadata:n,steps:e,fromStep:a,toStep:i,orgSettings:{ai:c,browser:l}},it={controller:M,context:P,storage:k,codeEvalTools:g,usageTracker:new Ta,logger:d},Ge={test:{},step:{onDynamicAIActionStatusUpdateEvent:oe=>{r.emit("dynamicCommandStatusUpdate",oe)},onDynamicAIActionEvaluatingEvent:oe=>{r.emit("dynamicCommandEvaluating",oe)},onDynamicCommandGenerated:oe=>{r.emit("dynamicCommandGenerated",oe)},onDynamicCommandExecuted:oe=>{r.emit("dynamicCommandExecuted",oe)}}},Ye=new Op(r,k,b,T),Nt=await dp({fixtures:it,options:Te,callbacks:Ge,inputs:q,testParams:{tracer:Ye}}),Ie={logger:d,cacheStorage:z,orgId:b,testId:T,originalStepsWithCaches:{steps:Y},updatedStepsWithCaches:{steps:e}};return Nt?.status==="PASSED"?await Ku(Ie):Nt?.status==="FAILED"&&await Yu(Ie),await Ye.finish(),f?.(Nt),Nt.status};var MI={event:"execute",createHandler:nW};import{cloneDeep as iW}from"lodash-es";var aW=r=>async({command:e},t)=>{let{logger:n,generatorFactory:o,metadata:i}=r,a=iW(e),s=cA(a);if(s.category!=="NO_DESCRIPTION_PROVIDED"){if(s.category!=="NONE"){t?.({result:s});return}"cache"in a&&(a.cache=void 0);try{let l=await(await o(i.orgId,n)).getLintStepResult({command:a},{logger:n});t?.({result:l})}catch(c){n.error({event:"lint",err:c},"Failed to lint step"),t?.({result:void 0})}}},II={event:"lintStep",createHandler:aW};var sW=({metadata:r,logger:e,storageFactory:t,globalE2eStateManager:n})=>{let{sessionId:o,orgId:i}=r;return async(a,s)=>{let{description:c,command:l,testMetadata:u,returnScreenshot:d}=a;e.info({params:a},`Locate handler called - ${c}`);let p=n.getSession(o);if(!p)throw new Error("No active session found");let{controller:m,context:h}=p;m.setOpen();let g=await t(i),f=fi.parse(u.advanced??{}),y={},S;if(c){if("useSelector"in l&&l.useSelector)try{let T=await m.locateElementWithSelector(c,"iframeUrl"in l?l.iframeUrl:void 0);S=T.resolution.locator,y={target:T.target,thoughts:T.thoughts}}catch(T){e.warn({err:T},"Failed resolving target with selector"),s({err:`Failed locating element: ${T.message}`,decisions:T instanceof _r?T.decisions:void 0});return}else try{let T=await m.locateElement({description:c,disableCache:f.disableAICaching??!1,skipWait:!0,testContext:h,source:di(l),iframeUrl:"iframeUrl"in l?l.iframeUrl:void 0,memory:"cache"in l&&l.cache&&"target"in l.cache&&wc(l.cache.target.memory)?l.cache.target.memory:void 0,logger:e});y={target:T.target,thoughts:T.thoughts},S=T.resolution.locator}catch(T){(async()=>{try{let A=await m.browser.getCondensedHtml({skipWait:!0});e.warn({err:T,html:A.slice(0,1e5)},"Failed locating element with AI")}catch(A){e.warn({err:A},"Failed grabbing HTML after trying to locate element with AI")}})(),s({err:`${T.message}`});return}if(l.type==="SELECT_OPTION"&&S)try{y.options=await m.browser.getSelectOptions(S)}catch(T){e.warn({err:T},"Failed getting select options"),s({err:`Failed getting select options: ${T.message}`});return}e.info({result:y},"Locate handler result")}if(d)try{let{buffer:T,width:A,height:b}=await m.screenshotWithDimensions({clearHighlights:!0,locator:S}),C=await g.uploadScreenshot(T);y.screenshot={data:C,width:A,height:b},e.info({width:A,height:b},"Captured screenshot during locate")}catch(T){e.error({err:T},"Error capturing screenshot during locate"),s({err:`Error taking screenshot: ${T.message}`});return}if(s({result:y}),S)try{await Promise.all([m.browser.scrollIntoViewIfNeeded(S),m.browser.highlight(S)])}catch(T){e.warn({err:T},"Error highlighting element, continuing...")}}},PI={event:"locate",createHandler:sW};var lW=({metadata:r,logger:e,globalE2eStateManager:t})=>{let{sessionId:n}=r;return async({event:o,percentX:i,percentY:a})=>{let s=t.getSession(n);if(!s)throw new Error("No active session found");let c=s.controller.browser;if(c.closed||c.getActivePage().isClosed()){e.warn("Ignoring mouse move because the browser is closed");return}try{await c.clickMouseFromPositionPercentages(o,i,a)}catch(l){e.error({err:l},"Error performing click during cloud recording in control mode")}}},OI={event:"mouseClickEvent",createHandler:lW};var cW=({metadata:r,generatorFactory:e,logger:t,socket:n,globalE2eStateManager:o})=>{let{sessionId:i,orgId:a,testId:s}=r;return async({stepId:c,parentStepIdChain:l,attribute:u})=>{let d=o.getSession(i);if(!d)throw new Error("No active session found");let{controller:p}=d,m=await e(a,t);p.setOpen(),d.browserBehavior.showOverlay=!0;let h=new AbortController;h.signal.addEventListener("abort",async()=>{try{d.browserBehavior.showOverlay=!1,await p.stopRecordMode()}catch(y){t.warn({err:y},"Failed to stop record mode in target click socket handler")}},{once:!0});let g=!1,f=(y,S)=>{S.type!=="PRESET_ACTION"||S.command.type!=="CLICK"||(n.emit("targetRecordingUpdate",{type:y,stepId:c,parentStepIdChain:l,command:S.command,attribute:u}),h.abort(),g=!0)};setTimeout(()=>{g||(h.abort(),n.emit("targetRecordingUpdate",{type:"error",err:"Timed out waiting for click event",stepId:c,parentStepIdChain:l,attribute:u}))},1e4),await p.startRecordMode({params:{generator:m,logger:t,testId:s,orgId:a,callbacks:{onActionReceived:y=>f("clickReceived",y),onStepRecorded:y=>f("descriptionGenerated",y)}},abortController:h,isClickToRecord:!0}),n.emit("targetRecordingUpdate",{type:"listenersInitialized",stepId:c,parentStepIdChain:l,attribute:u})}},LI={event:"recordTargetClick",createHandler:cW};var uW=({metadata:r,logger:e,globalE2eStateManager:t})=>{let{sessionId:n}=r;return async({key:o})=>{let i=t.getSession(n);if(!i)throw new Error("No active session found");if(o==="Dead")return;let{controller:a}=i;if(a.browser.closed||a.browser.getActivePage().isClosed()){e.debug({sessionId:n},"Browser is closed, ignoring keyboard press socket event");return}try{a.setOpen(),await a.browser.keyDown(o,{})}catch(s){if(s.message.includes("has been closed")){e.debug({sessionId:n,err:s},"Browser is closed, ignoring key down socket event error");return}throw s}}},NI={event:"keyDownEvent",createHandler:uW};var dW=({metadata:r,logger:e,globalE2eStateManager:t})=>{let{sessionId:n}=r;return async({key:o})=>{let i=t.getSession(n);if(!i)throw new Error("No active session found");if(o==="Dead")return;let{controller:a}=i;if(a.browser.closed||a.browser.getActivePage().isClosed()){e.debug({sessionId:n},"Browser is closed, ignoring keyboard press socket event");return}try{a.setOpen(),await a.browser.keyUp(o,{})}catch(s){if(s.message.includes("has been closed")){e.debug({sessionId:n,err:s},"Browser is closed, ignoring key up socket event error");return}throw s}}},DI={event:"keyUpEvent",createHandler:dW};var pW=({metadata:r,logger:e,globalE2eStateManager:t})=>{let{sessionId:n}=r,o,i=0,a=(l,u)=>{let d=async()=>{o=void 0};clearTimeout(o),o=setTimeout(d,Math.min(1e3,250*(i+1)))},s,c=0;return async l=>{let u=t.getSession(n);if(!u)throw new Error("No active session found");let{controller:d,browserBehavior:p}=u,m=d.browser;if(m.closed||m.getActivePage().isClosed()){e.warn("Ignoring mouse move because the page is closed");return}if(l.event==="scroll"){let h=await m.scrollFromPositionPercentages(l.percentX,l.percentY,s?.x??0,s?.y??0),g=u.browserBehavior.recordingState?.transformer;g&&h&&g.recordScroll(h);return}p.showOverlay&&a(m,l);try{let h=await m.moveMouseFromPositionPercentages(l.percentX,l.percentY);c=0,s=h}catch(h){c++,c%5===0&&e.warn({err:h,mouseErrors:c},"Error in socket mouse move handler")}}},kI={event:"mouseMoveEvent",createHandler:pW};var mW=({metadata:r,generatorFactory:e,socket:t,logger:n,globalE2eStateManager:o})=>{let{sessionId:i,orgId:a,testId:s}=r;return async({stepId:c})=>{let l=o.getSession(i);if(!l)throw new Error("No active session found");let{controller:u,browserBehavior:d}=l,p=await e(a,n);n.info("Starting cloud recording");let m=new AbortController,h=await u.startRecordMode({params:{generator:p,logger:n,testId:s,orgId:a,callbacks:{onActionReceived:(g,f)=>{t.emit("stepRecorded",{stepId:c,step:g,offset:f})},onStepRecorded:(g,f)=>{t.emit("stepRecorded",{stepId:c,step:g,offset:f})}}},abortController:m,isClickToRecord:!1});d.recordingState={transformer:h}}},FI={event:"recordingStart",createHandler:mW};var hW=({metadata:r,logger:e,globalE2eStateManager:t})=>{let{sessionId:n}=r;return async()=>{let o=t.getSession(n);if(!o)throw new Error("No active session found");e.info("Stopping cloud recording"),await o.controller.stopRecordMode(),o.browserBehavior.recordingState=void 0,o.browserBehavior.showOverlay=!1}},UI={event:"recordingStop",createHandler:hW};var gW=({socket:r,metadata:e,logger:t,storageFactory:n,authorization:o,settingsFactory:i,globalE2eStateManager:a})=>async(s,c)=>{let{testId:l,sessionId:u,orgId:d}=e;t.info({testId:l,sessionId:u},"Refresh event received");let p=await i(d,t),m=await n(d),{baseUrl:h}=await Ki({testId:l,orgId:d,logger:t,storage:m,authorization:o,settings:p}),g=a.getSession(u);if(!g){r.emit("error",{message:"No session to refresh"});return}let{controller:f}=g;f.setOpen(),await f.browser.refresh();let y=f.browser.getViewport();t.info({baseUrl:h,viewport:y},`Session refreshed for test ${l} at ${h}`),c()},BI={event:"refresh",createHandler:gW};var fW=({socket:r,metadata:e,logger:t,storageFactory:n,authorization:o,settingsFactory:i,globalE2eStateManager:a})=>async()=>{let{testId:s,sessionId:c,orgId:l}=e;t.info({testId:s,sessionId:c},"Reset event received");let u=await i(l,t),d=await n(l),{baseUrl:p,envName:m,testName:h,environmentVariables:g}=await Ki({testId:s,orgId:l,logger:t,storage:d,authorization:o,settings:u}),f=a.getSession(c);if(!f){r.emit("error",{message:"No session to reset"});return}let{controller:y,context:S}=f;await y.browser.reset({newUrl:p});let T=y.browser.baseUrl;S.reset({baseUrl:T,currentUrl:y.browser.url(),variablesFromEnvironment:g,envName:m,testName:h});let A=y.browser.getViewport(),b=$r.USER_AGENT;t.info({baseUrl:p,viewport:A},`Session reset for test ${s} at ${T}`),r.emit("session",{url:T,userAgent:b,viewport:A,sessionId:c})},HI={event:"reset",createHandler:fW};var SW=({metadata:r,globalE2eStateManager:e})=>{let{sessionId:t}=r;return async({url:n})=>{let o=e.getSession(t);if(!o)throw new Error("No active session found");await o.controller.browser.switchToPage({type:"SUBSTRING",substring:n})}},zI={event:"switchTab",createHandler:SW};async function GI(r){return _I(r)}var jI=[QA,MI,PI,HI,BI,YA,zI,II,LI,FI,UI,kI,OI,NI,DI,JA,XA];var VI=r=>{let{logger:e}=r,t=new yW(r.baseServer,{cors:{origin:"*",methods:["GET","POST"]},pingTimeout:15*60*1e3,pingInterval:15*60*1e3,maxHttpBufferSize:1e7,perMessageDeflate:!0});return t.on("connection",async n=>{let o;try{e.info({event:"connection",transport:n.conn.transport.name},"Websocket connection established"),o=await GI({...r,socket:n,logger:e}),e=e.child(o)}catch(i){e.error({event:"connection",type:"websocket",err:i},"Failed to setup connection"),n.emit("error",{message:i instanceof Error?i.message:`${i}`}),n.disconnect(!0);return}jI.forEach(i=>EW(i,{...r,socket:n,metadata:o,logger:e}))}),t},EW=(r,e)=>{let t=r.createHandler(e),n=(...o)=>{["mouseMoveEvent","keyDownEvent","keyUpEvent","mouseClickEvent","lintStep"].includes(r.event)||e.logger.debug({...e.metadata,event:r.event},`Websocket event (${r.event})`);let i=a=>{e.logger.error({event:r.event,type:"websocket",err:a instanceof Error?a:new Error(`${a}`)},"Unhandled exception in socket handler"),e.socket.emit("error",{message:a instanceof Error?a.message:`${a}`})};try{let a=t.apply(void 0,o);a&&typeof a.catch=="function"&&a.catch(i)}catch(a){i(a)}};e.socket.on(r.event,n)};import{Router as AW}from"express";import{Router as TW}from"express";import ac from"fs";import ic from"path";import{v4 as vW}from"uuid";import RW from"yaml";import{hostname as bW}from"os";var oc="2.28.1",et=Ma({app:"desktop-server",hostname:bW(),disableConsoleLogs:!0}).child({cliVersion:oc});(async()=>{try{let r=await Qn(et);r.gitBranchName&&et.addBinding("branch",r.gitBranchName)}catch{}})();var hs=TW();async function BS(r){return(await sd(r,et)).map(n=>{let o=r.modules[n.moduleId];if(!o){E.warn(`Found a dangling module with ID ${n.moduleId} that could not be found on disk.`);return}return{...o,content:n}}).filter(n=>n!==void 0)}hs.get("/",Me(async(r,e)=>{let t=se(),n=await Z(t),o=await BS(n);e.status(200).json(o)}));hs.post("/",Me(async(r,e)=>{let t;try{t=UT.parse(r.body)}catch(s){e.status(400).json({error:`Invalid request body: ${s}`});return}try{go(t.name)}catch(s){e.status(400).json({error:`Invalid module name: ${s}`});return}let n=se(),o=(await Z(n)).modules;if(Object.values(o).find(s=>s.name===t.name)){e.status(400).send(`A module with the name "${t.name}" already exists. Please choose a different name.`);return}let i=ic.join(n.rootDir,t.folderPath??"");if(!ac.existsSync(i)||!ac.statSync(i).isDirectory()){e.status(400).json({error:`The folder configured for module creation '${i}' does not exist.`});return}let a=await ad({...t,folder:i,project:n});e.status(201).json(a)}));hs.get("/:moduleId",Me(async(r,e)=>{if(!r.params.moduleId){e.status(400).json({error:"Missing moduleId in url path."});return}let t=await Z(se()),n=t.modules[r.params.moduleId];if(!n){e.status(404).json({error:"Module not found."});return}try{let o=await nn(n,t,E);e.json(o)}catch(o){e.status(400).json({err:o})}}));hs.post("/:moduleId/duplicate",Me(async(r,e)=>{if(!r.params.moduleId){e.status(400).json({error:"Missing moduleId in url path."});return}let t;try{t=FT.parse(r.body)}catch(g){e.status(400).json({error:`Invalid request body: ${g}`});return}try{go(t.name)}catch(g){e.status(400).json({error:g.message});return}let n=se(),o=await Z(n),i=o.modules[r.params.moduleId];if(!i){e.status(404).json({error:"Module not found."});return}if(Object.values(o.modules).find(g=>g.name===t.name)){e.status(400).send(`A module with the name "${t.name}" already exists. Please choose a different name.`);return}let a=await nn(i,o,E),s=ic.join(n.rootDir,ic.dirname(i.relativePath));if(!ac.existsSync(s)||!ac.statSync(s).isDirectory()){e.status(400).json({error:`The folder configured for module creation '${s}' does not exist.`});return}let c=Ue(t.name),l=ic.join(s,`${c}.module.yaml`),u=vW(),{stepsToSave:d}=await nt({stepLists:{steps:a.steps},createNewCacheIds:!0,cacheCreationParams:{orgId:wt()}}),p={fileType:he.MODULE,schemaVersion:Ce,moduleId:u,name:t.name,description:"",enabled:!0,steps:d.steps,parameters:a.parameters,defaultParameters:a.defaultParameters,parameterEnums:a.parameterEnums,defaultCacheKey:a.defaultCacheKey,defaultCacheTtl:a.defaultCacheTtl,defaultCacheAllInvocations:a.defaultCacheAllInvocations,autoAuth:a.autoAuth,advanced:a.advanced},m=RW.stringify(p);ac.writeFileSync(l,m,"utf-8");let h={relativeFilePath:ic.relative(n.rootDir,l)};e.status(201).json(h)}));hs.patch("/:moduleId/metadata",Me(async(r,e)=>{if(!r.params.moduleId){e.status(400).json({error:"Missing moduleId in url path."});return}let t;try{t=BT.parse(r.body)}catch(i){e.status(400).json({error:`Invalid request body: ${i}`});return}let n=se(),o=await Z(n);_A({moduleId:r.params.moduleId,content:t,momenticFiles:o,logger:E,project:n}),e.status(201).json({message:"ok"})}));var $I=hs;var WI=AW();WI.get("/",Me(async(r,e)=>{let t=se(),n=await Z(t),o=new Set;n?.tests&&Object.values(n.tests).forEach(l=>{l.labels?.forEach(u=>o.add(u))});let i=Array.from(o).sort(),a=Object.values(n.tests),s=await BS(n),c={labels:i,tests:a,modules:s};e.status(200).json(c)}));var qI=WI;import{Router as wW}from"express";var HS=wW();HS.get("/",Me((r,e)=>{let t=ld(se(),et);e.status(200).json(t)}));HS.get("/names",Me((r,e)=>{let n=se().config.environments?.map(o=>o.name)??[];e.status(200).json(n)}));var KI=HS;import{Router as CW}from"express";var YI=CW();YI.get("/",Me((r,e)=>{let t={userId:Po(),orgId:wt(),cliVersion:oc??"0.0.0"};e.status(200).json(t)}));var XI=YI;import{StreamableHTTPServerTransport as kq}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{isInitializeRequest as Fq}from"@modelcontextprotocol/sdk/types.js";import{randomUUID as Uq}from"crypto";import{Router as Bq}from"express";import{McpServer as Nq}from"@modelcontextprotocol/sdk/server/mcp.js";import{SSEServerTransport as Dq}from"@modelcontextprotocol/sdk/server/sse.js";import{streamObject as PW}from"ai";import Dp from"dedent";import{z as Wo}from"zod";import{tool as xW}from"ai";import{z as _W}from"zod";var JI=(r,e)=>({builder:n=>xW({description:r.schema.description,inputSchema:_W.object(r.schema.inputSchema),execute:async o=>{let i=e(n);n.logger.info({input:o},`Executing tool ${r.schema.name}`);try{await r.handle(n,o,i,void 0)}catch(s){i.addError(String(s))}let a=await i.serialize();return a.isError?n.logger.error({toolName:r.schema.name,input:o,err:a.content.map(s=>s.text).join(`
4364
4364
  `)},"Tool execution resulted in error"):n.logger.info({toolName:r.schema.name,input:o},"Tool execution completed"),a}}),tool:r});var sc=class{results=[];isError;addResult(e){this.results.push(e)}addError(e){this.results.push(`Error: ${e}`),this.isError=!0}getResult(){return this.results.join(`
4365
4365
  `)}async serialize(){let e=[];return this.results.length&&(e.push("### Result"),e.push(this.results.join(`
4366
4366
  `)),e.push("")),{content:[{type:"text",text:e.join(`
@@ -4795,7 +4795,7 @@ ${r.map(p=>`${bt}- ${p}`).join(`
4795
4795
  `)}`),Object.values(e.tests).forEach(p=>{r.some(m=>p.relativePath.includes(m))&&c.add(p.fullFilePath)}))}else{!n&&!await Ut("No test paths or substrings were provided. Do you want to run all tests?")&&(s.error("Cancelled by user."),process.exit(1));let u=Object.values(e.tests);s.info(`Reading all ${u.length} tests in the project from local disk.`),u.forEach(d=>{c.add(d.fullFilePath)})}for(let u of c){let d=gy.relative(t.rootDir,u);o&&!o.some(p=>new RegExp(p).test(d))&&c.delete(u),i&&i.some(p=>new RegExp(p).test(d))&&c.delete(u)}let l=Array.from(c).map(async u=>{try{let d=await ut(u,X,e);if(mK.gt(d.schemaVersion,Ce)&&s.warn(`Test ${u} has schema version ${d.schemaVersion}, which is greater than what is currently supported by this SDK. Please update your momentic package version to avoid unexpected behavior.`),a&&a.length>0){let p=d.labels||[];if(!a.some(h=>p.includes(h)))return null}return{...d,fullFilePath:u,relativeFilePath:gy.relative(t.rootDir,u)}}catch(d){s.error(`Failed to read and resolve test at '${u}': ${d}`),process.exit(1)}});return Promise.all(l).then(dK)}function EO({testDefinitions:r,quarantinedTestReasons:e,onlyQuarantined:t=!1,skipQuarantined:n=!1}){if(t){let[u,d]=rm(r,h=>h.id in e),[p,m]=rm(u,h=>h.disabled||n);return{testsToSkip:p,quarantinedTestsToSkip:[],testsToRun:m,quarantinedTestsToRun:[]}}let[o,i]=rm(r,u=>u.disabled),[a,s]=rm(i,u=>u.id in e);return{testsToSkip:o,testsToRun:s,quarantinedTestsToRun:n?[]:a,quarantinedTestsToSkip:n?a:[]}}function bO({testsToRun:r,quarantinedTestsToRun:e,quarantinedTestReasons:t,testInputMatrix:n}){let o=[],i=(a,s,c)=>{n?n.forEach((l,u)=>{o.push({inputs:l,inputIndex:u,testDefinition:a,quarantined:s,quarantinedReason:c})}):o.push({inputs:void 0,testDefinition:a,quarantined:s,quarantinedReason:c})};return r.forEach(a=>i(a,!1)),e.forEach(a=>i(a,!0,t[a.id])),o}async function TO({project:r,apiClient:e}){let t=await Z(r),n=await vs({tests:[],momenticFiles:t,yes:!0,project:r,logger:new vi(40,{})}),o=(await e.getQuarantinedTests()).quarantined,i=new Set(o.map(s=>s.testId)),a=n.filter(s=>i.has(s.id));E.info(a.map(s=>s.relativeFilePath).join(`
4796
4796
  `))}async function vO({test:r,reason:e,apiClient:t,project:n,identity:o}){let i=(await Z(n)).tests,a=Object.values(i),s=(await t.getQuarantinedTests()).quarantined,c=new Set(s.map(p=>p.testId)),l=a.filter(p=>c.has(p.id)),u=await em({prompt:"Select a test to unquarantine.",inputtedTest:r,testOptions:l}),d=await tm({prompt:"Enter a reason for unquarantining the test.",inputtedReason:e});await t.unquarantineTest(u,d,o),E.success(`Test ${u.name} has been successfully removed from quarantine.`)}function RO(r){return r?Ue(r):"Unknown suite"}async function AO({client:r,orgId:e,suitePaths:t,wait:n,waitTimeout:o,...i}){let{suiteRunIds:a,runGroupIds:s}=await r.queueSuiteRuns({paths:t,...i});X.info({orgId:e,suiteRunIds:a,runGroupIds:s,suitePaths:t},"Queued suites remotely"),E.dimmed(`Queued ${t.length} suites.`),n||process.exit(0);let c=Date.now();E.dimmed(`Waiting for ${t.length} suites to finish. You can view results upon completion at:`);for(let f of s)E.dimmed(`${bt}- ${r.getAppUrl()}/run-groups/${f}`);let l=new Set,u=[],d=f=>(f.status==="FAILED"||f.status==="PASSED"||f.status==="CANCELLED")&&f.runs.every(S=>S.status==="FAILED"&&(S.failureReason||S.finishedAt&&Date.now()-S.finishedAt.getTime()>30*1e3)||S.status==="PASSED"||S.status==="CANCELLED"),p=await Iu({name:"suites",getResults:async()=>{let f=s.filter(T=>!u.some(A=>A.id===T)),y=await r.bulkGetRunGroupStatus(f),S=[];for(let T of y)d(T)?u.push(T):S.push(T);return[...u,...S]},timeoutMs:o?o*1e3:void 0,checkDone:f=>(f.forEach(y=>{y.status==="RUNNING"&&(l.has(y.id)||(l.add(y.id),E.log(`${l.size}/${s.length} ${RO(y.suite?.name)}`)))}),f.every(d))}),m=r.getAppUrl(),g=Ia({results:p,startTime:c,onFailed:f=>{let y=RO(f.suite?.name),S=f.runs.filter(A=>A.status==="FAILED").length,T=f.runs.length;E.error(`${y} (${S}/${T} tests failed):`);for(let A of f.runs)if(A.status==="FAILED"){let b=A.testName||A.test?.name;E.error(` ${b?Ue(b):"Unknown test"} (${m}/runs/${A.id})`)}},entity:"suite",getDisplayLine:f=>` ${f.suite?.name?Ue(f.suite.name):"Unknown suite name"} (${m}/run-groups/${f.id})`});process.exit(g.failed>0?1:0)}async function wO({tests:r,client:e,orgId:t,...n}){!n.yes&&!await Ut(`This command will queue ${r.length} tests to run remotely on Momentic's infrastructure. Results will be available on ${e.getAppUrl()}. Continue?`)&&process.exit(1);let{queuedTests:o,runIds:i}=await e.queueTests({testPaths:r,...n});if(X.info({queuedTests:o,runIds:i,orgId:t},"Queued tests remotely"),E.dimmed(`Queued ${o.length} tests. Processing time may depend on a variety of factors, including how many tests have already been queued from your organization.`),n.wait||process.exit(0),!i.length)return;E.dimmed(`Waiting for ${o.length} tests to complete.`);let a=new Set,s=[],c=m=>m.status==="FAILED"&&m.failureReason||m.status==="PASSED"||m.status==="CANCELLED",l=e.getAppUrl(),u=Date.now(),d=await Iu({name:"runs",getResults:async()=>{let m=i.filter(f=>!s.some(y=>y.id===f)),h=await e.bulkGetRunStatus(m),g=[];for(let f of h)c(f)?s.push(f):g.push(f);return[...s,...g]},timeoutMs:n.waitTimeout?n.waitTimeout*1e3:void 0,checkDone:m=>(m.forEach(h=>{if(h.status==="RUNNING"&&!a.has(h.id)){a.add(h.id);let g=h.testName||h.test?.name;g&&E.log(`${a.size}/${o.length} ${Ue(g)}`)}}),m.every(c))}),p=Ia({results:d,startTime:u,onFailed:m=>{let h=m.testName||m.test?.name;Pu(m,h?Ue(h):"Unknown test")},getDisplayLine:m=>{let h=m.testName||m.test?.name,g=` ${h?Ue(h):"Unknown test"}`;return m.id&&(g+=` (${l}/runs/${m.id})`),g},entity:"test"});process.exit(p.failed>0?1:0)}import{randomUUID as QK}from"crypto";import ZK from"fs";import{existsSync as xK,mkdirSync as _K,statSync as MK}from"fs";import{randomUUID as CO}from"crypto";import fy from"fs";import{hostname as hK}from"os";import Sy from"path";async function nm(r,e,t,n){if(n){let o=await e.getScreenshot(r,n);if(o){let i=`${n}-screenshot.jpeg`,a=Sy.join(t,i);return fy.writeFileSync(a,o),i}}}async function gK(r,e,t,n){let o=n.runId??CO(),i={uuid:o,historyId:o,testCaseId:n.test.id,fullName:n.test.name,name:Ue(n.test.name),status:n.status==="PASSED"?"passed":n.status==="CANCELLED"?"skipped":"failed",start:n.lastAttemptStartedAt.getTime(),stop:n.finishedAt.getTime(),parameters:[],labels:[{name:"suite",value:t.suiteName},{name:"host",value:hK()},{name:"platform",value:"momentic"},{name:"attempts",value:n.attempts.toString()}],steps:[]};n.runId&&i.labels?.push({name:"runUrl",value:`https://app.momentic.ai/runs/${n.runId}`});for(let[s,c]of Object.entries(n.parameters))c!=null&&i.parameters.push({name:s,value:JSON.stringify(c)});n.results&&await fK(r,e,t.folder,i.steps,n.results);let a=`${o}-result.json`;fy.writeFileSync(Sy.join(t.folder,a),JSON.stringify(i,void 0,2))}async function Rs(r,e,t,n){let o={name:rn(n),start:n.startedAt.getTime(),stop:n.finishedAt.getTime(),status:n.status==="SUCCESS"?"passed":n.status==="CANCELLED"?"skipped":"failed",labels:[],steps:[],attachments:[]};n.beforeUrl&&o.labels?.push({name:"URL before step",value:n.beforeUrl}),n.afterUrl&&o.labels?.push({name:"URL after step",value:n.afterUrl});let i=await nm(r,e,t,n.beforeSnapshot);i&&o.attachments.push({name:"Screenshot before step",source:i,type:"image/jpeg"});let a=await nm(r,e,t,n.afterSnapshot);if(a&&o.attachments.push({name:"Screenshot after step",source:a,type:"image/jpeg"}),n.message&&(o.statusDetails={message:n.message}),n.data){let s=`${CO()}-attachment.json`,c=Sy.join(t,s);fy.writeFileSync(c,JSON.stringify(n.data,null,2)),o.attachments.push({name:"Step output data",source:s,type:"text/plain"})}return o}async function fK(r,e,t,n,o){for(let i of o)switch(i.type){case"PRESET_ACTION":{n.push(await Rs(r,e,t,i));break}case"CONDITIONAL":{let a=await Rs(r,e,t,i);a.steps=[],i.assertionResult&&a.steps.push(await Rs(r,e,t,i.assertionResult)),a.steps.push(...await Promise.all(i.results.map(s=>Rs(r,e,t,s)))),n.push(a);break}case"AI_ACTION":case"SECTION":case"MODULE":{let a=await Rs(r,e,t,i);if(a.steps=await Promise.all(i.results.map(s=>Rs(r,e,t,s))),i.type==="MODULE"&&i.inputs){a.parameters=[];for(let[s,c]of Object.entries(i.inputs))a.parameters.push({name:s,value:c})}n.push(a)}}}async function xO(r,e,t,n){for(let o of n.runs)await gK(r,e,{folder:t,suiteName:n.suiteName},o)}import SK from"junit-report-builder";import om from"path";function yK(r,e){if(e.name(r.test.name).className(r.test.name).file(om.relative(".",r.filePath)).property("id",r.test.id).property("dd_tags[id]",r.test.id),r.test.labels&&(e.property("labels",r.test.labels.join(",")),r.test.labels.forEach(t=>{e.property("dd_tags[label]",t)})),r.baseUrl&&(e.property("base_url",r.baseUrl),e.property("dd_tags[base_url]",r.baseUrl)),r.runId&&(e.property("run_url",`https://app.momentic.ai/runs/${r.runId}`),e.property("dd_tags[run_url]",`https://app.momentic.ai/runs/${r.runId}`)),r.quarantined&&(e.property("quarantined","true"),e.property("dd_tags[quarantined]","true"),r.quarantinedReason&&(e.property("quarantined_reason",r.quarantinedReason),e.property("dd_tags[quarantined_reason]",r.quarantinedReason))),r.beforeResults?.some(t=>t.status==="FAILED")&&(e.property("setup_failed","true"),e.property("dd_tags[setup_failed]","true")),r.results?.some(t=>t.status==="FAILED")&&(e.property("main_failed","true"),e.property("dd_tags[main_failed]","true")),r.afterResults?.some(t=>t.status==="FAILED")&&(e.property("teardown_failed","true"),e.property("dd_tags[teardown_failed]","true")),r.status==="FAILED"){if(r.failureReason){let t=Bc[r.failureDetails?.classification?.reason||r.failureReason],n=r.failureDetails?.classification?.summary||da[r.failureReason];r.runId&&(n+=` Visit https://app.momentic.ai/runs/${r.runId} for more details.`),e.failure(n,t)}r.failureDetails?.errorStack&&e.stacktrace(r.failureDetails.errorStack)}else r.status==="CANCELLED"&&e.skipped();return e.time((r.finishedAt.getTime()-r.lastAttemptStartedAt.getTime())/1e3).property("started_at",r.lastAttemptStartedAt.toISOString()).property("dd_tags[started_at]",r.lastAttemptStartedAt.toISOString()).property("finished_at",r.finishedAt.toISOString()).property("dd_tags[finished_at]",r.finishedAt.toISOString()),e.property("attempts",r.attempts.toString()).property("dd_tags[attempts]",r.attempts.toString()),r.parameters.envName&&(e.property("environment",r.parameters.envName),e.property("dd_tags[environment]",r.parameters.envName)),r.parameters.urlOverride&&e.property("url_override",r.parameters.urlOverride),e}function EK(r,{suiteId:e,suiteName:t,startedAt:n,finishedAt:o,runs:i,testsToSkip:a,quarantinedTestsToSkip:s,quarantinedTestReasons:c}){let l=r.testSuite().name(t);e&&l.property("id",e),l.timestamp(n).property("startedAt",n.toISOString()).property("finishedAt",o.toISOString()).time((o.getTime()-n.getTime())/1e3);for(let u of i){let d=l.testCase();yK(u,d)}for(let u of a){let d=l.testCase();d.name(u.name).className(u.name).file(om.relative(".",u.relativeFilePath)).property("id",u.id),u.baseUrl&&d.property("baseUrl",u.baseUrl),u.labels&&(d.property("labels",u.labels.join(",")),u.labels.forEach(p=>{d.property("dd_tags[label]",p)})),d.skipped()}for(let u of s){let d=l.testCase();d.name(u.name).className(u.name).file(om.relative(".",u.relativeFilePath)).property("id",u.id).property("quarantined","true");let p=c[u.id];p&&d.property("quarantinedReason",p),u.baseUrl&&d.property("baseUrl",u.baseUrl),u.labels&&(d.property("labels",u.labels.join(",")),u.labels.forEach(m=>{d.property("dd_tags[label]",m)})),d.skipped()}return l}function _O(r,e){let t=SK.newBuilder();EK(t,e),t.writeTo(om.join(r,`${e.suiteName}.xml`))}import bK from"fs";import TK from"path";function MO(r){return{title:rn(r),duration:r.finishedAt.getTime()-r.startedAt.getTime(),error:r.status==="FAILED"?{value:r.failureReason}:void 0,steps:r.results&&r.type!=="PRESET_ACTION"?r.results.map(MO):[]}}async function vK(r,e,t,n){if(n.results?.length){let o=await nm(r,e,t,n.results[n.results.length-1].afterSnapshot);return o?[{name:"Final state screenshot",path:o,contentType:"image/jpeg"}]:[]}return[]}async function RK(r,e,t,n){return{status:n.status==="PASSED"?"passed":n.status==="CANCELLED"?"interrupted":"failed",duration:n.finishedAt.getTime()-n.lastAttemptStartedAt.getTime(),error:n.status==="FAILED"&&n.failureReason?{value:n.failureDetails?.classification?.reason||n.failureReason,message:n.failureDetails?.classification?.summary||da[n.failureReason]}:void 0,retry:n.attempts-1,steps:n.results?.map(MO)||[],startTime:n.lastAttemptStartedAt.toISOString(),attachments:await vK(r,e,t,n)}}async function AK(r,e,t,n){return{expectedStatus:"passed",status:n.status==="PASSED"?"expected":"unexpected",results:[await RK(r,e,t,n)]}}async function wK(r,e,t,n){return{tags:[],title:n.test.name,ok:n.status==="PASSED",tests:[await AK(r,e,t,n)],id:n.runId,file:n.filePath}}function yy(r,e){return r.reduce((t,n)=>e(n)?t+1:t,0)}async function CK(r,e,t,n){return{suites:[{title:n.suiteName,file:n.projectConfigPath,specs:await Promise.all(n.runs.map(o=>wK(r,e,t,o)))}],errors:[],stats:{startTime:n.startedAt.toISOString(),duration:n.finishedAt.getTime()-n.startedAt.getTime(),expected:yy(n.runs,o=>o.status==="PASSED"),unexpected:yy(n.runs,o=>o.status!=="PASSED"),flaky:yy(n.runs,o=>!!o.isFlake),skipped:0}}}async function IO(r,e,t,n){let o=await CK(r,e,t,n);bK.writeFileSync(TK.join(t,`${n.suiteName}.json`),JSON.stringify(o,null,2))}async function PO(r,e,t,n,o){switch(xK(o)?MK(o).isDirectory()||(E.error(`The specified reporter output directory '${o}' exists on disk but is not a folder. Please move or delete the existing object or specify a different reporter path.`),process.exit(1)):(E.info(`Reporter output directory '${o}' does not exist on disk, creating it now...`),_K(o,{recursive:!0})),t){case"junit":_O(o,n);return;case"allure":case"allure-json":await xO(r,e,o,n);return;case"playwright-json":await IO(r,e,o,n);return;default:throw new Error(`Unknown reporter format requested: '${t}'`)}}import e2 from"wait-on";import{execSync as IK}from"child_process";import{platform as PK}from"os";function Ey(){return OO()?(E.dimmed("Setting device pixel ratio to 2 automatically since a Mac OS Retina screen was detected."),E.dimmed(`If you are using a low pixel-density monitor, you should manually set --pixel-ratio to 1 to avoid incorrect viewport calculations. Confirm your device's pixel-ratio at https://www.mydevice.io.
4797
4797
  `),2):(E.dimmed("Setting device pixel ratio to 1."),E.dimmed(`If you are using Momentic on a high-pixel density (HiDPI) monitor, relaunch with the --pixel-ratio option to avoid incorrect viewport calculations. Confirm your device's pixel-ratio at https://www.mydevice.io.
4798
- `),1)}function OO(){return PK()==="darwin"&&IK("system_profiler SPDisplaysDataType").toString().includes("Retina")}function by(r){OO()&&r===1&&(E.warn("If you are using Momentic on a Retina screen, relaunch with the --pixel-ratio option to avoid incorrect viewport calculations."),E.warn("Confirm your device's pixel-ratio at https://www.mydevice.io."))}import OK from"@actions/exec";import LK from"@actions/io";import NK from"quote";import DK from"string-argv";async function LO(r,e=!0){let t=DK(r),n=await LK.which(t[0],!0),o=t.slice(1),i=OK.exec(NK(n),o,{delay:100});if(e)return i}import kK from"csv-parser";import{createReadStream as FK}from"fs";function Ty(r){return new Promise((e,t)=>{let n=[];FK(r).pipe(kK()).on("data",o=>n.push(o)).on("end",()=>e(n)).on("error",o=>t(o))})}import As from"semver";import{z as im}from"zod";var wr="2.27.2",UK="https://registry.npmjs.org/momentic",BK=im.object({versions:im.record(im.string(),im.unknown()).optional()});async function Zt(r){try{await HK(r)}catch(e){E.warn({err:e},"Failed to check CLI version against NPM servers")}}async function vy(){let r=await j(fetch(UK),{milliseconds:5e3});if(!r.ok)throw new Error(`Got error status code ${r.statusText}`);let e=await r.json(),t=BK.parse(e).versions;if(!t)throw new Error("Failed to fetch npm registry data. Skipping version check.");let n=wr;for(let o of Object.keys(t))As.valid(o)&&As.major(o)===As.major(wr)&&As.gt(o,n)&&As.prerelease(o)===null&&(n=o);return n}async function HK(r){let e;for(let t=0;t<2;t++)try{e=await vy()}catch(n){r.warn({err:n},"Failed to fetch latest version from npm registry")}if(!e){r.warn("Failed to fetch npm registry data. Skipping version check.");return}As.eq(wr,e)||(E.warn(`Update available: v${wr} -> v${e}`),E.warn("This version may be missing critical fixes, features, and security updates."),E.warn('Run "npx momentic@latest upgrade" to update'))}async function io(){try{await j(Promise.all([lR(),Lt.flush()]),{milliseconds:5e3})}catch{}}import{partition as zK}from"lodash-es";function am(r){return r.length===1?"test":"tests"}function NO(r){return r===1?"1 worker":`${r} workers`}function DO(r){r.length!==0&&(E.info(`Skipping ${r.length} disabled ${am(r)}:`),r.forEach(e=>{E.info(`${bt}- ${[e.relativeFilePath]}`)}),E.log(""))}function kO(r,e){r.length!==0&&(E.info(`Skipping ${r.length} quarantined ${am(r)}:`),r.forEach(t=>{E.info(`${bt}- ${[t.relativeFilePath]}: ${e[t.id]}`)}),E.log(""))}function GK(r,e){r.length!==0&&(E.info(`Running ${r.length} quarantined ${am(r)} with ${NO(e)}:`),r.forEach(t=>{E.info(`${bt}- ${[t.testDefinition.relativeFilePath]}${typeof t.inputIndex=="number"?` with input set ${t.inputIndex}`:""}`)}),E.log(""))}function jK(r,e,t){e.length===0&&r.length>0||(E.info(`Running ${e.length} ${am(e)} with ${NO(t)}:`),e.forEach(n=>{E.info(`${bt}- ${[n.testDefinition.relativeFilePath]}${typeof n.inputIndex=="number"?` with input set ${n.inputIndex}`:""}`)}),E.log(""))}function FO({logger:r,localTestsToRunWithInputs:e,parallel:t,shardCount:n,shardIndex:o}){r.info({tests:e.length,shardCount:n,shardIndex:o,parallel:t},"Running local tests");let[i,a]=zK(e,s=>s.quarantined);GK(i,t),jK(i,a,t)}import{cloneDeep as ws}from"lodash-es";async function UO({orgId:r,codeEvalTools:e,logger:t,outputDefinitions:n,testContext:o}){let i={};for(let a of n){let{name:s,value:c}=a;i[s]=await sr({orgId:r,s:c,localTools:e,logger:t,context:o})}return i}async function BO({baseUrl:r,envName:e,testName:t,devicePixelRatio:n,apiClient:o,test:i,storageClient:a,codeEvalTools:s,generator:c,orgId:l,variables:u,logger:d,customHeaders:p,testInputs:m,localBrowserConfig:h,aiSettings:g,visualDiffScreenshotStorage:f,tracer:y}){let S=await pp({settings:h,customHeaders:p,envVariables:u,envName:e,testName:t,baseUrl:r,logger:d,localTools:s,orgId:l}),T={baseUrl:o.baseUrl,apiKey:o.apiKey,logger:X,mode:"runner"},A=S.browserType??"Chromium";if(!pR(A)){let M=`Browser ${A} is required by the test named ${i.name} but does not appear to be installed on this machine. Please install it using 'momentic install-browsers' before running tests. Attempting to continue...`;E.warn(M),X.warn(M)}let b=await $r.init({baseUrl:r,logger:d,userBrowserSettings:S,storage:a,enricher:new xo(T,c),contextArgs:{viewport:i.advanced.viewport??Kt,locale:i.advanced.locale??So,geolocation:i.advanced.geolocation??Eo,timezoneId:i.advanced.timezone??yo,colorScheme:i.advanced.colorScheme,deviceScaleFactor:n},callbacks:{onNetworkPage:M=>y.onNetworkPage(M),onNetworkLogs:M=>y.onNetworkLogs(M)},iconKnowledgeBase:null,videoOptions:y.videoOutputPath?{videoOutputPath:y.videoOutputPath,onVideoPageChange:({videoName:M})=>{y.setActiveVideo(M)}}:void 0}),C=new $o({browser:b,generator:c,logger:d,orgId:l,options:{scratchPadId:void 0,slowMoMs:S.slowMoMs,autoFollowNewTabs:S.autoFollowNewTabs,useMemory:g.useMemory,aiPageFiltering:g.aiPageFiltering},storage:a,localCodeEvalTools:s,visualDiffScreenshotStorage:f}),x=new or({baseUrl:r,currentUrl:C.browser.url(),variablesFromEnvironment:u,envName:e,testName:t});return i.parameters&&await Promise.all(i.parameters.map(async M=>{let{name:P,defaultValue:U,required:V}=M,k=m?.[P];V&&k===void 0&&(E.error(`Required parameter '${P}' is required by test '${i.name}' but not provided`),process.exit(1));let z=await sr({orgId:l,s:k??U,localTools:s,logger:d,context:or.dummyContext(x.getEnvName())});x.setMomenticSystemVariable(P,z)})),{controller:C,context:x}}async function HO({testAdvancedSettings:r,orgSettings:e,logger:t}){if(r.failureRecovery===!1||r.failureRecovery===void 0&&!e?.failureRecovery)return!1;if(!Ri){let n="This test is ineligible for failure recovery since this does not appear to be a CI environment";return t.warn(n),E.warn(n),!1}return!0}async function zO({attemptInputs:r,attemptFixtures:e,attemptMetadata:t}){let{orgId:n,runId:o}=t,{controller:i,context:a,codeEvalTools:s,storageClient:c,logger:l,usageTracker:u,tracer:d}=e,{test:p,orgSettings:m}=r;l.info(`Running test '${p.name}' locally (run link: https://app.momentic.ai/runs/${o})`);let h={controller:i,storage:c,usageTracker:u,context:a,logger:l,codeEvalTools:s},g={orgId:n,runId:o,testMetadata:p,steps:p.steps,beforeSteps:p.beforeSteps,afterSteps:p.afterSteps,orgSettings:m},f={collectDebugData:!0,reinitializeBrowser:!0,disableHealing:!await HO({testAdvancedSettings:p.advanced,orgSettings:m.ai,logger:l})};return await dp({fixtures:h,inputs:g,options:f,callbacks:{step:{},test:{onTestComplete:async()=>{await i.browser.cleanup()}}},testParams:{tracer:d}})}async function GO(r){let{testDefinition:e,logger:t}=r,n=new Date;try{return await VK(r)}catch(o){let i="Fatal error running test";return E.error(`${i}: ${o.message}`),t.error({err:o},i),{results:[],parameters:r,failureReason:"UnknownError",failureDetails:{errorMessage:o.message,errorStack:o.stack},status:"FAILED",attempts:0,test:e,filePath:e.relativeFilePath,startedAt:n,lastAttemptStartedAt:n,finishedAt:new Date,outputs:{}}}}async function VK(r){let{testDefinition:e,project:t,apiClient:n,orgId:o,urlOverride:i,runSigIntHandlers:a,runGroupTracer:s,logger:c,gitMetadata:l,cacheOptions:u,runId:d,testInputs:p,quarantined:m,quarantinedReason:h,usageTracker:g}=r,f=new Pa(n,o),y=Io({orgId:o,client:n,gitMetadata:l,regenerateCache:u.regenerateCache??!1,alwaysSaveCache:u.alwaysSaveCache??!1,noCache:u.noCache??!1,bustOldestCachePercentage:u.bustOldestCachePercentage}),S=await Gu({cacheStorage:y,logger:c,schemaVersion:e.schemaVersion,stepLists:{steps:e.steps,beforeSteps:e.beforeSteps,afterSteps:e.afterSteps},testId:e.id}),T=S.steps,A=S.beforeSteps??void 0,b=S.afterSteps??void 0,C=r.envName??WK(e),x,M={};if(C){try{x=Oi(C,t,c)}catch(k){let z=`Failed to resolve environment ${C} for test ${e.name}: ${k}`;throw new Error(z)}M=x.variables}let P=e.baseUrl;if(i)P=i;else if(!P){let k=M[Tt];typeof k=="string"&&(P=k)}if(!P){let k=`Cannot run test with no base URL and no ${Tt} variable defined in its environment`;throw new Error(k)}let U=await s.startRun({logger:c,runId:d,originalSteps:{beforeSteps:e.beforeSteps,steps:e.steps,afterSteps:e.afterSteps},testId:e.id,testName:e.name,testDescription:e.description??void 0,testLabels:e.labels,baseUrl:P,environmentName:C,schemaVersion:e.schemaVersion,resolvedInputs:p,quarantined:m,quarantinedReason:h}),V=c.child(U.loggerBindings||{});Object.entries(U.envVarBindings||{}).forEach(([k,z])=>{M[k]=z});try{let k=await $K({...r,variables:M,envName:C,resolvedEnv:x,baseUrl:P,storageClient:f,tracer:U,logger:V,cacheStorage:y,stepsWithCaches:T,beforeStepsWithCaches:A,afterStepsWithCaches:b,usageTracker:g});return await U.finish({logger:c,status:k.status,finishedAt:k.finishedAt,failureDetails:k.failureDetails,failureReason:k.failureReason,isFlake:k.isFlake,failureRecoveryDetails:k.failureRecoveryDetails}),{runId:U.runId,...k}}finally{a?.pop()}}async function $K(r){let{testDefinition:e,stepsWithCaches:t,beforeStepsWithCaches:n,afterStepsWithCaches:o,project:i,regenerateGoldenFiles:a,apiClient:s,generator:c,baseUrl:l,storageClient:u,orgId:d,envName:p,urlOverride:m,customHeaders:h,testInputs:g,variables:f,resolvedEnv:y,retriesOverride:S,devicePixelRatio:T,logUpdate:A,tracer:b,logger:C,cacheStorage:x,gitMetadata:M,quarantined:P,quarantinedReason:U,usageTracker:V}=r,k=i.config.ai?.aiFailureAnalysis??!1,z=new Date,Q=new $a(i,a),Y={...i.config},Te={envName:p,urlOverride:m,customHeaders:h,testInputs:g},q,it=Math.abs(S??i.config.retries??e.retries??0),Ge=[];C.info({...M,labels:e.labels,name:e.name,cwd:process.cwd()},"Starting test run using CLI");for(let Ye=0;Ye<=it;Ye++){let Nt=await b.startAttempt(),Ie=C.child(Nt.loggerBindings||{}),oe={...e,steps:ws(t),beforeSteps:ws(n),afterSteps:ws(o)};Ye!==0&&A("RETRY",`attempt ${Ye+1}/${it+1}`);let jt=new Date,Fn=Y.advanced?.fakerConstantSeed,Un=new vn({httpClient:new Bt({baseUrl:s.baseUrl,apiKey:s.apiKey,logger:Ie,mode:"runner"}),fakerSeed:Fn?Ca:void 0}),cm=Nt;try{let{controller:Bn,context:Qo}=await BO({tracer:Nt,baseUrl:l,envName:p,testName:oe.name,apiClient:s,devicePixelRatio:T,logger:Ie,storageClient:u,codeEvalTools:Un,test:oe,generator:c,orgId:d,variables:f,customHeaders:h,testInputs:g,localBrowserConfig:{...i.config.browser||{},...y?.browser||{},...oe.advanced},aiSettings:{...i.config.ai||{},...oe.advanced||{}},visualDiffScreenshotStorage:Q});q=await zO({attemptMetadata:{attemptNumber:Ye+1,orgId:d,runId:b.runId},attemptFixtures:{logger:Ie,storageClient:u,usageTracker:V,codeEvalTools:Un,apiClient:s,context:Qo,controller:Bn,tracer:Nt},attemptInputs:{test:oe,orgSettings:Y}});let Cr=new Date,pn={logger:C,cacheStorage:x,orgId:d,testId:e.id,originalStepsWithCaches:{steps:ws(t),beforeSteps:ws(n),afterSteps:ws(o)},updatedStepsWithCaches:{steps:oe.steps,beforeSteps:oe.beforeSteps,afterSteps:oe.afterSteps}};q?.status==="PASSED"?await Ku(pn):q?.status==="FAILED"&&Ye===it&&await Yu(pn),await Nt.finish({logger:Ie,result:q}),Ge.unshift(q.status);let Zo=await UO({orgId:d,codeEvalTools:Un,logger:Ie,outputDefinitions:e.outputs??[],testContext:Qo}),K=Ob(Ge),yc=Ye+1;if(q.status!=="FAILED")return{...q,parameters:Te,test:oe,filePath:oe.relativeFilePath,startedAt:z,lastAttemptStartedAt:jt,finishedAt:Cr,attempts:yc,baseUrl:l,outputs:Zo,isFlake:K,quarantined:P,quarantinedReason:U};let ao=q.failedStepResult,Kr=ao?.message||"Unknown failure",so=ao?.failureReason??HE(Kr)??"UnknownError",Cs=Ie.child({errResult:ao,failureReason:so,errorMessage:Kr,numAttempts:it+1,name:oe.name});if(Ye<it){Cs.warn(`Retrying failed execution attempt for run: ${Kr}`);continue}Cs.error(`Test failed after all exhausting attempts: ${Kr}`);let xs=new Error(Kr),_s={errorMessage:Kr,errorStack:xs.stack},Zi;if(k){let Hn;try{if(q.results&&q.results.length>0){let{classification:Ec,aiFailureReason:um}=await TA({logger:Ie,browserStateStorage:cm,generator:c,fullResults:q,failureReason:so,error:xs,maxItemsFromEnd:void 0,numStepsWithScreenshots:void 0,disableCache:!1});Hn=Ec,Zi=um}}catch(Ec){Ie.warn({err:Ec},"Failed to classify test results")}Hn&&(_s.classification=Hn,so=Zi??so)}return{...q,parameters:Te,failureDetails:_s,failureReason:so,test:oe,filePath:oe.relativeFilePath,startedAt:z,lastAttemptStartedAt:jt,finishedAt:Cr,attempts:Ye+1,baseUrl:l,outputs:Zo,quarantined:P,quarantinedReason:U}}catch(Bn){Is(Bn);let Qo=`Encountered fatal platform error while running test '${oe.name}': ${Bn}`,Cr=new Date,pn=Ye+1;Ie.error({err:Bn},Qo),E.error(Qo);let Zo={errorMessage:Bn.message,errStack:Bn.stack},K={status:"FAILED",failureDetails:Zo,failureReason:"InternalPlatformError",finishedAt:Cr};return await Nt.finish({logger:Ie,result:{status:"FAILED",results:[]}}),{...K,results:[],parameters:Te,test:oe,filePath:oe.relativeFilePath,startedAt:z,lastAttemptStartedAt:jt,finishedAt:new Date,attempts:pn,baseUrl:l,outputs:{},quarantined:P,quarantinedReason:U}}}throw new Error("This code should not be reachable")}function WK(r){for(let e of r.envs??[])if(e.default)return e.name}import YK from"adm-zip";import XK from"path";var gr="assets";function qK(r){switch(r){case"PASSED":return"SUCCESS";case"FAILED":return"FAILED";case"CANCELLED":return"CANCELLED";case"RUNNING":case"PENDING":case"RETRYING":case"WAITING_FOR_USER":return"RUNNING"}}var Qi=class{constructor(e,t,n,o){this.orgId=e;this.testId=t;this.testName=n;this.diskStorage=o}children=[];finished=!1;stepFrequenciesByType={};async getScreenshot(e,t){return this.diskStorage.readFile(`${gr}/${t}.jpeg`)}async getHtmlSnapshot(e,t){return this.diskStorage.readFile(`${gr}/${t}.html`)?.toString()}getParentStepIdChain(){return[]}recordStepStat(e){e.type!=="PRESET_ACTION"?this.stepFrequenciesByType[e.type]=(this.stepFrequenciesByType[e.type]||0)+1:this.stepFrequenciesByType[e.command.type]=(this.stepFrequenciesByType[e.command.type]||0)+1}sendFinalizedStepStats(){for(let[e,t]of Object.entries(this.stepFrequenciesByType))Lt.increment("test_step_execution",t,[`type:${e}`,"platform:browser","executor:cli",`orgId:${this.orgId}`])}async startStep(e){let{step:t}=e;this.recordStepStat(t);let n={step:t,status:"RUNNING",startedAt:new Date},o=new Ry(this.orgId,this.testId,this.testName,n,this.diskStorage);return this.children.push(o),o}async finish(e){this.finished||(this.finished=!0,await Promise.all(this.children.map(t=>t.finishInternal({status:qK(e.status),finishedAt:e.finishedAt}))),this.sendFinalizedStepStats())}};function KK(r){switch(r){case"SUCCESS":return"PASSED";case"FAILED":return"FAILED";case"CANCELLED":return"CANCELLED";case"RUNNING":return"RUNNING";case"IDLE":return"PENDING"}}var Ry=class{constructor(e,t,n,o,i){this.orgId=e;this.testId=t;this.testName=n;this.metadata=o;this.diskStorage=i}children=[];finished=!1;getParentStepIdChain(){return[]}attachBeforeScreenshot(e){let{snapshotId:t,screenshot:n}=e;this.metadata.beforeSnapshotId=t,this.diskStorage.storeFile({name:`${gr}/${t}.jpeg`,contents:n})}attachAfterScreenshot(e){let{snapshotId:t,screenshot:n}=e;this.metadata.afterSnapshotId=t,this.diskStorage.storeFile({name:`${gr}/${t}.jpeg`,contents:n})}attachBeforeHtmlSnapshot(e){let{snapshotId:t,html:n}=e;this.metadata.beforeSnapshotId=t,this.diskStorage.storeFile({name:`${gr}/${t}.html`,contents:n})}attachAfterHtmlSnapshot(e){let{snapshotId:t,html:n}=e;this.metadata.afterSnapshotId=t,this.diskStorage.storeFile({name:`${gr}/${t}.html`,contents:n})}recordTargetAutoHeal(e){let{healType:t}=e,n=t==="AI"?"ai-target-heal":"cache-heal";Lt.increment("test_event",1,[`name:${n}`,`orgId:${this.orgId}`]),this.metadata.healMetadata={healType:t,healedAt:new Date}}recordStepDuration(e){let t=e.step.type!=="PRESET_ACTION"?e.step.type:e.step.command.type;Lt.distribution("test_step_duration",e.durationMs,[`type:${t}`,"platform:browser","executor:cli",`orgId:${this.orgId}`])}async finishInternal(e){this.finished||(this.finished=!0,await Promise.all(this.children.map(t=>t.finish({status:KK(e.status),finishedAt:e.finishedAt}))))}async finish(e){await this.finishInternal(e.step)}async startSubSteps(){let e=new Qi(this.orgId,this.testId,this.testName,this.diskStorage);return this.children.push(e),e}};var gc=class{constructor(e,t,n,o,i,a,s){this.orgId=e;this.testId=t;this.testName=n;this.runAttemptId=o;this.metadata=i;this.diskStorage=a;this.recordVideo=s;this.diskStorage.mkdir(gr),this.harPagesStream=this.diskStorage.createFileStream(`${gr}/har-pages.log`),this.inProgressHarEntries={},this.harEntriesStream=this.diskStorage.createFileStream(`${gr}/har-entries.log`)}finished=!1;children=[];harPagesStream;inProgressHarEntries;harEntriesStream;get loggerBindings(){return{runAttemptId:this.runAttemptId}}get videoOutputPath(){if(this.recordVideo)return XK.resolve(this.diskStorage.cwd(),"assets")}setActiveVideo(e){this.recordVideo&&(this.metadata.activeVideos=this.metadata.activeVideos||[],this.metadata.activeVideos.push({videoName:e,timestamp:new Date}))}onNetworkPage(e){this.finished||this.harPagesStream.write(`${JSON.stringify(e)}
4798
+ `),1)}function OO(){return PK()==="darwin"&&IK("system_profiler SPDisplaysDataType").toString().includes("Retina")}function by(r){OO()&&r===1&&(E.warn("If you are using Momentic on a Retina screen, relaunch with the --pixel-ratio option to avoid incorrect viewport calculations."),E.warn("Confirm your device's pixel-ratio at https://www.mydevice.io."))}import OK from"@actions/exec";import LK from"@actions/io";import NK from"quote";import DK from"string-argv";async function LO(r,e=!0){let t=DK(r),n=await LK.which(t[0],!0),o=t.slice(1),i=OK.exec(NK(n),o,{delay:100});if(e)return i}import kK from"csv-parser";import{createReadStream as FK}from"fs";function Ty(r){return new Promise((e,t)=>{let n=[];FK(r).pipe(kK()).on("data",o=>n.push(o)).on("end",()=>e(n)).on("error",o=>t(o))})}import As from"semver";import{z as im}from"zod";var wr="2.28.1",UK="https://registry.npmjs.org/momentic",BK=im.object({versions:im.record(im.string(),im.unknown()).optional()});async function Zt(r){try{await HK(r)}catch(e){E.warn({err:e},"Failed to check CLI version against NPM servers")}}async function vy(){let r=await j(fetch(UK),{milliseconds:5e3});if(!r.ok)throw new Error(`Got error status code ${r.statusText}`);let e=await r.json(),t=BK.parse(e).versions;if(!t)throw new Error("Failed to fetch npm registry data. Skipping version check.");let n=wr;for(let o of Object.keys(t))As.valid(o)&&As.major(o)===As.major(wr)&&As.gt(o,n)&&As.prerelease(o)===null&&(n=o);return n}async function HK(r){let e;for(let t=0;t<2;t++)try{e=await vy()}catch(n){r.warn({err:n},"Failed to fetch latest version from npm registry")}if(!e){r.warn("Failed to fetch npm registry data. Skipping version check.");return}As.eq(wr,e)||(E.warn(`Update available: v${wr} -> v${e}`),E.warn("This version may be missing critical fixes, features, and security updates."),E.warn('Run "npx momentic@latest upgrade" to update'))}async function io(){try{await j(Promise.all([lR(),Lt.flush()]),{milliseconds:5e3})}catch{}}import{partition as zK}from"lodash-es";function am(r){return r.length===1?"test":"tests"}function NO(r){return r===1?"1 worker":`${r} workers`}function DO(r){r.length!==0&&(E.info(`Skipping ${r.length} disabled ${am(r)}:`),r.forEach(e=>{E.info(`${bt}- ${[e.relativeFilePath]}`)}),E.log(""))}function kO(r,e){r.length!==0&&(E.info(`Skipping ${r.length} quarantined ${am(r)}:`),r.forEach(t=>{E.info(`${bt}- ${[t.relativeFilePath]}: ${e[t.id]}`)}),E.log(""))}function GK(r,e){r.length!==0&&(E.info(`Running ${r.length} quarantined ${am(r)} with ${NO(e)}:`),r.forEach(t=>{E.info(`${bt}- ${[t.testDefinition.relativeFilePath]}${typeof t.inputIndex=="number"?` with input set ${t.inputIndex}`:""}`)}),E.log(""))}function jK(r,e,t){e.length===0&&r.length>0||(E.info(`Running ${e.length} ${am(e)} with ${NO(t)}:`),e.forEach(n=>{E.info(`${bt}- ${[n.testDefinition.relativeFilePath]}${typeof n.inputIndex=="number"?` with input set ${n.inputIndex}`:""}`)}),E.log(""))}function FO({logger:r,localTestsToRunWithInputs:e,parallel:t,shardCount:n,shardIndex:o}){r.info({tests:e.length,shardCount:n,shardIndex:o,parallel:t},"Running local tests");let[i,a]=zK(e,s=>s.quarantined);GK(i,t),jK(i,a,t)}import{cloneDeep as ws}from"lodash-es";async function UO({orgId:r,codeEvalTools:e,logger:t,outputDefinitions:n,testContext:o}){let i={};for(let a of n){let{name:s,value:c}=a;i[s]=await sr({orgId:r,s:c,localTools:e,logger:t,context:o})}return i}async function BO({baseUrl:r,envName:e,testName:t,devicePixelRatio:n,apiClient:o,test:i,storageClient:a,codeEvalTools:s,generator:c,orgId:l,variables:u,logger:d,customHeaders:p,testInputs:m,localBrowserConfig:h,aiSettings:g,visualDiffScreenshotStorage:f,tracer:y}){let S=await pp({settings:h,customHeaders:p,envVariables:u,envName:e,testName:t,baseUrl:r,logger:d,localTools:s,orgId:l}),T={baseUrl:o.baseUrl,apiKey:o.apiKey,logger:X,mode:"runner"},A=S.browserType??"Chromium";if(!pR(A)){let M=`Browser ${A} is required by the test named ${i.name} but does not appear to be installed on this machine. Please install it using 'momentic install-browsers' before running tests. Attempting to continue...`;E.warn(M),X.warn(M)}let b=await $r.init({baseUrl:r,logger:d,userBrowserSettings:S,storage:a,enricher:new xo(T,c),contextArgs:{viewport:i.advanced.viewport??Kt,locale:i.advanced.locale??So,geolocation:i.advanced.geolocation??Eo,timezoneId:i.advanced.timezone??yo,colorScheme:i.advanced.colorScheme,deviceScaleFactor:n},callbacks:{onNetworkPage:M=>y.onNetworkPage(M),onNetworkLogs:M=>y.onNetworkLogs(M)},iconKnowledgeBase:null,videoOptions:y.videoOutputPath?{videoOutputPath:y.videoOutputPath,onVideoPageChange:({videoName:M})=>{y.setActiveVideo(M)}}:void 0}),C=new $o({browser:b,generator:c,logger:d,orgId:l,options:{scratchPadId:void 0,slowMoMs:S.slowMoMs,autoFollowNewTabs:S.autoFollowNewTabs,useMemory:g.useMemory,aiPageFiltering:g.aiPageFiltering},storage:a,localCodeEvalTools:s,visualDiffScreenshotStorage:f}),x=new or({baseUrl:r,currentUrl:C.browser.url(),variablesFromEnvironment:u,envName:e,testName:t});return i.parameters&&await Promise.all(i.parameters.map(async M=>{let{name:P,defaultValue:U,required:V}=M,k=m?.[P];V&&k===void 0&&(E.error(`Required parameter '${P}' is required by test '${i.name}' but not provided`),process.exit(1));let z=await sr({orgId:l,s:k??U,localTools:s,logger:d,context:or.dummyContext(x.getEnvName())});x.setMomenticSystemVariable(P,z)})),{controller:C,context:x}}async function HO({testAdvancedSettings:r,orgSettings:e,logger:t}){if(r.failureRecovery===!1||r.failureRecovery===void 0&&!e?.failureRecovery)return!1;if(!Ri){let n="This test is ineligible for failure recovery since this does not appear to be a CI environment";return t.warn(n),E.warn(n),!1}return!0}async function zO({attemptInputs:r,attemptFixtures:e,attemptMetadata:t}){let{orgId:n,runId:o}=t,{controller:i,context:a,codeEvalTools:s,storageClient:c,logger:l,usageTracker:u,tracer:d}=e,{test:p,orgSettings:m}=r;l.info(`Running test '${p.name}' locally (run link: https://app.momentic.ai/runs/${o})`);let h={controller:i,storage:c,usageTracker:u,context:a,logger:l,codeEvalTools:s},g={orgId:n,runId:o,testMetadata:p,steps:p.steps,beforeSteps:p.beforeSteps,afterSteps:p.afterSteps,orgSettings:m},f={collectDebugData:!0,reinitializeBrowser:!0,disableHealing:!await HO({testAdvancedSettings:p.advanced,orgSettings:m.ai,logger:l})};return await dp({fixtures:h,inputs:g,options:f,callbacks:{step:{},test:{onTestComplete:async()=>{await i.browser.cleanup()}}},testParams:{tracer:d}})}async function GO(r){let{testDefinition:e,logger:t}=r,n=new Date;try{return await VK(r)}catch(o){let i="Fatal error running test";return E.error(`${i}: ${o.message}`),t.error({err:o},i),{results:[],parameters:r,failureReason:"UnknownError",failureDetails:{errorMessage:o.message,errorStack:o.stack},status:"FAILED",attempts:0,test:e,filePath:e.relativeFilePath,startedAt:n,lastAttemptStartedAt:n,finishedAt:new Date,outputs:{}}}}async function VK(r){let{testDefinition:e,project:t,apiClient:n,orgId:o,urlOverride:i,runSigIntHandlers:a,runGroupTracer:s,logger:c,gitMetadata:l,cacheOptions:u,runId:d,testInputs:p,quarantined:m,quarantinedReason:h,usageTracker:g}=r,f=new Pa(n,o),y=Io({orgId:o,client:n,gitMetadata:l,regenerateCache:u.regenerateCache??!1,alwaysSaveCache:u.alwaysSaveCache??!1,noCache:u.noCache??!1,bustOldestCachePercentage:u.bustOldestCachePercentage}),S=await Gu({cacheStorage:y,logger:c,schemaVersion:e.schemaVersion,stepLists:{steps:e.steps,beforeSteps:e.beforeSteps,afterSteps:e.afterSteps},testId:e.id}),T=S.steps,A=S.beforeSteps??void 0,b=S.afterSteps??void 0,C=r.envName??WK(e),x,M={};if(C){try{x=Oi(C,t,c)}catch(k){let z=`Failed to resolve environment ${C} for test ${e.name}: ${k}`;throw new Error(z)}M=x.variables}let P=e.baseUrl;if(i)P=i;else if(!P){let k=M[Tt];typeof k=="string"&&(P=k)}if(!P){let k=`Cannot run test with no base URL and no ${Tt} variable defined in its environment`;throw new Error(k)}let U=await s.startRun({logger:c,runId:d,originalSteps:{beforeSteps:e.beforeSteps,steps:e.steps,afterSteps:e.afterSteps},testId:e.id,testName:e.name,testDescription:e.description??void 0,testLabels:e.labels,baseUrl:P,environmentName:C,schemaVersion:e.schemaVersion,resolvedInputs:p,quarantined:m,quarantinedReason:h}),V=c.child(U.loggerBindings||{});Object.entries(U.envVarBindings||{}).forEach(([k,z])=>{M[k]=z});try{let k=await $K({...r,variables:M,envName:C,resolvedEnv:x,baseUrl:P,storageClient:f,tracer:U,logger:V,cacheStorage:y,stepsWithCaches:T,beforeStepsWithCaches:A,afterStepsWithCaches:b,usageTracker:g});return await U.finish({logger:c,status:k.status,finishedAt:k.finishedAt,failureDetails:k.failureDetails,failureReason:k.failureReason,isFlake:k.isFlake,failureRecoveryDetails:k.failureRecoveryDetails}),{runId:U.runId,...k}}finally{a?.pop()}}async function $K(r){let{testDefinition:e,stepsWithCaches:t,beforeStepsWithCaches:n,afterStepsWithCaches:o,project:i,regenerateGoldenFiles:a,apiClient:s,generator:c,baseUrl:l,storageClient:u,orgId:d,envName:p,urlOverride:m,customHeaders:h,testInputs:g,variables:f,resolvedEnv:y,retriesOverride:S,devicePixelRatio:T,logUpdate:A,tracer:b,logger:C,cacheStorage:x,gitMetadata:M,quarantined:P,quarantinedReason:U,usageTracker:V}=r,k=i.config.ai?.aiFailureAnalysis??!1,z=new Date,Q=new $a(i,a),Y={...i.config},Te={envName:p,urlOverride:m,customHeaders:h,testInputs:g},q,it=Math.abs(S??i.config.retries??e.retries??0),Ge=[];C.info({...M,labels:e.labels,name:e.name,cwd:process.cwd()},"Starting test run using CLI");for(let Ye=0;Ye<=it;Ye++){let Nt=await b.startAttempt(),Ie=C.child(Nt.loggerBindings||{}),oe={...e,steps:ws(t),beforeSteps:ws(n),afterSteps:ws(o)};Ye!==0&&A("RETRY",`attempt ${Ye+1}/${it+1}`);let jt=new Date,Fn=Y.advanced?.fakerConstantSeed,Un=new vn({httpClient:new Bt({baseUrl:s.baseUrl,apiKey:s.apiKey,logger:Ie,mode:"runner"}),fakerSeed:Fn?Ca:void 0}),cm=Nt;try{let{controller:Bn,context:Qo}=await BO({tracer:Nt,baseUrl:l,envName:p,testName:oe.name,apiClient:s,devicePixelRatio:T,logger:Ie,storageClient:u,codeEvalTools:Un,test:oe,generator:c,orgId:d,variables:f,customHeaders:h,testInputs:g,localBrowserConfig:{...i.config.browser||{},...y?.browser||{},...oe.advanced},aiSettings:{...i.config.ai||{},...oe.advanced||{}},visualDiffScreenshotStorage:Q});q=await zO({attemptMetadata:{attemptNumber:Ye+1,orgId:d,runId:b.runId},attemptFixtures:{logger:Ie,storageClient:u,usageTracker:V,codeEvalTools:Un,apiClient:s,context:Qo,controller:Bn,tracer:Nt},attemptInputs:{test:oe,orgSettings:Y}});let Cr=new Date,pn={logger:C,cacheStorage:x,orgId:d,testId:e.id,originalStepsWithCaches:{steps:ws(t),beforeSteps:ws(n),afterSteps:ws(o)},updatedStepsWithCaches:{steps:oe.steps,beforeSteps:oe.beforeSteps,afterSteps:oe.afterSteps}};q?.status==="PASSED"?await Ku(pn):q?.status==="FAILED"&&Ye===it&&await Yu(pn),await Nt.finish({logger:Ie,result:q}),Ge.unshift(q.status);let Zo=await UO({orgId:d,codeEvalTools:Un,logger:Ie,outputDefinitions:e.outputs??[],testContext:Qo}),K=Ob(Ge),yc=Ye+1;if(q.status!=="FAILED")return{...q,parameters:Te,test:oe,filePath:oe.relativeFilePath,startedAt:z,lastAttemptStartedAt:jt,finishedAt:Cr,attempts:yc,baseUrl:l,outputs:Zo,isFlake:K,quarantined:P,quarantinedReason:U};let ao=q.failedStepResult,Kr=ao?.message||"Unknown failure",so=ao?.failureReason??HE(Kr)??"UnknownError",Cs=Ie.child({errResult:ao,failureReason:so,errorMessage:Kr,numAttempts:it+1,name:oe.name});if(Ye<it){Cs.warn(`Retrying failed execution attempt for run: ${Kr}`);continue}Cs.error(`Test failed after all exhausting attempts: ${Kr}`);let xs=new Error(Kr),_s={errorMessage:Kr,errorStack:xs.stack},Zi;if(k){let Hn;try{if(q.results&&q.results.length>0){let{classification:Ec,aiFailureReason:um}=await TA({logger:Ie,browserStateStorage:cm,generator:c,fullResults:q,failureReason:so,error:xs,maxItemsFromEnd:void 0,numStepsWithScreenshots:void 0,disableCache:!1});Hn=Ec,Zi=um}}catch(Ec){Ie.warn({err:Ec},"Failed to classify test results")}Hn&&(_s.classification=Hn,so=Zi??so)}return{...q,parameters:Te,failureDetails:_s,failureReason:so,test:oe,filePath:oe.relativeFilePath,startedAt:z,lastAttemptStartedAt:jt,finishedAt:Cr,attempts:Ye+1,baseUrl:l,outputs:Zo,quarantined:P,quarantinedReason:U}}catch(Bn){Is(Bn);let Qo=`Encountered fatal platform error while running test '${oe.name}': ${Bn}`,Cr=new Date,pn=Ye+1;Ie.error({err:Bn},Qo),E.error(Qo);let Zo={errorMessage:Bn.message,errStack:Bn.stack},K={status:"FAILED",failureDetails:Zo,failureReason:"InternalPlatformError",finishedAt:Cr};return await Nt.finish({logger:Ie,result:{status:"FAILED",results:[]}}),{...K,results:[],parameters:Te,test:oe,filePath:oe.relativeFilePath,startedAt:z,lastAttemptStartedAt:jt,finishedAt:new Date,attempts:pn,baseUrl:l,outputs:{},quarantined:P,quarantinedReason:U}}}throw new Error("This code should not be reachable")}function WK(r){for(let e of r.envs??[])if(e.default)return e.name}import YK from"adm-zip";import XK from"path";var gr="assets";function qK(r){switch(r){case"PASSED":return"SUCCESS";case"FAILED":return"FAILED";case"CANCELLED":return"CANCELLED";case"RUNNING":case"PENDING":case"RETRYING":case"WAITING_FOR_USER":return"RUNNING"}}var Qi=class{constructor(e,t,n,o){this.orgId=e;this.testId=t;this.testName=n;this.diskStorage=o}children=[];finished=!1;stepFrequenciesByType={};async getScreenshot(e,t){return this.diskStorage.readFile(`${gr}/${t}.jpeg`)}async getHtmlSnapshot(e,t){return this.diskStorage.readFile(`${gr}/${t}.html`)?.toString()}getParentStepIdChain(){return[]}recordStepStat(e){e.type!=="PRESET_ACTION"?this.stepFrequenciesByType[e.type]=(this.stepFrequenciesByType[e.type]||0)+1:this.stepFrequenciesByType[e.command.type]=(this.stepFrequenciesByType[e.command.type]||0)+1}sendFinalizedStepStats(){for(let[e,t]of Object.entries(this.stepFrequenciesByType))Lt.increment("test_step_execution",t,[`type:${e}`,"platform:browser","executor:cli",`orgId:${this.orgId}`])}async startStep(e){let{step:t}=e;this.recordStepStat(t);let n={step:t,status:"RUNNING",startedAt:new Date},o=new Ry(this.orgId,this.testId,this.testName,n,this.diskStorage);return this.children.push(o),o}async finish(e){this.finished||(this.finished=!0,await Promise.all(this.children.map(t=>t.finishInternal({status:qK(e.status),finishedAt:e.finishedAt}))),this.sendFinalizedStepStats())}};function KK(r){switch(r){case"SUCCESS":return"PASSED";case"FAILED":return"FAILED";case"CANCELLED":return"CANCELLED";case"RUNNING":return"RUNNING";case"IDLE":return"PENDING"}}var Ry=class{constructor(e,t,n,o,i){this.orgId=e;this.testId=t;this.testName=n;this.metadata=o;this.diskStorage=i}children=[];finished=!1;getParentStepIdChain(){return[]}attachBeforeScreenshot(e){let{snapshotId:t,screenshot:n}=e;this.metadata.beforeSnapshotId=t,this.diskStorage.storeFile({name:`${gr}/${t}.jpeg`,contents:n})}attachAfterScreenshot(e){let{snapshotId:t,screenshot:n}=e;this.metadata.afterSnapshotId=t,this.diskStorage.storeFile({name:`${gr}/${t}.jpeg`,contents:n})}attachBeforeHtmlSnapshot(e){let{snapshotId:t,html:n}=e;this.metadata.beforeSnapshotId=t,this.diskStorage.storeFile({name:`${gr}/${t}.html`,contents:n})}attachAfterHtmlSnapshot(e){let{snapshotId:t,html:n}=e;this.metadata.afterSnapshotId=t,this.diskStorage.storeFile({name:`${gr}/${t}.html`,contents:n})}recordTargetAutoHeal(e){let{healType:t}=e,n=t==="AI"?"ai-target-heal":"cache-heal";Lt.increment("test_event",1,[`name:${n}`,`orgId:${this.orgId}`]),this.metadata.healMetadata={healType:t,healedAt:new Date}}recordStepDuration(e){let t=e.step.type!=="PRESET_ACTION"?e.step.type:e.step.command.type;Lt.distribution("test_step_duration",e.durationMs,[`type:${t}`,"platform:browser","executor:cli",`orgId:${this.orgId}`])}async finishInternal(e){this.finished||(this.finished=!0,await Promise.all(this.children.map(t=>t.finish({status:KK(e.status),finishedAt:e.finishedAt}))))}async finish(e){await this.finishInternal(e.step)}async startSubSteps(){let e=new Qi(this.orgId,this.testId,this.testName,this.diskStorage);return this.children.push(e),e}};var gc=class{constructor(e,t,n,o,i,a,s){this.orgId=e;this.testId=t;this.testName=n;this.runAttemptId=o;this.metadata=i;this.diskStorage=a;this.recordVideo=s;this.diskStorage.mkdir(gr),this.harPagesStream=this.diskStorage.createFileStream(`${gr}/har-pages.log`),this.inProgressHarEntries={},this.harEntriesStream=this.diskStorage.createFileStream(`${gr}/har-entries.log`)}finished=!1;children=[];harPagesStream;inProgressHarEntries;harEntriesStream;get loggerBindings(){return{runAttemptId:this.runAttemptId}}get videoOutputPath(){if(this.recordVideo)return XK.resolve(this.diskStorage.cwd(),"assets")}setActiveVideo(e){this.recordVideo&&(this.metadata.activeVideos=this.metadata.activeVideos||[],this.metadata.activeVideos.push({videoName:e,timestamp:new Date}))}onNetworkPage(e){this.finished||this.harPagesStream.write(`${JSON.stringify(e)}
4799
4799
  `)}onNetworkLogs(e){if(!this.finished)for(let[t,n]of Object.entries(e))n.response?(delete this.inProgressHarEntries[t],this.harEntriesStream.write(`${JSON.stringify(n)}
4800
4800
  `)):this.inProgressHarEntries[t]=n}attachConsoleLogs(e){let{logs:t}=e;this.diskStorage.storeFile({name:"console.json",contents:JSON.stringify(t,null,2)})}attachBrowserCrashDump(e){let{crashReportDirFetcher:t,logger:n}=e,o=t();if(!o)return;let i=new YK;i.addLocalFolder(o,void 0,a=>a!==".DS_Store"),this.diskStorage.storeFile({name:`${gr}/${Xh}`,contents:i.toBuffer()}),n.info({browserCrashZipName:Xh},"Attached browser crash ZIP")}async finish(e){if(this.finished)return;this.finished=!0;let{logger:t,result:n}=e,o={...this.metadata,status:n.status,finishedAt:new Date,results:qu(n.results,t),beforeResults:n.beforeResults?qu(n.beforeResults,t):void 0,afterResults:n.afterResults?qu(n.afterResults,t):void 0};await Promise.all(this.children.map(i=>i.finish({status:o.status,finishedAt:o.finishedAt})));for(let i of Object.values(this.inProgressHarEntries))this.harEntriesStream.write(`${JSON.stringify(i)}
4801
4801
  `);try{this.harEntriesStream.end()}catch{}try{this.harPagesStream.end()}catch{}this.diskStorage.storeFile({name:"metadata.json",contents:JSON.stringify(o,null,2)})}async startBeforeStepList(){let e=new Qi(this.orgId,this.testId,this.testName,this.diskStorage);return this.children.push(e),e}async startMainStepList(){let e=new Qi(this.orgId,this.testId,this.testName,this.diskStorage);return this.children.push(e),e}async startAfterStepList(){let e=new Qi(this.orgId,this.testId,this.testName,this.diskStorage);return this.children.push(e),e}async getScreenshot(e,t){return this.diskStorage.readFile(`${gr}/${t}.jpeg`)}async getHtmlSnapshot(e,t){return this.diskStorage.readFile(`${gr}/${t}.html`)?.toString()}};import{randomUUID as JK}from"crypto";var fc=class{constructor(e,t,n,o,i,a,s){this.orgId=e;this.testId=t;this.testName=n;this.runId=o;this.metadata=i;this.diskStorage=a;this.recordVideo=s}children=[];finished=!1;get loggerBindings(){return{runId:this.runId}}get envVarBindings(){return{[U_]:this.runId}}async finish(e){if(this.finished)return;this.finished=!0;let t={...this.metadata,finishedAt:e.finishedAt||new Date,status:e.status,failureDetails:e.failureDetails,failureReason:e.failureReason,flake:e.isFlake||!1,failureRecoveryDetails:e.failureRecoveryDetails};await Promise.all(this.children.map(n=>n.finish({logger:e.logger,result:{status:t.status,results:[],beforeResults:[],afterResults:[]}}))),this.diskStorage.storeFile({name:"metadata.json",contents:JSON.stringify(t,null,2)}),this.diskStorage.close()}async startAttempt(){this.metadata.attempts=this.metadata.attempts+1,this.metadata.status="RUNNING",this.diskStorage.storeFile({name:"metadata.json",contents:JSON.stringify(this.metadata,null,2)});let e=this.diskStorage.cd(`attempts/${this.metadata.attempts}`),t=JK(),n={id:t,schemaVersion:Ce,runAttemptSchemaVersion:Yv,startedAt:new Date,status:"RUNNING"};e.storeFile({name:"metadata.json",contents:JSON.stringify(n,null,2)});let o=new gc(this.orgId,this.testId,this.testName,t,n,e,this.recordVideo);return this.children.push(o),o}};var Sc=class r{constructor(e,t,n,o,i){this.orgId=e;this.runGroupId=t;this.metadata=n;this.diskStorage=o;this.recordVideo=i}children=[];finished=!1;get loggerBindings(){return{orgId:this.orgId,runGroupId:this.runGroupId,branch:this.metadata.gitBranchName}}static async start({orgId:e,runGroupId:t,outputDir:n,gitMetadata:o,labels:i,recordVideo:a}){let s={...o,id:t,trigger:Or.CLI,startedAt:new Date,status:"RUNNING",cliVersion:wr,labels:i??[]},c=new _l(n);return c.storeFile({name:"metadata.json",contents:JSON.stringify(s,null,2)}),new r(e,t,s,c,a??!1)}async finish(e){if(this.finished)return;this.finished=!0;let{status:t}=e,n={...this.metadata,status:t,updatedAt:new Date,finishedAt:new Date};await Promise.all(this.children.map(o=>o.finish({logger:e.logger,status:n.status,finishedAt:n.finishedAt}))),this.diskStorage.storeFile({name:"metadata.json",contents:JSON.stringify(n,null,2)})}async startRun(e){let t=this.diskStorage.createRunArchive(e.runId),n={stepsSnapshot:e.originalSteps.steps,runGroupId:this.runGroupId,testId:e.testId,testName:e.testName,testDescription:e.testDescription,labels:e.testLabels,trigger:"CLI",status:"RUNNING",resolvedBaseUrl:e.baseUrl,environmentName:e.environmentName,resolvedInputs:e.resolvedInputs,cliVersion:wr,schemaVersion:e.schemaVersion,startedAt:new Date,attempts:0,quarantined:e.quarantined??!1,quarantinedReason:e.quarantinedReason,executionType:"WEB"};t.storeFile({name:"metadata.json",contents:JSON.stringify(n,null,2)});let o=new fc(this.orgId,e.testId,e.testName,e.runId,n,t,this.recordVideo);return this.children.push(o),o}};async function jO(r,e,t){if(t)return{};try{return(await e.getQuarantinedTests()).quarantined.reduce((o,i)=>(o[i.testId]=i.quarantinedReason,o),{})}catch(n){return r.warn({err:n},"Failed to fetch quarantined tests, proceeding without them."),{}}}async function VO(r){let{logger:e,tests:t,yes:n,start:o,waitOn:i,waitOnProxy:a,client:s,debugDataStorage:c,project:l,retriesOverride:u,urlOverride:d,envName:p,orgId:m,devicePixelRatio:h,customHeaders:g,testInputMatrix:f,reporter:y,include:S,exclude:T,labels:A,reporterDir:b=BA,outputDir:C=HA,uploadResults:x=!1,waitOnTimeout:M=60,parallel:P,shardIndex:U=1,shardCount:V=1,regenerateGoldenFiles:k,gitMetadata:z,cacheOptions:Q,ignoreQuarantine:Y,skipQuarantined:Te,onlyQuarantined:q,runGroupId:it,recordVideo:Ge,timeoutMinutes:Ye}=r;if(o&&(e.info({orgId:m},`Executing start command: ${o}`),await LO(o,!1)),i){e.info({orgId:m},`Waiting for url: ${i} with timeout: ${M} seconds.`);let tt=a?new URL(a):void 0,zn;tt&&(zn={host:tt.hostname,port:tt.port?parseInt(tt.port):tt.protocol.startsWith("https")?443:80,auth:tt.username||tt.password?{username:tt.username,password:tt.password}:void 0}),await e2({resources:[i],interval:2500,timeout:M*1e3,headers:{Accept:"*/*"},followRedirect:!0,verbose:!1,log:!0,strictSSL:!1,proxy:zn})}let Nt=new qn(l.config.ai?.agentConfig,{baseUrl:s.baseUrl,apiKey:s.apiKey,logger:e,mode:"runner"}),Ie=await Z(l),oe=await vs({tests:t,momenticFiles:Ie,yes:n,project:l,include:S,exclude:T,labels:A,logger:E}),jt=await jO(e,s,Y),{testsToSkip:Fn,quarantinedTestsToSkip:Un,testsToRun:cm,quarantinedTestsToRun:Bn}=EO({testDefinitions:oe,quarantinedTestReasons:jt,onlyQuarantined:q,skipQuarantined:Te});DO(Fn),kO(Un,jt);let Qo=bO({testsToRun:cm,quarantinedTestsToRun:Bn,quarantinedTestReasons:jt,testInputMatrix:f}),Cr=r2({globalTestsToRunWithInputs:Qo,shardIndex:U,shardCount:V});FO({logger:e,localTestsToRunWithInputs:Cr,parallel:P,shardCount:V,shardIndex:U});let pn=[],Zo=new Date,K=new Set,yc=async()=>{let tt=s.getAppUrl(),zn=Ia({results:pn,startTime:Zo.getTime(),onFailed:fr=>{Pu(fr,fr.filePath)},getDisplayLine:fr=>{let ei=`${bt}- ${fr.filePath}${fr.failureRecoveryDetails?" [recovered] ":""}`;return fr.runId&&(ei+=` ( link when uploaded: ${tt}/runs/${fr.runId} )`),ei},entity:"test"}),bc=pn.filter(fr=>!!fr.failureRecoveryDetails?.attempts);return bc.length>0&&E.warn(`Our AI agent automatically prevented ${bc.length} tests from failing due to transient issues. Use the run links above to review the additional steps that were executed.
@@ -4803,4 +4803,4 @@ ${r.map(p=>`${bt}- ${p}`).join(`
4803
4803
  `),E.info("This wizard will help you bootstrap a new Momentic project. If you need to import existing assets from Momentic Cloud, you can call the 'import' command after initialization."),lm.existsSync(ja)&&(E.error("A momentic.config.yaml file already exists in this directory. Please rename or remove it to initialize a new project."),process.exit(1));let e=r.name??await tR("Choose an identifier for your project, such as a service, product, or team name (default: 'app'):","app");await GA()||await Ut("A Git repository was not detected in the current directory. Momentic highly recommends initializing your project within a Git repository for seamless version control. Continue?")||process.exit(1),Oo({name:e,include:Pg},ja),E.success(`Initialized Momentic project file at ${sm.resolve(ja)}`)});Gt.command("app").addOption(Wr).addOption(qr).addOption(Xo).addOption(ay).addOption(lr).addOption(ly).addOption(cy).addOption(uy).action(async r=>{await Zt(X);let{apiKey:e,yes:t,server:n,pixelRatio:o,disableCache:i,saveCache:a,regenerateCache:s}=r,c=await Ct({configFilePath:r.config,nameFilter:void 0}),{errors:l}=await Kp({project:c,fix:!1});l>0&&(E.error(`Found ${l} errors`),E.warn("To fix these errors automatically, run the duplicate-ids check with the --fix flag and then commit the resulting changes"),process.exit(1)),xw(X);let u=new Qe({baseUrl:n,apiKey:e,logger:X});await lg({client:u,skipPrompts:t});let d=d2(import.meta.url),p=sm.dirname(d),m=sm.resolve(p,"..","static"),h=sm.resolve(p,"..","assets"),g=o??Ey();by(g),await HP({momenticServerUrl:n,apiKey:e,serverPort:Yp,appPort:Yp,staticDir:m,assetsDir:h,devicePixelRatio:g,regenerateCache:s,noCache:i,alwaysSaveCache:a,initialProject:c});let f=`http://localhost:${Yp}`;await u2(f)});var JO=Gt.command("queue").description("Queue tests or suites to run on Momentic Cloud");JO.command("suites").description("Run one or more suites on Momentic Cloud").addOption(Wr).addOption(qr).addOption(ty).addOption(ry).addOption(Xo).addArgument(pO).addOption(Zp).addOption(Qp).addOption(Jp).action(async(r,e)=>{await Zt(X);let{apiKey:t,server:n,wait:o,waitTimeout:i,env:a,urlOverride:s}=e,c=Xp(e.customHeaders),l=new Qe({baseUrl:n,apiKey:t,logger:X});(!r||!Array.isArray(r)||!r.length)&&(E.error("Must pass at least one suite to run."),process.exit(1));let{orgId:u}=await l.getAuthInfo();await AO({client:l,orgId:u,wait:o,suitePaths:r,waitTimeout:i,env:a,urlOverride:s,customHeaders:c}),await io()});JO.command("tests").description("Run one or more tests on Momentic Cloud").addOption(Wr).addOption(qr).addOption(Xo).addOption(Jp).addOption(sy).addOption(Zp).addOption(Qp).addOption(new cr("--all","Run all tests.").default(!1)).addOption(ty).addOption(ry).addArgument(uO).action(async(r,e)=>{await Zt(X);let{all:t,apiKey:n,env:o,server:i,inputCsv:a,urlOverride:s,wait:c,waitTimeout:l,yes:u}=e,d=Xp(e.customHeaders);for(let g of r)(g.endsWith(".yaml")||lm.existsSync(g))&&E.warn("Are you trying to run a test on your local machine? If so, please use the 'run' command instead of the 'queue' command");let p=new Qe({baseUrl:i,apiKey:n,logger:X}),{orgId:m}=await p.getAuthInfo(),h;a&&(h=await Ty(a)),await wO({client:p,orgId:m,tests:r,all:t,customHeaders:d,env:o,urlOverride:s,wait:c,waitTimeout:l,testInputMatrix:h,yes:u}),await io(),process.exit(0)});var p2=Gt.command("list").description("List test paths");p2.addOption(lr).addOption(Jo).addOption(oy).addOption(iy).addOption(new cr("--labels <labels...>","Only run tests with the specified label(s).")).addArgument(dy).action(async(r,e)=>{let t=await Ct({configFilePath:e.config,nameFilter:e.filter}),n=await Z(t),o=await vs({tests:r,momenticFiles:n,yes:!0,project:t,include:e.include,exclude:e.exclude,labels:e.labels,logger:new vi(40,{})});E.info(o.map(i=>i.relativeFilePath).join(`
4804
4804
  `)),process.exit(0)});var m2=Gt.command("run").alias("test").description("Run tests on the local machine");m2.addOption(Wr).addOption(qr).addOption(lr).addOption(Jo).addOption(Xo).addOption(Jp).addOption(sy).addOption(ly).addOption(cy).addOption(uy).addOption(iO).addOption(cO).addOption(aO).addOption(sO).addOption(lO).addOption(Qp).addOption(Zp).addOption(ay).addOption(new cr("--start <start>","Arbitrary setup command that will run before Momentic steps begin.")).addOption(new cr("--wait-on <waitOn>","URL to wait to become accessible before Momentic tests begin.")).addOption(new cr("--wait-on-proxy <waitOnProxy>","HTTP proxy to use with the --wait-on command. Specify as https://username:pass@domain.com:2345")).addOption(new cr("--wait-on-timeout <waitOnTimeout>","Max time in seconds to wait for the --wait-on URL to become accessible.").default(60).argParser(kn)).addOption(new cr("--retries <retries>","Number of retries to attempt when running tests locally. Defaults to each test's own retry configuration.").argParser(kn)).addOption(new cr("-p, --parallel <parallel>","The number of tests to run in parallel. Defaults to 1.").argParser(kn)).addOption(new cr("--labels <labels...>","Only run tests with the specified label(s).")).addOption(new cr("--update-golden-files","Update locally stored golden files for steps that this is enabled for.").default(!1)).addOption(ZP).addOption(eO).addOption(ny).addOption(tO).addOption(nO).addOption(rO).addOption(oy).addOption(iy).addOption(gO).addArgument(dy).action(async(r,e)=>{if(await Zt(X),e.shardIndex>e.shardCount)throw new Error("Shard index cannot be greater than shard count");let t=Xp(e.customHeaders),n=await Ct({configFilePath:e.config,nameFilter:e.filter}),o=e.parallel??n.config.parallel??1;qO().length<o*2&&E.warn(`You requested to run tests in parallel ${o} at a time on a machine with ${qO().length} cores. This may cause performance issues and test failures as Chrome requires at least 2 cores per browser instance.`),E.debug({projectName:n.config.name},"Identified project config");let{errors:i}=await Kp({project:n,fix:!1});i>0&&(E.error(`Found ${i} errors`),E.warn("To fix these errors automatically, run the duplicate-ids check with the --fix flag and then commit the resulting changes"),process.exit(1));let a=new Qe({baseUrl:e.server,apiKey:e.apiKey,logger:X});E.debug("Checking API key and dependencies");let{orgId:s,userId:c}=await lg({client:a,skipPrompts:e.yes});E.debug("API key check and browser installation complete");let l=new sl,u=e.outputDir??n.config.outputDir,d=e.reporterDir??n.config.reporterDir,p=l2(),m=X.child({cliVersion:wr,orgId:s,userId:c,runGroupId:p}),h=await Fr(X,a,n);m.info({gitMetadata:h,config:n.config,nodeVersion:process.versions.node},"Got local metadata");let g;e.inputCsv&&(g=await Ty(e.inputCsv));let f=e.pixelRatio??Ey();by(f);try{let y=await VO({...e,parallel:o,retriesOverride:e.retries,devicePixelRatio:f,tests:r,project:n,client:a,debugDataStorage:l,outputDir:u,uploadResults:e.uploadResults,reporterDir:d,customHeaders:t,envName:e.env,orgId:s,testInputMatrix:g,logger:m,regenerateGoldenFiles:e.updateGoldenFiles,gitMetadata:h,cacheOptions:{regenerateCache:e.regenerateCache,alwaysSaveCache:e.saveCache,noCache:e.disableCache,bustOldestCachePercentage:e.bustOldestCachePercentage},recordVideo:e.recordVideo??n.config.recordVideo,runGroupId:p,timeoutMinutes:e.timeoutMinutes});await io(),y.failed>0?process.exit(1):process.exit(0)}catch(y){E.error("Failed to run tests locally. Please check the error message below or run with the --verbose flag."),E.error(y),await io(),process.exit(1)}});var h2=Gt.command("apply").description("Apply an operation to local resources");h2.command("patch").addOption(Wr).addOption(qr).addOption(lr).addOption(Jo).addOption(Xo).addOption(new cr("--from <from>","Name or ID of the patch to apply").makeOptionMandatory()).addOption(new cr("--to <to>","Name or ID of the test to apply the patch to").makeOptionMandatory()).action(async r=>{await Zt(X);let{apiKey:e,server:t,config:n,yes:o}=r,i=await Ct({configFilePath:n}),a=X,s=new Qe({baseUrl:t,apiKey:e,logger:a}),c=await Z(i),l=c.tests[r.to]??Object.values(c.tests).find(d=>Ue(d.name)===r.to.trim());l||(E.error(`No test matching '${r.to}' could be found in the current project.`),process.exit(1));let u=await s.fetchTestFragment(r.from);await GP({client:s,test:l,fragment:u,yes:o,entities:c,logger:X}),process.exit(0)});var QO=Gt.command("results").description("Merge and upload test results.");QO.command("merge").description("Merge test results files.").addOption(ny).addArgument(mO).action(async(r,e)=>{await Zt(X);let{outputDir:t}=e;t||(E.error("Output directory is required."),process.exit(1)),lm.existsSync(r)||(E.warn("Results path does not exist, skipping merge."),process.exit(0)),lm.existsSync(t)&&E.warn(`Output directory ${t} already exists, removing before merging...`),WA(X,t,r)});QO.command("upload").description("Upload test results to Momentic cloud.").addOption(Wr).addOption(qr).addArgument(hO).action(async(r,e)=>{await Zt(X);let{apiKey:t,server:n}=e,o=X,i=new Qe({baseUrl:n,apiKey:t,logger:o});await dd({consoleLogger:E,resultsPath:r,client:i}),process.exit(0)});var wy=Gt.command("quarantine").description("Manage test quarantines");wy.command("add").description("Add a test to the quarantine. This will prevent it from running.").addOption(Wr).addOption(qr).addOption(lr).addOption(Jo).addOption(py).addArgument(my).action(async(r,e)=>{await Zt(X);let{apiKey:t,server:n,config:o,reason:i}=e,a=X,s=await Ct({configFilePath:o}),c=new Qe({baseUrl:n,apiKey:t,logger:a}),l=await Fr(X,c,s);await yO({test:r,reason:i,apiClient:c,project:s,logger:a,identity:l})});wy.command("list").description("List quarantined tests.").addOption(Wr).addOption(qr).addOption(lr).addOption(Jo).action(async r=>{let{apiKey:e,server:t,config:n}=r,o=X,i=await Ct({configFilePath:n}),a=new Qe({baseUrl:t,apiKey:e,logger:o});await TO({apiClient:a,project:i})});wy.command("remove").description("Remove a test from the quarantine. This will allow it to run again.").addOption(Wr).addOption(qr).addOption(lr).addOption(Jo).addOption(py).addArgument(my).action(async(r,e)=>{await Zt(X);let{apiKey:t,server:n,config:o,reason:i}=e,a=X,s=await Ct({configFilePath:o}),c=new Qe({baseUrl:n,apiKey:t,logger:a}),l=await Fr(X,c,s);await vO({test:r,reason:i,apiClient:c,project:s,identity:l})});Gt.command("upgrade").description("Upgrade your configuration to the latest recommended settings").addOption(lr).addOption(Jo).action(async r=>{let e=await Ct({configFilePath:r.config,nameFilter:r.filter});E.info("Updating Momentic version in package.json..."),await $O(),E.info("Updating project configuration..."),WO(e),E.success("Your project configuration was successfully updated to the latest recommended settings."),E.info("You can optionally run tests with the `--regenerate-cache` flag to entirely rebuild caches with the newer configuration. Warning: using this option will cause all steps to run without any cached data, resulting in significantly longer execution times.")});async function g2(){YO("Main program started");try{await Gt.parseAsync(process.argv),await io()}catch(r){let e={};try{e.playwrightVersion=s2("npx playwright --version").toString()}catch(t){X.error({err:t},"Error fetching debug information")}X.error({err:r,debugInfo:e},"Uncaught error in CLI"),Is(r,e),E.error(r),await io(),process.exit(1)}}c2.setMaxListeners(25);process.on("warning",r=>{X.warn({err:r},`Node warning received on CLI: ${r.message}`)});YO("CLI parsing setup complete");g2();
4805
4805
  //# sourceMappingURL=cli.js.map
4806
- //# debugId=e7177dc2-f0a2-521c-9f12-ce6944a8112e
4806
+ //# debugId=5eac6469-788b-5be3-9906-4739217289e9