momentic 1.0.43 → 1.0.44

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,7 +1,7 @@
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]="b7717b2d-47b9-50d6-93f5-7ce14d2edde3")}catch(e){}}();
4
- var My=Object.create;var cd=Object.defineProperty;var _y=Object.getOwnPropertyDescriptor;var ky=Object.getOwnPropertyNames;var Dy=Object.getPrototypeOf,Fy=Object.prototype.hasOwnProperty;var dd=(n,e)=>()=>(e||n((e={exports:{}}).exports,e),e.exports);var Uy=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of ky(e))!Fy.call(n,o)&&o!==t&&cd(n,o,{get:()=>e[o],enumerable:!(r=_y(e,o))||r.enumerable});return n};var zy=(n,e,t)=>(t=n!=null?My(Dy(n)):{},Uy(e||!n||!n.__esModule?cd(t,"default",{value:n,enumerable:!0}):t,n));var wf=dd((xJ,Sf)=>{"use strict";Sf.exports=gf;function gf(n,e,t){n instanceof RegExp&&(n=ff(n,t)),e instanceof RegExp&&(e=ff(e,t));var r=yf(n,e,t);return r&&{start:r[0],end:r[1],pre:t.slice(0,r[0]),body:t.slice(r[0]+n.length,r[1]),post:t.slice(r[1]+e.length)}}function ff(n,e){var t=e.match(n);return t?t[0]:null}gf.range=yf;function yf(n,e,t){var r,o,i,s,a,l=t.indexOf(n),c=t.indexOf(e,l+1),u=l;if(l>=0&&c>0){if(n===e)return[l,c];for(r=[],i=t.length;u>=0&&!a;)u==l?(r.push(u),l=t.indexOf(n,u+1)):r.length==1?a=[r.pop(),c]:(o=r.pop(),o<i&&(i=o,s=c),c=t.indexOf(e,u+1)),u=l<c&&l>=0?l:c;r.length&&(a=[i,s])}return a}});var Rf=dd((EJ,Af)=>{"use strict";var bf=wf();Af.exports=VE;var vf="\0SLASH"+Math.random()+"\0",Tf="\0OPEN"+Math.random()+"\0",sc="\0CLOSE"+Math.random()+"\0",xf="\0COMMA"+Math.random()+"\0",Ef="\0PERIOD"+Math.random()+"\0";function ic(n){return parseInt(n,10)==n?parseInt(n,10):n.charCodeAt(0)}function WE(n){return n.split("\\\\").join(vf).split("\\{").join(Tf).split("\\}").join(sc).split("\\,").join(xf).split("\\.").join(Ef)}function GE(n){return n.split(vf).join("\\").split(Tf).join("{").split(sc).join("}").split(xf).join(",").split(Ef).join(".")}function Cf(n){if(!n)return[""];var e=[],t=bf("{","}",n);if(!t)return n.split(",");var r=t.pre,o=t.body,i=t.post,s=r.split(",");s[s.length-1]+="{"+o+"}";var a=Cf(i);return i.length&&(s[s.length-1]+=a.shift(),s.push.apply(s,a)),e.push.apply(e,s),e}function VE(n){return n?(n.substr(0,2)==="{}"&&(n="\\{\\}"+n.substr(2)),Zo(WE(n),!0).map(GE)):[]}function qE(n){return"{"+n+"}"}function KE(n){return/^-?0\d/.test(n)}function YE(n,e){return n<=e}function JE(n,e){return n>=e}function Zo(n,e){var t=[],r=bf("{","}",n);if(!r)return[n];var o=r.pre,i=r.post.length?Zo(r.post,!1):[""];if(/\$$/.test(r.pre))for(var s=0;s<i.length;s++){var a=o+"{"+r.body+"}"+i[s];t.push(a)}else{var l=/^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(r.body),c=/^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(r.body),u=l||c,d=r.body.indexOf(",")>=0;if(!u&&!d)return r.post.match(/,.*\}/)?(n=r.pre+"{"+r.body+sc+r.post,Zo(n)):[n];var m;if(u)m=r.body.split(/\.\./);else if(m=Cf(r.body),m.length===1&&(m=Zo(m[0],!1).map(qE),m.length===1))return i.map(function(U){return r.pre+m[0]+U});var p;if(u){var f=ic(m[0]),h=ic(m[1]),g=Math.max(m[0].length,m[1].length),y=m.length==3?Math.abs(ic(m[2])):1,v=YE,x=h<f;x&&(y*=-1,v=JE);var b=m.some(KE);p=[];for(var S=f;v(S,h);S+=y){var C;if(c)C=String.fromCharCode(S),C==="\\"&&(C="");else if(C=String(S),b){var I=g-C.length;if(I>0){var O=new Array(I+1).join("0");S<0?C="-"+O+C.slice(1):C=O+C}}p.push(C)}}else{p=[];for(var L=0;L<m.length;L++)p.push.apply(p,Zo(m[L],!1))}for(var L=0;L<p.length;L++)for(var s=0;s<i.length;s++){var a=o+p[L]+i[s];(!e||u||a)&&t.push(a)}}return t}});var Ea=(n,e)=>{},co=()=>{},Ca=!1;try{let n=await import("@sentry/node"),{nodeProfilingIntegration:e}=await import("@sentry/profiling-node");Ea=n.captureException,co=n.profiler.stopProfiler,n.init({dsn:"https://89e980855f7b9c6e56fc6c7e7143888b@o4506426201800704.ingest.us.sentry.io/4508343221354497",integrations:[e()],environment:"production",release:process.env.SENTRY_RELEASE_NAME,tracesSampleRate:1}),n.profiler.startProfiler(),Ca=!0}catch{}import{Command as JR,Option as Qt}from"@commander-js/extra-typings";import{execSync as XR}from"child_process";import{z as _n}from"zod";import{z as X}from"zod";var xi=X.object({url:X.string(),method:X.union([X.literal("GET"),X.literal("POST"),X.literal("PUT"),X.literal("DELETE"),X.literal("PATCH")]),headers:X.record(X.string(),X.string()).optional(),params:X.record(X.string(),X.string()).optional(),body:X.string().optional(),timeout:X.number().int().optional().describe("Max seconds to wait for the request to complete")}),ud=X.object({url:X.string(),headers:X.record(X.string(),X.string()).optional(),query:X.string(),variables:X.record(X.string(),X.string()).optional(),timeout:X.number().int().optional().describe("Max seconds to wait for the request to complete")}),Ei=X.object({code:X.string(),fragment:X.boolean().optional(),environment:X.union([X.literal("NODE"),X.literal("BROWSER")]).optional().describe("default NODE"),timeout:X.number().int().max(60).optional().describe("Max seconds for the code to complete")});var pd=_n.object({id:_n.string().uuid(),skipped:_n.boolean().optional(),envKey:_n.string().optional().describe("key in the environment to save the result of this step to")}),Aa=pd.merge(xi).extend({type:_n.literal("REQUEST")}),Ra=pd.merge(Ei).extend({type:_n.literal("JAVASCRIPT")}),Ia=_n.discriminatedUnion("type",[Ra,Aa]);import{z as Lt}from"zod";import{z as kn}from"zod";var By=/^[a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$/,Pe=n=>{let e=n.trim().toLowerCase().replace(/[^a-z0-9]/g,"-");for(;e.includes("--");)e=e.replaceAll("--","-");return e.startsWith("-")&&(e=e.slice(1)),e.endsWith("-")&&(e=e.slice(0,e.length-1)),e};var Ci=kn.string().min(1).max(255).superRefine((n,e)=>{try{uo(n)}catch(t){return e.addIssue({code:kn.ZodIssueCode.custom,message:t.message,fatal:!0}),kn.NEVER}});function uo(n){if(n=n.toLowerCase().trim(),n.length===0||n.length>255)throw new Error("Name must be between 1 and 255 characters long");if(/[<>:"/\\|?*]/.test(n))throw new Error('Name contains one of the following invalid characters: <>:"/\\|?*');if(n.endsWith("-")||n.startsWith("-"))throw new Error("Name cannot start or end with a dash.");if(n.includes("\0"))throw new Error("Name cannot contain null characters");if(/^(con|prn|aux|nul|com[0-9]|lpt[0-9])(\..*)?$/i.test(n))throw new Error(`"${n}" is a reserved name on Windows and cannot be used as a filename.`);if(/^\.+$/.test(n)||/^\s|\s$/.test(n))throw new Error("Name cannot start or end with a space or dot.");if(n.endsWith(".yaml"))throw new Error('Name cannot end with ".yaml".');if(n==="none")throw new Error("Name cannot be 'none'.");if(n.match(By))throw new Error("Name cannot be a UUID. Please choose a different name.")}var Ai=kn.preprocess(n=>n===null?"":n,kn.union([kn.string().url(),kn.literal("")])).optional();import{isValidCron as $y}from"cron-validator";import{z as K}from"zod";import{z as Pa}from"zod";var Ri=Pa.object({width:Pa.number().min(200).max(1e4),height:Pa.number().min(200).max(1e4)}),md={"Desktop Large":{width:1920,height:1080},"Desktop Small":{width:1280,height:800},iPad:{width:768,height:1024},"Pixel 8":{width:448,height:998},"iPhone 15":{width:393,height:852}},hI=Object.keys(md);var Ot=md["Desktop Large"];import{z as ct}from"zod";var pe="BASE_URL",Ii="CURRENT_URL",dr="ENV_NAME",yI={[pe]:"https://www.google.com"},hd=ct.string().describe("Name of the fixture (must be available locally in the fixtures directory)."),Pi=ct.object({name:ct.string(),variables:ct.record(ct.string().describe("variable name"),ct.string().describe("variable value"))}),Oa=ct.object({localChromeExtensionPaths:ct.string().array().optional()}),Oi=ct.object({name:ct.string(),variables:ct.record(ct.string().describe("variable name"),ct.unknown().describe("variable value")),browser:Oa.optional()});var fd=1e4,gd=6e4,Dn=(t=>(t.CHROMIUM="Chromium",t.GOOGLE_CHROME="Google Chrome",t))(Dn||{}),po=K.object({browserType:K.nativeEnum(Dn).optional(),pageLoadTimeoutMs:K.number().optional().refine(n=>n===void 0||n<=gd&&n>=-1,{message:`Page load timeout must be between 0 and ${gd/1e3} seconds`}),smartWaitingTimeoutMs:K.number().optional().refine(n=>n===void 0||n<=fd&&n>=-1,{message:`Smart waiting timeout must be between 0 and ${fd/1e3} seconds`}),extraHeaders:K.record(K.string(),K.string()).optional().describe("HTTP headers to be sent on every request"),userAgent:K.string().optional(),basicAuthorization:K.object({username:K.string().optional(),password:K.string().optional()}).optional(),localChromeExtensionPaths:K.string().array().optional()});var jy=K.object({disableAICaching:K.boolean().default(!1),disableFailureRecovery:K.boolean().optional()}),Hy=K.object({viewport:Ri.optional()}),ur=Hy.merge(jy).merge(po),pr=K.object({cron:K.string().refine(n=>$y(n),{message:"Invalid cron expression."}).default("0 0 */1 * *"),enabled:K.boolean().default(!1),env:K.string().optional(),timeZone:K.string().default("America/Los_Angeles"),jobKey:K.string().optional()}),mr=K.object({onSuccess:K.boolean().default(!1),failureMessage:K.string().optional(),onFailure:K.boolean().default(!0),successMessage:K.string().optional()}),Wy=K.object({name:K.string(),required:K.boolean().optional(),defaultValue:K.string().describe("this is not optional because we need a value when the editor is first loaded")}),Li=Wy.array(),Gy=K.object({name:K.string(),value:K.string()}),yd=Gy.array(),Ni=K.object({name:K.string(),default:K.boolean().optional(),fixtures:hd.array().optional()});var Sd=Lt.object({id:Lt.string(),name:Ci,baseUrl:Ai.nullish(),schemaVersion:Lt.string(),advanced:Lt.unknown().optional(),retries:Lt.number(),envs:Lt.array(Ni).nullish(),parameters:Li.nullish()}),Vy=Lt.object({createdAt:Lt.coerce.date(),updatedAt:Lt.coerce.date(),schedule:pr.nullish(),notification:mr.nullish(),createdBy:Lt.string(),organizationId:Lt.string()}),qy=Sd.merge(Vy),II=qy.extend({steps:Ia.array()}),PI=Sd.extend({steps:Ia.array()});import{z as rt}from"zod";import{z as _o}from"zod";import{z as V}from"zod";function le(n){if(typeof n.ZodType.prototype.openapi<"u")return;n.ZodType.prototype.openapi=function(o){return new this.constructor({...this._def,openapi:o})};let e=n.ZodObject.prototype.extend;n.ZodObject.prototype.extend=function(...o){let i=e.apply(this,o);return i._def.extendMetadata={extends:this},delete i._def.openapi,i};let t=n.ZodObject.prototype.omit;n.ZodObject.prototype.omit=function(...o){let i=t.apply(this,o);return delete i._def.extendMetadata,delete i._def.openapi,i};let r=n.ZodObject.prototype.pick;n.ZodObject.prototype.pick=function(...o){let i=r.apply(this,o);return delete i._def.extendMetadata,delete i._def.openapi,i}}import*as $ from"zod";import{z as Ua}from"zod";import{z as Fa}from"zod";import{v4 as fe}from"uuid";import*as w from"zod";import{z as oe}from"zod";le(oe);var wd=oe.object({thoughts:oe.string(),result:oe.boolean(),relevantElements:oe.array(oe.number()).optional()}),mo=(r=>(r.CONTAINS="CONTAINS",r.STARTS_WITH="STARTS_WITH",r.EQUALS="EQUALS",r))(mo||{});var Ky=oe.object({type:oe.literal("ELEMENT_CONTENT"),negated:oe.boolean().optional(),operation:oe.nativeEnum(mo),value:oe.string()}).openapi({ref:"ElementContentAssertion"}),Yy=oe.object({type:oe.literal("ELEMENT_ATTRIBUTE"),negated:oe.boolean().optional(),operation:oe.nativeEnum(mo),attr:oe.string(),value:oe.string()}).openapi({ref:"ElementAttributeValueAssertion"}),ho=(o=>(o.EXISTS="EXISTS",o.VISIBLE="VISIBLE",o.ENABLED="ENABLED",o.EDITABLE="EDITABLE",o))(ho||{}),Jy=oe.object({type:oe.literal("ELEMENT_EXISTENCE"),negated:oe.boolean().optional(),condition:oe.nativeEnum(ho)}).openapi({ref:"ElementExistenceAssertion"}),bd=oe.discriminatedUnion("type",[Ky,Yy,Jy]).openapi({ref:"ManualElementAssertion"});var Xy=oe.object({type:oe.literal("CONTENT"),negated:oe.boolean().optional(),value:oe.string()}).openapi({ref:"PageContentAssertion"}),vd=oe.discriminatedUnion("type",[Xy]).openapi({ref:"ManualPageAssertion"});import*as G from"zod";le(G);var Fn=(a=>(a.AI="AI",a.AI_HEALED="AI_HEALED",a.CLICK_TO_FIND="CLICK_TO_FIND",a.XY_PERCENT="XY_PERCENT",a.RECORDING="RECORDING",a.USER_CSS_SELECTOR="USER_CSS_SELECTOR",a.HEURISTIC_HEALED="HEURISTIC_HEALED",a))(Fn||{}),Un=G.object({id:G.number().int(),dataMomenticId:G.number().int().optional(),selector:G.string().optional(),generatedSelectors:G.string().array().optional(),role:G.string().optional(),name:G.string().optional(),numChildren:G.number().optional(),content:G.string().optional(),pathFromRoot:G.string().optional(),serializedForm:G.string().optional(),nodeOnlySerializedForm:G.string().optional(),serializedHtml:G.string().optional().describe("pruned html including 1 neighbor and 1 layer of children. value for text inputs pruned."),nodeOnlySerializedHtml:G.string().optional().describe("outerHtml of the element without any children. value for text inputs pruned."),screenshotUrl:G.string().url().optional(),boundingBox:G.object({x:G.number().optional(),y:G.number().optional(),width:G.number(),height:G.number()}).describe("css pixel bounding box").optional(),inputDescription:G.string().optional().describe("the description that generated this cache"),targetSource:G.nativeEnum(Fn).optional(),targetUpdateTime:G.string().optional()}).openapi({ref:"A11yTargetWithCache"});function Mi(n){return!!(n.name||n.role||n.content||n.serializedForm||n.serializedHtml||n.screenshotUrl)}var Zy=G.object({type:G.literal("description"),elementDescriptor:G.string(),a11yData:Un.optional().describe("DEPRECATED: new a11y cache is stored in DB and resolved into the 'cache' field")}).openapi({ref:"DescriptionTarget"}),Qy=G.object({x:G.number(),y:G.number()}),eS=G.object({type:G.literal("coordinates"),pixels:Qy}).openapi({ref:"CoordinatesTarget"});function mn(n){return n.type==="description"}function Bt(n){return n.type==="coordinates"}var We=G.discriminatedUnion("type",[Zy,eS]).openapi({ref:"ElementTarget"});function La(n){if(!n)return!1;switch(n.type){case"description":return!!n.elementDescriptor}return!0}function Ge(n){if(!n)return"";switch(n.type){case"description":return n.elementDescriptor;case"coordinates":return`x: ${n.pixels.x}, y: ${n.pixels.y}`}}var Te=(N=>(N.AI_EXTRACT="AI_EXTRACT",N.AI_ASSERTION="AI_ASSERTION",N.AI_WAIT="AI_WAIT",N.AUTH_LOAD="AUTH_LOAD",N.AUTH_SAVE="AUTH_SAVE",N.BLUR="BLUR",N.CAPTCHA="CAPTCHA",N.CLICK="CLICK",N.COOKIE="COOKIE",N.DIALOG="DIALOG",N.DRAG="DRAG",N.ELEMENT_CHECK="ELEMENT_CHECK",N.FILE_UPLOAD="FILE_UPLOAD",N.FOCUS="FOCUS",N.GO_BACK="GO_BACK",N.GO_FORWARD="GO_FORWARD",N.HOVER="HOVER",N.JAVASCRIPT="JAVASCRIPT",N.LOCAL_STORAGE="LOCAL_STORAGE",N.MOUSE_DRAG="MOUSE_DRAG",N.NAVIGATE="NAVIGATE",N.NEW_TAB="NEW_TAB",N.PAGE_CHECK="PAGE_CHECK",N.PRESS="PRESS",N.REFRESH="REFRESH",N.REQUEST="REQUEST",N.GRAPHQL_REQUEST="GRAPHQL_REQUEST",N.SCROLL_DOWN="SCROLL_DOWN",N.SCROLL_UP="SCROLL_UP",N.SCROLL_LEFT="SCROLL_LEFT",N.SCROLL_RIGHT="SCROLL_RIGHT",N.SELECT_OPTION="SELECT_OPTION",N.TAB="TAB",N.TYPE="TYPE",N.VISUAL_DIFF="VISUAL_DIFF",N.WAIT="WAIT",N.WAIT_FOR_URL="WAIT_FOR_URL",N.SUCCESS="SUCCESS",N))(Te||{});le(w);var q=w.object({thoughts:w.string().optional(),id:w.string().uuid().describe("unique identifier to this step, used for step cache")}),gt=w.object({useSelector:w.boolean().optional(),force:w.boolean().optional(),disableCache:w.boolean().optional().describe("disable element caching for this step"),iframeUrl:w.string().optional().describe("url or url regex for the iframe")}).openapi({ref:"CommonTargetingOptions"}),$t=w.object({target:Un}).optional().openapi({ref:"SingleTargetCache"}),_i=w.object({loadTimeout:w.number().int().max(60).optional().describe("Max seconds for the page to load")}),tS=q.merge(_i).merge(w.object({type:w.literal("NAVIGATE"),url:w.string()})).openapi({ref:"NavigateCommand"}),ki=gt.merge(w.object({cache:$t})),hr=q.merge(ki.merge(w.object({target:We.optional(),type:w.literal("SCROLL_UP"),deltaY:w.number().optional()}))).openapi({ref:"ScrollUpCommand"}),fr=q.merge(ki.merge(w.object({target:We.optional(),type:w.literal("SCROLL_DOWN"),deltaY:w.number().optional()}))).openapi({ref:"ScrollDownCommand"}),gr=q.merge(ki.merge(w.object({target:We.optional(),type:w.literal("SCROLL_LEFT"),deltaX:w.number().optional()}))).openapi({ref:"ScrollLeftCommand"}),yr=q.merge(ki.merge(w.object({target:We.optional(),type:w.literal("SCROLL_RIGHT"),deltaX:w.number().optional()}))).openapi({ref:"ScrollRightCommand"}),WI=w.discriminatedUnion("type",[hr,fr,gr,yr]).openapi({ref:"AllScrollCommands"}),nS=q.merge(w.object({type:w.literal("DIALOG"),action:w.union([w.literal("ACCEPT"),w.literal("DISMISS")])})).openapi({ref:"DialogCommand"}),rS=q.merge(w.object({type:w.literal("WAIT"),delay:w.number()})).openapi({ref:"WaitCommand"}),GI=w.discriminatedUnion("type",[w.object({type:w.literal("EXACT_MATCH"),url:w.string()}),w.object({type:w.literal("GLOB_MATCH"),glob:w.string()}),w.object({type:w.literal("REGEX_MATCH"),regex:w.string()})]),oS=w.object({caseInsensitive:w.boolean().optional().describe("Whether to ignore case when matching the URL"),negated:w.boolean().optional().describe("Wait for the URL to NOT match the provided matcher instead."),timeout:w.number().int().optional().describe("Max seconds to wait for the URL to match")}),iS=q.extend({type:w.literal("WAIT_FOR_URL"),url:w.string().describe("Deprecated: url or glob to wait for. New commands should use the discriminated matcher field.")}).merge(oS).openapi({ref:"WaitUrlCommand"}),sS=q.merge(_i).merge(w.object({type:w.literal("REFRESH")})).openapi({ref:"RefreshCommand"}),aS=q.merge(w.object({type:w.literal("GO_BACK")})).openapi({ref:"GoBackCommand"}),lS=q.merge(w.object({type:w.literal("GO_FORWARD")})).openapi({ref:"GoForwardCommand"}),cS=q.extend({type:w.literal("AUTH_SAVE")}).openapi({ref:"AuthSaveCommand"}),dS=q.extend({type:w.literal("AUTH_LOAD"),storageState:w.string().describe("JSON string auth state. Leave blank or set to the empty string to clear all existing authentication.")}).openapi({ref:"AuthLoadCommand"}),Ma=q.merge(gt).extend({type:w.literal("CAPTCHA")}).openapi({ref:"CaptchaCommand"}),uS=q.merge(Ei).extend({type:w.literal("JAVASCRIPT"),envKey:w.string().optional()}).openapi({ref:"JavaScriptCommand"}),fo=q.merge(gt).merge(w.object({type:w.literal("CLICK"),target:We,doubleClick:w.boolean().optional(),rightClick:w.boolean().optional(),waitForUrl:w.string().optional().describe("Deprecated: wait for the click to trigger a page load or new tab that matches the provided URL or URL glob (e.g. https://google.com/**/*)."),waitForDownload:w.boolean().optional().describe("Wait for the click to trigger a file download and for the file download to complete."),cache:$t})).openapi({ref:"ClickCommand"}),go=q.merge(gt).merge(w.object({type:w.literal("DRAG"),fromTarget:We,toTarget:We,hoverSeconds:w.number().optional().describe("Seconds to hover the object before dropping"),cache:w.object({fromTarget:Un.optional(),toTarget:Un.optional()}).optional()})).openapi({ref:"DragCommand"}),yo=q.merge(gt).merge(w.object({type:w.literal("MOUSE_DRAG"),target:We.optional(),deltaX:w.string().describe("pixels to move horizontally, can be template"),deltaY:w.string().describe("pixels to move vertically, can be template"),steps:w.number().optional(),cache:$t})).openapi({ref:"MouseDragCommand"}),So=q.merge(gt).merge(w.object({type:w.literal("HOVER"),target:We,cache:$t})).openapi({ref:"HoverCommand"}),wo=q.merge(gt).merge(w.object({type:w.literal("FOCUS"),target:We,cache:$t})).openapi({ref:"FocusCommand"}),bo=q.merge(gt).extend({type:w.literal("BLUR"),target:We.optional(),cache:$t}).openapi({ref:"BlurCommand"}),pS=w.object({type:w.literal("URL"),url:w.string()}).describe("Accessible link to the file, either public http or local file://").openapi({ref:"UrlSource"}),mS=q.extend({type:w.literal("FILE_UPLOAD"),fileSource:w.discriminatedUnion("type",[pS]),filename:w.string().optional()}).openapi({ref:"FileUploadCommand"}),hS=w.discriminatedUnion("type",[w.object({type:w.literal("VALUE"),value:w.string()}),w.object({type:w.literal("LABEL"),label:w.string()}),w.object({type:w.literal("INDEX"),index:w.number().int()})]),vo=q.merge(gt).extend({type:w.literal("SELECT_OPTION"),target:We,cache:$t,option:w.string().describe("option value, deprecated old field").optional(),choice:hS.optional().describe("new field for selecting options, optional for backcompat")}).openapi({ref:"SelectOptionCommand"}),_a=w.union([w.literal("MULTIMODAL"),w.literal("VISION_ONLY")]),ka=q.merge(w.object({type:w.literal("AI_ASSERTION"),assertion:w.string(),disableCache:w.boolean().optional(),iframeUrl:w.string().optional(),contextChoice:_a.optional(),timeout:w.number().int().optional().describe("Max seconds to wait for assertion to be true")})).openapi({ref:"AIAssertionCommand"}),fS=ka.extend({type:w.literal("AI_WAIT")}).openapi({ref:"AIWaitCommand"}),zn=5,Da=600,To=q.merge(gt).extend({type:w.literal("ELEMENT_CHECK"),target:We,assertion:bd,cache:$t,timeout:w.number().int().min(0).max(Da).optional().describe("max seconds to wait for the assertion to be true")}).openapi({ref:"ElementAssertionCommand"}),gS=q.extend({type:w.literal("PAGE_CHECK"),assertion:vd,iframeUrl:w.string().optional().describe("url or url regex for the iframe"),timeout:w.number().int().min(0).max(Da).optional().describe("max seconds to wait for the assertion to be true")}).openapi({ref:"PageAssertionCommand"}),yS=q.merge(w.object({type:w.literal("AI_EXTRACT"),goal:w.string(),schema:w.string().optional(),envKey:w.string().optional(),disableCache:w.boolean().optional(),iframeUrl:w.string().optional()})).openapi({ref:"AIExtractCommand"}),SS=w.object({clearContent:w.boolean().optional(),pressKeysSequentially:w.boolean().optional().describe("Deprecated: this is now the default. Please set delay to zero if you wish to achieve instant typing behavior."),delay:w.number().min(0).max(1e3).optional().describe("Delay between each press in milliseconds."),force:w.boolean().optional(),pressEnter:w.boolean().optional()}),xo=q.merge(gt).merge(SS).extend({type:w.literal("TYPE"),target:We.optional(),value:w.string(),cache:$t}).openapi({ref:"TypeCommand"}),wS=q.merge(w.object({type:w.literal("PRESS"),value:w.string()})).openapi({ref:"PressCommand"}),bS=w.object({type:w.literal("SUBSTRING"),substring:w.string()}),vS=w.object({type:w.literal("REGEX"),pattern:w.string()}),TS=w.object({type:w.literal("INDEX"),index:w.number()}),xS=w.discriminatedUnion("type",[bS,vS,TS]),ES=q.merge(_i).merge(w.object({type:w.literal("TAB"),url:w.string().optional().describe("deprecated field - new instances should use the discriminated union"),action:xS.optional()})).openapi({ref:"TabCommand"}),CS=q.merge(_i).merge(w.object({type:w.literal("NEW_TAB"),url:w.string()})).openapi({ref:"NewTabCommand"}),AS=q.merge(w.object({type:w.literal("COOKIE"),value:w.string()})).openapi({ref:"CookieCommand"}),RS=q.merge(w.object({type:w.literal("LOCAL_STORAGE"),key:w.string(),value:w.string()})).openapi({ref:"LocalStorageCommand"}),IS=q.extend({type:w.literal("REQUEST")}).merge(xi).openapi({ref:"RequestCommand"}),PS=q.extend({type:w.literal("GRAPHQL_REQUEST")}).merge(ud).openapi({ref:"GraphQLRequestCommand"}),OS=q.merge(w.object({type:w.literal("SUCCESS"),condition:ka.optional()})).openapi({ref:"SuccessCommand"}),LS=q.merge(w.object({type:w.literal("FAILURE")})).openapi({ref:"FailureCommand"}),NS=w.object({data:w.string().describe("location at which to find a jpg"),width:w.number(),height:w.number()}),Eo=q.merge(gt).merge(w.object({type:w.literal("VISUAL_DIFF"),threshold:w.number().optional().describe("default 0.1"),target:We.optional(),screenshot:NS.optional(),cache:$t})).openapi({ref:"VisualDiffCommand"}),Di=w.discriminatedUnion("type",[fo,xo,wS,vo,tS,fr,hr,ka,So,rS,OS]),MS=w.discriminatedUnion("type",[fS,yS,dS,cS,Ma,AS,nS,go,To,mS,aS,lS,uS,RS,yo,CS,gS,sS,IS,PS,gr,yr,ES,Eo,wo,bo,iS]),Fi=w.discriminatedUnion("type",[...Di.options,...MS.options]).openapi({ref:"Command"}),xd=w.discriminatedUnion("type",[...Di.options,LS]);function hn(n){let e;switch(n){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:fe(),type:n};break;case"AUTH_LOAD":{e={id:fe(),type:n,storageState:""};break}case"AI_EXTRACT":e={id:fe(),type:n,goal:""};break;case"DIALOG":e={id:fe(),type:n,action:"DISMISS"};break;case"DRAG":e={id:fe(),type:n,fromTarget:{type:"description",elementDescriptor:""},toTarget:{type:"description",elementDescriptor:""}};break;case"MOUSE_DRAG":e={id:fe(),type:n,deltaX:"0",deltaY:"0",steps:1};break;case"WAIT_FOR_URL":e={id:fe(),type:n,url:""};break;case"WAIT":e={id:fe(),type:n,delay:1};break;case"BLUR":e={id:fe(),type:n};break;case"HOVER":case"FOCUS":case"CLICK":e={id:fe(),type:n,target:{type:"description",elementDescriptor:""}};break;case"COOKIE":case"PRESS":case"TYPE":e={id:fe(),type:n,value:"",clearContent:!0};break;case"SELECT_OPTION":e={id:fe(),type:n,target:{type:"description",elementDescriptor:""},choice:{type:"VALUE",value:""}};break;case"NAVIGATE":case"NEW_TAB":case"TAB":e={id:fe(),type:n,url:""};break;case"REQUEST":e={id:fe(),type:n,url:"",method:"GET"};break;case"GRAPHQL_REQUEST":e={id:fe(),type:n,url:"",query:""};break;case"LOCAL_STORAGE":e={id:fe(),type:n,key:"",value:""};break;case"JAVASCRIPT":e={id:fe(),type:n,code:""};break;case"AI_WAIT":case"AI_ASSERTION":e={id:fe(),type:n,assertion:""};break;case"FILE_UPLOAD":{e={id:fe(),type:n,fileSource:{type:"URL",url:""}};break}case"ELEMENT_CHECK":{e={id:fe(),type:n,target:{type:"description",elementDescriptor:""},assertion:{type:"ELEMENT_EXISTENCE",condition:"EXISTS"}};break}case"PAGE_CHECK":{e={id:fe(),type:n,assertion:{type:"CONTENT",value:""}};break}default:return(r=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(n)}return e}import{z as Sr}from"zod";var tt=Sr.object({index:Sr.number().optional().describe("global index within a test (in-order traversal)"),id:Sr.string(),skipped:Sr.boolean().optional(),envKey:Sr.string().optional().describe("key in the environment to save the result of this step to"),aiSuggested:Sr.boolean().optional()});le(Fa);var yt=tt.extend({type:Fa.literal("PRESET_ACTION"),command:Fi,skipped:Fa.boolean().optional()}).openapi({ref:"PresetAction"});le(Ua);var wr=tt.extend({type:Ua.literal("AI_ACTION"),text:Ua.string(),steps:yt.array().optional()}).openapi({ref:"AIAction"});import{z as de}from"zod";var _S=de.object({cacheKey:de.string(),cacheExpiryMs:de.number()}),za=tt.extend({id:de.string().uuid().describe("ID of the module step itself. Used to 'namespace' step cache entries."),inputs:de.record(de.string()).optional(),cacheConfig:_S.optional()}),br=za.extend({type:de.literal("MODULE"),moduleId:de.string().uuid()}),kS=de.union([br.pick({type:!0,moduleId:!0}),de.record(de.unknown())]),St=de.object({moduleId:de.string().uuid(),name:de.string(),description:de.string().nullish(),enabled:de.boolean().nullish(),parameters:de.string().array().nullish(),defaultParameters:de.record(de.string(),de.string()).nullish(),defaultCacheKey:de.string().nullish(),defaultCacheTtl:de.number().nullish(),defaultCacheAllInvocations:de.boolean().nullish(),autoAuth:de.boolean().nullish()});import{z as Fe}from"zod";import{z as Ba}from"zod";le(Ba);var Co=tt.extend({type:Ba.literal("AI_ACTION_DYNAMIC"),text:Ba.string()}).openapi({ref:"AIActionDynamic"});import{z as Ed}from"zod";var Ao=tt.extend({type:Ed.literal("CONDITIONAL"),skipped:Ed.boolean().optional()});import{z as wt}from"zod";var DS=wt.object({type:wt.literal("attr"),name:wt.string(),value:wt.string()}),FS=wt.object({type:wt.literal("css"),selector:wt.string()}),US=wt.object({type:wt.literal("url"),url:wt.string()}),zS=wt.union([DS,US,FS]),Ro=tt.extend({type:wt.literal("IFRAME"),identifier:zS});import{z as bt}from"zod";var $a=(r=>(r.ALWAYS="ALWAYS",r.ON_FAILURE="ON_FAILURE",r.ON_ACTION_FAILURE="ON_ACTION_FAILURE",r))($a||{});var BS=bt.discriminatedUnion("type",[bt.object({type:bt.literal("NAVIGATE_URL"),url:bt.string().url()}),bt.object({type:bt.literal("GO_TO_SECTION_START")})]),$S=bt.object({trigger:bt.nativeEnum($a).optional(),attempts:bt.number().int().optional(),restartBehavior:BS}),Io=tt.extend({type:bt.literal("SECTION"),description:bt.string().describe("user provided goal of what the section should accomplish"),plan:bt.string().array().optional(),autohealingConfig:$S.optional()});var Cd=St.merge(za).extend({type:Fe.literal("RESOLVED_MODULE"),steps:Fe.lazy(()=>xe.array())}),ja=St.extend({steps:Fe.lazy(()=>xe.array())}),jS=Ro.extend({steps:Fe.lazy(()=>vt.array())}),HS=Ro.extend({steps:Fe.lazy(()=>xe.array())}),WS=Io.extend({steps:Fe.lazy(()=>vt.array())}),GS=Io.extend({steps:Fe.lazy(()=>xe.array())}),VS=Ao.extend({blocks:Fe.object({assertion:Fe.lazy(()=>yt),steps:Fe.lazy(()=>vt.array())}).array(),elseSteps:Fe.lazy(()=>vt.array().optional())}),qS=Ao.extend({blocks:Fe.object({assertion:Fe.lazy(()=>yt),steps:Fe.lazy(()=>xe.array())}).array(),elseSteps:Fe.lazy(()=>xe.array().optional())}),vt=Fe.discriminatedUnion("type",[yt,wr,Co,br,VS,jS,WS]),xe=Fe.discriminatedUnion("type",[yt,wr,Co,Cd,qS,HS,GS]);var Tt="1.0.18";import{z as $n}from"zod";import{z as KS}from"zod";var tO=KS.discriminatedUnion("type",[bo,Ma,fo,go,wo,So,yo,hr,fr,gr,yr,vo,xo,Eo,To]);function Ad(n){return["AI_ASSERTION","ELEMENT_CHECK","PAGE_CHECK"].includes(n)}import{z as YS}from"zod";var nt={type:!0,cache:!0},Bn=YS.discriminatedUnion("type",[bo.pick(nt),fo.pick(nt),go.pick(nt),To.pick(nt),wo.pick(nt),So.pick(nt),yo.pick(nt),hr.pick(nt),fr.pick(nt),gr.pick(nt),yr.pick(nt),vo.pick(nt),xo.pick(nt),Eo.pick(nt)]),Ha=Object.values(Te).filter(n=>Bn.options.some(e=>e.shape.type.safeParse(n).success));Fi.options.forEach(n=>{if("target"in n.shape&&!Ha.includes(n.shape.type.value))throw new Error(`Command ${n.shape.type.value} has a target but no cache`)});var Wa=$n.object({key:$n.string(),testId:$n.string().optional(),moduleId:$n.string().optional(),organizationId:$n.string(),value:Bn}),Rd=$n.record($n.string(),Wa);import{cloneDeep as Lo}from"lodash-es";var JS=n=>{let e=Id(n,0);if(e===void 0||!ZS(n[e]))return;let t=Id(n,e+1);if(t!==void 0)return QS(n,e,t)},Pd=JS,Id=(n,e)=>{for(let t=e;t<n.length;t+=1){let r=n[t];if(!XS(r))return t}},XS=n=>n===" "||n===" "||n===`
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]="904cac85-fa3c-5af8-a93b-644e0eaba702")}catch(e){}}();
4
+ var My=Object.create;var cd=Object.defineProperty;var _y=Object.getOwnPropertyDescriptor;var ky=Object.getOwnPropertyNames;var Dy=Object.getPrototypeOf,Fy=Object.prototype.hasOwnProperty;var dd=(n,e)=>()=>(e||n((e={exports:{}}).exports,e),e.exports);var Uy=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of ky(e))!Fy.call(n,o)&&o!==t&&cd(n,o,{get:()=>e[o],enumerable:!(r=_y(e,o))||r.enumerable});return n};var zy=(n,e,t)=>(t=n!=null?My(Dy(n)):{},Uy(e||!n||!n.__esModule?cd(t,"default",{value:n,enumerable:!0}):t,n));var wf=dd((xJ,Sf)=>{"use strict";Sf.exports=gf;function gf(n,e,t){n instanceof RegExp&&(n=ff(n,t)),e instanceof RegExp&&(e=ff(e,t));var r=yf(n,e,t);return r&&{start:r[0],end:r[1],pre:t.slice(0,r[0]),body:t.slice(r[0]+n.length,r[1]),post:t.slice(r[1]+e.length)}}function ff(n,e){var t=e.match(n);return t?t[0]:null}gf.range=yf;function yf(n,e,t){var r,o,i,s,a,l=t.indexOf(n),c=t.indexOf(e,l+1),u=l;if(l>=0&&c>0){if(n===e)return[l,c];for(r=[],i=t.length;u>=0&&!a;)u==l?(r.push(u),l=t.indexOf(n,u+1)):r.length==1?a=[r.pop(),c]:(o=r.pop(),o<i&&(i=o,s=c),c=t.indexOf(e,u+1)),u=l<c&&l>=0?l:c;r.length&&(a=[i,s])}return a}});var Rf=dd((EJ,Af)=>{"use strict";var bf=wf();Af.exports=VE;var vf="\0SLASH"+Math.random()+"\0",Tf="\0OPEN"+Math.random()+"\0",sc="\0CLOSE"+Math.random()+"\0",xf="\0COMMA"+Math.random()+"\0",Ef="\0PERIOD"+Math.random()+"\0";function ic(n){return parseInt(n,10)==n?parseInt(n,10):n.charCodeAt(0)}function WE(n){return n.split("\\\\").join(vf).split("\\{").join(Tf).split("\\}").join(sc).split("\\,").join(xf).split("\\.").join(Ef)}function GE(n){return n.split(vf).join("\\").split(Tf).join("{").split(sc).join("}").split(xf).join(",").split(Ef).join(".")}function Cf(n){if(!n)return[""];var e=[],t=bf("{","}",n);if(!t)return n.split(",");var r=t.pre,o=t.body,i=t.post,s=r.split(",");s[s.length-1]+="{"+o+"}";var a=Cf(i);return i.length&&(s[s.length-1]+=a.shift(),s.push.apply(s,a)),e.push.apply(e,s),e}function VE(n){return n?(n.substr(0,2)==="{}"&&(n="\\{\\}"+n.substr(2)),Zo(WE(n),!0).map(GE)):[]}function qE(n){return"{"+n+"}"}function KE(n){return/^-?0\d/.test(n)}function YE(n,e){return n<=e}function JE(n,e){return n>=e}function Zo(n,e){var t=[],r=bf("{","}",n);if(!r)return[n];var o=r.pre,i=r.post.length?Zo(r.post,!1):[""];if(/\$$/.test(r.pre))for(var s=0;s<i.length;s++){var a=o+"{"+r.body+"}"+i[s];t.push(a)}else{var l=/^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(r.body),c=/^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(r.body),u=l||c,d=r.body.indexOf(",")>=0;if(!u&&!d)return r.post.match(/,.*\}/)?(n=r.pre+"{"+r.body+sc+r.post,Zo(n)):[n];var m;if(u)m=r.body.split(/\.\./);else if(m=Cf(r.body),m.length===1&&(m=Zo(m[0],!1).map(qE),m.length===1))return i.map(function(U){return r.pre+m[0]+U});var p;if(u){var f=ic(m[0]),h=ic(m[1]),g=Math.max(m[0].length,m[1].length),y=m.length==3?Math.abs(ic(m[2])):1,v=YE,x=h<f;x&&(y*=-1,v=JE);var b=m.some(KE);p=[];for(var S=f;v(S,h);S+=y){var C;if(c)C=String.fromCharCode(S),C==="\\"&&(C="");else if(C=String(S),b){var I=g-C.length;if(I>0){var O=new Array(I+1).join("0");S<0?C="-"+O+C.slice(1):C=O+C}}p.push(C)}}else{p=[];for(var L=0;L<m.length;L++)p.push.apply(p,Zo(m[L],!1))}for(var L=0;L<p.length;L++)for(var s=0;s<i.length;s++){var a=o+p[L]+i[s];(!e||u||a)&&t.push(a)}}return t}});var Ea=(n,e)=>{},co=()=>{},Ca=!1;try{let n=await import("@sentry/node"),{nodeProfilingIntegration:e}=await import("@sentry/profiling-node");Ea=n.captureException,co=n.profiler.stopProfiler,n.init({dsn:"https://89e980855f7b9c6e56fc6c7e7143888b@o4506426201800704.ingest.us.sentry.io/4508343221354497",integrations:[e()],environment:"staging",release:process.env.SENTRY_RELEASE_NAME,tracesSampleRate:1}),n.profiler.startProfiler(),Ca=!0}catch{}import{Command as JR,Option as Qt}from"@commander-js/extra-typings";import{execSync as XR}from"child_process";import{z as _n}from"zod";import{z as X}from"zod";var xi=X.object({url:X.string(),method:X.union([X.literal("GET"),X.literal("POST"),X.literal("PUT"),X.literal("DELETE"),X.literal("PATCH")]),headers:X.record(X.string(),X.string()).optional(),params:X.record(X.string(),X.string()).optional(),body:X.string().optional(),timeout:X.number().int().optional().describe("Max seconds to wait for the request to complete")}),ud=X.object({url:X.string(),headers:X.record(X.string(),X.string()).optional(),query:X.string(),variables:X.record(X.string(),X.string()).optional(),timeout:X.number().int().optional().describe("Max seconds to wait for the request to complete")}),Ei=X.object({code:X.string(),fragment:X.boolean().optional(),environment:X.union([X.literal("NODE"),X.literal("BROWSER")]).optional().describe("default NODE"),timeout:X.number().int().max(60).optional().describe("Max seconds for the code to complete")});var pd=_n.object({id:_n.string().uuid(),skipped:_n.boolean().optional(),envKey:_n.string().optional().describe("key in the environment to save the result of this step to")}),Aa=pd.merge(xi).extend({type:_n.literal("REQUEST")}),Ra=pd.merge(Ei).extend({type:_n.literal("JAVASCRIPT")}),Ia=_n.discriminatedUnion("type",[Ra,Aa]);import{z as Lt}from"zod";import{z as kn}from"zod";var By=/^[a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$/,Pe=n=>{let e=n.trim().toLowerCase().replace(/[^a-z0-9]/g,"-");for(;e.includes("--");)e=e.replaceAll("--","-");return e.startsWith("-")&&(e=e.slice(1)),e.endsWith("-")&&(e=e.slice(0,e.length-1)),e};var Ci=kn.string().min(1).max(255).superRefine((n,e)=>{try{uo(n)}catch(t){return e.addIssue({code:kn.ZodIssueCode.custom,message:t.message,fatal:!0}),kn.NEVER}});function uo(n){if(n=n.toLowerCase().trim(),n.length===0||n.length>255)throw new Error("Name must be between 1 and 255 characters long");if(/[<>:"/\\|?*]/.test(n))throw new Error('Name contains one of the following invalid characters: <>:"/\\|?*');if(n.endsWith("-")||n.startsWith("-"))throw new Error("Name cannot start or end with a dash.");if(n.includes("\0"))throw new Error("Name cannot contain null characters");if(/^(con|prn|aux|nul|com[0-9]|lpt[0-9])(\..*)?$/i.test(n))throw new Error(`"${n}" is a reserved name on Windows and cannot be used as a filename.`);if(/^\.+$/.test(n)||/^\s|\s$/.test(n))throw new Error("Name cannot start or end with a space or dot.");if(n.endsWith(".yaml"))throw new Error('Name cannot end with ".yaml".');if(n==="none")throw new Error("Name cannot be 'none'.");if(n.match(By))throw new Error("Name cannot be a UUID. Please choose a different name.")}var Ai=kn.preprocess(n=>n===null?"":n,kn.union([kn.string().url(),kn.literal("")])).optional();import{isValidCron as $y}from"cron-validator";import{z as K}from"zod";import{z as Pa}from"zod";var Ri=Pa.object({width:Pa.number().min(200).max(1e4),height:Pa.number().min(200).max(1e4)}),md={"Desktop Large":{width:1920,height:1080},"Desktop Small":{width:1280,height:800},iPad:{width:768,height:1024},"Pixel 8":{width:448,height:998},"iPhone 15":{width:393,height:852}},hI=Object.keys(md);var Ot=md["Desktop Large"];import{z as ct}from"zod";var pe="BASE_URL",Ii="CURRENT_URL",dr="ENV_NAME",yI={[pe]:"https://www.google.com"},hd=ct.string().describe("Name of the fixture (must be available locally in the fixtures directory)."),Pi=ct.object({name:ct.string(),variables:ct.record(ct.string().describe("variable name"),ct.string().describe("variable value"))}),Oa=ct.object({localChromeExtensionPaths:ct.string().array().optional()}),Oi=ct.object({name:ct.string(),variables:ct.record(ct.string().describe("variable name"),ct.unknown().describe("variable value")),browser:Oa.optional()});var fd=1e4,gd=6e4,Dn=(t=>(t.CHROMIUM="Chromium",t.GOOGLE_CHROME="Google Chrome",t))(Dn||{}),po=K.object({browserType:K.nativeEnum(Dn).optional(),pageLoadTimeoutMs:K.number().optional().refine(n=>n===void 0||n<=gd&&n>=-1,{message:`Page load timeout must be between 0 and ${gd/1e3} seconds`}),smartWaitingTimeoutMs:K.number().optional().refine(n=>n===void 0||n<=fd&&n>=-1,{message:`Smart waiting timeout must be between 0 and ${fd/1e3} seconds`}),extraHeaders:K.record(K.string(),K.string()).optional().describe("HTTP headers to be sent on every request"),userAgent:K.string().optional(),basicAuthorization:K.object({username:K.string().optional(),password:K.string().optional()}).optional(),localChromeExtensionPaths:K.string().array().optional()});var jy=K.object({disableAICaching:K.boolean().default(!1),disableFailureRecovery:K.boolean().default(!0)}),Hy=K.object({viewport:Ri.optional()}),ur=Hy.merge(jy).merge(po),pr=K.object({cron:K.string().refine(n=>$y(n),{message:"Invalid cron expression."}).default("0 0 */1 * *"),enabled:K.boolean().default(!1),env:K.string().optional(),timeZone:K.string().default("America/Los_Angeles"),jobKey:K.string().optional()}),mr=K.object({onSuccess:K.boolean().default(!1),failureMessage:K.string().optional(),onFailure:K.boolean().default(!0),successMessage:K.string().optional()}),Wy=K.object({name:K.string(),required:K.boolean().optional(),defaultValue:K.string().describe("this is not optional because we need a value when the editor is first loaded")}),Li=Wy.array(),Gy=K.object({name:K.string(),value:K.string()}),yd=Gy.array(),Ni=K.object({name:K.string(),default:K.boolean().optional(),fixtures:hd.array().optional()});var Sd=Lt.object({id:Lt.string(),name:Ci,baseUrl:Ai.nullish(),schemaVersion:Lt.string(),advanced:Lt.unknown().optional(),retries:Lt.number(),envs:Lt.array(Ni).nullish(),parameters:Li.nullish()}),Vy=Lt.object({createdAt:Lt.coerce.date(),updatedAt:Lt.coerce.date(),schedule:pr.nullish(),notification:mr.nullish(),createdBy:Lt.string(),organizationId:Lt.string()}),qy=Sd.merge(Vy),II=qy.extend({steps:Ia.array()}),PI=Sd.extend({steps:Ia.array()});import{z as rt}from"zod";import{z as _o}from"zod";import{z as V}from"zod";function le(n){if(typeof n.ZodType.prototype.openapi<"u")return;n.ZodType.prototype.openapi=function(o){return new this.constructor({...this._def,openapi:o})};let e=n.ZodObject.prototype.extend;n.ZodObject.prototype.extend=function(...o){let i=e.apply(this,o);return i._def.extendMetadata={extends:this},delete i._def.openapi,i};let t=n.ZodObject.prototype.omit;n.ZodObject.prototype.omit=function(...o){let i=t.apply(this,o);return delete i._def.extendMetadata,delete i._def.openapi,i};let r=n.ZodObject.prototype.pick;n.ZodObject.prototype.pick=function(...o){let i=r.apply(this,o);return delete i._def.extendMetadata,delete i._def.openapi,i}}import*as $ from"zod";import{z as Ua}from"zod";import{z as Fa}from"zod";import{v4 as fe}from"uuid";import*as w from"zod";import{z as oe}from"zod";le(oe);var wd=oe.object({thoughts:oe.string(),result:oe.boolean(),relevantElements:oe.array(oe.number()).optional()}),mo=(r=>(r.CONTAINS="CONTAINS",r.STARTS_WITH="STARTS_WITH",r.EQUALS="EQUALS",r))(mo||{});var Ky=oe.object({type:oe.literal("ELEMENT_CONTENT"),negated:oe.boolean().optional(),operation:oe.nativeEnum(mo),value:oe.string()}).openapi({ref:"ElementContentAssertion"}),Yy=oe.object({type:oe.literal("ELEMENT_ATTRIBUTE"),negated:oe.boolean().optional(),operation:oe.nativeEnum(mo),attr:oe.string(),value:oe.string()}).openapi({ref:"ElementAttributeValueAssertion"}),ho=(o=>(o.EXISTS="EXISTS",o.VISIBLE="VISIBLE",o.ENABLED="ENABLED",o.EDITABLE="EDITABLE",o))(ho||{}),Jy=oe.object({type:oe.literal("ELEMENT_EXISTENCE"),negated:oe.boolean().optional(),condition:oe.nativeEnum(ho)}).openapi({ref:"ElementExistenceAssertion"}),bd=oe.discriminatedUnion("type",[Ky,Yy,Jy]).openapi({ref:"ManualElementAssertion"});var Xy=oe.object({type:oe.literal("CONTENT"),negated:oe.boolean().optional(),value:oe.string()}).openapi({ref:"PageContentAssertion"}),vd=oe.discriminatedUnion("type",[Xy]).openapi({ref:"ManualPageAssertion"});import*as G from"zod";le(G);var Fn=(a=>(a.AI="AI",a.AI_HEALED="AI_HEALED",a.CLICK_TO_FIND="CLICK_TO_FIND",a.XY_PERCENT="XY_PERCENT",a.RECORDING="RECORDING",a.USER_CSS_SELECTOR="USER_CSS_SELECTOR",a.HEURISTIC_HEALED="HEURISTIC_HEALED",a))(Fn||{}),Un=G.object({id:G.number().int(),dataMomenticId:G.number().int().optional(),selector:G.string().optional(),generatedSelectors:G.string().array().optional(),role:G.string().optional(),name:G.string().optional(),numChildren:G.number().optional(),content:G.string().optional(),pathFromRoot:G.string().optional(),serializedForm:G.string().optional(),nodeOnlySerializedForm:G.string().optional(),serializedHtml:G.string().optional().describe("pruned html including 1 neighbor and 1 layer of children. value for text inputs pruned."),nodeOnlySerializedHtml:G.string().optional().describe("outerHtml of the element without any children. value for text inputs pruned."),screenshotUrl:G.string().url().optional(),boundingBox:G.object({x:G.number().optional(),y:G.number().optional(),width:G.number(),height:G.number()}).describe("css pixel bounding box").optional(),inputDescription:G.string().optional().describe("the description that generated this cache"),targetSource:G.nativeEnum(Fn).optional(),targetUpdateTime:G.string().optional()}).openapi({ref:"A11yTargetWithCache"});function Mi(n){return!!(n.name||n.role||n.content||n.serializedForm||n.serializedHtml||n.screenshotUrl)}var Zy=G.object({type:G.literal("description"),elementDescriptor:G.string(),a11yData:Un.optional().describe("DEPRECATED: new a11y cache is stored in DB and resolved into the 'cache' field")}).openapi({ref:"DescriptionTarget"}),Qy=G.object({x:G.number(),y:G.number()}),eS=G.object({type:G.literal("coordinates"),pixels:Qy}).openapi({ref:"CoordinatesTarget"});function mn(n){return n.type==="description"}function Bt(n){return n.type==="coordinates"}var We=G.discriminatedUnion("type",[Zy,eS]).openapi({ref:"ElementTarget"});function La(n){if(!n)return!1;switch(n.type){case"description":return!!n.elementDescriptor}return!0}function Ge(n){if(!n)return"";switch(n.type){case"description":return n.elementDescriptor;case"coordinates":return`x: ${n.pixels.x}, y: ${n.pixels.y}`}}var Te=(N=>(N.AI_EXTRACT="AI_EXTRACT",N.AI_ASSERTION="AI_ASSERTION",N.AI_WAIT="AI_WAIT",N.AUTH_LOAD="AUTH_LOAD",N.AUTH_SAVE="AUTH_SAVE",N.BLUR="BLUR",N.CAPTCHA="CAPTCHA",N.CLICK="CLICK",N.COOKIE="COOKIE",N.DIALOG="DIALOG",N.DRAG="DRAG",N.ELEMENT_CHECK="ELEMENT_CHECK",N.FILE_UPLOAD="FILE_UPLOAD",N.FOCUS="FOCUS",N.GO_BACK="GO_BACK",N.GO_FORWARD="GO_FORWARD",N.HOVER="HOVER",N.JAVASCRIPT="JAVASCRIPT",N.LOCAL_STORAGE="LOCAL_STORAGE",N.MOUSE_DRAG="MOUSE_DRAG",N.NAVIGATE="NAVIGATE",N.NEW_TAB="NEW_TAB",N.PAGE_CHECK="PAGE_CHECK",N.PRESS="PRESS",N.REFRESH="REFRESH",N.REQUEST="REQUEST",N.GRAPHQL_REQUEST="GRAPHQL_REQUEST",N.SCROLL_DOWN="SCROLL_DOWN",N.SCROLL_UP="SCROLL_UP",N.SCROLL_LEFT="SCROLL_LEFT",N.SCROLL_RIGHT="SCROLL_RIGHT",N.SELECT_OPTION="SELECT_OPTION",N.TAB="TAB",N.TYPE="TYPE",N.VISUAL_DIFF="VISUAL_DIFF",N.WAIT="WAIT",N.WAIT_FOR_URL="WAIT_FOR_URL",N.SUCCESS="SUCCESS",N))(Te||{});le(w);var q=w.object({thoughts:w.string().optional(),id:w.string().uuid().describe("unique identifier to this step, used for step cache")}),gt=w.object({useSelector:w.boolean().optional(),force:w.boolean().optional(),disableCache:w.boolean().optional().describe("disable element caching for this step"),iframeUrl:w.string().optional().describe("url or url regex for the iframe")}).openapi({ref:"CommonTargetingOptions"}),$t=w.object({target:Un}).optional().openapi({ref:"SingleTargetCache"}),_i=w.object({loadTimeout:w.number().int().max(60).optional().describe("Max seconds for the page to load")}),tS=q.merge(_i).merge(w.object({type:w.literal("NAVIGATE"),url:w.string()})).openapi({ref:"NavigateCommand"}),ki=gt.merge(w.object({cache:$t})),hr=q.merge(ki.merge(w.object({target:We.optional(),type:w.literal("SCROLL_UP"),deltaY:w.number().optional()}))).openapi({ref:"ScrollUpCommand"}),fr=q.merge(ki.merge(w.object({target:We.optional(),type:w.literal("SCROLL_DOWN"),deltaY:w.number().optional()}))).openapi({ref:"ScrollDownCommand"}),gr=q.merge(ki.merge(w.object({target:We.optional(),type:w.literal("SCROLL_LEFT"),deltaX:w.number().optional()}))).openapi({ref:"ScrollLeftCommand"}),yr=q.merge(ki.merge(w.object({target:We.optional(),type:w.literal("SCROLL_RIGHT"),deltaX:w.number().optional()}))).openapi({ref:"ScrollRightCommand"}),WI=w.discriminatedUnion("type",[hr,fr,gr,yr]).openapi({ref:"AllScrollCommands"}),nS=q.merge(w.object({type:w.literal("DIALOG"),action:w.union([w.literal("ACCEPT"),w.literal("DISMISS")])})).openapi({ref:"DialogCommand"}),rS=q.merge(w.object({type:w.literal("WAIT"),delay:w.number()})).openapi({ref:"WaitCommand"}),GI=w.discriminatedUnion("type",[w.object({type:w.literal("EXACT_MATCH"),url:w.string()}),w.object({type:w.literal("GLOB_MATCH"),glob:w.string()}),w.object({type:w.literal("REGEX_MATCH"),regex:w.string()})]),oS=w.object({caseInsensitive:w.boolean().optional().describe("Whether to ignore case when matching the URL"),negated:w.boolean().optional().describe("Wait for the URL to NOT match the provided matcher instead."),timeout:w.number().int().optional().describe("Max seconds to wait for the URL to match")}),iS=q.extend({type:w.literal("WAIT_FOR_URL"),url:w.string().describe("Deprecated: url or glob to wait for. New commands should use the discriminated matcher field.")}).merge(oS).openapi({ref:"WaitUrlCommand"}),sS=q.merge(_i).merge(w.object({type:w.literal("REFRESH")})).openapi({ref:"RefreshCommand"}),aS=q.merge(w.object({type:w.literal("GO_BACK")})).openapi({ref:"GoBackCommand"}),lS=q.merge(w.object({type:w.literal("GO_FORWARD")})).openapi({ref:"GoForwardCommand"}),cS=q.extend({type:w.literal("AUTH_SAVE")}).openapi({ref:"AuthSaveCommand"}),dS=q.extend({type:w.literal("AUTH_LOAD"),storageState:w.string().describe("JSON string auth state. Leave blank or set to the empty string to clear all existing authentication.")}).openapi({ref:"AuthLoadCommand"}),Ma=q.merge(gt).extend({type:w.literal("CAPTCHA")}).openapi({ref:"CaptchaCommand"}),uS=q.merge(Ei).extend({type:w.literal("JAVASCRIPT"),envKey:w.string().optional()}).openapi({ref:"JavaScriptCommand"}),fo=q.merge(gt).merge(w.object({type:w.literal("CLICK"),target:We,doubleClick:w.boolean().optional(),rightClick:w.boolean().optional(),waitForUrl:w.string().optional().describe("Deprecated: wait for the click to trigger a page load or new tab that matches the provided URL or URL glob (e.g. https://google.com/**/*)."),waitForDownload:w.boolean().optional().describe("Wait for the click to trigger a file download and for the file download to complete."),cache:$t})).openapi({ref:"ClickCommand"}),go=q.merge(gt).merge(w.object({type:w.literal("DRAG"),fromTarget:We,toTarget:We,hoverSeconds:w.number().optional().describe("Seconds to hover the object before dropping"),cache:w.object({fromTarget:Un.optional(),toTarget:Un.optional()}).optional()})).openapi({ref:"DragCommand"}),yo=q.merge(gt).merge(w.object({type:w.literal("MOUSE_DRAG"),target:We.optional(),deltaX:w.string().describe("pixels to move horizontally, can be template"),deltaY:w.string().describe("pixels to move vertically, can be template"),steps:w.number().optional(),cache:$t})).openapi({ref:"MouseDragCommand"}),So=q.merge(gt).merge(w.object({type:w.literal("HOVER"),target:We,cache:$t})).openapi({ref:"HoverCommand"}),wo=q.merge(gt).merge(w.object({type:w.literal("FOCUS"),target:We,cache:$t})).openapi({ref:"FocusCommand"}),bo=q.merge(gt).extend({type:w.literal("BLUR"),target:We.optional(),cache:$t}).openapi({ref:"BlurCommand"}),pS=w.object({type:w.literal("URL"),url:w.string()}).describe("Accessible link to the file, either public http or local file://").openapi({ref:"UrlSource"}),mS=q.extend({type:w.literal("FILE_UPLOAD"),fileSource:w.discriminatedUnion("type",[pS]),filename:w.string().optional()}).openapi({ref:"FileUploadCommand"}),hS=w.discriminatedUnion("type",[w.object({type:w.literal("VALUE"),value:w.string()}),w.object({type:w.literal("LABEL"),label:w.string()}),w.object({type:w.literal("INDEX"),index:w.number().int()})]),vo=q.merge(gt).extend({type:w.literal("SELECT_OPTION"),target:We,cache:$t,option:w.string().describe("option value, deprecated old field").optional(),choice:hS.optional().describe("new field for selecting options, optional for backcompat")}).openapi({ref:"SelectOptionCommand"}),_a=w.union([w.literal("MULTIMODAL"),w.literal("VISION_ONLY")]),ka=q.merge(w.object({type:w.literal("AI_ASSERTION"),assertion:w.string(),disableCache:w.boolean().optional(),iframeUrl:w.string().optional(),contextChoice:_a.optional(),timeout:w.number().int().optional().describe("Max seconds to wait for assertion to be true")})).openapi({ref:"AIAssertionCommand"}),fS=ka.extend({type:w.literal("AI_WAIT")}).openapi({ref:"AIWaitCommand"}),zn=5,Da=600,To=q.merge(gt).extend({type:w.literal("ELEMENT_CHECK"),target:We,assertion:bd,cache:$t,timeout:w.number().int().min(0).max(Da).optional().describe("max seconds to wait for the assertion to be true")}).openapi({ref:"ElementAssertionCommand"}),gS=q.extend({type:w.literal("PAGE_CHECK"),assertion:vd,iframeUrl:w.string().optional().describe("url or url regex for the iframe"),timeout:w.number().int().min(0).max(Da).optional().describe("max seconds to wait for the assertion to be true")}).openapi({ref:"PageAssertionCommand"}),yS=q.merge(w.object({type:w.literal("AI_EXTRACT"),goal:w.string(),schema:w.string().optional(),envKey:w.string().optional(),disableCache:w.boolean().optional(),iframeUrl:w.string().optional()})).openapi({ref:"AIExtractCommand"}),SS=w.object({clearContent:w.boolean().optional(),pressKeysSequentially:w.boolean().optional().describe("Deprecated: this is now the default. Please set delay to zero if you wish to achieve instant typing behavior."),delay:w.number().min(0).max(1e3).optional().describe("Delay between each press in milliseconds."),force:w.boolean().optional(),pressEnter:w.boolean().optional()}),xo=q.merge(gt).merge(SS).extend({type:w.literal("TYPE"),target:We.optional(),value:w.string(),cache:$t}).openapi({ref:"TypeCommand"}),wS=q.merge(w.object({type:w.literal("PRESS"),value:w.string()})).openapi({ref:"PressCommand"}),bS=w.object({type:w.literal("SUBSTRING"),substring:w.string()}),vS=w.object({type:w.literal("REGEX"),pattern:w.string()}),TS=w.object({type:w.literal("INDEX"),index:w.number()}),xS=w.discriminatedUnion("type",[bS,vS,TS]),ES=q.merge(_i).merge(w.object({type:w.literal("TAB"),url:w.string().optional().describe("deprecated field - new instances should use the discriminated union"),action:xS.optional()})).openapi({ref:"TabCommand"}),CS=q.merge(_i).merge(w.object({type:w.literal("NEW_TAB"),url:w.string()})).openapi({ref:"NewTabCommand"}),AS=q.merge(w.object({type:w.literal("COOKIE"),value:w.string()})).openapi({ref:"CookieCommand"}),RS=q.merge(w.object({type:w.literal("LOCAL_STORAGE"),key:w.string(),value:w.string()})).openapi({ref:"LocalStorageCommand"}),IS=q.extend({type:w.literal("REQUEST")}).merge(xi).openapi({ref:"RequestCommand"}),PS=q.extend({type:w.literal("GRAPHQL_REQUEST")}).merge(ud).openapi({ref:"GraphQLRequestCommand"}),OS=q.merge(w.object({type:w.literal("SUCCESS"),condition:ka.optional()})).openapi({ref:"SuccessCommand"}),LS=q.merge(w.object({type:w.literal("FAILURE")})).openapi({ref:"FailureCommand"}),NS=w.object({data:w.string().describe("location at which to find a jpg"),width:w.number(),height:w.number()}),Eo=q.merge(gt).merge(w.object({type:w.literal("VISUAL_DIFF"),threshold:w.number().optional().describe("default 0.1"),target:We.optional(),screenshot:NS.optional(),cache:$t})).openapi({ref:"VisualDiffCommand"}),Di=w.discriminatedUnion("type",[fo,xo,wS,vo,tS,fr,hr,ka,So,rS,OS]),MS=w.discriminatedUnion("type",[fS,yS,dS,cS,Ma,AS,nS,go,To,mS,aS,lS,uS,RS,yo,CS,gS,sS,IS,PS,gr,yr,ES,Eo,wo,bo,iS]),Fi=w.discriminatedUnion("type",[...Di.options,...MS.options]).openapi({ref:"Command"}),xd=w.discriminatedUnion("type",[...Di.options,LS]);function hn(n){let e;switch(n){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:fe(),type:n};break;case"AUTH_LOAD":{e={id:fe(),type:n,storageState:""};break}case"AI_EXTRACT":e={id:fe(),type:n,goal:""};break;case"DIALOG":e={id:fe(),type:n,action:"DISMISS"};break;case"DRAG":e={id:fe(),type:n,fromTarget:{type:"description",elementDescriptor:""},toTarget:{type:"description",elementDescriptor:""}};break;case"MOUSE_DRAG":e={id:fe(),type:n,deltaX:"0",deltaY:"0",steps:1};break;case"WAIT_FOR_URL":e={id:fe(),type:n,url:""};break;case"WAIT":e={id:fe(),type:n,delay:1};break;case"BLUR":e={id:fe(),type:n};break;case"HOVER":case"FOCUS":case"CLICK":e={id:fe(),type:n,target:{type:"description",elementDescriptor:""}};break;case"COOKIE":case"PRESS":case"TYPE":e={id:fe(),type:n,value:"",clearContent:!0};break;case"SELECT_OPTION":e={id:fe(),type:n,target:{type:"description",elementDescriptor:""},choice:{type:"VALUE",value:""}};break;case"NAVIGATE":case"NEW_TAB":case"TAB":e={id:fe(),type:n,url:""};break;case"REQUEST":e={id:fe(),type:n,url:"",method:"GET"};break;case"GRAPHQL_REQUEST":e={id:fe(),type:n,url:"",query:""};break;case"LOCAL_STORAGE":e={id:fe(),type:n,key:"",value:""};break;case"JAVASCRIPT":e={id:fe(),type:n,code:""};break;case"AI_WAIT":case"AI_ASSERTION":e={id:fe(),type:n,assertion:""};break;case"FILE_UPLOAD":{e={id:fe(),type:n,fileSource:{type:"URL",url:""}};break}case"ELEMENT_CHECK":{e={id:fe(),type:n,target:{type:"description",elementDescriptor:""},assertion:{type:"ELEMENT_EXISTENCE",condition:"EXISTS"}};break}case"PAGE_CHECK":{e={id:fe(),type:n,assertion:{type:"CONTENT",value:""}};break}default:return(r=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(n)}return e}import{z as Sr}from"zod";var tt=Sr.object({index:Sr.number().optional().describe("global index within a test (in-order traversal)"),id:Sr.string(),skipped:Sr.boolean().optional(),envKey:Sr.string().optional().describe("key in the environment to save the result of this step to"),aiSuggested:Sr.boolean().optional()});le(Fa);var yt=tt.extend({type:Fa.literal("PRESET_ACTION"),command:Fi,skipped:Fa.boolean().optional()}).openapi({ref:"PresetAction"});le(Ua);var wr=tt.extend({type:Ua.literal("AI_ACTION"),text:Ua.string(),steps:yt.array().optional()}).openapi({ref:"AIAction"});import{z as de}from"zod";var _S=de.object({cacheKey:de.string(),cacheExpiryMs:de.number()}),za=tt.extend({id:de.string().uuid().describe("ID of the module step itself. Used to 'namespace' step cache entries."),inputs:de.record(de.string()).optional(),cacheConfig:_S.optional()}),br=za.extend({type:de.literal("MODULE"),moduleId:de.string().uuid()}),kS=de.union([br.pick({type:!0,moduleId:!0}),de.record(de.unknown())]),St=de.object({moduleId:de.string().uuid(),name:de.string(),description:de.string().nullish(),enabled:de.boolean().nullish(),parameters:de.string().array().nullish(),defaultParameters:de.record(de.string(),de.string()).nullish(),defaultCacheKey:de.string().nullish(),defaultCacheTtl:de.number().nullish(),defaultCacheAllInvocations:de.boolean().nullish(),autoAuth:de.boolean().nullish()});import{z as Fe}from"zod";import{z as Ba}from"zod";le(Ba);var Co=tt.extend({type:Ba.literal("AI_ACTION_DYNAMIC"),text:Ba.string()}).openapi({ref:"AIActionDynamic"});import{z as Ed}from"zod";var Ao=tt.extend({type:Ed.literal("CONDITIONAL"),skipped:Ed.boolean().optional()});import{z as wt}from"zod";var DS=wt.object({type:wt.literal("attr"),name:wt.string(),value:wt.string()}),FS=wt.object({type:wt.literal("css"),selector:wt.string()}),US=wt.object({type:wt.literal("url"),url:wt.string()}),zS=wt.union([DS,US,FS]),Ro=tt.extend({type:wt.literal("IFRAME"),identifier:zS});import{z as bt}from"zod";var $a=(r=>(r.ALWAYS="ALWAYS",r.ON_FAILURE="ON_FAILURE",r.ON_ACTION_FAILURE="ON_ACTION_FAILURE",r))($a||{});var BS=bt.discriminatedUnion("type",[bt.object({type:bt.literal("NAVIGATE_URL"),url:bt.string().url()}),bt.object({type:bt.literal("GO_TO_SECTION_START")})]),$S=bt.object({trigger:bt.nativeEnum($a).optional(),attempts:bt.number().int().optional(),restartBehavior:BS}),Io=tt.extend({type:bt.literal("SECTION"),description:bt.string().describe("user provided goal of what the section should accomplish"),plan:bt.string().array().optional(),autohealingConfig:$S.optional()});var Cd=St.merge(za).extend({type:Fe.literal("RESOLVED_MODULE"),steps:Fe.lazy(()=>xe.array())}),ja=St.extend({steps:Fe.lazy(()=>xe.array())}),jS=Ro.extend({steps:Fe.lazy(()=>vt.array())}),HS=Ro.extend({steps:Fe.lazy(()=>xe.array())}),WS=Io.extend({steps:Fe.lazy(()=>vt.array())}),GS=Io.extend({steps:Fe.lazy(()=>xe.array())}),VS=Ao.extend({blocks:Fe.object({assertion:Fe.lazy(()=>yt),steps:Fe.lazy(()=>vt.array())}).array(),elseSteps:Fe.lazy(()=>vt.array().optional())}),qS=Ao.extend({blocks:Fe.object({assertion:Fe.lazy(()=>yt),steps:Fe.lazy(()=>xe.array())}).array(),elseSteps:Fe.lazy(()=>xe.array().optional())}),vt=Fe.discriminatedUnion("type",[yt,wr,Co,br,VS,jS,WS]),xe=Fe.discriminatedUnion("type",[yt,wr,Co,Cd,qS,HS,GS]);var Tt="1.0.18";import{z as $n}from"zod";import{z as KS}from"zod";var tO=KS.discriminatedUnion("type",[bo,Ma,fo,go,wo,So,yo,hr,fr,gr,yr,vo,xo,Eo,To]);function Ad(n){return["AI_ASSERTION","ELEMENT_CHECK","PAGE_CHECK"].includes(n)}import{z as YS}from"zod";var nt={type:!0,cache:!0},Bn=YS.discriminatedUnion("type",[bo.pick(nt),fo.pick(nt),go.pick(nt),To.pick(nt),wo.pick(nt),So.pick(nt),yo.pick(nt),hr.pick(nt),fr.pick(nt),gr.pick(nt),yr.pick(nt),vo.pick(nt),xo.pick(nt),Eo.pick(nt)]),Ha=Object.values(Te).filter(n=>Bn.options.some(e=>e.shape.type.safeParse(n).success));Fi.options.forEach(n=>{if("target"in n.shape&&!Ha.includes(n.shape.type.value))throw new Error(`Command ${n.shape.type.value} has a target but no cache`)});var Wa=$n.object({key:$n.string(),testId:$n.string().optional(),moduleId:$n.string().optional(),organizationId:$n.string(),value:Bn}),Rd=$n.record($n.string(),Wa);import{cloneDeep as Lo}from"lodash-es";var JS=n=>{let e=Id(n,0);if(e===void 0||!ZS(n[e]))return;let t=Id(n,e+1);if(t!==void 0)return QS(n,e,t)},Pd=JS,Id=(n,e)=>{for(let t=e;t<n.length;t+=1){let r=n[t];if(!XS(r))return t}},XS=n=>n===" "||n===" "||n===`
5
5
  `||n==="\r",ZS=n=>n==="{"||n==="[",QS=(n,e,t)=>{let r;for(let o=t-1;o>e;o-=1){let i=n[o];if(i==="\r")return;if(i===`
6
6
  `)return ew(r);if(r===void 0)r=i;else if(r[0]===i)r+=i;else return}},ew=n=>n===void 0?0:n[0]===" "?n.length:n;var Od=(n,e)=>{let t=Ga(n,"toPrecision",e,e);return t===void 0?Ga(n,"toExponential",e,e):t},Ga=(n,e,t,r)=>{let i=n[e](r).replace(tw,"$1").replace(nw,"$1");return i.length<=t?i:r===1?void 0:Ga(n,e,t,r-1)},tw=/(e)\+/iu,nw=/\.?0*($|e)/iu;var Nd=(n,e)=>{if(typeof n!="string")throw new TypeError(`Input must be a JSON string: ${n}`);rw(e)},rw=n=>{if(ow(n),n<0)throw new TypeError(`"maxSize" argument must be positive: ${n}`);if(n<Ld)throw new TypeError(`"maxSize" argument must be at least ${Ld}: ${n}`)},ow=n=>{if(n===void 0)throw new TypeError('"maxSize" argument must be defined');if(!Number.isInteger(n))throw new TypeError(`"maxSize" argument must be an integer: ${n}`)},Ld=7;var Ui=(n,e,t)=>{let r=_d(e,t);return Md(n,e,r)},Md=(n,e,t)=>{if(t>=e)return t;let r=n[t];return r>=mw&&r<=hw?Md(n,e,t+1):t},zi=(n,e,t)=>{if(t===void 0)return t;let r=_d(e,t);return iw(n,r)},iw=(n,e)=>sw(n,e)?e-3:aw(n,e)?e-2:lw(n,e)?e-1:e,sw=(n,e)=>e>=3&&n[e-3]>=cw&&n[e-3]<=dw,aw=(n,e)=>e>=2&&n[e-2]>=uw,lw=(n,e)=>e>=1&&n[e-1]>=pw,_d=(n,e)=>e<0||Object.is(e,-0)?Math.max(n+e,0):e,cw=240,dw=244,uw=224,pw=194,mw=128,hw=191;var kd=(n,e,t)=>{let r=globalThis.Buffer.from(n),o=Ui(r,r.length,e),i=zi(r,r.length,t);return o===0&&i>=r.length?r.toString():r.toString("utf8",o,i)};var Dd=/[\uD800-\uDFFF]/gu,Fd="\uFFFD";var Bi=n=>fw(n)?n.replace(Dd,Fd):n,fw=n=>{for(let e=0;e<n.length;e+=1){let t=n.codePointAt(e);if(t>=55296&&t<=57343)return!0}return!1};var Ka=({input:n,targetByteCount:e,firstStartSurrogate:t,lastStartSurrogate:r,firstEndSurrogate:o,lastEndSurrogate:i,increment:s,canBacktrack:a,shift:l,charIndexInit:c})=>{let u=c,d=u,m=0;for(;m<e;u+=s){d=u;let f=n.charCodeAt(u);if(Number.isNaN(f))break;if(f<=127){m+=1;continue}if(f<=2047){m+=2;continue}if(m+=3,f<t||f>r)continue;let h=n.charCodeAt(u+s);Number.isNaN(h)||h<o||h>i||(m+=1,u+=s)}return(a&&m>e?d:u)+l};var Ya=(n,e,t)=>e<0||Object.is(e,-0)?vw(n,e,t):bw(n,e,t),bw=(n,e,t)=>Ka({input:n,targetByteCount:e,firstStartSurrogate:55296,lastStartSurrogate:56319,firstEndSurrogate:56320,lastEndSurrogate:57343,increment:1,canBacktrack:t,shift:0,charIndexInit:0}),vw=(n,e,t)=>Ka({input:n,targetByteCount:-e,firstStartSurrogate:56320,lastStartSurrogate:57343,firstEndSurrogate:55296,lastEndSurrogate:56319,increment:-1,canBacktrack:!t,shift:1,charIndexInit:n.length-1});var $i=(n,e,t)=>{let r=Ya(n,e,!1),o=Tw(n,t),i=r===0&&o===void 0?n:n.slice(r,o);return Bi(i)},Tw=(n,e)=>{if(e===void 0)return e;let t=Ya(n,e,!0);return t===n.length?void 0:t};var zd=(n,e,t)=>{let{textEncoder:r,textDecoder:o}=xw(),i=Ew(n),{written:s}=r.encodeInto(n,i),a=Ui(i,s,e),l=zi(i,s,t),c=l===void 0?s:Math.min(l,s),u=i.subarray(a,c);return o.decode(u)},xw=()=>(Ja===void 0&&(Ja=new globalThis.TextEncoder,Ud=new globalThis.TextDecoder("utf8",{fatal:!1})),{textEncoder:Ja,textDecoder:Ud}),Ja,Ud,Ew=n=>{let e=n.length*3;return e>Cw?new Uint8Array(e):((ji===void 0||ji.length<e)&&(ji=new Uint8Array(e)),ji)},Cw=1e5,ji;var Bd=(n,e)=>{if(e===void 0)return e;let t=Xa(n,e);return t>=n.length*$d?void 0:t},Xa=(n,e)=>e<=n.length*-$d?0:e,$d=4;var jd=(n,e,t)=>{if(typeof n!="string")throw new TypeError(`First argument must be a string: ${n}`);Aw(e),Rw(t)},Aw=n=>{if(n===void 0)throw new TypeError("Second argument is required.");Hd("Second",n)},Rw=n=>{n!==void 0&&Hd("Third",n)},Hd=(n,e)=>{if(!Number.isInteger(e))throw new TypeError(`${n} argument must be an integer: ${e}`)};var Wd=n=>{let e=!0,t=0;for(let r=0;r<Za;r+=1){let o=Iw(n,r);o<=127||(e&&(e=!1),o>2047&&(t+=1))}return{asciiOnly:e,longCharsPercentage:t/Za}},Iw=(n,e)=>{let t=Za-1,r=1-(t-e)/t,o=Math.round(r*(n.length-1));return n.charCodeAt(o)},Za=50;var Pw=(n,e,t)=>{if(jd(n,e,t),n==="")return n;let r=Xa(n,e),o=Bd(n,t);return o===void 0&&Object.is(r,0)?Bi(n):Ow(n,r,o)},Gd=Pw,Ow=(n,e,t)=>{if(n.length<=Lw)return $i(n,e,t);let{asciiOnly:r,longCharsPercentage:o}=Wd(n);return r?Mw(n,e,t):o>=Nw?$i(n,e,t):Vd(n,e,t)},Lw=200,Nw=.4,Mw=(n,e,t)=>"Buffer"in globalThis&&"from"in globalThis.Buffer?kd(n,e,t):Vd(n,e,t),Vd=(n,e,t)=>"TextEncoder"in globalThis?zd(n,e,t):$i(n,e,t);var Kd=(n,e)=>{let t=JSON.stringify(n),r=Dw(t),o=Gd(r,0,e-qd.length-Po.length*2),s=`${_w(o)}${qd}`;return Fw(s)},_w=n=>n.replace(kw,""),kw=/(\\|\\u[0-9a-fA-F]{0,3})$/u,Dw=n=>n.slice(Po.length,-Po.length),Fw=n=>`${Po}${n}${Po}`,Po='"',qd="...";var Yd=n=>globalThis.Buffer.byteLength(n);var Qa=n=>{let e=n.length,t=e;for(let r=0;r<e;r+=1){let o=n.charCodeAt(r);if(o<=Uw)continue;if(o<=zw){t+=1;continue}if(t+=2,o<Bw||o>$w)continue;let i=n.charCodeAt(r+1);i<jw||i>Hw||(r+=1)}return t},Uw=127,zw=2047,Bw=55296,$w=56319,jw=56320,Hw=57343;var Jd=()=>Ww.bind(void 0,new TextEncoder),Ww=(n,e)=>{let t=Gw(e);return n.encodeInto(e,t).written},Gw=n=>{let e=n.length*3;return e>Vw?new Uint8Array(e):((Hi===void 0||Hi.length<e)&&(Hi=new Uint8Array(e)),Hi)},Vw=1e5,Hi;var Kw=()=>"Buffer"in globalThis&&"byteLength"in globalThis.Buffer?Yd:"TextEncoder"in globalThis?Yw.bind(void 0,Jd()):Qa,Yw=(n,e)=>e.length<100?Qa(e):n(e),Xd=Kw();var Zd=n=>{if(n===null)return Jw;if(n===!0)return Xw;if(n===!1)return Zw;let e=typeof n;return e==="object"?Qw:e==="number"?JSON.stringify(n).length:el(n)},Jw=4,Xw=4,Zw=5,Qw=2,el=n=>Xd(JSON.stringify(n));var Wi=({size:n,increment:e,maxSize:t,truncatedProps:r,path:o,value:i})=>{let s=n+e,a=s>t;return a?{size:n,stop:a,truncatedProps:[...r,{path:o,value:i}]}:{size:s,stop:a,truncatedProps:r}},eu=n=>Zd(n),tu=(n,e,t)=>{let r=ru({empty:n,indent:e,depth:t,keySpaceSize:0}),o=ou(n);return r+o},nu=({key:n,empty:e,indent:t,depth:r})=>{let o=ru({empty:e,indent:t,depth:r,keySpaceSize:1}),i=el(n),s=ou(e);return o+i+eb+s},eb=1,ru=({empty:n,indent:e,depth:t,keySpaceSize:r})=>{if(e===void 0)return 0;let o=Qd+e*(t+1),i=n?Qd+e*t:0;return r+o+i},Qd=1,ou=n=>n?0:tb,tb=1;var Gi=({parent:n,truncatedProps:e,path:t,increment:r,maxSize:o,key:i,empty:s,size:a,truncateValue:l,indent:c,depth:u})=>{let d=n[i],m=[...t,i],{size:p,stop:f,truncatedProps:h}=Wi({size:a,increment:r,maxSize:o,truncatedProps:e,path:m,value:d});return f?{empty:s,size:p,truncatedProps:h}:nb({value:d,truncatedProps:e,path:m,maxSize:o,empty:s,size:a,newSize:p,truncateValue:l,indent:c,depth:u})},nb=({value:n,truncatedProps:e,path:t,maxSize:r,empty:o,size:i,newSize:s,truncateValue:a,indent:l,depth:c})=>{let{value:u,size:d,truncatedProps:m}=a({value:n,truncatedProps:e,path:t,size:s,maxSize:r,indent:l,depth:c+1});return u===void 0?{empty:o,size:i,truncatedProps:m}:{empty:!1,size:d,value:u,truncatedProps:m}};var iu=({array:n,truncatedProps:e,path:t,size:r,maxSize:o,truncateValue:i,indent:s,depth:a})=>{let l=[],c={empty:!0,size:r,truncatedProps:e};for(let u=0;u<n.length;u+=1){let d=tu(c.empty,s,a);c=Gi({parent:n,truncatedProps:c.truncatedProps,path:t,increment:d,maxSize:o,key:u,empty:c.empty,size:c.size,truncateValue:i,indent:s,depth:a}),c.value!==void 0&&l.push(c.value)}return{value:l,size:c.size,truncatedProps:c.truncatedProps}};var su=({object:n,truncatedProps:e,path:t,size:r,maxSize:o,truncateValue:i,indent:s,depth:a})=>{let l={},c={empty:!0,size:r,truncatedProps:e};for(let u in n){let d=nu({key:u,empty:c.empty,indent:s,depth:a});c=Gi({parent:n,truncatedProps:c.truncatedProps,path:t,increment:d,maxSize:o,key:u,empty:c.empty,size:c.size,truncateValue:i,indent:s,depth:a}),c.value!==void 0&&(l[u]=c.value)}return{value:l,size:c.size,truncatedProps:c.truncatedProps}};var Vi=({value:n,truncatedProps:e,path:t,size:r,maxSize:o,indent:i,depth:s})=>{let a=eu(n),{size:l,stop:c,truncatedProps:u}=Wi({size:r,increment:a,maxSize:o,truncatedProps:e,path:t,value:n});return c?{value:void 0,size:l,truncatedProps:u}:rb({value:n,truncatedProps:u,path:t,size:l,maxSize:o,indent:i,depth:s})},rb=({value:n,truncatedProps:e,path:t,size:r,maxSize:o,indent:i,depth:s})=>typeof n!="object"||n===null?{value:n,size:r,truncatedProps:e}:Array.isArray(n)?iu({array:n,truncatedProps:e,path:t,size:r,maxSize:o,truncateValue:Vi,indent:i,depth:s}):su({object:n,truncatedProps:e,path:t,size:r,maxSize:o,truncateValue:Vi,indent:i,depth:s});var ob=(n,e)=>{Nd(n,e);let t=ib(n),r=sb(n),{value:o,truncatedProps:i}=Vi({value:r,truncatedProps:[],path:[],size:0,maxSize:e,indent:t,depth:0});return{jsonString:ab({newValue:o,value:r,maxSize:e,indent:t}),truncatedProps:i}},Oo=ob,ib=n=>{let e=Pd(n);return typeof e=="string"?e.length:e},sb=n=>{try{return JSON.parse(n)}catch(e){throw new TypeError(`Invalid JSON string: "${n}"
7
7
  ${e.message}`)}},ab=({newValue:n,value:e,maxSize:t,indent:r})=>n!==void 0?JSON.stringify(n,void 0,r):typeof e=="number"?Od(e,t):Kd(e,t);import*as jn from"zod";le(jn);var No=jn.object({env:jn.record(jn.unknown())}).openapi({ref:"TestContextSnapshot"}),lb="\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022",cb=[pe,dr],au=[Ii,pe,dr],xt=class n{env={};varsFromMomenticEnvironment={};constructor(e){this.reset(e)}static dummyContext(e=void 0,t={}){return new n({baseUrl:"about:blank",currentUrl:"about:blank",envName:e,variablesFromEnvironment:t})}static fromSnapshot({snapshot:e,environmentVariables:t}){let r=e.env[pe]??"about:blank",o=e.env[Ii]??"about:blank",i=e.env[dr],s={};for(let[l,c]of Object.entries(e.env))au.includes(l)||(t??{})[l]===void 0&&(s[l]=c);return new n({baseUrl:r,currentUrl:o,dynamicVariables:s,envName:i,variablesFromEnvironment:t??{}})}setEnvVariables(e){let t=Lo(e);this.env=Object.assign(this.env,t)}setInputs(e){e&&this.setEnvVariables(e)}setMomenticSystemVariable(e,t){this.varsFromMomenticEnvironment[e]=t}getVariable(e){return this.env[e]}setVariable(e,t){cb.includes(e)||(this.env[e]=t)}getEnvName(){return this.env[dr]}toObjectCopy(){let e={env:Object.assign({},this.env,this.varsFromMomenticEnvironment)};return Lo(e)}toEditorDisplayCopy(){return this.toObjectCopy()}toRedactedDisplayCopy(){let e=this.toObjectCopy();e.env=Object.fromEntries(Object.entries(e.env).map(([r,o])=>au.includes(r)||this.varsFromMomenticEnvironment[r]===void 0?[r,o]:[r,lb]));for(let[r,o]of Object.entries(e.env)){if(!o){e.env[r]=o;continue}let{jsonString:i}=Oo(JSON.stringify(o),1e3);try{e.env[r]=JSON.parse(i)}catch{e.env[r]=void 0}}let{jsonString:t}=Oo(JSON.stringify(e.env),5e3);try{e.env=JSON.parse(t)}catch{e.env={}}return e}setCurrentUrl(e){this.env[Ii]=e}reset(e){this.env={},this.varsFromMomenticEnvironment={},this.setEnvVariables(e.dynamicVariables??{}),this.setCurrentUrl(e.currentUrl),this.varsFromMomenticEnvironment=Lo(e.variablesFromEnvironment),this.setMomenticSystemVariable(pe,e.baseUrl),e.envName&&this.setMomenticSystemVariable(dr,e.envName)}getDynamicVariablesCopy(){return Lo(this.env)}getVariablesFromEnvironmentCopy(){return Lo(this.varsFromMomenticEnvironment)}};import{z as Hn}from"zod";le(Hn);var ie=(c=>(c.AI_PROVIDER="AIProviderError",c.USER_INFRA="UserInfrastructureError",c.ACTION_FAILURE="ActionFailureError",c.ASSERTION_FAILURE="AssertionFailureError",c.CONFIG_ERROR="UserConfigurationError",c.WEB_AGENT_PLATFORM="InternalWebAgentError",c.UNKNOWN_PLATFORM="InternalPlatformError",c.JOB_TIMEOUT="JobTimeoutError",c.UNKNOWN="UnknownError",c))(ie||{});var lu=["JobTimeoutError","UserConfigurationError","UserInfrastructureError"],cu={ActionFailureError:"Action failure",AssertionFailureError:"Assertion failure",UserInfrastructureError:"Infrastructure failure",UserConfigurationError:"Configuration error",AIProviderError:"AI provider error",InternalWebAgentError:"Momentic AI agent error",JobTimeoutError:"Job timeout",InternalPlatformError:"Unknown Momentic platform error",UnknownError:"Unknown error"},du={ActionFailureError:"A browser action such as a click or type failed to execute because of the underlying page state is incorrect, suggesting a bug in the application itself.",AssertionFailureError:"An AI assertion or check failed for a legitimate reason, such as a missing element, a change in the page structure, or an unexpected state (e.g. loading state).",AIProviderError:"The AI provider failed to return a response or returned a malformed response.",UserInfrastructureError:"The user's web application exhibited an infrastructure failure, such as a page load timeout, a 5XX status code, maintenance page, or session crash.",UserConfigurationError:"The error message suggests a user-caused misconfiguration in the test, such as an undefined variable, a missing base URL, an empty test/module input parameter, or an invalid step option",JobTimeoutError:"The test took too long to complete, suggesting a problem with the test itself.",InternalWebAgentError:"The AI testing framework failed to find the correct element or evaluate the assertion correctly, even though the test steps and application state look valid. In other words, the AI agent failed to understand the page.",UnknownError:"An unknown error occurred. Please refer to the failure details in the run for more information or reach out to Momentic Support for assistance.",InternalPlatformError:"An unknown error occurred with the Momentic platform. Please reach out to Momentic Support for assistance."},tl=Hn.object({reason:Hn.nativeEnum(ie),summary:Hn.string()}).openapi({ref:"TestResultClassification"}),qi=Hn.object({errorMessage:Hn.string(),errorStack:Hn.string().optional(),classification:tl.optional()}).openapi({ref:"TestFailureDetails"});le($);var Ue=(i=>(i.SUCCESS="SUCCESS",i.FAILED="FAILED",i.RUNNING="RUNNING",i.IDLE="IDLE",i.CANCELLED="CANCELLED",i))(Ue||{}),Ki=(r=>(r.SUCCESS="SUCCESS",r.FAILED="FAILED",r.CANCELLED="CANCELLED",r))(Ki||{}),nl=$.object({beforeUrl:$.string().optional(),afterUrl:$.string().optional(),message:$.string().optional(),beforeScreenshot:$.string().optional(),afterScreenshot:$.string().optional(),beforeSnapshot:$.string().optional(),afterSnapshot:$.string().optional(),startedAt:$.coerce.date(),finishedAt:$.coerce.date()}),db=nl.extend({viewport:$.object({height:$.number(),width:$.number()}),status:$.nativeEnum(Ki),message:$.string().optional(),elementInteracted:$.string().optional()}),fn=nl.extend({status:$.nativeEnum(Ue),message:$.string().optional(),data:$.unknown().optional(),beforeTestContext:No.optional(),afterTestContext:No.optional(),failureReason:$.nativeEnum(ie).optional(),details:$.unknown().describe("Parse using StepExecutionLogSchema.array() to get type safety. We don't explicitly type it because it's non-critical information.")}).openapi({ref:"StepResultMetadata"}),Yi=fn.merge(yt).extend({results:db.array()}),ub=fn.merge(wr).extend({results:$.lazy(()=>Yi.array())}),pb=fn.merge(Co).extend({results:$.lazy(()=>Yi.array())}),mb=fn.merge(br).extend({moduleName:$.string().optional(),results:$.lazy(()=>jt.array())}),hb=fn.merge(Ao).extend({assertion:Yi.optional(),results:$.lazy(()=>jt.array()).describe("results for the block actually executed")}),fb=fn.merge(Ro).extend({results:$.lazy(()=>jt.array())}),gb=fn.merge(Io).extend({results:$.lazy(()=>jt.array()),healingAttempts:$.lazy(()=>jt.array().array()).optional()}),jt=$.discriminatedUnion("type",[ub,pb,Yi,mb,hb,fb,gb]),gn=fn.pick({startedAt:!0,finishedAt:!0,status:!0,message:!0,data:!0}),uu=nl.extend({index:$.number().optional(),description:$.string(),pageState:$.string().optional()});le(V);var Wn={WEBHOOK:"WEBHOOK",CRON:"CRON",MANUAL:"MANUAL",CLI:"CLI"},Ee=(a=>(a.PENDING="PENDING",a.RUNNING="RUNNING",a.PASSED="PASSED",a.FAILED="FAILED",a.CANCELLED="CANCELLED",a.RETRYING="RETRYING",a.WAITING_FOR_USER="WAITING_FOR_USER",a))(Ee||{});var ze=V.string().pipe(V.coerce.date()).or(V.date()),Mo=V.object({id:V.string(),runKey:V.string(),organizationId:V.string(),createdAt:ze,createdBy:V.string(),flake:V.boolean().nullish(),scheduledAt:ze.or(V.null()),startedAt:ze.or(V.null()),updatedAt:ze.nullish(),finishedAt:ze.or(V.null()),resolvedBaseUrl:V.string().nullish(),status:V.nativeEnum(Ee),trigger:V.nativeEnum(Wn),attempts:V.number(),runAttempts:V.array(V.object({id:V.string(),status:V.nativeEnum(Ee),startedAt:ze.or(V.null()),finishedAt:ze.or(V.null())})).optional(),videos:V.array(V.string()).optional(),failureReason:V.nativeEnum(ie).nullish(),failureDetails:qi.nullish(),testId:V.string().nullish(),testName:V.string().nullish(),test:V.object({name:V.string(),id:V.string()}).nullish().default(null),suiteId:V.string().nullish()}).openapi({ref:"RunMetadata"}),yb={id:!0,status:!0,testName:!0,testId:!0,test:{select:{name:!0,id:!0}},failureReason:!0,failureDetails:!0},pu=Mo.pick({...yb,test:!0}),fN=Mo.omit({failureReason:!0,failureDetails:!0}),rl=Mo.extend({results:jt.array(),resolvedInputs:V.record(V.string(),V.string()).nullish(),test:V.object({name:V.string(),id:V.string(),baseUrl:V.string().nullish(),advanced:ur.nullish()}).nullish()}),mu=n=>n.includes("PASSED")&&n.includes("FAILED");var Sb=_o.object({id:_o.string().uuid(),startedAt:ze.or(_o.null()),finishedAt:ze.or(_o.null()),status:_o.nativeEnum(Ee)}),wN=Sb.array();var Ji=(t=>(t.JUNIT="junit",t.ALLURE="allure",t))(Ji||{});import{z as Oe}from"zod";import*as ee from"zod";var AN=ee.object({thoughts:ee.string().optional().describe("only provided if a description was provided"),target:Un.optional().describe("only provided if a description was provided"),pageState:ee.string().optional().describe("serialized a11y tree, only provided if a description was provided"),options:ee.object({label:ee.string(),value:ee.string()}).array().optional().describe("list of options, provided for <select> elements only"),screenshot:ee.object({data:ee.string(),height:ee.number().int(),width:ee.number().int()}).optional().describe("only provided if returnScreenshot is true")}),hu="<select> element",fu="text input or contenteditable element",wb="text input element",ol=[hu,fu,wb];function gu(n,e){if(n===e)return!0;for(let t of ol){if(!n.startsWith(t))continue;let r=n.slice(t.length+2);if(ol.some(o=>e.startsWith(o)&&e.slice(o.length+2)===r)||r===e)return!0}return!!ol.some(t=>e.startsWith(t)&&e.slice(t.length+2)===n)}function Xi(n,e){if(!e||"useSelector"in n&&n.useSelector)return e;switch(n.type){case"SELECT_OPTION":return`${hu}: ${e}`;case"TYPE":return`${fu}: ${e}`;default:return e}return e}var ko=ee.object({matched:ee.boolean(),reason:ee.string().optional().describe("Human understandable description"),logs:ee.string().array().optional().describe("Logs for debugging")}),bb=ko.extend({type:ee.literal("A11Y_ID")}),vb=ko.extend({type:ee.literal("USER_SELECTOR")}),Tb=ko.extend({type:ee.literal("CSS_SELECTOR"),selectors:ee.string().array()}),xb=ko.extend({type:ee.literal("HTML_DISTANCE"),distance:ee.number().optional(),closestElement:ee.string().optional(),savedElement:ee.string().optional()}),Eb=ko.extend({type:ee.literal("TEMPLATE_MATCHING"),elementImageUrl:ee.string().url()}),yu=ee.discriminatedUnion("type",[bb,vb,Tb,xb,Eb]);var Cb=Oe.object({type:Oe.literal("TARGETING"),name:Oe.string().optional().describe("Target name for steps with multiple targets"),elementLocationDecisions:yu.array(),pageState:Oe.string().optional(),targetSource:Oe.nativeEnum(Fn).optional(),targetUpdateTime:Oe.string().optional()}),Ab=Oe.object({type:Oe.literal("AI_LOCATION"),matched:Oe.boolean(),pageState:Oe.string().optional(),ragUsed:Oe.boolean().optional(),thoughts:Oe.string().optional()}),Rb=Oe.object({type:Oe.literal("ASSERTION"),relevantElementsSerialized:Oe.string().array().optional(),pageState:Oe.string().optional(),ragUsed:Oe.boolean().optional()}),Su=Oe.discriminatedUnion("type",[Cb,Ab,Rb]);function Zi(){return{details:[]}}import{z as Be}from"zod";var Ib=Be.object({id:Be.string(),name:Be.string()}),kN=Ib.merge(Be.object({createdAt:ze,createdBy:Be.string(),schedule:pr,notification:mr,environment:Be.object({name:Be.string()}).nullish()})),wu=Be.object({id:Be.string().uuid(),orgId:Be.string(),createdAt:ze,startedAt:ze.or(Be.null()),finishedAt:ze.or(Be.null()),status:Be.nativeEnum(Ee),trigger:Be.nativeEnum(Wn),suite:Be.object({id:Be.string(),name:Be.string()}).nullish(),runs:Mo.array()}),DN=wu.pick({id:!0,createdAt:!0,startedAt:!0,finishedAt:!0,status:!0,trigger:!0,suite:!0}),bu=wu.extend({runs:pu.array()});var vu=rt.object({startedAt:rt.coerce.date(),finishedAt:rt.coerce.date(),status:rt.nativeEnum(Ue),message:rt.string().optional(),data:rt.unknown().optional()}),Ob=vu.merge(Ra).extend({type:rt.literal("JAVASCRIPT")}),Lb=vu.merge(Aa).extend({type:rt.literal("REQUEST")}),Nb=rt.discriminatedUnion("type",[Ob,Lb]),Tu=rt.object({startedAt:rt.coerce.date(),finishedAt:rt.coerce.date().nullish(),status:rt.nativeEnum(Ee),results:Nb.array(),failureReason:rt.string().nullish(),failureDetails:qi.nullish()});import{z as ot}from"zod";var Mb=ot.object({id:ot.string(),organizationId:ot.string(),createdAt:ot.coerce.date(),updatedAt:ot.coerce.date(),createdBy:ot.string(),scheduledAt:ot.coerce.date().nullish(),startedAt:ot.coerce.date().nullish(),finishedAt:ot.coerce.date().nullish(),status:ot.nativeEnum(Ee),trigger:ot.nativeEnum(Wn),results:Tu.array().nullish(),apiTestName:ot.string().nullish(),apiTestPath:ot.string().nullish(),apiTestId:ot.string().nullish()}),eM=Mb.pick({status:!0,startedAt:!0,finishedAt:!0});import{z as tn}from"zod";var Qi=tn.object({x:tn.number(),y:tn.number(),correlation:tn.number()}),cM=tn.object({searchImageBase64String:tn.string(),pageImageBase64String:tn.string(),id:tn.string().uuid(),timeoutMs:tn.number().max(1e4).min(0).optional()});import{z as k}from"zod";var xu=k.object({phrase:k.string()}),il=k.object({thoughts:k.string().optional(),result:k.union([k.literal("NOT_FOUND"),k.string(),k.number(),k.array(k.unknown()),k.record(k.unknown(),k.unknown()),k.unknown()])}),Eu=k.object({thoughts:k.string(),id:k.number().int()}),_b=k.discriminatedUnion("op",[k.object({op:k.literal("replace"),path:k.string(),value:k.string()}),k.object({op:k.literal("add"),path:k.string(),value:k.string()}),k.object({op:k.literal("remove"),path:k.string()})]),mM=k.object({thoughts:k.string(),patches:_b.array()}),Cu=[k.literal("add"),k.literal("replace"),k.literal("remove")],kb=k.object({op:k.union(Cu),path:k.string(),value:xe.optional()}),Au=k.object({patches:kb.array(),thoughts:k.string()});var Db=k.object({thoughts:k.string(),op:k.union(Cu),value:k.union([k.null(),xe])}),Ru=k.object({reasoning:k.string(),scenario:k.string(),patch:Db.or(k.null())});import{z as Ye}from"zod";var Fb=Ye.object({content:Ye.string(),ids:Ye.string().array(),tokenLength:Ye.number()}),Ub=Ye.object({chunks:Fb.array(),numRecs:Ye.number()}),gM=Ye.object({ids:Ye.string().array(),score:Ye.number(),tokenLength:Ye.number()}),yM=Ye.object({description:Ye.string(),tokenLimit:Ye.number()}).merge(Ub),Iu=Ye.object({ids:Ye.number().array()});import{z as _}from"zod";var Ht=_.object({disableCache:_.boolean().optional(),loggerTags:_.record(_.string(),_.unknown()).optional()}),sl=_.object({generatedStep:Di.optional(),serializedCommand:_.string().optional(),elementInteracted:_.string().optional()}),zb=sl.extend({state:_.union([_.literal("PENDING"),_.literal("DONE")]),screenshotBase64AfterCommand:_.string().optional(),urlAfterCommand:_.string().optional()}),TM=_.object({goal:_.string(),browserState:_.string(),screenshot:_.string(),feedback:_.string().optional()}),xM=_.object({goal:_.string(),browserState:_.string()}),Pu=_.object({goal:_.string(),browserState:_.string(),screenshot:_.string().optional(),returnSchema:_.string().optional()}),Ou=_.object({goal:_.string(),browserState:_.string(),screenshot:_.string(),url:_.string(),contextChoice:_a.optional()}),EM=_.object({url:_.string(),goal:_.string()}),Lu=_.object({goal:_.string(),browserState:_.string(),startingScreenshot:_.string(),screenshot:_.string(),url:_.string(),history:zb.array()}),Nu=_.object({results:jt.array(),errorMessage:_.string(),errorStack:_.string().optional()}),Mu=_.object({results:_.array(jt),goal:_.string(),errorMessage:_.string()}),CM=_.object({failedResults:uu.array(),currentUrl:_.string(),currentPageState:_.string(),currentScreenshot:_.string()});import{z as vr}from"zod";var IM=vr.object({goal:vr.string(),completionType:vr.string().describe("type of completion these keywords will be used for")}),_u=vr.object({keywords:vr.array(vr.string())});var zM=new Set(Object.values(Te));var Bb={AI_ACTION:"AI action",AI_ACTION_DYNAMIC:"Dynamic AI action",RESOLVED_MODULE:"Module",AI_ASSERTION:"AI check",AI_WAIT:"AI wait",AI_EXTRACT:"AI extract",CLICK:"Click",TYPE:"Type",JAVASCRIPT:"JavaScript",SELECT_OPTION:"Select",PRESS:"Press",NAVIGATE:"Navigate",SCROLL_UP:"Scroll up",SCROLL_DOWN:"Scroll down",SCROLL_LEFT:"Scroll left",SCROLL_RIGHT:"Scroll right",HOVER:"Hover",BLUR:"Blur",FILE_UPLOAD:"File upload",FOCUS:"Focus",GO_BACK:"Go back",GO_FORWARD:"Go forward",WAIT:"Wait",REFRESH:"Refresh",TAB:"Switch tab",NEW_TAB:"New tab",COOKIE:"Cookie",LOCAL_STORAGE:"Local storage",REQUEST:"API request",GRAPHQL_REQUEST:"GraphQL request",CAPTCHA:"CAPTCHA",DRAG:"Drag & drop",VISUAL_DIFF:"Visual diff",DIALOG:"Dialog",MOUSE_DRAG:"Mouse drag",AUTH_LOAD:"Load auth state",AUTH_SAVE:"Save auth state",ELEMENT_CHECK:"Element check",PAGE_CHECK:"Page check",WAIT_FOR_URL:"Wait for URL",SUCCESS:"Done"},BM={AI_ACTION:["ai","action","agent"],AI_ACTION_DYNAMIC:["ai","action","dynamic","agent"],RESOLVED_MODULE:[],AI_ASSERTION:["ai","check","asserrt","make sure"],AI_WAIT:[],AI_EXTRACT:["ai","extract","data"],CLICK:["click","press"],TYPE:["type","input","write","press"],JAVASCRIPT:["js","javascript","code","execute"],SELECT_OPTION:["select","option","choose"],PRESS:["keyboard","type","key"],NAVIGATE:["go to","visit"],SCROLL_UP:[],SCROLL_DOWN:[],SCROLL_LEFT:[],SCROLL_RIGHT:[],HOVER:["scroll into view","go to"],BLUR:[],FILE_UPLOAD:[],FOCUS:[],GO_BACK:[],GO_FORWARD:[],WAIT:[],REFRESH:[],TAB:[],NEW_TAB:[],COOKIE:[],LOCAL_STORAGE:[],REQUEST:[],GRAPHQL_REQUEST:[],CAPTCHA:[],DRAG:[],VISUAL_DIFF:[],DIALOG:[],MOUSE_DRAG:[],AUTH_LOAD:[],AUTH_SAVE:[],ELEMENT_CHECK:[],PAGE_CHECK:[],WAIT_FOR_URL:[],SUCCESS:[]},$M={AI_ACTION:"Ask AI achieve a specific goal. Caches the steps for reuse. Please use Dynamic AI action instead.",AI_ACTION_DYNAMIC:"Ask AI achieve a specific goal. Fully dynamic. Our most capable AI agent.",RESOLVED_MODULE:"A list of steps that can be reused in multiple tests.",AI_ASSERTION:"Ask AI whether something is true on the page, retrying until a configurable timeout.",AI_WAIT:"Wait until AI considers a condition to be true.",CLICK:"Click on an element on the page based on a description.",DIALOG:"Specify how native browser dialogs should be handled.",AI_EXTRACT:"Ask AI to extract data from the page based on a description.",HOVER:"Hover over an element on the page based on a description.",FILE_UPLOAD:"Automatically upload a file when the next file chooser is activated.",FOCUS:"Focus an element on the page based on a description.",BLUR:"Remove focus from an element on the page based on a description.",SELECT_OPTION:"Select an option from an HTML Select <select> element based on a description.",TYPE:"Type the specified text into an element.",PRESS:"Press the specified keys using the keyboard. (e.g. Control+A)",NAVIGATE:"Navigate to the specified URL.",SCROLL_UP:"Scroll up by a specified height.",SCROLL_DOWN:"Scroll down by a specified height.",SCROLL_LEFT:"Scroll left by a specified width.",SCROLL_RIGHT:"Scroll right by a specified width.",GO_BACK:"Go back in browser history.",GO_FORWARD:"Go forward in browser history.",WAIT:"Wait for the specified number of seconds.",REFRESH:"Refresh the page. This will not clear cookies or session data.",TAB:"Switch to different tab in the browser.",NEW_TAB:"Create and switch to a new tab in the browser.",COOKIE:"Set a cookie that will persist throughout the browser session",LOCAL_STORAGE:"Set a local storage value that will persist throughout the browser session",CAPTCHA:"Solve CAPTCHAs on the page. This feature is only available on Momentic Cloud and may take up to 60 seconds. Disabling CAPTCHAs in non-production environments is strongly advised.",REQUEST:"Make an API request to a URL.",GRAPHQL_REQUEST:"Make a GraphQL request to a URL.",JAVASCRIPT:"Run JavaScript code.",DRAG:"Click and drag an element to another location.",VISUAL_DIFF:"Compare a screenshot of the page or a specific element to a baseline image.",MOUSE_DRAG:"Click and drag the mouse by a specified distance.",AUTH_LOAD:"Load or clear session state using a JSON snapshot including cookies, local storage, and IndexDB entries.",AUTH_SAVE:"Save auth state (cookies, local storage) into a JavaScript object format usable by 'Load auth state'.",ELEMENT_CHECK:"Assert on an element's state using pre-built conditions, including content, visibility, attribute value checks.",PAGE_CHECK:"Assert on the active page's state using pre-built conditions, including URL and content checks.",WAIT_FOR_URL:"Wait for the active page's URL to match a specific URL or glob pattern. If a new tab is opened, this command will wait for the new tab's URL to match instead.",SUCCESS:"Indicate the entire AI action has succeeded, optionally based on a condition."};import{z as D}from"zod";var VM=D.object({body:D.string(),to:D.string(),from:D.string()}),qM=D.object({from:D.string().optional(),to:D.string(),timeout:D.number().optional(),beforeDate:D.string().pipe(D.coerce.date()).or(D.date()).optional(),afterDate:D.string().pipe(D.coerce.date()).or(D.date()).optional()}),KM=D.object({to:D.string(),from:D.string(),subject:D.string(),body:D.string()}),YM=D.object({inbox:D.string(),afterDate:D.string().pipe(D.coerce.date()).or(D.date()).optional(),timeout:D.number().optional(),trimWhitespace:D.boolean().optional()}),JM=D.object({inbox:D.string(),limit:D.number().optional(),afterDate:D.string().pipe(D.coerce.date()).or(D.date()).optional(),trimWhitespace:D.boolean().optional()});var ku=D.object({result:D.unknown(),variableUpdates:D.record(D.string(),D.unknown()).optional(),error:D.string().optional(),success:D.boolean()}),XM=D.object({id:D.string().optional(),orgId:D.string(),momenticLambdaAuthHash:D.string(),code:D.string(),fragment:D.boolean(),state:No,timeoutMs:D.number().optional()}),Tr=15e3;var r_={AI_ACTION:5,AI_ACTION_DYNAMIC:5,AI_ASSERTION:3,AI_WAIT:3,AI_EXTRACT:3,SUCCESS:3,AUTH_LOAD:0,AUTH_SAVE:0,CAPTCHA:3,VISUAL_DIFF:0,JAVASCRIPT:1,ELEMENT_CHECK:1,PAGE_CHECK:0,CLICK:1,DRAG:1,FILE_UPLOAD:0,SELECT_OPTION:1,REQUEST:0,GRAPHQL_REQUEST:0,TYPE:1,PRESS:0,NAVIGATE:0,DIALOG:0,SCROLL_UP:1,SCROLL_DOWN:1,SCROLL_LEFT:1,SCROLL_RIGHT:1,GO_BACK:0,GO_FORWARD:0,WAIT:0,WAIT_FOR_URL:0,REFRESH:0,TAB:0,NEW_TAB:0,COOKIE:0,LOCAL_STORAGE:0,HOVER:1,FOCUS:1,BLUR:1,MOUSE_DRAG:1};import*as Ve from"zod";le(Ve);var $b=Ve.object({url:Ve.string(),lineNumber:Ve.number(),columnNumber:Ve.number()}).openapi({ref:"CodeLocation"}),es=Ve.object({timestamp:Ve.number(),text:Ve.string(),type:Ve.string(),tabIndex:Ve.number(),args:Ve.unknown().array().optional(),url:Ve.string().optional(),location:$b.optional()}).openapi({ref:"ConsoleLog"}),Du=es.array(),jb=Du.array();import*as ll from"zod";import{z as A}from"zod";var Hb=A.object({name:A.string(),version:A.string(),comment:A.string().optional()}),Wb=A.object({name:A.string(),version:A.string(),comment:A.string().optional()}),Gb=A.object({onContentLoad:A.number().optional(),onLoad:A.number().optional(),comment:A.string().optional()}),Uu=A.object({startedDateTime:A.string(),id:A.string(),title:A.string().optional(),pageTimings:Gb,comment:A.string().optional()}),Vb=A.array(Uu),qb=A.object({name:A.string(),value:A.string(),path:A.string().optional(),domain:A.string().optional(),expires:A.string().optional(),httpOnly:A.boolean().optional(),secure:A.boolean().optional(),comment:A.string().optional()}),zu=A.array(qb),Kb=A.object({name:A.string(),value:A.string(),comment:A.string().optional()}),Bu=A.array(Kb),Yb=A.object({name:A.string(),value:A.string(),comment:A.string().optional()}),Jb=A.array(Yb),Xb=A.object({name:A.string(),value:A.string().optional(),fileName:A.string().optional(),contentType:A.string().optional(),comment:A.string().optional()}),Zb=A.array(Xb),Qb=A.object({mimeType:A.string(),params:Zb,text:A.string(),comment:A.string().optional()}),ev=A.object({method:A.string(),url:A.string(),httpVersion:A.string().optional(),cookies:zu,headers:Bu,queryString:Jb,postData:Qb.optional(),headersSize:A.number().optional(),bodySize:A.number().optional(),comment:A.string().optional()}),tv=A.object({size:A.number().optional(),compression:A.number().optional(),mimeType:A.string().optional(),text:A.string().optional(),encoding:A.string().optional(),comment:A.string().optional()}),nv=A.object({status:A.number(),statusText:A.string(),httpVersion:A.string().optional(),cookies:zu,headers:Bu,content:tv,redirectURL:A.string().optional(),headersSize:A.number().optional(),bodySize:A.number().optional(),comment:A.string().optional()}),Fu=A.object({expires:A.string().optional(),lastAccess:A.string(),eTag:A.string(),hitCount:A.number(),comment:A.string().optional()}),rv=A.object({beforeRequest:Fu.optional(),afterRequest:Fu.optional(),comment:A.string().optional()}),ov=A.object({blocked:A.number().optional(),dns:A.number().optional(),connect:A.number().optional(),send:A.number(),wait:A.number(),receive:A.number(),ssl:A.number().optional(),comment:A.string().optional()}),$u=A.object({pageref:A.string().optional(),startedDateTime:A.string(),time:A.number().optional(),request:ev,response:nv.optional(),cache:rv.optional(),timings:ov,serverIPAddress:A.string().optional(),connection:A.string().optional(),comment:A.string().optional()}),iv=A.array($u),sv=A.object({version:A.string().default("1.1"),creator:Hb.optional(),browser:Wb.optional(),pages:Vb.optional(),entries:iv,comment:A.string().optional()}),av=A.object({log:sv}),ju=A.record(A.string(),Uu),Hu=A.record(A.string(),$u);function al(n,e){return{log:{version:"1.2",creator:{name:"Momentic, Inc.",version:"1.0.0"},pages:Object.values(n).sort((t,r)=>new Date(t.startedDateTime).getTime()-new Date(r.startedDateTime).getTime()),entries:Object.values(e).sort((t,r)=>new Date(t.startedDateTime).getTime()-new Date(r.startedDateTime).getTime())}}}le(ll);var lv=ll.object({logsPerPage:es.array().array(),harPages:ju.optional(),harEntries:Hu.optional()}).openapi({ref:"DebugData"});import{parseString as cv,splitCookiesString as dv}from"set-cookie-parser";import{z as ne}from"zod";var Wu=ne.object({name:ne.string(),value:ne.string(),url:ne.string().optional(),domain:ne.string().optional(),path:ne.string().optional(),expires:ne.number().default(Date.now()/1e3+60*60*24*365),httpOnly:ne.boolean().optional(),secure:ne.boolean().default(!0),sameSite:ne.union([ne.literal("Strict"),ne.literal("Lax"),ne.literal("None")]).default("None")});function Gu(n){let e=[],t=dv(n);for(let r of t){let o=cv(r);if(!o.name)throw new Error("Name missing from cookie");if(!o.value)throw new Error("Value missing from cookie");let i;if(o.sameSite){let c=o.sameSite.trim().toLowerCase();if(c==="strict")i="Strict";else if(c==="lax")i="Lax";else if(c==="none")i="None";else throw new Error(`Invalid sameSite setting in cookie: ${c}`)}o.httpOnly===void 0&&(o.httpOnly=!1),!o.path&&o.domain&&(o.path="/");let s=Wu.parse({...o,expires:o.expires?o.expires.getTime()/1e3:void 0,sameSite:i});e.push(s);let a=[s.name,...Object.keys(s)].map(c=>c.toLowerCase()),l=r.match(/\b(\w+)=([^;]*)/g);if(l)for(let c of l){let[u,d]=c.split("=");if(!u||!d)throw new Error(`Invalid key-value pair in cookie: ${c}`);a.includes(u.toLowerCase())||e.push({...s,name:u,value:d})}}return e}var uv=ne.object({origin:ne.string(),localStorage:ne.array(ne.object({name:ne.string(),value:ne.string()}))}),pv=ne.object({entries:ne.record(ne.string(),ne.array(ne.tuple([ne.unknown(),ne.unknown()]))),version:ne.number().optional()}),ts=ne.object({cookies:Wu.array().optional(),origins:uv.array().optional(),idb:ne.record(ne.string(),pv).optional().describe("key is db name")});var ns=class extends Error{constructor(e,t,r,o={}){super(`The ${r} with id ${t} is invalid: ${e}`,o),this.name="InvalidEntityError"}};var rs=class extends Error{constructor(e,t={}){super(e,t),this.name="TemplateMatcherThresholdError"}};function Vu(n){for(let e of Object.values(ie))if(n.includes(e))return e}var R=class extends Error{reason;constructor(e,t,r){let o=!1;for(let s of Object.values(ie))if(t.startsWith(s)){o=!0,e=s;break}let i=o?t:`${e}${t?`: ${t}`:""}`;super(i,r?.errOptions),this.name="TestFailureError",this.stack=this.stack?.slice(this.name.length+2),this.reason=e,Object.defineProperty(this,"lastScreenshotBuffer",{value:r?.lastScreenshotBuffer,enumerable:!1})}getLastScreenshotBuffer(){return"lastScreenshotBuffer"in this?this.lastScreenshotBuffer:void 0}toString(){return this.message}toJSON(){return{message:this.message}}},yn=class extends Error{decisions;constructor(e,t,r={}){super(e,r),this.decisions=t,this.name="NoElementsFoundError"}toString(){return`${this.message}
@@ -2586,7 +2586,7 @@ ${C||""}`}return g}shallowClone(){let e=new n({id:this.id,role:this.role,name:th
2586
2586
  `};if(i&&t.isNodeUniqueEnoughForDirectMatch){let{ok:u,reason:d}=t.isNodeUniqueEnoughForDirectMatch(i);if(!u)return{error:`[MOMENTIC] Closest node is not unique enough: ${d}
2587
2587
  ${a}`};e.push(`Node is unique enough: ${d}`)}return{dataMomenticId:s,mPathSelector:r&&i?t.getMPathSelector?.(i):void 0,closestDistance:l,closestNodeSerialized:a,logs:e}};import{randomUUID as ex}from"crypto";var tx="[redacted due to size]",nx=1e4;async function fh(n,e,t){let r=new Date().toISOString();e.harPages||(e.harPages={}),e.harPages[n]={id:n,startedDateTime:r,title:await t.title(),pageTimings:{}}}async function gh(n,e,t,r){try{await rx(n,e,t)}catch(o){o.message.includes("browser has been closed")||r.warn({err:o,pageId:n},"Error handling new network request, skipping...")}}function Zn(n){return n<0?0:n}function uh(n){return{timings:{blocked:Zn(n.domainLookupStart),dns:Zn(n.domainLookupEnd-n.domainLookupStart),connect:Zn(n.connectEnd-n.connectStart),send:Zn(n.responseStart-n.requestStart),wait:0,receive:Zn(n.responseEnd-n.responseStart),ssl:Zn(n.connectEnd-n.secureConnectionStart)},total:Zn(n.responseEnd)}}async function rx(n,e,t){let r=ex(),o=t.timing(),i=new URL(t.url()),s=[...i.searchParams.entries()].map(([f,h])=>({name:f,value:h})),a={...await hh(t),url:i.toString(),method:t.method(),queryString:s,postData:await ix(t)},l={pageref:n,startedDateTime:new Date(o.startTime).toISOString(),request:a,timings:uh(o).timings};ph(e,l,r);let c=await t.response();if(c){await c.finished();let f={};try{f=await sx(c)}catch{}let h={...await hh(c),status:c.status(),statusText:c.statusText(),content:f,redirectURL:c.headers().location};l.response=h}let u;try{u=await t.sizes(),l.request.bodySize=u.requestBodySize,l.request.headersSize=u.requestHeadersSize}catch{}l.response&&u&&(l.response.bodySize=u.responseBodySize,l.response.headersSize=u.responseHeadersSize,l.response.content.size=u.responseBodySize);let d=t.timing(),{timings:m,total:p}=uh(d);l.time=p,l.timings=m,ph(e,l,r)}function ph(n,e,t){n.harEntries||(n.harEntries={}),n.harEntries[t]=e}function mh(n){try{return new Date(n).toISOString()}catch{return}}function ox(n){let e={name:"",value:""},t=!0;for(let r of n.split(/; */)){let o=r.indexOf("="),i=o!==-1?r.substring(0,o).trim():r.trim(),s=o!==-1?r.substring(o+1,r.length).trim():"";if(t){t=!1,e.name=Kt(i),e.value=Kt(s);continue}i==="Domain"&&(e.domain=Kt(s)),i==="Expires"&&(e.expires=mh(s)),i==="HttpOnly"&&(e.httpOnly=!0),i==="Max-Age"&&(e.expires=mh(Date.now()+ +s*1e3)),i==="Path"&&(e.path=Kt(s)),i==="Secure"&&(e.secure=!0)}return e}async function hh(n){let e=await n.headersArray(),t=[];for(let r of e.filter(o=>o.name.toLowerCase()==="cookie"))t.push(...r.value.split(";").map(ox));return{headers:e.map(r=>({name:Kt(r.name),value:Kt(r.value)})),cookies:t}}async function ix(n){let e=n.postData();if(!e)return;let t=await n.headerValue("content-type"),r={mimeType:t??"application/octet-stream",text:Kt(e),params:[]};if(t==="application/x-www-form-urlencoded"){let o=new URLSearchParams(e.toString());for(let[i,s]of o.entries())r.params.push({name:Kt(i),value:s?Kt(s):void 0})}return r}async function sx(n){return{mimeType:await n.headerValue("content-type")??void 0,text:Kt(await n.text()),encoding:await n.headerValue("content-encoding")??void 0}}function Kt(n){return n.length>nx?tx:n}import{mkdirSync as ax,rmSync as yh,statSync as lx}from"fs";import*as Fl from"node:fs";import cx from"nodejs-file-downloader";import{tmpdir as dx}from"os";import Rn,{basename as ux,dirname as px}from"path";var Ul="file://",Dl=Rn.join(dx(),"momentic","downloads"),kl=1e4,mx=50*1024*1024;async function Sh(n){let{uri:e}=n;return e.startsWith(Ul)?fx(n):e.startsWith("http")?yx(n):gx(n)}function hx(n,e){let t=Rn.join(Dl,n,e.slice(Ul.length)),r=Rn.join(Dl,n),o=t.startsWith(r);if(!Fl.existsSync(t)||!o)throw new R("UserConfigurationError",`The referenced file (${e}) does not exist. Please make sure that it has been downloaded successfully.`);return t}async function fx({uri:n,orgId:e}){let t=hx(e,n);return{filePath:t,cleanup:()=>{yh(px(t),{recursive:!0,force:!0})}}}async function gx({uri:n}){let e=Rn.resolve(n);if(!Fl.existsSync(e))throw new R("UserConfigurationError",`The referenced file (${n}) does not exist on disk. Please make sure that it has been downloaded successfully.`);return{filePath:e,cleanup:()=>{}}}async function yx({uri:n,logger:e,orgId:t}){let r=new URL(n);r.search&&(r.search="");let o=ux(r.href),i=Bl(o),s=Rn.extname(i);if(Ip.includes(s))throw new Error(`Downloading files with extension ${s} is not allowed.`);let a=zl(t),l=new cx({url:n,fileName:i,directory:a,maxAttempts:2,headers:{"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36"},timeout:kl}),{downloadStatus:c,filePath:u}=await H(l.download(),{milliseconds:kl,message:`Download timed out after ${kl}ms`});if(c!=="COMPLETE")throw new Error(`Download ended in non-success status: ${c}`);if(!u)throw new Error("File path of successfully downloaded file was empty");let m=lx(u).size;if(m>mx)throw new Error("File size exceeds the maximum limit of 50MB");e.info({fileSizeInBytes:m,filePath:u,fileName:i},"Downloaded file to disk");let p;return{filePath:u,cleanup:()=>{clearTimeout(p),p=setTimeout(()=>yh(a,{recursive:!0,force:!0}),10*60*1e3)}}}function wh(n,e){return`${Ul}${n}/${e}`}function zl(n){let e=Math.random().toString(36).substring(4),t=Rn.join(Dl,n,e);return ax(t,{recursive:!0}),t}function Bl(n){let e=Rn.extname(n),t=Rn.basename(n,e);return n=(t.length>100?t.slice(t.length-100):t)+e,n=n.trim().replaceAll(" ","_"),n}async function bh(n,e){let[t,r]=await n.evaluate(async()=>{let o=window,i={};try{let s=await indexedDB.databases();for(let a of s){if(!a.name)continue;let l=await o.exportIdbToObject?.(a.name,a.version);l&&(i[a.name]=l)}return[i,void 0]}catch(s){return[void 0,s.message]}});return r&&e.warn({err:r},"Failed to fetch indexedDB data"),t}async function vh(n,e,t){if(e){t.debug("Importing indexedDB data");try{await n.evaluate(async r=>{let o=window;for(let[i,s]of Object.entries(r))await o.importObjectToIdb?.(i,s)},e)}catch(r){t.warn({err:r},"Failed to import indexedDB data")}}}async function Th(n,e){try{await n.evaluate(async()=>{window.localStorage.clear(),window.sessionStorage.clear(),await indexedDB.databases().then(t=>{t.forEach(r=>{r.name&&indexedDB.deleteDatabase(r.name)})})},{timeout:1e3})}catch(t){e.debug({err:t},"Failed clearing index db data, continuing...")}}var Es=class{limit;windowMs;userActions;constructor(e,t){this.limit=e,this.windowMs=t,this.userActions=new Map}_cleanup(e,t="DEFAULT_USER"){let r=Date.now(),o=`${t}:${e}`;if(this.userActions.has(o)){let s=this.userActions.get(o)?.filter(a=>r-a<=this.windowMs)??[];s.length>0?this.userActions.set(o,s):this.userActions.delete(o)}}increment(e,t="DEFAULT_USER"){let r=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(r),!1)}};function xh(){return async n=>{let{fragment:e,code:t,context:r}=n,{env:o}=r||{},i=Object.getPrototypeOf(async function(){}).constructor;return{result:await Promise.resolve(new i("env",e?`return ${t}`:t)(o))}}}async function kt({root:n,fn:e,arg:t,timeout:r,waitForPageLoad:o}){return await o(),await H(n.evaluate(e,t),{milliseconds:r})}import{errors as Sx}from"playwright-core";async function Qn({func:n,action:e,logger:t,callbacks:r,retryTimeoutMs:o,targetingResult:i}){let s=Date.now(),a;for(;Date.now()-s<o;)try{return await n(i)}catch(l){let c=l;if(c.message.includes("waiting for locator")&&c.message.includes("data-momentic-id")&&!c.message.includes("locator resolved")&&!c.message.includes("waiting for element to be")){t.warn("Attempting to recover from removed data-momentic-ids by re-adding ids to DOM");let u=await r.state.getRoot(),[d]=await Promise.all([n(i),r.addMomenticIds(u)]);return d}else if(c instanceof Sx.TimeoutError)t.warn({err:c},`Encountered Playwright error while ${e}, retrying...`),a=await wx(c,i.locator,r,t);else throw c}throw a}async function wx(n,e,t,r){return n.message.includes("attempt #")?bx(n,e,t,r):vx(n)}async function bx(n,e,t,r){let o=n.message.split(/- retrying \w+ action, attempt #\d+/).filter(l=>l.length>0);if(!o.length)return r.warn({err:n},"Failed to parse Playwright error message for translation, returning raw message"),n;let i=o.length>2?o[o.length-2]:o[0];i=i.replace(/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g,"").replaceAll(" - ","").trim().replaceAll(`
2588
2588
  `,";").replace(/\s+/g," ");let s="",a=await _t(e,r);if(a&&(s=`Target element HTML: ${Ne(a,100,!0)}`),i.includes("element is not enabled"))return new R("ActionFailureError",`The element you attempted to interact with was disabled for the entire timeout duration. Please explicitly wait for the element to be enabled, change the element description to target an interactive element, or turn on the 'disable stability checks' option. ${s}`,{errOptions:{cause:n}});if(i.includes("intercepts pointer events")){let l="",c=i.match(/<.*?data-momentic-id="(\d+)".*?intercepts pointer events/)?.[1];if(c){let u=(await t.state.getRoot()).locator(`[data-momentic-id="${c}"]`),d=await _t(u,r);d&&(l=`Covering element HTML: ${Ne(d,100,!0)}`)}return new R("ActionFailureError",`The element you attempted to interact with was covered by another element such as dropdown, popup, or dialog for the entire timeout duration. Please add a step to hide the covering element or turn on the 'disable stability checks' option. ${s}
2589
- ${l}`,{errOptions:{cause:n}})}if(i.includes("element is not visible")){let l="The element you attempted to interact with has no bounding box or is explicitly hidden.";try{let c=await e.boundingBox({timeout:1e3});c?c.height===0?l="The element you attempted to interact with has zero height.":c.width===0&&(l="The element you attempted to interact with has zero width."):l="The element you attempted to interact with has no bounding box."}catch{}return new R("ActionFailureError",`${l} Please explicitly wait for the element to be visible or turn on the 'disable stability checks' option. ${s}`,{errOptions:{cause:n}})}return n}function vx(n){let e=n.message;if(e.includes("waiting for locator")&&e.includes("data-momentic-id")&&!e.match(/attempting \w+ action/))throw new R("ActionFailureError","The element you targeted was removed or replaced by a page load, animation, or JavaScript code during the interaction. Please wait for the page to be stable before this step.",{errOptions:{cause:n}});return n}async function Eh(n,e,t,r,o){try{await Tx(n,e,t,r)}catch(i){o.error({err:i,tabIndex:e},"Error handling new console log")}}async function Tx(n,e,t,r){let o=r.text();o.length>Wo&&(o=o.slice(0,Wo)+"...(TRUNCATED)");let i=[];for(let s of r.args())try{let a=await s.jsonValue(),l=JSON.stringify(a);l.length>Wo?i.push(l.slice(0,Wo)+"...(TRUNCATED)"):(typeof a!="object"||Object.keys(a).length>0)&&i.push(a)}catch{}$l(n,t,e,{url:n.url(),location:r.location(),type:r.type(),text:r.text(),args:i})}function $l(n,e,t,r){let o=Date.now(),i=e.logsPerPage;if(i.length<=t||i[t]===void 0){i[t]=[];for(let s=0;s<t;s++)i[s]===void 0&&(i[s]=[])}i[t].length>Nl&&(i[t]=i[t].slice(Math.floor(Nl/2)),i[t]?.push({url:n.url(),timestamp:o,type:"warning",text:"[MOMENTIC] Truncated console logs due to buffer overflow",tabIndex:t})),i[t].push({...r,tabIndex:t,timestamp:o})}async function In({fn:n,codePath:e,logObject:t,signal:r,logger:o}){r?.throwIfAborted();let i=Date.now(),s=await bn({promise:n(),signal:r,codePath:e,logger:o}),a=Date.now();return t[e]=a-i,s}async function Ch({locator:n,logger:e}){if(await n.evaluate(o=>o.tagName.toLowerCase(),void 0,{timeout:1e3})!=="input")return;let r=await n.boundingBox({timeout:1e3});if(r===null){e.warn({elementDisplayString:await _t(n,e)},"Attempting to click on element with no bounding box");return}if(!(r.width>5||r.height>5))try{let o=await n.evaluate(s=>{let a=window;if(!a.CssSelectorGenerator)return{type:"error",error:"[MOMENTIC] Missing CSS selector libraries"};let l=s.parentElement;if(!l)return{type:"error",error:"Input click target has no parent for redirection"};let c=a.CssSelectorGenerator.getCssSelector(l,{}),u=s.getBoundingClientRect(),d=l.getBoundingClientRect(),m={x:Math.min(Math.max(1,u.left-d.left),d.width-1),y:Math.min(Math.max(1,u.top-d.top),d.height-1)};return{type:"result",selector:c,relativePoint:m,serializedForm:l.outerHTML.slice(0,500)}},{timeout:1e3});if(o.type==="error")throw new Error(o.error);let i=n.page().locator(o.selector);return await i.waitFor({state:"attached",timeout:1e3}),e.info(o,`Redirected click to parent element with selector: ${o.selector}`),{locator:i,relativePoint:o.relativePoint}}catch(o){e.error({err:o},"Failed finding parent label for Chakra element");return}}var Rh=["date","datetime-local","month","time","week"],Ah={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 Ih(n,e,t,r){let o=(await n.evaluate(()=>document.activeElement?.getAttribute("type"))??"").toLowerCase();return Ah[o]&&(Ah[o].test(e)&&r.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,r.debug("Transforming datetime input to use sequential key presses")),!1}async function Cs(n,e,t){try{return await jl(e),await n.evaluate(r=>{let o=window;o.momenticIsEligible=c=>{let d=window.getComputedStyle(c,null).getPropertyValue("display");if(d==="none"||d==="contents")return!1;let m=c.getBoundingClientRect();return!(!m.height||!m.width)},o.removeHighlightTimers=o.removeHighlightTimers||[],o.removeHighlightFunctions=o.removeHighlightFunctions||{};let i=0;for(;!o.momenticIsEligible(r)&&i<3;){if(!r.parentElement)throw new Error("No eligible non-empty parent found for highlighting");r=r.parentElement,i++}let s=r.style.getPropertyValue("outline"),a=r.style.getPropertyPriority("outline");r.style.setProperty("outline","5px dashed rgb(255, 0, 153)","important");let l=`momentic${Math.floor(Math.random()*1e7)}`;o[l]=()=>{r.style.removeProperty("outline"),r.style.setProperty("outline",s,a),r.getAttribute("style")||r.removeAttribute("style")},o.removeHighlightTimers.push(setTimeout(()=>{o[l](),o.removeHighlightFunctions?.[l]&&delete o.removeHighlightFunctions[l]},5e3)),o.removeHighlightFunctions[l]=o[l]},void 0,{timeout:1e3}),!0}catch(r){return t.debug({err:r},"Failed to add node highlight, a page navigation likely occurred. This is non-fatal for tests."),!1}}async function jl(n){await n.evaluate(()=>{let e=window,t=e.removeHighlightTimers||[];for(;t.length;){let r=t.pop();clearTimeout(r)}Object.values(e.removeHighlightFunctions??{}).forEach(r=>{r()})},{timeout:1e3})}async function Hl(n){let e=n.featureFlags.isBooleanFlagEnabled("visual_actions");return Qn({action:"clicking element",targetingResult:n.targetingResult,logger:n.logger,retryTimeoutMs:n.retryTimeoutMs,callbacks:n.browserCallbacks,func:async t=>Oh({...n,targetingResult:t,useVisualClick:e})})}function Ax(n){return n.message.includes("locator.click: Timeout")&&n.message.includes("click action done")}async function Rx(n,e){let{logger:t,redirectionAttempts:r=0,browserCallbacks:o,disableRedirection:i}=e,s=e.targetingResult.locator,a=o.state.getDomGraph();if(!i&&a&&n.message.includes("intercepts pointer events")&&r<2){t.warn("Attempting locator redirection due to covering error");let l=await Ox(s,a,t);if(l)return Oh({...e,targetingResult:{...s,locator:l},redirectionAttempts:r+1})}throw n}async function Oh(n){let{options:e,logger:t,browserCallbacks:r,controllerCallbacks:o,disableRedirection:i,useVisualClick:s}=n,a=n.targetingResult.locator,l=n.position,c=await r.state.getRoot(),u=(await r.state.getOpenPages()).map(h=>h.url);if(!i){let h=await Ch({locator:a,logger:t});h&&(a=h.locator,l=h.relativePoint)}await Cs(a,c,t);let d=r.state.url(),m,p;e?.waitForDownload&&(m=(async()=>{try{return await a.page().waitForEvent("download",{timeout:1e4})}catch(h){h instanceof Cx.TimeoutError?p=new R("ActionFailureError",`Download did not complete in ${1e4}ms`):p=new R("ActionFailureError",`Download failed: ${h.message}`)}})());let f=null;try{f=await a.getAttribute("target",{timeout:1e3})}catch(h){t.warn({err:h},"Failed to get attributes of element about to be clicked, continuing...")}if(s)await Px({logger:t,targetingResult:n.targetingResult,position:l,options:e});else{let h=e?.force||n.targetingResult.hints?.force||!1;try{t.debug("Executing click"),e?.doubleClick?await a.dblclick({button:e.rightClick?"right":"left",timeout:3e3,position:l,force:h,delay:25}):await a.click({button:e?.rightClick?"right":"left",timeout:3e3,position:l,delay:25,force:h})}catch(g){let y=g;if(Ax(y))t.warn({err:y},"Click action timed out while waiting for navigation after completion, continuing...");else return Rx(y,{...n,targetingResult:{...a,locator:a}})}}if(f==="_blank"&&(t.debug("Waiting for new page promise due to _blank target"),await r.waitForPageLoad()),e?.waitForUrl&&await r.waitForUrl({beforeUrl:d,beforePages:u,waitForUrl:e.waitForUrl}),e?.waitForDownload){if(p)throw p;if(m){if(!o?.createIsolatedFolder)throw new R("InternalWebAgentError","Cannot wait for download without a callback to create an isolated folder");return t.info("Waiting for download to start and complete"),{downloadedFile:await H(Lx(m,o.createIsolatedFolder,t),{milliseconds:1e4,fallback:()=>{throw new R("ActionFailureError",`Download timed out after ${1e4}ms`)},signal:r.signal})}}else throw new Error("No download promise or error but the step requested to wait for a download")}}async function Ix(n,e){if(n.hints?.clickableXY)return e.debug({hints:n.hints},"Using click coordinates from hint"),n.hints.clickableXY;let t=await n.locator.boundingBox({timeout:1e3});if(!t)throw new R("ActionFailureError","Element does not have a bounding box");let r=t.x+t.width/2,o=t.y+t.height/2;return{x:r,y:o}}async function Px({logger:n,options:e,targetingResult:t,position:r}){let o,i;if(r){let c=await t.locator.boundingBox({timeout:1e3});o=c?.x??0+r.x,i=c?.y??0+r.y,n.debug({clickX:o,clickY:i},"Clicking using XY: determined click coordinates using predefined position")}else({x:o,y:i}=await Ix(t,n)),n.debug({clickX:o,clickY:i},"Clicking using XY: determined click coordinates with bounding box");let s=t.locator.page(),a=e?.rightClick?"right":"left",l=25;e?.doubleClick?await s.mouse.dblclick(o,i,{button:a,delay:l}):await s.mouse.click(o,i,{button:a,delay:l})}async function Ox(n,e,t){let r=await n.evaluate(a=>a.getAttribute("data-momentic-id"));if(!r)return;let o=xs(r,e,t);if(!o.length){t.error("No candidates found for parent-based locator redirection");return}let i=parseInt(o[0].attributes?.[it]??"");if(isNaN(i))return;n=n.page().locator(`[data-momentic-id="${i}"]`);let s=await _t(n,t);return t.warn({candidateMomenticId:i,serializedHtml:s},"Trying new locator based on parent-direction after covering error"),n}async function Lx(n,e,t){t.info("Download detected, saving file to disk");let r=await n,o=await r.path(),i=Bl(r.suggestedFilename()),s=e();await r.saveAs(Ex(s,i)),Ph(o,{force:!0}),setTimeout(()=>{Ph(s,{recursive:!0,force:!0})},5*60*1e3);let a=wh(xx(s),i);return t.debug({uri:a,downloadFolder:s},"Saved download to isolated folder"),a}async function Wl({frame:n,page:e,deltaX:t,directionX:r,deltaY:o,directionY:i,signal:s}){if(!t&&!o)return;let a=r==="left"?-1:1,l=i==="up"?-1:1;if(n)await n.evaluate(([c,u,d,m])=>window.scrollTo(window.scrollX+(c??window.innerWidth)*d,window.scrollY+(u??window.innerHeight)*m),[t,o,a,l]);else{let c=e.viewportSize()||Ot,u=await e.evaluate(()=>document.body.scrollHeight),[d,m,p]=await e.evaluate(()=>{let h=document.activeElement;if(!h)return[void 0,void 0,void 0];let g=h.getBoundingClientRect();return[h.scrollTop,g.x,g.y]});await e.mouse.wheel((t??c.width)*a,(o??c.height)*l);let f=Date.now();for(;Date.now()-f<2e3;){s?.throwIfAborted();let h=await e.evaluate(()=>document.body.scrollHeight),[g,y,v]=await e.evaluate(()=>{let x=document.activeElement;if(!x)return[void 0,void 0,void 0];let b=x.getBoundingClientRect();return[x.scrollTop,b.x,b.y]});if(h===u&&g===d&&y===m&&v===p)break;u=h,d=g,m=y,p=v,await Z(500)}}}async function Ur(n,e){let t,r;for(let o=0;o<4;o++)try{return t=n.pages(),await Promise.all(t.map(async i=>({title:e?.getTitles?await i.title():"",url:i.url()})))}catch(i){r=i,await Z(500)}throw new Error(`Failed to get tab titles after all retries: ${r?.message}`)}async function Vl({context:n,page:e,logger:t,timeoutMs:r=8e3,retries:o=2}){try{let i=await H(n.newCDPSession(e),{milliseconds:r,fallback:()=>{throw new R("UserInfrastructureError",`Failed to initialize Chrome session within the page load timeout (${e.url()})`)}});return await Gl.init(i,t)}catch(i){if(o>0)return t.debug({err:i},"Failed to initialize CDP session, re-creating CDP client"),await Z(500),Vl({context:n,page:e,logger:t,timeoutMs:r,retries:o-1});throw i}}var Gl=class n{constructor(e,t){this.session=e;this.logger=t}cdpInitializingPromise=void 0;cdpCrashDetails=void 0;cdpFullyDead=!1;static async init(e,t){let r=new n(e,t);try{await H(r.registerHandlers(e),{milliseconds:8e3,message:`CDP handler registration timed out after ${8e3}ms`})}catch(o){throw r.cdpFullyDead=!0,new R("UserInfrastructureError",`Failed to initialize CDP client: ${o}`)}return r}async registerHandlers(e){e.on("Target.attachedToTarget",async()=>{try{await e.send("Runtime.runIfWaitingForDebugger")}catch(t){this.logger.debug({err:t},"Failed to run Runtime.runIfWaitingForDebugger")}}),e.on("Target.targetCrashed",t=>{this.cdpCrashDetails={...this.cdpCrashDetails??{},targetCrashDetails:`${t}`},this.logger.error({payload:t},"CDP session crashed, Momentic will likely not function correctly")}),e.on("Inspector.targetCrashed",t=>{this.cdpCrashDetails={...this.cdpCrashDetails??{},inspectorCrashDetails:`${t}`},this.logger.error({payload:t},"CDP inspector session crashed, Momentic will likely not function correctly")}),await e.send("Accessibility.enable"),await e.send("DOM.enable"),await e.send("Overlay.enable")}async send({method:e,params:t,timeout:r,reinitializer:o}){if(await this.cdpInitializingPromise,this.cdpCrashDetails){if(this.cdpFullyDead||!o)throw new R("UserInfrastructureError",`The browser inspector session encountered a critical crash: ${JSON.stringify(this.cdpCrashDetails)}`);this.logger.warn(`Detected crashed CDP client before method ${e}, reinitializing before proceeding...`),await this.reinitialize(o)}try{return await H(this.session.send(e,t),{milliseconds:r??8e3,message:`Chrome command ${e} timed out after ${r??8e3}ms. This is likely an infrastructure issue caused by a lack of compute resources or a crash at the browser level.`})}catch(i){throw o&&["Internal error","Target crashed"].some(s=>i.message.includes(s))&&!this.cdpInitializingPromise&&(this.logger.warn({err:i},`CDP crashed during CDP method ${e}, re-initializing client`),await this.reinitialize(o)),i}}async reinitialize(e){await this.cdpInitializingPromise;let t=async()=>{let r=this.session;this.session=await e(),await this.registerHandlers(this.session);try{await H(r.detach(),{milliseconds:1e3})}catch(o){this.logger.warn({err:o},"Failed to detach old CDP session after reinitialization, continuing...")}};this.cdpInitializingPromise=(async()=>{try{await H(t(),{milliseconds:8e3,message:`CDP reinitialization timed out after ${8e3}ms`}),this.cdpCrashDetails=void 0,this.cdpFullyDead=!1}catch(r){this.cdpCrashDetails={...this.cdpCrashDetails??{},reinitializeError:`${r}`},this.cdpFullyDead=!0}finally{this.cdpInitializingPromise=void 0}})(),await this.cdpInitializingPromise}on(e,t){return this.session.on(e,t),this.session}off(e,t){return this.session.off(e,t),this.session}addListener(e,t){return this.session.addListener(e,t),this.session}removeListener(e,t){return this.session.removeListener(e,t),this.session}};var ql=Vo(kh(),"momentic","chromium"),Jx=Vo(kh(),"video"),zr=process.env.TWO_CAPTCHA_KEY,Kl=qx(Dh);Kl.use(Kx({provider:{id:"2captcha",token:zr},visualFeedback:!0}));var Jt=class n{static USER_AGENT=Vx["Desktop Chrome"].userAgent;abortSignal=void 0;contextInitialized=!1;browser;context;properties;page;userControlledBrowserSettings;pageLoadPromise=null;lastTabChangeEventTimeout=void 0;mockedServices;a11yIdToNodeMap={};dataMomenticIdToNodeMap={};selectorToNodeMap={};mostRecentA11yTreeRoot;domGraph=void 0;cdpClient;debugData={logsPerPage:[],harPages:{},harEntries:{}};enricher;storage;featureFlagStore;logger;activeFrame;activeFrameCache;transformer;baseUrl;originsVisited=new Set;viewport;onTabsChange=void 0;videos=[];constructor({storage:e,featureFlagStore:t,enricher:r,browser:o,context:i,page:s,baseUrl:a,logger:l,cdpClient:c,mockedServices:u,userBrowserSettings:d,viewport:m,onTabsChange:p,properties:f}){if(Pp(d),this.mockedServices=u,this.storage=e,this.featureFlagStore=t,this.enricher=r,this.browser=o,this.context=i,this.cdpClient=c,this.page=s,this.baseUrl=a,this.logger=l,this.userControlledBrowserSettings=d,this.viewport=m||Ot,this.onTabsChange=p,this.properties=f,f.recordVideo){let h=this.page.video();h&&this.videos.push(h)}}async registerAbortSignal(e){this.abortSignal=e}async initializeContext(){if(this.contextInitialized)return;this.userControlledBrowserSettings.extraHeaders&&await this.context.setExtraHTTPHeaders(this.userControlledBrowserSettings.extraHeaders),await this.context.grantPermissions(["clipboard-read","clipboard-write","microphone","camera"]);let e=this.featureFlagStore.getAllFlags(),t=[this.context.addInitScript({content:El.cssGeneratorLibJs}),this.context.addInitScript({content:El.htmlUtilsLibJs}),this.context.addInitScript({content:`window._MOMENTIC_BROWSER = true; window._MOMENTIC_FEATURE_FLAGS = ${JSON.stringify(e)};`})],r=Promise.all(Object.entries(this.mockedServices).map(([s,a])=>this.context.route(s,l=>a.handle(l)))),o=s=>this.handleNewPageEvent(s);this.context.on("page",o),this.handleNewPageEventHelper(this.page),this.context.on("close",()=>{this.logger.debug("Chrome browser context was closed"),this.context.off("page",o)});let i=Promise.all(t);await Promise.all([i,r]),this.contextInitialized=!0}static async init({baseUrl:e,logger:t,storage:r,featureFlagStore:o,enricher:i,mockedServices:s,userBrowserSettings:a,contextArgs:l,timeout:c,browserbaseConnectUrl:u,onTabsChange:d,recordVideo:m}){process.env.PW_TEST_SCREENSHOT_NO_FONTS_READY="1";let p={headless:!0,handleSIGTERM:!1,chromiumSandbox:!1,channel:a.browserType==="Google Chrome"?"chrome":void 0},f={viewport:Ot,userAgent:a.userAgent??n.USER_AGENT,geolocation:{latitude:37.7749,longitude:-122.4194},locale:"en-US",timezoneId:"America/Los_Angeles",httpCredentials:a.basicAuthorization?{username:a.basicAuthorization.username??"",password:a.basicAuthorization.password??""}:void 0,...l??{}},h=["--disable-dev-shm-usage","--no-first-run","--renderer-process-limit=2","--disable-site-isolation-for-policy","--disable-site-isolation-trials","--autoplay-policy=user-gesture-required","--disable-add-to-shelf","--disable-desktop-notifications","--use-fake-device-for-media-stream","--use-fake-ui-for-media-stream","--ignore-gpu-blocklist","--use-gl=angle","--use-angle=gl-egl"],g=!1;if(a.localChromeExtensionPaths?.length){g=!0;for(let I of a.localChromeExtensionPaths){let O=Vo(I,"manifest.json");if(!Rs(O))throw new R("UserConfigurationError",`Chrome extension path ${O} does not exist.`)}}let y=null,v,x,b={systemDevicePixelRatio:l?.deviceScaleFactor,recordVideo:m};if(g){let I=Vo(ql,`momentic-session-${Date.now()}`);if(!Rs(I))try{Fx(I,{recursive:!0})}catch(L){throw new R("UserConfigurationError",`Failed to create browser cache directory. Please make sure you have sufficient permissions to create the ${ql} folder: ${L}`)}let O=[...h];if(a.localChromeExtensionPaths){let L=a.localChromeExtensionPaths.map(U=>Gx(U)).join(",");O.push(`--disable-extensions-except=${L}`,"--headless=new"),b.isNewHeadless=!0}f?.deviceScaleFactor&&O.push(`--force-device-scale-factor=${f.deviceScaleFactor}`,`--device-scale-factor=${f.deviceScaleFactor}`),f.viewport&&O.push(`--window-size=${f.viewport.width},${f.viewport.height}`),v=await Dh.launchPersistentContext(Vo(ql,`momentic-session-${Date.now()}`),{...p,...f,ignoreDefaultArgs:["--disable-extensions","--disable-component-extensions-with-background-pages"],args:O,baseURL:e}),t.debug({sharedContextOptions:f,sharedBrowserOptions:p,chromeArgs:O},"Browser initialization context args (persistent)"),x=v.pages()[0]}else if(u){y=await Kl.connectOverCDP(u);let I=y.contexts()[0];if(!I)throw new Error("Failed to get browserbase default context");let O=I.pages()[0];if(!O)throw new Error("Failed to get browserbase default page");v=I,x=O}else{y=await Kl.launch({...p,args:h});let I={...f,baseURL:e,recordVideo:m?{dir:Jx}:void 0};v=await y.newContext(I),t.debug({contextArgs:I,sharedBrowserOptions:p,chromeArgs:h},"Browser initialization context args (standard)"),x=await v.newPage()}let S=await Vl({context:v,page:x,logger:t,timeoutMs:c}),C=new n({browser:y,context:v,page:x,baseUrl:e,logger:t,storage:r,featureFlagStore:o,mockedServices:s||{},enricher:i,userBrowserSettings:a,cdpClient:S,viewport:f.viewport||Ot,onTabsChange:d,properties:b});return await C.initializeContext(),C}async handleAvailableTabsChangeHelper(){try{let e=await Ur(this.context,{getTitles:!0}),t=this.page.url();this.onTabsChange?.(e,t)}catch(e){this.logger.error({err:e},"Error sending available tabs to frontend")}}handleAvailableTabsChange(){try{clearTimeout(this.lastTabChangeEventTimeout),this.lastTabChangeEventTimeout=setTimeout(()=>this.handleAvailableTabsChangeHelper(),500)}catch(e){this.logger.warn({err:e},"Error handling available tabs change")}}handlePageClosedEvent(e){let t=async()=>{try{if(this.page!==e){this.logger.info({url:e.url()},"Detected background page was closed"),this.handleAvailableTabsChange();return}this.logger.info({url:e.url()},"Detected active page was closed, switching to another tab");let r=this.context.pages();for(let o=r.length-1;o>=0;o--){let i=r[o];if(!(!i||i.isClosed()||!xn(i.url()))){this.logger.info(`Automatically switching to tab ${o} after close: ${i.url()}`),await this.switchToPage({type:"INDEX",index:o});break}}}catch(r){this.logger.warn({err:r},"Error in page close event handler")}finally{this.pageLoadPromise=null}};this.pageLoadPromise=t()}handleNewPageEvent(e){let t=e.url();if(this.logger.info({url:t},"Detected new page event, registering handlers and waiting for load to complete"),this.properties.recordVideo){let r=e.video();r&&this.videos.push(r)}try{this.handleNewPageEventHelper(e)}catch(r){this.logger.warn({err:r},"Error handling new page open, continuing....")}}handleNewPageEventHelper(e){let t=Dx(),r=fh(t,this.debugData,e);e.on("close",s=>this.handlePageClosedEvent(s)),e.on("framenavigated",s=>{s===e.mainFrame()&&this.handleFrameNavigationEvent(s)});let o=this.context.pages().indexOf(e);e.on("console",s=>{Eh(e,o,this.debugData,s,this.logger)}),e.on("request",s=>{gh(t,this.debugData,s,this.logger)});let i=this.pageLoadPromise;this.pageLoadPromise=(async()=>{try{await i,await r,await this.loadFrameAndRecordUrl(e),this.handleAvailableTabsChange()}catch(s){this.logger.error({err:s},"Failed to wait for new page to load")}finally{this.pageLoadPromise=null}})()}handleFrameNavigationEvent(e){let t=e.url();if(!t||t==="about:blank"||!xn(t))return;this.logger.debug({url:t},"Detected frame navigation event, adding to page load promise");let r=this.pageLoadPromise;this.pageLoadPromise=(async()=>{try{await Promise.resolve(r),await this.loadFrameAndRecordUrl(e),this.handleAvailableTabsChange()}catch(o){this.logger.error({err:o},"Failed to wait for frame navigation to finish")}finally{this.pageLoadPromise=null}})()}getBrowserCallbacks(){return{waitForPageLoad:()=>this.waitForPageLoad(),waitForUrl:e=>this.waitForUrl(e),addMomenticIds:e=>this.addMomenticIds(e),getBrowserState:e=>this.getBrowserState(e),state:{url:()=>this.url(),getDomGraph:()=>this.domGraph,getOpenPages:()=>this.getOpenPages(),getRoot:()=>this.getActivePageOrFrame()},pageLoadTimeoutMs:this.pageLoadTimeout,signal:this.abortSignal}}async getLocatorFromCdpFrame(e,t){let r=this.page;for(let l of t)r=r.frameLocator(`iframe[${l}]`);let o;for(let l of["src","name","id","title"])if(this.getAttributeFromStringArray(e.attributes??[],l)){o=l;break}if(!o)throw new Error(`Failed to find a unique attribute to identify frame with url matching '${e.contentDocument?.documentURL}'. Please attach a unique 'id', 'name', 'title', or 'src' attribute to the frame.`);let i=this.getAttributeFromStringArray(e.attributes??[],o),s=r.locator(`iframe[${o}=${JSON.stringify(i)}]`),a=await(await s.evaluateHandle(l=>l,{timeout:1e3})).asElement().contentFrame();if(!a)throw new Error(`Got null frame from locator: ${s}`);return await this.loadFrameAndRecordUrl(a,this.abortSignal),a}async getMatchingFrameWithCdp(e){if(e.type!=="url")throw new Error("Only url frame identifiers are supported at the moment");let t=e.url,o=[{node:(await this.cdpClient.send({method:"DOM.getDocument",params:{pierce:!0,depth:-1},reinitializer:()=>this.createRawCDPSession()})).root,selectorChain:[]}],i=[];for(;o.length>0;){let s=o.pop(),a=s.node,l=s.selectorChain;if(a.nodeName.toLowerCase()==="iframe"){let c=this.getAttributeFromStringArray(a.attributes??[],"src")||a.contentDocument?.documentURL;if(!c)continue;t.startsWith("/")&&t.endsWith("/")?new RegExp(t.slice(1,-1)).test(c)&&(this.logger.debug({frameUrl:c},"Found frame with src matching regex"),i.push({node:a,frame:await this.getLocatorFromCdpFrame(a,l)})):t.trim()===c.trim()&&(this.logger.debug({frameUrl:c},"Found frame with exact URL match"),i.push({node:a,frame:await this.getLocatorFromCdpFrame(a,l)}));let u=!1;for(let d of["src","name","id","title"]){let m=this.getAttributeFromStringArray(a.attributes??[],d);if(m){l=[...l,`${d}=${JSON.stringify(m)}`],u=!0;break}}if(!u){this.logger.debug({attrs:a.attributes},"Could not find a unique attribute to identify possible intermediate frame, skipping...");continue}}for(let c of a.children??[])o.push({node:c,selectorChain:l});a.contentDocument&&o.push({node:a.contentDocument,selectorChain:l})}if(i.length===1)return i[0];throw i.length>1?new Error(`Found multiple frames with src matching '${t}'. Please use a more specific selector.`):new Error(`Failed to find frame with src matching: ${t}`)}async resolveActiveFrame(){if(!this.activeFrame)throw new Error("No active frame set but attempting to get active frame");if(this.activeFrame.type==="url")return this.getMatchingFrameWithCdp(this.activeFrame);throw new Error(`Frame identifier type ${this.activeFrame.type} is not yet supported`)}ping(){if(this.closed)throw new Error("Page has been closed")}setActiveFrame(e){e?(this.activeFrame=e,this.activeFrameCache=void 0):(this.activeFrame=void 0,this.activeFrameCache=void 0)}async reset(e){for(this.abortSignal=void 0,this.debugData.logsPerPage=[],this.debugData.harPages={},this.debugData.harEntries={},this.a11yIdToNodeMap={},this.dataMomenticIdToNodeMap={},this.selectorToNodeMap={},this.pageLoadPromise=null,this.activeFrame=void 0,this.activeFrameCache=void 0;this.videos.length>0;)this.videos.pop();await this.clearAuthState({closeNonActiveTabs:!0}),await this.reinitializeCDPClient(),await this.navigate({url:e.newUrl??this.baseUrl,initialNavigation:!0,loadTimeoutMs:e.timeout})}async cleanup(){this.abortSignal=void 0;try{this.originsVisited.clear(),await this.context.close(),await this.browser?.close(),this.browser=null}catch(e){this.logger.warn({err:e},"Error cleaning up browser, continuing...")}finally{this.browser=null}}get closed(){return this.context.pages().every(e=>e.isClosed())||!!this.browser&&!this.browser.isConnected()}async ensureMomenticBrowserScriptsLoaded(e,t,r){let o=Date.now();for(;Date.now()-o<8e3;){r?.throwIfAborted();try{if(await kt({fn:()=>{let s=window;return!!(s.generateCssSelectors&&s.evaluateCssSelectors&&s.generateHtmlCacheAttributes&&s.ldist)},timeout:1e3,arg:void 0,waitForPageLoad:()=>this.waitForPageLoad(),root:e}))return}catch{}t.debug("Waiting for momentic browser scripts to load..."),await Z(500)}throw new Error(`Failed to load momentic browser scripts on page ${e.url()}`)}async html(){let e=await this.getActivePageOrFrame();return await this.ensureMomenticBrowserScriptsLoaded(e,this.logger),kt({root:e,fn:()=>{let t=window;if(!t?.getFullHtmlTree)throw new Error("Missing Momentic HTML library when fetching page HTML");return t.getFullHtmlTree()},arg:void 0,timeout:1e3,waitForPageLoad:()=>this.waitForPageLoad()})}url(){return this.page.url()}async screenshot(e){let{retries:t=1}=e;try{let r=await this.screenshotHelper({...e,retries:t});if(r.byteLength>5e6)this.logger.error("Page screenshot is greater than 5MB, which may cause performance issues with some AI models");else if(r.length===0)throw new Error("Got empty screenshot");return r}catch(r){if(t<=0)throw r;return this.logger.debug({pageUrl:this.page.url(),err:r},"Failed taking screenshot, retrying..."),await Z(250),this.screenshot({...e,retries:t-1})}}async screenshotHelper({locator:e,quality:t,scale:r="css",saveToDiskPath:o,hideCaret:i,timeout:s,respectActiveFrame:a,disableAnimations:l,clearHighlights:c=!1}){let u={fullPage:!1,type:"jpeg",quality:t,scale:r,caret:i?"hide":"initial",path:o,timeout:s??3e3,animations:l?"disabled":void 0};if(c){let y=await this.getActivePageOrFrame();await jl(y)}a&&this.activeFrame&&(e=await(await this.getActivePageOrFrame()).frameElement()),e&&(u.scale="css");let d;if(u.scale==="css"||this.properties.isNewHeadless)d=await this.page.screenshot(u);else{let y=await this.cdpClient.send({method:"Page.captureScreenshot",params:{format:"jpeg",quality:t,optimizeForSpeed:!0},reinitializer:()=>this.createRawCDPSession()});d=Buffer.from(y.data,"base64"),u.path&&zx(u.path,d)}if(!e)return d;let m=await e.boundingBox({timeout:1e3});if(!m)throw new Error("Attempted to screenshot an element that is not visible on the page");let{x:p,y:f,width:h,height:g}=m;if(!h||!g)throw new Error("Attempted to screenshot an element with zero width or height");if(p<0||f<0)throw new Error("Attempted to screenshot an element with negative coordinates");p=Math.floor(p),f=Math.floor(f),h=Math.ceil(h),g=Math.ceil(g);try{d=await(await Bx.fromBuffer(d)).crop({x:p,y:f,w:h,h:g}).getBuffer("image/jpeg")}catch(y){throw new Error(`Failed taking element screenshot at coordinates (${p}, ${f}) with size (${h}, ${g}): ${y}`)}return d}async getViewport(){return this.viewport}async navigate({url:e,initialNavigation:t=!1,loadTimeoutMs:r=this.pageLoadTimeout}){bm(e)&&(e=new URL(e,this.baseUrl).toString());let o=Date.now();this.logger.debug(`Navigating to ${e}`),t||(await this.waitForPageLoad(),await this.waitForDOMStability());let i=!1,s;for(let l=0;l<2;l++)try{await this.page.goto(e,{timeout:r,waitUntil:"domcontentloaded"}),i=!0;break}catch(c){if(this.abortSignal?.throwIfAborted(),s=c,s.message.includes("Timeout")&&s.message.includes("exceeded"))break}if(!i)throw new R("UserInfrastructureError",s?.message??"Failed to load page");await this.loadFrameAndRecordUrl(this.page,this.abortSignal),this.logger.debug({url:e},`Navigation complete in ${Math.floor(Date.now()-o)}ms`);let a=this.url();if(rh.has(a))throw new R("UserInfrastructureError",`${e} took too long to load \u{1F61E}. Please ensure the site is accessible and returns content within the page load timeout.`);if(t)try{await this.exposeRecordingBindings()}catch(l){l instanceof Error&&l.message.includes("already registered")||this.logger.error({err:l},"Failed to install Momentic libraries for action recording")}}async type(e,t={},r=!1){await this.directTypeHelper(e,t,r)}async getActiveElement(e){try{return await kt({root:e,fn:()=>document.activeElement?{tag:document.activeElement.tagName.toLowerCase(),contentEditable:document.activeElement.getAttribute("contenteditable")??void 0,textContent:document.activeElement.textContent??void 0}:void 0,arg:void 0,timeout:1e3,waitForPageLoad:()=>this.waitForPageLoad()})}catch(t){this.logger.warn({err:t},"Failed to get active element");return}}async directTypeHelper(e,t={},r=!1){let o=await this.getActivePageOrFrame();if(await Ih(o,e,t,this.logger))return;await this.page.waitForTimeout(25);let i=await this.getActiveElement(o);if(r){let s=Date.now();for(;Date.now()-s<this.smartWaitingTimeout&&(!i||i.tag==="body");)await Z(250),this.abortSignal?.throwIfAborted(),i=await this.getActiveElement(o);i||this.logger.warn("No active element found to type into, attempting anyways")}t.clearContent&&(i?.tag==="input"||i?.tag==="textarea"?(process.platform==="darwin"?await this.page.keyboard.press("Meta+A"):await this.page.keyboard.press("Control+A"),await this.page.keyboard.press("Backspace")):this.logger.warn({activeElementDetails:i},"Currently active element is not eligible for replace content, skipping...")),await this.page.keyboard.type(e,{delay:t.delay??0}),t.pressEnter&&await this.page.keyboard.press("Enter")}async scrollIntoView(e){await e.scrollIntoViewIfNeeded({timeout:2e3})}async highlight(e,t){try{let r=await this.resolveTarget(null,e,{skipFetchTree:!0,skipSaveToCache:!0,signal:t});return await this.highlightTarget(r.locator),!0}catch(r){return this.logger.debug({err:r,target:e},"Failed to highlight target"),!1}}async highlightTarget(e){return Cs(e,await this.getActivePageOrFrame(),this.logger)}recordUrlVisited(e){try{let t=new URL(e).origin;if(t==="null")return;this.originsVisited.add(t)}catch(t){this.logger.warn({err:t},"Failed to record origin visited")}}async waitForPageLoad(){if(!this.pageLoadPromise)return;let e=!1;await H((async()=>{for(;this.pageLoadPromise;){if(e)return;this.abortSignal?.throwIfAborted();try{await bn({promise:Promise.resolve(this.pageLoadPromise),signal:this.abortSignal,codePath:"waitForPageLoadInChromeBrowser",logger:this.logger})}catch(r){this.logger.warn({err:r},"Page load promise rejected, continuing...");return}}})(),{milliseconds:this.pageLoadTimeout,fallback:()=>{throw e=!0,new R("UserInfrastructureError",`Page load timed out after ${this.pageLoadTimeout}ms`)}})}async clearAuthState(e){await this.context.clearCookies();for(let o of this.originsVisited)this.logger.debug({origin:o},`Clearing data using CDP for origin ${o}`),await this.cdpClient.send({method:"Storage.clearDataForOrigin",params:{origin:o,storageTypes:"all"},reinitializer:()=>this.createRawCDPSession()}),this.originsVisited.delete(o);let t=this.context.pages().indexOf(this.page),r=[...this.context.pages()];for(let o=0;o<r.length;o++){let i=r[o];if(i.isClosed())continue;let s=i.url();try{this.originsVisited.delete(new URL(s).origin)}catch{}await Th(i,this.logger),o!==t&&e.closeNonActiveTabs&&(this.logger.debug(`Closing tab ${o} with URL ${s}`),await i.close())}}async loadAuthState(e){await this.waitForPageLoad(),await this.waitForDOMStability(),!e||Object.keys(e).length===0?await this.clearAuthState({closeNonActiveTabs:!1}):await this.loadAuthStateHelper(e),await this.refresh(),await this.waitForDOMStability()}async loadAuthStateHelper(e){let t=[];for(let i of e.cookies??[]){let s=await this.setCookie(i);t=t.concat(s)}this.logger.debug(`Loaded ${e.cookies?.length??0} cookies`),await this.cdpClient.send({method:"DOMStorage.enable",params:void 0,reinitializer:()=>this.createRawCDPSession()});let r=0;for(let i of e.origins??[])for(let s of i.localStorage)try{await this.cdpClient.send({method:"DOMStorage.setDOMStorageItem",params:{storageId:{securityOrigin:new URL(i.origin).origin,isLocalStorage:!0},key:s.name,value:s.value}}),r++}catch(a){this.logger.warn({err:a,origin:i},"Failed to set local storage entry");break}this.logger.debug(`Loaded ${r} local storage entries`);let o=e.idb;o&&Object.keys(o).length>0&&(await vh(this.page,o,this.logger),this.logger.debug(`Loaded ${Object.keys(o??{}).length} indexedDB databases`))}async saveAuthState(){await this.waitForPageLoad(),await this.waitForDOMStability();let e=await this.context.storageState();return e.idb=await bh(this.page,this.logger),e}async getOpenPages(e){return Ur(this.context,e)}saveA11yDetailsToCache(e,t){t.id=e.id,t.content=e.content,t.name=e.name,t.role=e.role,t.numChildren=e.children.length,t.serializedForm=e.getSerializedFormWithContext(),t.nodeOnlySerializedForm=e.getNodeOnlySerializedForm()}async saveNodeDetailsToCache({node:e,target:t,dataMomenticId:r,locator:o,logger:i=this.logger}){if(e&&this.saveA11yDetailsToCache(e,t),!(t.generatedSelectors&&t.generatedSelectors.length>1)){if(r&&(t.dataMomenticId=r),o)try{let s=await this.fetchHtmlAttributes(o,i);Object.assign(t,s)}catch(s){i.warn({err:s},"Failed to fetch HTML attributes for target")}else i.debug("No locator found for target, skipping HTML attribute generation");try{await this.saveElementVisualAttributes(t,o,i)}catch(s){i.debug({err:s},"Failed to save element visual details")}}}async saveElementVisualAttributes(e,t,r){if(!t)return;await t.scrollIntoViewIfNeeded({timeout:1e3});let o=await t.boundingBox({timeout:1e3});if(!o||!o.width||!o.height){r.debug("Skipping visual attributes saving for element with no bounding box after action"),e.boundingBox=void 0,e.screenshotUrl=void 0;return}e.boundingBox=o;let{x:i=0,y:s=0,width:a=0,height:l=0}=o;if(e.boundingBox&&Math.abs(e.boundingBox.width-a)<1&&Math.abs(e.boundingBox.height-l)<1&&Math.abs((e.boundingBox.x??0)-i)<1&&Math.abs((e.boundingBox.y??0)-s)<1||!Ll.includes(e?.role??""))return;let c=await this.screenshot({locator:t,retries:0});e.screenshotUrl=await this.storage.uploadScreenshot(c),r.debug({oldBox:e.boundingBox,newBox:o,url:e.screenshotUrl},"Updated element screenshot")}async resolveTargetUsingCssSelectors(e,t,r){if(!t.generatedSelectors||t.generatedSelectors.length<2||!t.nodeOnlySerializedHtml)throw new Error("Insufficient data to resolve target using CSS selectors");let o;try{o=await kt({fn:c=>window.evaluateCssSelectors(c),arg:{selectors:t.generatedSelectors,ldistThreshold:.075,serializedNodeWithText:t.nodeOnlySerializedHtml},root:e,timeout:2e3,waitForPageLoad:()=>this.waitForPageLoad()})}catch(c){throw new Error(`Failed to evaluate CSS selectors in browser: ${c}`)}let i=o.result;if(i)r.debug(o,"CSS selector evaluation returned an element");else throw new Error(`CSS selector evaluation returned no eligible elements:
2589
+ ${l}`,{errOptions:{cause:n}})}if(i.includes("element is not visible")){let l="The element you attempted to interact with has no bounding box or is explicitly hidden.";try{let c=await e.boundingBox({timeout:1e3});c?c.height===0?l="The element you attempted to interact with has zero height.":c.width===0&&(l="The element you attempted to interact with has zero width."):l="The element you attempted to interact with has no bounding box."}catch{}return new R("ActionFailureError",`${l} Please explicitly wait for the element to be visible or turn on the 'disable stability checks' option. ${s}`,{errOptions:{cause:n}})}return n}function vx(n){let e=n.message;if(e.includes("waiting for locator")&&e.includes("data-momentic-id")&&!e.match(/attempting \w+ action/))throw new R("ActionFailureError","The element you targeted was removed or replaced by a page load, animation, or JavaScript code during the interaction. Please wait for the page to be stable before this step.",{errOptions:{cause:n}});return n}async function Eh(n,e,t,r,o){try{await Tx(n,e,t,r)}catch(i){o.error({err:i,tabIndex:e},"Error handling new console log")}}async function Tx(n,e,t,r){let o=r.text();o.length>Wo&&(o=o.slice(0,Wo)+"...(TRUNCATED)");let i=[];for(let s of r.args())try{let a=await s.jsonValue(),l=JSON.stringify(a);l.length>Wo?i.push(l.slice(0,Wo)+"...(TRUNCATED)"):(typeof a!="object"||Object.keys(a).length>0)&&i.push(a)}catch{}$l(n,t,e,{url:n.url(),location:r.location(),type:r.type(),text:r.text(),args:i})}function $l(n,e,t,r){let o=Date.now(),i=e.logsPerPage;if(i.length<=t||i[t]===void 0){i[t]=[];for(let s=0;s<t;s++)i[s]===void 0&&(i[s]=[])}i[t].length>Nl&&(i[t]=i[t].slice(Math.floor(Nl/2)),i[t]?.push({url:n.url(),timestamp:o,type:"warning",text:"[MOMENTIC] Truncated console logs due to buffer overflow",tabIndex:t})),i[t].push({...r,tabIndex:t,timestamp:o})}async function In({fn:n,codePath:e,logObject:t,signal:r,logger:o}){r?.throwIfAborted();let i=Date.now(),s=await bn({promise:n(),signal:r,codePath:e,logger:o}),a=Date.now();return t[e]=a-i,s}async function Ch({locator:n,logger:e}){if(await n.evaluate(o=>o.tagName.toLowerCase(),void 0,{timeout:1e3})!=="input")return;let r=await n.boundingBox({timeout:1e3});if(r===null){e.warn({elementDisplayString:await _t(n,e)},"Attempting to click on element with no bounding box");return}if(!(r.width>5||r.height>5))try{let o=await n.evaluate(s=>{let a=window;if(!a.CssSelectorGenerator)return{type:"error",error:"[MOMENTIC] Missing CSS selector libraries"};let l=s.parentElement;if(!l)return{type:"error",error:"Input click target has no parent for redirection"};let c=a.CssSelectorGenerator.getCssSelector(l,{}),u=s.getBoundingClientRect(),d=l.getBoundingClientRect(),m={x:Math.min(Math.max(1,u.left-d.left),d.width-1),y:Math.min(Math.max(1,u.top-d.top),d.height-1)};return{type:"result",selector:c,relativePoint:m,serializedForm:l.outerHTML.slice(0,500)}},{timeout:1e3});if(o.type==="error")throw new Error(o.error);let i=n.page().locator(o.selector);return await i.waitFor({state:"attached",timeout:1e3}),e.info(o,`Redirected click to parent element with selector: ${o.selector}`),{locator:i,relativePoint:o.relativePoint}}catch(o){e.error({err:o},"Failed finding parent label for Chakra element");return}}var Rh=["date","datetime-local","month","time","week"],Ah={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 Ih(n,e,t,r){let o=(await n.evaluate(()=>document.activeElement?.getAttribute("type"))??"").toLowerCase();return Ah[o]&&(Ah[o].test(e)&&r.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,r.debug("Transforming datetime input to use sequential key presses")),!1}async function Cs(n,e,t){try{return await jl(e),await n.evaluate(r=>{let o=window;o.momenticIsEligible=c=>{let d=window.getComputedStyle(c,null).getPropertyValue("display");if(d==="none"||d==="contents")return!1;let m=c.getBoundingClientRect();return!(!m.height||!m.width)},o.removeHighlightTimers=o.removeHighlightTimers||[],o.removeHighlightFunctions=o.removeHighlightFunctions||{};let i=0;for(;!o.momenticIsEligible(r)&&i<3;){if(!r.parentElement)throw new Error("No eligible non-empty parent found for highlighting");r=r.parentElement,i++}let s=r.style.getPropertyValue("outline"),a=r.style.getPropertyPriority("outline");r.style.setProperty("outline","5px dashed rgb(255, 0, 153)","important");let l=`momentic${Math.floor(Math.random()*1e7)}`;o[l]=()=>{r.style.removeProperty("outline"),r.style.setProperty("outline",s,a),r.getAttribute("style")||r.removeAttribute("style")},o.removeHighlightTimers.push(setTimeout(()=>{o[l](),o.removeHighlightFunctions?.[l]&&delete o.removeHighlightFunctions[l]},5e3)),o.removeHighlightFunctions[l]=o[l]},void 0,{timeout:1e3}),!0}catch(r){return t.debug({err:r},"Failed to add node highlight, a page navigation likely occurred. This is non-fatal for tests."),!1}}async function jl(n){await n.evaluate(()=>{let e=window,t=e.removeHighlightTimers||[];for(;t.length;){let r=t.pop();clearTimeout(r)}Object.values(e.removeHighlightFunctions??{}).forEach(r=>{r()})},{timeout:1e3})}async function Hl(n){let e=n.featureFlags.isBooleanFlagEnabled("visual_actions");return Qn({action:"clicking element",targetingResult:n.targetingResult,logger:n.logger,retryTimeoutMs:n.retryTimeoutMs,callbacks:n.browserCallbacks,func:async t=>Oh({...n,targetingResult:t,useVisualClick:e})})}function Ax(n){return n.message.includes("locator.click: Timeout")&&n.message.includes("click action done")}async function Rx(n,e){let{logger:t,redirectionAttempts:r=0,browserCallbacks:o,disableRedirection:i}=e,s=e.targetingResult.locator,a=o.state.getDomGraph();if(!i&&a&&n.message.includes("intercepts pointer events")&&r<2){t.warn("Attempting locator redirection due to covering error");let l=await Ox(s,a,t);if(l)return Oh({...e,targetingResult:{...s,locator:l},redirectionAttempts:r+1})}throw n}async function Oh(n){let{options:e,logger:t,browserCallbacks:r,controllerCallbacks:o,disableRedirection:i,useVisualClick:s}=n,a=n.targetingResult.locator,l=n.position,c=await r.state.getRoot(),u=(await r.state.getOpenPages()).map(h=>h.url);if(!i){let h=await Ch({locator:a,logger:t});h&&(a=h.locator,l=h.relativePoint)}await Cs(a,c,t);let d=r.state.url(),m,p;e?.waitForDownload&&(m=(async()=>{try{return await a.page().waitForEvent("download",{timeout:1e4})}catch(h){h instanceof Cx.TimeoutError?p=new R("ActionFailureError",`Download did not complete in ${1e4}ms`):p=new R("ActionFailureError",`Download failed: ${h.message}`)}})());let f=null;try{f=await a.getAttribute("target",{timeout:1e3})}catch(h){t.warn({err:h},"Failed to get attributes of element about to be clicked, continuing...")}if(s)await Px({logger:t,targetingResult:n.targetingResult,position:l,options:e});else{let h=e?.force||n.targetingResult.hints?.force||!1;try{t.debug("Executing click"),e?.doubleClick?await a.dblclick({button:e.rightClick?"right":"left",timeout:3e3,position:l,force:h,delay:25}):await a.click({button:e?.rightClick?"right":"left",timeout:3e3,position:l,delay:25,force:h})}catch(g){let y=g;if(Ax(y))t.warn({err:y},"Click action timed out while waiting for navigation after completion, continuing...");else return Rx(y,{...n,targetingResult:{...a,locator:a}})}}if(f==="_blank"&&(t.debug("Waiting for new page promise due to _blank target"),await r.waitForPageLoad()),e?.waitForUrl&&await r.waitForUrl({beforeUrl:d,beforePages:u,waitForUrl:e.waitForUrl}),e?.waitForDownload){if(p)throw p;if(m){if(!o?.createIsolatedFolder)throw new R("InternalWebAgentError","Cannot wait for download without a callback to create an isolated folder");return t.info("Waiting for download to start and complete"),{downloadedFile:await H(Lx(m,o.createIsolatedFolder,t),{milliseconds:1e4,fallback:()=>{throw new R("ActionFailureError",`Download timed out after ${1e4}ms`)},signal:r.signal})}}else throw new Error("No download promise or error but the step requested to wait for a download")}}async function Ix(n,e){if(n.hints?.clickableXY)return e.debug({hints:n.hints},"Using click coordinates from hint"),n.hints.clickableXY;let t=await n.locator.boundingBox({timeout:1e3});if(!t)throw new R("ActionFailureError","Element does not have a bounding box");let r=t.x+t.width/2,o=t.y+t.height/2;return{x:r,y:o}}async function Px({logger:n,options:e,targetingResult:t,position:r}){let o,i;if(r){let c=await t.locator.boundingBox({timeout:1e3});o=c?.x??0+r.x,i=c?.y??0+r.y,n.debug({clickX:o,clickY:i},"Clicking using XY: determined click coordinates using predefined position")}else({x:o,y:i}=await Ix(t,n)),n.debug({clickX:o,clickY:i},"Clicking using XY: determined click coordinates with bounding box");let s=t.locator.page(),a=e?.rightClick?"right":"left",l=25;e?.doubleClick?await s.mouse.dblclick(o,i,{button:a,delay:l}):await s.mouse.click(o,i,{button:a,delay:l})}async function Ox(n,e,t){let r=await n.evaluate(a=>a.getAttribute("data-momentic-id"));if(!r)return;let o=xs(r,e,t);if(!o.length){t.error("No candidates found for parent-based locator redirection");return}let i=parseInt(o[0].attributes?.[it]??"");if(isNaN(i))return;n=n.page().locator(`[data-momentic-id="${i}"]`);let s=await _t(n,t);return t.warn({candidateMomenticId:i,serializedHtml:s},"Trying new locator based on parent-direction after covering error"),n}async function Lx(n,e,t){t.info("Download detected, saving file to disk");let r=await n,o=await r.path(),i=Bl(r.suggestedFilename()),s=e();await r.saveAs(Ex(s,i)),Ph(o,{force:!0}),setTimeout(()=>{Ph(s,{recursive:!0,force:!0})},5*60*1e3);let a=wh(xx(s),i);return t.debug({uri:a,downloadFolder:s},"Saved download to isolated folder"),a}async function Wl({frame:n,page:e,deltaX:t,directionX:r,deltaY:o,directionY:i,signal:s}){if(!t&&!o)return;let a=r==="left"?-1:1,l=i==="up"?-1:1;if(n)await n.evaluate(([c,u,d,m])=>window.scrollTo(window.scrollX+(c??window.innerWidth)*d,window.scrollY+(u??window.innerHeight)*m),[t,o,a,l]);else{let c=e.viewportSize()||Ot,u=await e.evaluate(()=>document.body.scrollHeight),[d,m,p]=await e.evaluate(()=>{let h=document.activeElement;if(!h)return[void 0,void 0,void 0];let g=h.getBoundingClientRect();return[h.scrollTop,g.x,g.y]});await e.mouse.wheel((t??c.width)*a,(o??c.height)*l);let f=Date.now();for(;Date.now()-f<2e3;){s?.throwIfAborted();let h=await e.evaluate(()=>document.body.scrollHeight),[g,y,v]=await e.evaluate(()=>{let x=document.activeElement;if(!x)return[void 0,void 0,void 0];let b=x.getBoundingClientRect();return[x.scrollTop,b.x,b.y]});if(h===u&&g===d&&y===m&&v===p)break;u=h,d=g,m=y,p=v,await Z(500)}}}async function Ur(n,e){let t,r;for(let o=0;o<4;o++)try{return t=n.pages(),await Promise.all(t.map(async i=>({title:e?.getTitles?await i.title():"",url:i.url()})))}catch(i){r=i,await Z(500)}throw new Error(`Failed to get tab titles after all retries: ${r?.message}`)}async function Vl({context:n,page:e,logger:t,timeoutMs:r=8e3,retries:o=2}){try{let i=await H(n.newCDPSession(e),{milliseconds:r,fallback:()=>{throw new R("UserInfrastructureError",`Failed to initialize Chrome session within the page load timeout (${e.url()})`)}});return await Gl.init(i,t)}catch(i){if(o>0)return t.debug({err:i},"Failed to initialize CDP session, re-creating CDP client"),await Z(500),Vl({context:n,page:e,logger:t,timeoutMs:r,retries:o-1});throw i}}var Gl=class n{constructor(e,t){this.session=e;this.logger=t}cdpInitializingPromise=void 0;cdpCrashDetails=void 0;cdpFullyDead=!1;static async init(e,t){let r=new n(e,t);try{await H(r.registerHandlers(e),{milliseconds:8e3,message:`CDP handler registration timed out after ${8e3}ms`})}catch(o){throw r.cdpFullyDead=!0,new R("UserInfrastructureError",`Failed to initialize CDP client: ${o}`)}return r}async registerHandlers(e){e.on("Target.attachedToTarget",async()=>{try{await e.send("Runtime.runIfWaitingForDebugger")}catch(t){this.logger.debug({err:t},"Failed to run Runtime.runIfWaitingForDebugger")}}),e.on("Target.targetCrashed",t=>{this.cdpCrashDetails={...this.cdpCrashDetails??{},targetCrashDetails:`${t}`},this.logger.error({payload:t},"CDP session crashed, Momentic will likely not function correctly")}),e.on("Inspector.targetCrashed",t=>{this.cdpCrashDetails={...this.cdpCrashDetails??{},inspectorCrashDetails:`${t}`},this.logger.error({payload:t},"CDP inspector session crashed, Momentic will likely not function correctly")}),await e.send("Accessibility.enable"),await e.send("DOM.enable"),await e.send("Overlay.enable")}async send({method:e,params:t,timeout:r,reinitializer:o}){if(await this.cdpInitializingPromise,this.cdpCrashDetails){if(this.cdpFullyDead||!o)throw new R("UserInfrastructureError",`The browser inspector session encountered a critical crash: ${JSON.stringify(this.cdpCrashDetails)}`);this.logger.warn(`Detected crashed CDP client before method ${e}, reinitializing before proceeding...`),await this.reinitialize(o)}try{return await H(this.session.send(e,t),{milliseconds:r??8e3,message:`Chrome command ${e} timed out after ${r??8e3}ms. This is likely an infrastructure issue caused by a lack of compute resources or a crash at the browser level.`})}catch(i){throw o&&["Internal error","Target crashed"].some(s=>i.message.includes(s))&&!this.cdpInitializingPromise&&(this.logger.warn({err:i},`CDP crashed during CDP method ${e}, re-initializing client`),await this.reinitialize(o)),i}}async reinitialize(e){await this.cdpInitializingPromise;let t=async()=>{let r=this.session;this.session=await e(),await this.registerHandlers(this.session);try{await H(r.detach(),{milliseconds:1e3})}catch(o){this.logger.warn({err:o},"Failed to detach old CDP session after reinitialization, continuing...")}};this.cdpInitializingPromise=(async()=>{try{await H(t(),{milliseconds:8e3,message:`CDP reinitialization timed out after ${8e3}ms`}),this.cdpCrashDetails=void 0,this.cdpFullyDead=!1}catch(r){this.cdpCrashDetails={...this.cdpCrashDetails??{},reinitializeError:`${r}`},this.cdpFullyDead=!0}finally{this.cdpInitializingPromise=void 0}})(),await this.cdpInitializingPromise}on(e,t){return this.session.on(e,t),this.session}off(e,t){return this.session.off(e,t),this.session}addListener(e,t){return this.session.addListener(e,t),this.session}removeListener(e,t){return this.session.removeListener(e,t),this.session}};var ql=Vo(kh(),"momentic","chromium"),Jx=Vo(kh(),"video"),zr=process.env.TWO_CAPTCHA_KEY,Kl=qx(Dh);Kl.use(Kx({provider:{id:"2captcha",token:zr},visualFeedback:!0}));var Jt=class n{static USER_AGENT=Vx["Desktop Chrome"].userAgent;abortSignal=void 0;contextInitialized=!1;browser;context;properties;page;userControlledBrowserSettings;pageLoadPromise=null;lastTabChangeEventTimeout=void 0;mockedServices;a11yIdToNodeMap={};dataMomenticIdToNodeMap={};selectorToNodeMap={};mostRecentA11yTreeRoot;domGraph=void 0;cdpClient;debugData={logsPerPage:[],harPages:{},harEntries:{}};enricher;storage;featureFlagStore;logger;activeFrame;activeFrameCache;transformer;baseUrl;originsVisited=new Set;viewport;onTabsChange=void 0;videos=[];constructor({storage:e,featureFlagStore:t,enricher:r,browser:o,context:i,page:s,baseUrl:a,logger:l,cdpClient:c,mockedServices:u,userBrowserSettings:d,viewport:m,onTabsChange:p,properties:f}){if(Pp(d),this.mockedServices=u,this.storage=e,this.featureFlagStore=t,this.enricher=r,this.browser=o,this.context=i,this.cdpClient=c,this.page=s,this.baseUrl=a,this.logger=l,this.userControlledBrowserSettings=d,this.viewport=m||Ot,this.onTabsChange=p,this.properties=f,f.recordVideo){let h=this.page.video();h&&this.videos.push(h)}}async registerAbortSignal(e){this.abortSignal=e}async initializeContext(){if(this.contextInitialized)return;this.userControlledBrowserSettings.extraHeaders&&await this.context.setExtraHTTPHeaders(this.userControlledBrowserSettings.extraHeaders),await this.context.grantPermissions(["clipboard-read","clipboard-write","microphone","camera"]);let e=this.featureFlagStore.getAllFlags(),t=[this.context.addInitScript({content:El.cssGeneratorLibJs}),this.context.addInitScript({content:El.htmlUtilsLibJs}),this.context.addInitScript({content:`window._MOMENTIC_BROWSER = true; window._MOMENTIC_FEATURE_FLAGS = ${JSON.stringify(e)};`})],r=Promise.all(Object.entries(this.mockedServices).map(([s,a])=>this.context.route(s,l=>a.handle(l)))),o=s=>this.handleNewPageEvent(s);this.context.on("page",o),this.handleNewPageEventHelper(this.page),this.context.on("close",()=>{this.logger.debug("Chrome browser context was closed"),this.context.off("page",o)});let i=Promise.all(t);await Promise.all([i,r]),this.contextInitialized=!0}static async init({baseUrl:e,logger:t,storage:r,featureFlagStore:o,enricher:i,mockedServices:s,userBrowserSettings:a,contextArgs:l,timeout:c,browserbaseConnectUrl:u,onTabsChange:d,recordVideo:m}){process.env.PW_TEST_SCREENSHOT_NO_FONTS_READY="1";let p={headless:!0,handleSIGTERM:!1,chromiumSandbox:!1,channel:a.browserType==="Google Chrome"?"chrome":void 0},f={viewport:Ot,userAgent:a.userAgent??n.USER_AGENT,geolocation:{latitude:37.7749,longitude:-122.4194},locale:"en-US",timezoneId:"America/Los_Angeles",httpCredentials:a.basicAuthorization?{username:a.basicAuthorization.username??"",password:a.basicAuthorization.password??""}:void 0,...l??{}},h=["--disable-dev-shm-usage","--no-first-run","--renderer-process-limit=2","--disable-site-isolation-for-policy","--disable-site-isolation-trials","--autoplay-policy=user-gesture-required","--disable-add-to-shelf","--disable-desktop-notifications","--use-fake-device-for-media-stream","--use-fake-ui-for-media-stream","--ignore-gpu-blocklist","--use-gl=angle","--use-angle=gl-egl"],g=!1;if(a.localChromeExtensionPaths?.length){g=!0;for(let I of a.localChromeExtensionPaths){let O=Vo(I,"manifest.json");if(!Rs(O))throw new R("UserConfigurationError",`Chrome extension path ${O} does not exist.`)}}let y=null,v,x,b={systemDevicePixelRatio:l?.deviceScaleFactor,recordVideo:m};if(g){let I=Vo(ql,`momentic-session-${Date.now()}`);if(!Rs(I))try{Fx(I,{recursive:!0})}catch(L){throw new R("UserConfigurationError",`Failed to create browser cache directory. Please make sure you have sufficient permissions to create the ${ql} folder: ${L}`)}let O=[...h];if(a.localChromeExtensionPaths){let L=a.localChromeExtensionPaths.map(U=>Gx(U)).join(",");O.push(`--disable-extensions-except=${L}`,"--headless=new"),b.isNewHeadless=!0}f?.deviceScaleFactor&&O.push(`--force-device-scale-factor=${f.deviceScaleFactor}`,`--device-scale-factor=${f.deviceScaleFactor}`),f.viewport&&O.push(`--window-size=${f.viewport.width},${f.viewport.height}`),v=await Dh.launchPersistentContext(Vo(ql,`momentic-session-${Date.now()}`),{...p,...f,ignoreDefaultArgs:["--disable-extensions","--disable-component-extensions-with-background-pages"],args:O,baseURL:e}),t.debug({sharedContextOptions:f,sharedBrowserOptions:p,chromeArgs:O},"Browser initialization context args (persistent)"),x=v.pages()[0]}else if(u){y=await Kl.connectOverCDP(u);let I=y.contexts()[0];if(!I)throw new Error("Failed to get browserbase default context");let O=I.pages()[0];if(!O)throw new Error("Failed to get browserbase default page");v=I,x=O}else{y=await Kl.launch({...p,args:h});let I={...f,baseURL:e,recordVideo:m?{dir:Jx}:void 0};v=await y.newContext(I),t.debug({contextArgs:I,sharedBrowserOptions:p,chromeArgs:h},"Browser initialization context args (standard)"),x=await v.newPage()}let S=await Vl({context:v,page:x,logger:t,timeoutMs:c}),C=new n({browser:y,context:v,page:x,baseUrl:e,logger:t,storage:r,featureFlagStore:o,mockedServices:s||{},enricher:i,userBrowserSettings:a,cdpClient:S,viewport:f.viewport||Ot,onTabsChange:d,properties:b});return await C.initializeContext(),C}async handleAvailableTabsChangeHelper(){try{let e=await Ur(this.context,{getTitles:!0}),t=this.page.url();this.onTabsChange?.(e,t)}catch(e){this.logger.error({err:e},"Error sending available tabs to frontend")}}handleAvailableTabsChange(){try{clearTimeout(this.lastTabChangeEventTimeout),this.lastTabChangeEventTimeout=setTimeout(()=>this.handleAvailableTabsChangeHelper(),500)}catch(e){this.logger.warn({err:e},"Error handling available tabs change")}}handlePageClosedEvent(e){let t=async()=>{try{if(this.page!==e){this.logger.info({url:e.url()},"Detected background page was closed"),this.handleAvailableTabsChange();return}this.logger.info({url:e.url()},"Detected active page was closed, switching to another tab");let r=this.context.pages();for(let o=r.length-1;o>=0;o--){let i=r[o];if(!(!i||i.isClosed()||!xn(i.url()))){this.logger.info(`Automatically switching to tab ${o} after close: ${i.url()}`),await this.switchToPage({type:"INDEX",index:o});break}}}catch(r){this.logger.warn({err:r},"Error in page close event handler")}finally{this.pageLoadPromise=null}};this.pageLoadPromise=t()}handleNewPageEvent(e){let t=e.url();if(this.logger.info({url:t},"Detected new page event, registering handlers and waiting for load to complete"),this.properties.recordVideo){let r=e.video();r&&this.videos.push(r)}try{this.handleNewPageEventHelper(e)}catch(r){this.logger.warn({err:r},"Error handling new page open, continuing....")}}handleNewPageEventHelper(e){let t=Dx(),r=fh(t,this.debugData,e);e.on("close",s=>this.handlePageClosedEvent(s)),e.on("framenavigated",s=>{s===e.mainFrame()&&this.handleFrameNavigationEvent(s)});let o=this.context.pages().indexOf(e);e.on("console",s=>{Eh(e,o,this.debugData,s,this.logger)}),e.on("request",s=>{gh(t,this.debugData,s,this.logger)});let i=this.pageLoadPromise;this.pageLoadPromise=(async()=>{try{await i,await r,await this.loadFrameAndRecordUrl(e),this.handleAvailableTabsChange()}catch(s){this.logger.error({err:s},"Failed to wait for new page to load")}finally{this.pageLoadPromise=null}})()}handleFrameNavigationEvent(e){let t=e.url();if(!t||t==="about:blank"||!xn(t))return;this.logger.debug({url:t},"Detected frame navigation event, adding to page load promise");let r=this.pageLoadPromise;this.pageLoadPromise=(async()=>{try{await Promise.resolve(r),await this.loadFrameAndRecordUrl(e),this.handleAvailableTabsChange()}catch(o){this.logger.error({err:o},"Failed to wait for frame navigation to finish")}finally{this.pageLoadPromise=null}})()}getBrowserCallbacks(){return{waitForPageLoad:()=>this.waitForPageLoad(),waitForUrl:e=>this.waitForUrl(e),addMomenticIds:e=>this.addMomenticIds(e),getBrowserState:e=>this.getBrowserState(e),state:{url:()=>this.url(),getDomGraph:()=>this.domGraph,getOpenPages:()=>this.getOpenPages(),getRoot:()=>this.getActivePageOrFrame()},pageLoadTimeoutMs:this.pageLoadTimeout,signal:this.abortSignal}}async getLocatorFromCdpFrame(e,t){let r=this.page;for(let l of t)r=r.frameLocator(`iframe[${l}]`);let o;for(let l of["src","name","id","title"])if(this.getAttributeFromStringArray(e.attributes??[],l)){o=l;break}if(!o)throw new Error(`Failed to find a unique attribute to identify frame with url matching '${e.contentDocument?.documentURL}'. Please attach a unique 'id', 'name', 'title', or 'src' attribute to the frame.`);let i=this.getAttributeFromStringArray(e.attributes??[],o),s=r.locator(`iframe[${o}=${JSON.stringify(i)}]`),a=await(await s.evaluateHandle(l=>l,{timeout:1e3})).asElement().contentFrame();if(!a)throw new Error(`Got null frame from locator: ${s}`);return await this.loadFrameAndRecordUrl(a,this.abortSignal),a}async getMatchingFrameWithCdp(e){if(e.type!=="url")throw new Error("Only url frame identifiers are supported at the moment");let t=e.url,o=[{node:(await this.cdpClient.send({method:"DOM.getDocument",params:{pierce:!0,depth:-1},reinitializer:()=>this.createRawCDPSession()})).root,selectorChain:[]}],i=[];for(;o.length>0;){let s=o.pop(),a=s.node,l=s.selectorChain;if(a.nodeName.toLowerCase()==="iframe"){let c=this.getAttributeFromStringArray(a.attributes??[],"src")||a.contentDocument?.documentURL;if(!c)continue;t.startsWith("/")&&t.endsWith("/")?new RegExp(t.slice(1,-1)).test(c)&&(this.logger.debug({frameUrl:c},"Found frame with src matching regex"),i.push({node:a,frame:await this.getLocatorFromCdpFrame(a,l)})):t.trim()===c.trim()&&(this.logger.debug({frameUrl:c},"Found frame with exact URL match"),i.push({node:a,frame:await this.getLocatorFromCdpFrame(a,l)}));let u=!1;for(let d of["src","name","id","title"]){let m=this.getAttributeFromStringArray(a.attributes??[],d);if(m){l=[...l,`${d}=${JSON.stringify(m)}`],u=!0;break}}if(!u){this.logger.debug({attrs:a.attributes},"Could not find a unique attribute to identify possible intermediate frame, skipping...");continue}}for(let c of a.children??[])o.push({node:c,selectorChain:l});a.contentDocument&&o.push({node:a.contentDocument,selectorChain:l})}if(i.length===1)return i[0];throw i.length>1?new Error(`Found multiple frames with src matching '${t}'. Please use a more specific selector.`):new Error(`Failed to find frame with src matching: ${t}`)}async resolveActiveFrame(){if(!this.activeFrame)throw new Error("No active frame set but attempting to get active frame");if(this.activeFrame.type==="url")return this.getMatchingFrameWithCdp(this.activeFrame);throw new Error(`Frame identifier type ${this.activeFrame.type} is not yet supported`)}ping(){if(this.closed)throw new Error("Page has been closed")}setActiveFrame(e){e?(this.activeFrame=e,this.activeFrameCache=void 0):(this.activeFrame=void 0,this.activeFrameCache=void 0)}async reset(e){for(this.abortSignal=void 0,this.debugData.logsPerPage=[],this.debugData.harPages={},this.debugData.harEntries={},this.a11yIdToNodeMap={},this.dataMomenticIdToNodeMap={},this.selectorToNodeMap={},this.pageLoadPromise=null,this.activeFrame=void 0,this.activeFrameCache=void 0;this.videos.length>0;)this.videos.pop();await this.clearAuthState({closeNonActiveTabs:!0}),await this.reinitializeCDPClient(),await this.navigate({url:e.newUrl??this.baseUrl,initialNavigation:!0,loadTimeoutMs:e.timeout})}async cleanup(){this.abortSignal=void 0;try{this.originsVisited.clear(),await this.context.close(),await this.browser?.close(),this.browser=null}catch(e){this.logger.warn({err:e},"Error cleaning up browser, continuing...")}finally{this.browser=null}}get closed(){return this.context.pages().every(e=>e.isClosed())||!!this.browser&&!this.browser.isConnected()}async ensureMomenticBrowserScriptsLoaded(e,t,r){let o=Date.now();for(;Date.now()-o<8e3;){r?.throwIfAborted();try{if(await kt({fn:()=>{let s=window;return!!(s.generateCssSelectors&&s.evaluateCssSelectors&&s.generateHtmlCacheAttributes&&s.ldist)},timeout:1e3,arg:void 0,waitForPageLoad:()=>this.waitForPageLoad(),root:e}))return}catch{}t.debug("Waiting for momentic browser scripts to load..."),await Z(500)}throw new Error(`Failed to load momentic browser scripts on page ${e.url()}`)}async html(){let e=await this.getActivePageOrFrame();return await this.ensureMomenticBrowserScriptsLoaded(e,this.logger),kt({root:e,fn:()=>{let t=window;if(!t?.getFullHtmlTree)throw new Error("Missing Momentic HTML library when fetching page HTML");return t.getFullHtmlTree()},arg:void 0,timeout:1e3,waitForPageLoad:()=>this.waitForPageLoad()})}url(){return this.page.url()}async screenshot(e){let{retries:t=1}=e;try{let r=await this.screenshotHelper({...e,retries:t});if(r.byteLength>5e6)this.logger.error("Page screenshot is greater than 5MB, which may cause performance issues with some AI models");else if(r.length===0)throw new Error("Got empty screenshot");return r}catch(r){if(t<=0)throw r;return this.logger.debug({pageUrl:this.page.url(),err:r},"Failed taking screenshot, retrying..."),await Z(250),this.screenshot({...e,retries:t-1})}}async screenshotHelper({locator:e,quality:t,scale:r="css",saveToDiskPath:o,hideCaret:i,timeout:s,respectActiveFrame:a,disableAnimations:l,clearHighlights:c=!1}){let u={fullPage:!1,type:"jpeg",quality:t,scale:r,caret:i?"hide":"initial",path:o,timeout:s??3e3,animations:l?"disabled":void 0};if(c){let y=await this.getActivePageOrFrame();await jl(y)}a&&this.activeFrame&&(e=await(await this.getActivePageOrFrame()).frameElement()),e&&(u.scale="css");let d;if(u.scale==="css"||this.properties.isNewHeadless)d=await this.page.screenshot(u);else{let y=await this.cdpClient.send({method:"Page.captureScreenshot",params:{format:"jpeg",quality:t,optimizeForSpeed:!0},reinitializer:()=>this.createRawCDPSession()});d=Buffer.from(y.data,"base64"),u.path&&zx(u.path,d)}if(!e)return d;let m=await e.boundingBox({timeout:1e3});if(!m)throw new Error("Attempted to screenshot an element that is not visible on the page");let{x:p,y:f,width:h,height:g}=m;if(!h||!g)throw new Error("Attempted to screenshot an element with zero width or height");if(p<0||f<0)throw new Error("Attempted to screenshot an element with negative coordinates");p=Math.floor(p),f=Math.floor(f),h=Math.ceil(h),g=Math.ceil(g);try{d=await(await Bx.fromBuffer(d)).crop({x:p,y:f,w:h,h:g}).getBuffer("image/jpeg")}catch(y){throw new Error(`Failed taking element screenshot at coordinates (${p}, ${f}) with size (${h}, ${g}): ${y}`)}return d}async getViewport(){return this.viewport}async navigate({url:e,initialNavigation:t=!1,loadTimeoutMs:r=this.pageLoadTimeout}){bm(e)&&(e=new URL(e,this.baseUrl).toString());let o=Date.now();this.logger.debug(`Navigating to ${e}`),t||(await this.waitForPageLoad(),await this.waitForDOMStability());let i=!1,s;for(let l=0;l<2;l++)try{await this.page.goto(e,{timeout:r,waitUntil:"domcontentloaded"}),i=!0;break}catch(c){if(this.abortSignal?.throwIfAborted(),s=c,s.message.includes("Timeout")&&s.message.includes("exceeded"))break}if(!i)throw new R("UserInfrastructureError",s?.message??"Failed to load page");await this.loadFrameAndRecordUrl(this.page,this.abortSignal),this.logger.debug({url:e},`Navigation complete in ${Math.floor(Date.now()-o)}ms`);let a=this.url();if(rh.has(a),t)try{await this.exposeRecordingBindings()}catch(l){l instanceof Error&&l.message.includes("already registered")||this.logger.error({err:l},"Failed to install Momentic libraries for action recording")}}async type(e,t={},r=!1){await this.directTypeHelper(e,t,r)}async getActiveElement(e){try{return await kt({root:e,fn:()=>document.activeElement?{tag:document.activeElement.tagName.toLowerCase(),contentEditable:document.activeElement.getAttribute("contenteditable")??void 0,textContent:document.activeElement.textContent??void 0}:void 0,arg:void 0,timeout:1e3,waitForPageLoad:()=>this.waitForPageLoad()})}catch(t){this.logger.warn({err:t},"Failed to get active element");return}}async directTypeHelper(e,t={},r=!1){let o=await this.getActivePageOrFrame();if(await Ih(o,e,t,this.logger))return;await this.page.waitForTimeout(25);let i=await this.getActiveElement(o);if(r){let s=Date.now();for(;Date.now()-s<this.smartWaitingTimeout&&(!i||i.tag==="body");)await Z(250),this.abortSignal?.throwIfAborted(),i=await this.getActiveElement(o);i||this.logger.warn("No active element found to type into, attempting anyways")}t.clearContent&&(i?.tag==="input"||i?.tag==="textarea"?(process.platform==="darwin"?await this.page.keyboard.press("Meta+A"):await this.page.keyboard.press("Control+A"),await this.page.keyboard.press("Backspace")):this.logger.warn({activeElementDetails:i},"Currently active element is not eligible for replace content, skipping...")),await this.page.keyboard.type(e,{delay:t.delay??0}),t.pressEnter&&await this.page.keyboard.press("Enter")}async scrollIntoView(e){await e.scrollIntoViewIfNeeded({timeout:2e3})}async highlight(e,t){try{let r=await this.resolveTarget(null,e,{skipFetchTree:!0,skipSaveToCache:!0,signal:t});return await this.highlightTarget(r.locator),!0}catch(r){return this.logger.debug({err:r,target:e},"Failed to highlight target"),!1}}async highlightTarget(e){return Cs(e,await this.getActivePageOrFrame(),this.logger)}recordUrlVisited(e){try{let t=new URL(e).origin;if(t==="null")return;this.originsVisited.add(t)}catch(t){this.logger.warn({err:t},"Failed to record origin visited")}}async waitForPageLoad(){if(!this.pageLoadPromise)return;let e=!1;await H((async()=>{for(;this.pageLoadPromise;){if(e)return;this.abortSignal?.throwIfAborted();try{await bn({promise:Promise.resolve(this.pageLoadPromise),signal:this.abortSignal,codePath:"waitForPageLoadInChromeBrowser",logger:this.logger})}catch(r){this.logger.warn({err:r},"Page load promise rejected, continuing...");return}}})(),{milliseconds:this.pageLoadTimeout,fallback:()=>{throw e=!0,new R("UserInfrastructureError",`Page load timed out after ${this.pageLoadTimeout}ms`)}})}async clearAuthState(e){await this.context.clearCookies();for(let o of this.originsVisited)this.logger.debug({origin:o},`Clearing data using CDP for origin ${o}`),await this.cdpClient.send({method:"Storage.clearDataForOrigin",params:{origin:o,storageTypes:"all"},reinitializer:()=>this.createRawCDPSession()}),this.originsVisited.delete(o);let t=this.context.pages().indexOf(this.page),r=[...this.context.pages()];for(let o=0;o<r.length;o++){let i=r[o];if(i.isClosed())continue;let s=i.url();try{this.originsVisited.delete(new URL(s).origin)}catch{}await Th(i,this.logger),o!==t&&e.closeNonActiveTabs&&(this.logger.debug(`Closing tab ${o} with URL ${s}`),await i.close())}}async loadAuthState(e){await this.waitForPageLoad(),await this.waitForDOMStability(),!e||Object.keys(e).length===0?await this.clearAuthState({closeNonActiveTabs:!1}):await this.loadAuthStateHelper(e),await this.refresh(),await this.waitForDOMStability()}async loadAuthStateHelper(e){let t=[];for(let i of e.cookies??[]){let s=await this.setCookie(i);t=t.concat(s)}this.logger.debug(`Loaded ${e.cookies?.length??0} cookies`),await this.cdpClient.send({method:"DOMStorage.enable",params:void 0,reinitializer:()=>this.createRawCDPSession()});let r=0;for(let i of e.origins??[])for(let s of i.localStorage)try{await this.cdpClient.send({method:"DOMStorage.setDOMStorageItem",params:{storageId:{securityOrigin:new URL(i.origin).origin,isLocalStorage:!0},key:s.name,value:s.value}}),r++}catch(a){this.logger.warn({err:a,origin:i},"Failed to set local storage entry");break}this.logger.debug(`Loaded ${r} local storage entries`);let o=e.idb;o&&Object.keys(o).length>0&&(await vh(this.page,o,this.logger),this.logger.debug(`Loaded ${Object.keys(o??{}).length} indexedDB databases`))}async saveAuthState(){await this.waitForPageLoad(),await this.waitForDOMStability();let e=await this.context.storageState();return e.idb=await bh(this.page,this.logger),e}async getOpenPages(e){return Ur(this.context,e)}saveA11yDetailsToCache(e,t){t.id=e.id,t.content=e.content,t.name=e.name,t.role=e.role,t.numChildren=e.children.length,t.serializedForm=e.getSerializedFormWithContext(),t.nodeOnlySerializedForm=e.getNodeOnlySerializedForm()}async saveNodeDetailsToCache({node:e,target:t,dataMomenticId:r,locator:o,logger:i=this.logger}){if(e&&this.saveA11yDetailsToCache(e,t),!(t.generatedSelectors&&t.generatedSelectors.length>1)){if(r&&(t.dataMomenticId=r),o)try{let s=await this.fetchHtmlAttributes(o,i);Object.assign(t,s)}catch(s){i.warn({err:s},"Failed to fetch HTML attributes for target")}else i.debug("No locator found for target, skipping HTML attribute generation");try{await this.saveElementVisualAttributes(t,o,i)}catch(s){i.debug({err:s},"Failed to save element visual details")}}}async saveElementVisualAttributes(e,t,r){if(!t)return;await t.scrollIntoViewIfNeeded({timeout:1e3});let o=await t.boundingBox({timeout:1e3});if(!o||!o.width||!o.height){r.debug("Skipping visual attributes saving for element with no bounding box after action"),e.boundingBox=void 0,e.screenshotUrl=void 0;return}e.boundingBox=o;let{x:i=0,y:s=0,width:a=0,height:l=0}=o;if(e.boundingBox&&Math.abs(e.boundingBox.width-a)<1&&Math.abs(e.boundingBox.height-l)<1&&Math.abs((e.boundingBox.x??0)-i)<1&&Math.abs((e.boundingBox.y??0)-s)<1||!Ll.includes(e?.role??""))return;let c=await this.screenshot({locator:t,retries:0});e.screenshotUrl=await this.storage.uploadScreenshot(c),r.debug({oldBox:e.boundingBox,newBox:o,url:e.screenshotUrl},"Updated element screenshot")}async resolveTargetUsingCssSelectors(e,t,r){if(!t.generatedSelectors||t.generatedSelectors.length<2||!t.nodeOnlySerializedHtml)throw new Error("Insufficient data to resolve target using CSS selectors");let o;try{o=await kt({fn:c=>window.evaluateCssSelectors(c),arg:{selectors:t.generatedSelectors,ldistThreshold:.075,serializedNodeWithText:t.nodeOnlySerializedHtml},root:e,timeout:2e3,waitForPageLoad:()=>this.waitForPageLoad()})}catch(c){throw new Error(`Failed to evaluate CSS selectors in browser: ${c}`)}let i=o.result;if(i)r.debug(o,"CSS selector evaluation returned an element");else throw new Error(`CSS selector evaluation returned no eligible elements:
2590
2590
  ${o.logs.join(`
2591
2591
  `)}`);let s,a,l;if(this.featureFlagStore.isBooleanFlagEnabled("visual_actions")){let c=i.mPath.join(" > ");s=e.locator(c),a=this.selectorToNodeMap[c]}else l=parseInt(i.dataMomenticId),a=this.dataMomenticIdToNodeMap[l],s=e.locator(i.workingSelectors[0]);return t.generatedSelectors=void 0,await this.saveNodeDetailsToCache({root:e,node:a,target:t,dataMomenticId:l,locator:s,logger:r}),t.generatedSelectors=Array.from(new Set([...i.workingSelectors??[],...t.generatedSelectors??[]])),{a11yNode:a,displayString:i.serializedElement,locator:s,decisions:[{type:"CSS_SELECTOR",matched:!0,reason:`${i.workingSelectors.length} CSS selectors matched the following element: ${i.serializedElement}`,selectors:i.workingSelectors.slice(0,5)}]}}async resolveTarget(e,t,r={}){let{skipFetchTree:o=!1,targetName:i,logger:s=this.logger,signal:a=this.abortSignal,skipSaveToCache:l}=r;s.debug({target:t,skipFetchTree:o},"Resolve target called");let c=await this.getActivePageOrFrame();if(await this.ensureMomenticBrowserScriptsLoaded(c,s,a),t.id>0&&!Mi(t)){let p=this.a11yIdToNodeMap[t.id];if(!p)throw new R("InternalWebAgentError",`Resolving target failed because id ${t.id} does not exist on the page. This generally indicates an incorrect element was targeted.`);let f=await this.getLocatorFromA11yNode(c,p);return l||await this.saveNodeDetailsToCache({root:c,node:p,target:t,dataMomenticId:p.dataMomenticId,locator:f,logger:s}),{locator:f,a11yNode:p,displayString:p.getNodeOnlySerializedForm(),decisions:[]}}let u=Date.now(),d=0,m;for(;d<1||Date.now()-u<this.smartWaitingTimeout;){this.abortSignal?.throwIfAborted(),d++;let p=Date.now()-u>this.smartWaitingTimeout-2e3;try{m=await this.resolveTargetHelper({root:c,target:t,cssSelectorOnly:!0,skipFetchTreeWait:!0,skipFetchTree:o,logger:s,signal:a});break}catch(f){p&&s.debug({err:f},`Could not resolve target through CSS selectors only (x${d})`),await Z(500,this.abortSignal)}}return m||(s.debug("Waiting for page stability and retrying all target matching methods"),m=await this.resolveTargetHelper({root:c,target:t,cssSelectorOnly:!1,skipFetchTreeWait:!1,skipFetchTree:o,logger:s,signal:a}),t.targetSource="HEURISTIC_HEALED",t.targetUpdateTime=new Date().toISOString(),s.debug({decisions:m.decisions},"Target resolution succeeded after waiting")),e?.details?.push({type:"TARGETING",name:i,elementLocationDecisions:m.decisions,pageState:m.pageState,targetSource:t.targetSource,targetUpdateTime:t.targetUpdateTime}),m}async resolveTargetHelper({root:e,target:t,cssSelectorOnly:r,skipFetchTree:o,skipFetchTreeWait:i,logger:s,signal:a,skipSaveToCache:l}){let c=[];if(t.id<0&&t.selector){let f=e.locator(t.selector),h;try{h=await _t(f,s)??""}catch(g){throw new yn(`'${t.selector}' failed to resolve: ${g}`,[{type:"USER_SELECTOR",matched:!1}])}return c.push({type:"USER_SELECTOR",matched:!0,reason:`The user-provided CSS selector ${t.selector} matched an element on the page.`}),{locator:f,a11yNode:void 0,pageState:void 0,displayString:h,decisions:c}}let u;o||(u=(await this.getBrowserState({skipWait:i,logger:s,abortSignal:a})).serialize(),s.debug({skipFetchTreeWait:i,tree:u},"Got a11y tree before attempting target resolution"));let d=this.a11yIdToNodeMap[t.id],m=d?.getNodeOnlySerializedForm();if(d&&t.serializedForm&&m===t.serializedForm){let f=await this.getLocatorFromA11yNode(e,d);return l||await this.saveNodeDetailsToCache({root:e,node:d,target:t,dataMomenticId:d.dataMomenticId,locator:f,logger:s}),c.push({type:"A11Y_ID",matched:!0,reason:`An element with the same Chrome-internal accessibility node ID matched the saved content exactly: ${m}.`}),{locator:f,a11yNode:d,displayString:m,decisions:c,pageState:u}}let p;if(t.generatedSelectors){let f;try{f=await this.resolveTargetUsingCssSelectors(e,t,s)}catch(h){p=h}if(f)return{...f,pageState:u,decisions:[...c,...f.decisions]};r||(c.push({type:"CSS_SELECTOR",matched:!1,reason:p?.message,selectors:jx(t.generatedSelectors)}),t.generatedSelectors=void 0)}if(r)throw new yn(`Could not resolve target with CSS selector only: ${p?.message}`,c);{let f=await this.resolveTargetWithSecondaryMethods({root:e,tree:u,target:t,decisions:c,logger:s,signal:a,skipSaveToCache:l});if(f)return f}throw s.debug({target:t,decisions:c},"Failed to find any relevant node"),new yn(`Could not find any relevant node given cached target: ${JSON.stringify(t)}`,c)}async resolveTargetWithSecondaryMethods(e){if(!e.target.boundingBox){this.logger.debug("Skipping secondary resolution methods because we don't have a bbox saved");return}let t=await this.resolveTargetWithSecondaryMethodsHelper(e);if(!t)return;let{x:r,y:o,width:i,height:s}=e.target.boundingBox,a=await t.locator.boundingBox({timeout:1e3});if(!a){this.logger.debug({proposedNode:t.displayString},"Rejecting secondary matching result due to lack of a bounding box");return}let{x:l,y:c,width:u,height:d}=a;if(Math.abs(u-i)>50||Math.abs(d-s)>50){this.logger.debug({newW:u,oldW:i,newH:d,oldH:s,proposedNode:t.displayString},"Rejecting secondary matching result due to difference in dimensions");return}else if(r&&o&&(!l||!c)){this.logger.debug({oldX:r,oldY:o,proposedNode:t.displayString},"Rejecting secondary matching result due to new result not having x/y coords");return}else if(Math.abs((l??0)-(r??0))>200||Math.abs((c??0)-(o??0))>200){this.logger.debug({newX:l,newY:c,oldX:r,oldY:o,proposedNode:t.displayString},"Rejecting secondary matching result due to large difference in x/y coords");return}return t}async resolveTargetWithSecondaryMethodsHelper({root:e,tree:t,target:r,decisions:o,logger:i,signal:s,skipSaveToCache:a}){if(r.nodeOnlySerializedHtml&&r.nodeOnlySerializedHtml.trim().length<10){let u="Refusing to attempt HTML comparison since the saved element is too short.";o.push({type:"HTML_DISTANCE",matched:!1,reason:u})}else if(r.nodeOnlySerializedHtml){let u=await e.content();u.length>5e5&&(u=u.slice(5e5)+"...");try{let d=await kt({fn:p=>dh(p),arg:{nodeOnlySerializedHtml:r.nodeOnlySerializedHtml},timeout:2e3,root:e,waitForPageLoad:()=>this.waitForPageLoad()}),m=Math.floor(.075*r.nodeOnlySerializedHtml.length);if(d.closestDistance&&d.closestDistance>=m){let p=`Closest HTML candidate still has too far distance (${d.closestDistance}) from threshold (${m})`;o.push({type:"HTML_DISTANCE",matched:!1,reason:p,distance:d.closestDistance,closestElement:d.closestNodeSerialized})}else{if(d.error)throw new Error(d.error);if(d.dataMomenticId||d.mPathSelector){let p=d.dataMomenticId?parseInt(d.dataMomenticId):void 0,f,h;if(p)f=this.dataMomenticIdToNodeMap[p],h=e.locator(`[${it}="${p}"]`);else if(d.mPathSelector)f=this.selectorToNodeMap[d.mPathSelector],h=e.locator(d.mPathSelector);else throw new Error("HTML ldist comparison returned no error, data momentic id, or mPath selector");let g=d.closestNodeSerialized??await _t(h,i)??"unknown element";return a||await this.saveNodeDetailsToCache({root:e,node:f,target:r,dataMomenticId:p,locator:h,logger:i}),o.push({type:"HTML_DISTANCE",matched:!0,reason:`Found an element on the page within ${m} string comparison distance of the saved element.`,logs:d.logs,distance:d.closestDistance,closestElement:g,savedElement:r.nodeOnlySerializedHtml}),i.debug({result:d,originalTarget:r,displayString:g},"Resolved cached target to new node with pure html levenshtein distance"),{locator:h,a11yNode:f,displayString:g,decisions:o,pageState:u}}else throw new Error(`Got invalid HTML evaluation result: ${JSON.stringify(d)}`)}}catch(d){i.debug({err:d},"Failed to find closest HTML node using levenshtein distance"),o.push({type:"HTML_DISTANCE",matched:!1,reason:`Error finding closest HTML node by string distance: ${d}`})}}let l=r.screenshotUrl,c=r.role??"";if(l&&Ll.includes(c))try{let u=await this.resolveTargetWithScreenshot({root:e,oldTarget:r,screenshotUrl:l,signal:s,skipSaveToCache:a});return{...u,decisions:[...o,...u.decisions],pageState:t}}catch(u){s?.throwIfAborted(),o.push({type:"TEMPLATE_MATCHING",matched:!1,reason:`Error finding closest element using saved screenshot: ${u}`,elementImageUrl:l}),i.warn({err:u},"Did not find any close element using saved screenshot")}}async resolveTargetWithScreenshot({root:e,screenshotUrl:t,oldTarget:r,signal:o,skipSaveToCache:i}){let s;if(!this.enricher)throw new Error("Enricher not available for screenshot resolution");let a=await this.screenshot({retries:0}),c=await(await fetch(t)).arrayBuffer(),u=Yx(),d=await this.enricher.runTemplateMatching({id:u,searchImageBase64String:Buffer.from(c).toString("base64"),pageImageBase64String:a.toString("base64")},{signal:o});this.logger.debug({id:u,templateMatch:d},"Template matching got successful result");let{target:m,locator:p}=await this.getTargetFromPositionPercentages({percentX:d.x,percentY:d.y}),f=m.boundingBox?.width,h=m.boundingBox?.height;if(!f||!h)throw s="Rejecting target from screenshot due to no bounding box",new Error(s);let g=m.id,y=this.a11yIdToNodeMap[g];return i||await this.saveNodeDetailsToCache({root:e,target:r,node:y,locator:p,dataMomenticId:g}),{locator:p,a11yNode:y,displayString:m.nodeOnlySerializedHtml??"",decisions:[{type:"TEMPLATE_MATCHING",matched:!0,reason:"Found element using screenshot",elementImageUrl:t}]}}async resolveTargetWithXY(e,t=!1){if(this.logger.debug({target:e,skipFetchTree:t},"Resolve target through x / y positioning called"),!t){let s=(await this.getBrowserState({})).serialize();this.logger.debug({tree:s},"Got a11y tree for x / y resolution")}let r=await this.getActivePageOrFrame(),{target:o}=await this.getTargetFromPixelPosition(e);if((o.generatedSelectors??[]).length>0)return{locator:r.locator(o.generatedSelectors[0]),a11yNode:this.a11yIdToNodeMap[o.id],displayString:o.nodeOnlySerializedHtml??o.nodeOnlySerializedForm??"Unknown element",decisions:[]};let i=this.a11yIdToNodeMap[o.id];if(i&&i.dataMomenticId)return{locator:r.locator(`[${it}="${i.dataMomenticId}"]`),a11yNode:i,displayString:i.getNodeOnlySerializedForm(),decisions:[]};throw new Error("Could not resolve target with x / y through either raw HTML or the accessibility tree")}async typeIntoTarget(e,t,r={}){await this.highlightTarget(t.locator);let o=await t.locator.getAttribute("type",{timeout:1e3})??"",i=Rh.some(s=>s===o.toLowerCase());return await Hl({targetingResult:t,options:{force:r.force},logger:this.logger,retryTimeoutMs:this.smartWaitingTimeout,position:i?{x:1,y:1}:void 0,disableRedirection:!0,browserCallbacks:this.getBrowserCallbacks(),featureFlags:this.featureFlagStore}),this.directTypeHelper(e,r)}async click(e,t,r={}){return Hl({targetingResult:e,options:r,logger:this.logger,retryTimeoutMs:this.smartWaitingTimeout,controllerCallbacks:t,browserCallbacks:this.getBrowserCallbacks(),featureFlags:this.featureFlagStore})}async waitForUrl({beforeUrl:e,waitForUrl:t,beforePages:r},o){let i=o?.timeout??this.pageLoadTimeout,s=Date.now(),a=(d,m)=>{o?.caseInsensitive&&(d=d.toLowerCase(),m=m.toLowerCase());let p=d===m||Hx.isMatch(d,m);return o?.negated?!p:p};r||(r=(await Ur(this.context)).map(d=>d.url));let l=!1,c=[],u=e;for(;Date.now()-s<i;){this.abortSignal?.throwIfAborted(),c=(await Ur(this.context)).map(m=>m.url);for(let m=c.length-1;m>=r.length;m--){let p=c[m];if(p!==e&&xn(p,this.logger)){a(p,t)&&await this.switchToPage({type:"INDEX",index:m});break}}if(u=(await this.getActivePageOrFrame()).url(),a(u,t)){l=!0;break}await Z(500,this.abortSignal)}if(!l)throw new R("ActionFailureError",`The active page URL ${o?.negated?"still matches":"did not match"} '${t}' in ${i}ms.
2592
2592
  Current tab: ${u}
@@ -2604,13 +2604,13 @@ globstar while`,e,m,t,p,f),this.matchOne(e.slice(m),t.slice(p),r))return this.de
2604
2604
  First test path: ${m}
2605
2605
 
2606
2606
  Second test path: ${o}`)}t.tests[d.id]={type:me.TEST,name:d.name,id:d.id,labels:d.labels,...u};return}catch(d){r.warn(`Skipping file '${o}' because it is missing Momentic test metadata: ${d}`);return}case me.MODULE:try{let d=St.parse(s);t.modules[d.moduleId]={type:me.MODULE,name:d.name,id:d.moduleId,...u};return}catch(d){r.warn(`Skipping file '${o}' because it is missing Momentic module metadata: ${d}`);return}default:r.warn(`Unsupported file type ${l}, skipping...`);return}}var Qr="momentic.config.yaml",mg="momentic.workspace.yaml",CA=we.object({projects:we.string().array().describe("list of glob patterns to find project (momentic.config.yaml) files")}),AA=we.union([we.string(),we.object({fromFile:we.string(),json:we.boolean().optional()})]),RA=we.object({name:Ac,baseUrl:we.string(),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(),AA).optional(),inheritFromShell:we.boolean().optional().describe("inherit all environment variables from the shell - might be noisy"),browser:Oa.optional().transform(n=>n&&(n.localChromeExtensionPaths&&(n.localChromeExtensionPaths=n.localChromeExtensionPaths.map(e=>e.startsWith("~")?Nn.join(EA.homedir(),e.slice(1)):e)),n))}),IA=we.object({name:Ac,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"),moduleCreationDir:we.string().optional(),testCreationDir:we.string().optional(),defaultGoldenFileDir:we.string().optional(),environments:we.array(RA).optional()});function gg(n,e){let t;try{t=vA(n,"utf-8")}catch(o){T.warn(`Could not read possible Momentic ${e} file at ${n}: ${o}`);return}let r;try{if(r=fg.parse(t),typeof r!="object"||r===null)throw new Error(`The ${e} file should parse as a map with key-value pairs, but is type ${typeof r} instead`)}catch(o){T.warn(`Possible Momentic ${e} file at ${n} does not parse as valid YAML: ${o}`);return}return r}function Pc(n){let e=gg(n,"project configuration");if(e!==void 0)try{return IA.parse(e)}catch(t){T.warn(`Possible Momentic project configuration file at ${n} does not adhere to the required schema: ${t}`);return}}function PA(n){let e=gg(n,"workspace configuration");if(e!==void 0)try{return CA.parse(e)}catch(t){T.warn(`Possible Momentic workspace configuration file at ${n} does not adhere to the required schema: ${t}`);return}}function OA(){let n=[],e=Ic(),t=Nn.parse(e).root,r=15,o=0;for(;o<r;){o++;let i=Nn.basename(e);if(Fo.includes(i))return T.warn(`Stopping search for Momentic projects since the current directory name (${i}) is likely a system artifact folder.`),n;for(let s of TA(e))if(s.endsWith(Qr)){let a=Nn.join(e,s),l=Pc(a);l&&n.push({configFilePath:a,config:l,rootDir:hg(a)})}if(n.length)return n;if(e=Nn.dirname(e),e===t)break}return n}function Mn(n={}){let{configFilePath:e,nameFilter:t}=n,r=Oc(e);if(t&&(r=r.filter(o=>o.config.name===t)),r.length>1)throw new Error(`Multiple valid projects were found in the same directory. Please use the '-c / --config' flag to disambiguate:
2607
- ${r.map(o=>o.configFilePath)}`);if(r.length===0)throw new Error("No valid Momentic project file available.");return r[0]}function LA(n){let e=PA(n);if(!e||!e.projects||!e.projects.length)return;let t=e.projects.map(i=>(i.endsWith("/")||(i+="/"),`${i}*${Qr}`)),r=Zr(t,{absolute:!1,cwd:Ic(),dotRelative:!1,maxDepth:Rc,nodir:!0}),o=[];for(let i of r){let s=Nn.join(Ic(),i),a=Pc(s);a&&o.push({configFilePath:s,config:a,rootDir:hg(s)})}return o}function Oc(n){if(n){n=Nn.resolve(n);let t=Pc(n);if(!t)throw new Error("No valid Momentic project file available.");return[{config:t,configFilePath:n,rootDir:Nn.dirname(n)}]}if(bA(mg)){let t=LA(mg);if(t)return t}return OA()}function eo(n,e){let t=fg.stringify(n);xA(e,t)}import to from"fs";import Lc from"path";import{z as Nc}from"zod";var NA=Nc.object({width:Nc.number(),height:Nc.number()}),no=class{defaultGoldenScreenshotDir;regenerateGoldenFiles;constructor(e,t){let r=Lc.join(e.rootDir,e.config.defaultGoldenFileDir??"golden/visual-diff");this.defaultGoldenScreenshotDir=r,this.regenerateGoldenFiles=t}async prepareGoldenScreenshotForComparison(e,t,r){if(t.screenshot?.data?.startsWith("https://")){let s=await fetch(t.screenshot.data);return{buffer:Buffer.from(await s.arrayBuffer()),width:t.screenshot.width,height:t.screenshot.height}}let o=t.screenshot?.data;o||(o=Lc.join(this.defaultGoldenScreenshotDir,`${t.id}.jpg`));let i=`${o}.metadata.json`;if(this.regenerateGoldenFiles)return to.mkdirSync(Lc.dirname(o),{recursive:!0}),to.writeFileSync(o,r.buffer),to.writeFileSync(i,JSON.stringify({width:r.width,height:r.height})),{buffer:Buffer.from(r.buffer),width:r.width,height:r.height};if(to.existsSync(o)){let s=to.readFileSync(o),a=NA.parse(JSON.parse(to.readFileSync(i,"utf-8")));return{buffer:s,width:a.width,height:a.height}}else throw new R("UserConfigurationError",`Cannot execute visual diff without a saved baseline screenshot at ${o}`)}};import MA from"fs";import yg from"micromatch";import _A from"path";var kA=new Es(10,60*1e3),Dc="https://api.momentic.ai",_c,Mc,Sg=n=>{Dc=n},oa=()=>Dc,wg=(n,e)=>{_c=n,Mc?.abort(),Mc=new AbortController;let t=Mc.signal,r=_A.basename(n.configFilePath);MA.watch(n.rootDir,{signal:t,persistent:!1,recursive:!0},(o,i)=>{i&&(i!==r&&n.config.include&&!yg.isMatch(i,n.config.include)||i!==r&&yg.isMatch(i,(n.config.exclude??[]).concat(is))||(kA.increment("setLocalProject")?T.error(`A file change under the ${n.rootDir} directory has caused Momentic to reload its configuration more than 10 times in the last minute. Please avoid making rapid changes to files in this directory as this may cause performance issues.`):_c=e(n.configFilePath)))})},he=()=>_c,ro,kc,bg=async n=>{if(ro)return ro;let e=new Xe({baseUrl:Dc,apiKey:n});try{return ro=await e.getOrgId(),kc=n,ro}catch(t){throw new Error(`Error checking API key against server: ${t}`)}},fi=()=>{if(!ro)throw new Error("Your organization ID appears invalid. Please contact Momentic support.");return ro},vg=()=>{if(!kc)throw new Error("Your API key appears invalid. Please contact Momentic support.");return kc};import Tg,{multistream as DA}from"pino";import FA from"pino-pretty";var Fc=new Map,UA=!0,Uc=class n{consoleLogger;ddClientToken;hostname;bindingAttributes;excludeAttributesInConsoleLogs;excludeTimestamps;disableConsoleLogs;site="https://http-intake.logs.us5.datadoghq.com/api/v2/logs";constructor({bindings:e,clientToken:t,hostname:r,excludeAttributesInConsoleLogs:o,excludeTimestamps:i,disableConsoleLogs:s}){this.ddClientToken=t,this.hostname=r,this.excludeAttributesInConsoleLogs=o,this.excludeTimestamps=i,this.disableConsoleLogs=s,this.bindingAttributes={...e,env:"production"};let a={base:o?{}:this.bindingAttributes,errorKey:"err",level:"debug",timestamp:!i};this.consoleLogger=UA?Tg(a):Tg(a,DA([{stream:FA({colorize:!0})}]))}child(e){return new n({clientToken:this.ddClientToken,bindings:{...this.bindingAttributes,...e},hostname:this.hostname,excludeAttributesInConsoleLogs:this.excludeAttributesInConsoleLogs,disableConsoleLogs:this.disableConsoleLogs})}flush(e){this.disableConsoleLogs||this.consoleLogger.flush(e)}log(e,t,r,...o){if(t&&r===void 0&&(r=`${t}`,t={}),this.disableConsoleLogs||this.consoleLogger[e](e==="error"?t:{testId:t.testId,runId:t.runId},r,...o),typeof t=="object"&&t&&"err"in t&&t.err instanceof Error){let s={};for(let a of Object.getOwnPropertyNames(t.err))s[a]=t.err[a];s.name=t.err.name,t.err=s}let i=Object.assign({},this.bindingAttributes,t&&typeof t=="object"?t:{});o.length>0&&(i.args=o),(async()=>{try{let s=await fetch(this.site,{method:"POST",headers:{Accept:"application/json","Content-Type":"application/json","DD-API-KEY":this.ddClientToken},body:JSON.stringify([{ddsource:this.bindingAttributes.app,hostname:this.hostname??"vercel",service:"momentic",message:{message:r||"",...i,level:e}}])});if(!s.ok)throw new Error(`Failed to log to Datadog: ${s.statusText})}`)}catch(s){this.disableConsoleLogs||this.consoleLogger.warn({obj:t,msg:r,args:o,err:s},"Failed to log to Datadog")}})()}debug(e,t,...r){this.log("debug",e,t,...r)}info(e,t,...r){this.log("info",e,t,...r)}warn(e,t,...r){this.log("warn",e,t,...r)}error(e,t,...r){this.log("error",e,t,...r)}bindings(){return this.bindingAttributes}addBinding(e,t){this.bindingAttributes[e]=t}setMinLevel(e){this.consoleLogger.level=e}enableConsoleLogs(){this.disableConsoleLogs=!1}},ia=({app:n,clientToken:e,hostname:t,excludeAttributesInConsoleLogs:r,excludeTimestamps:o,disableConsoleLogs:i})=>{if(!process.env.DD_CLIENT_TOKEN&&!process.env.NEXT_PUBLIC_DD_CLIENT_TOKEN&&!e)throw new Error("Missing DD_CLIENT_TOKEN");return Fc.has(n)||Fc.set(n,new Uc({bindings:{app:n},hostname:t,clientToken:e||process.env.NEXT_PUBLIC_DD_CLIENT_TOKEN||process.env.DD_CLIENT_TOKEN,excludeAttributesInConsoleLogs:r,excludeTimestamps:o,disableConsoleLogs:i})),Fc.get(n)};import{hostname as zA}from"os";var Ae=ia({app:"desktop-server",clientToken:"pubcfd7516a5c0ba852b42675cd97bee027",hostname:zA(),excludeAttributesInConsoleLogs:!0,excludeTimestamps:!0,disableConsoleLogs:!0}),xg=n=>{Ae.addBinding("version",n)};function Re(n){return function(...e){let t=e[e.length-1],r=n(...e);Promise.resolve(r).catch(t)}}var Eg=BA();Eg.get("/",Re((n,e)=>{let t=hf(he(),Ae);e.status(200).json(t)}));var Cg=Eg;import{Router as $A}from"express";var sa=class extends Pr{constructor(t,r){super(t,r);this.client=t;this.orgId=r}async getOrgId(t){return this.orgId}async fetchTestMetadata(t,r,o){let i=he(),a=mt(i,o).tests[t];if(a)return Fs(a.relativePath,i)}async fetchApiTestMetadata(t,r,o){throw new Error("API tests are not available in the desktop app")}async fetchEnvironment(t,r,o){let i=he();return Xo(r,i,o)}};var Ag=$A();Ag.get("/",Re((n,e)=>{let t=he(),r=mt(t,T),o=new Set;r?.tests&&Object.values(r.tests).forEach(s=>{s.labels?.forEach(a=>o.add(a))});let i=Array.from(o).sort();e.status(200).json(i)}));var Rg=Ag;import{Router as jA}from"express";import Ig from"fs";import Pg from"path";var aa=jA();aa.get("/",Re(async(n,e)=>{let t=mt(he(),T),o=(await uf(t,Ae)).filter(i=>i.enabled??!0);e.status(200).json(o)}));aa.post("/",Re(async(n,e)=>{let t;try{t=Ju.parse(n.body)}catch(s){e.status(400).json({error:`Invalid request body: ${s}`});return}try{uo(t.name)}catch(s){e.status(400).json({error:`Invalid module name: ${s}`});return}let r=he(),o=Pg.join(r.rootDir,r.config.moduleCreationDir??Pg.dirname(t.testFilePath));if(!Ig.existsSync(o)||!Ig.statSync(o).isDirectory()){e.status(400).json({error:`The folder configured for module creation '${o}' does not exist.`});return}let i=await df({...t,folder:o});e.status(201).json(i)}));aa.get("/:moduleId",Re(async(n,e)=>{if(!n.params.moduleId){e.status(400).json({error:"Missing moduleId in url path."});return}let t=mt(he(),T),r=t.modules[n.params.moduleId];if(!r){e.status(404).json({error:"Module not found."});return}try{let o=await rc(r,t,T);e.json(o)}catch(o){e.status(400).json({err:o})}}));var Og=aa;import{Router as HA}from"express";var la=HA();la.get("/",Re((n,e)=>{let t=Oc().map(r=>({name:r.config.name,configFilePath:r.configFilePath}));e.status(200).json(t)}));la.get("/current",Re((n,e)=>{let t=he(),r={name:t.config.name,configFilePath:t.configFilePath};e.status(200).json(r)}));la.post("/set",Re((n,e)=>{let t;try{t=Zu.parse(n.body)}catch(r){e.status(400).json({error:`Invalid request body: ${r}`});return}try{let r=Mn({configFilePath:t.configFilePath});wg(r,o=>Mn({configFilePath:o}))}catch(r){e.status(400).json({error:`Error setting project: ${r}`});return}e.sendStatus(204)}));var Lg=la;import{Router as WA}from"express";import zc from"path";import{v4 as GA}from"uuid";var or=WA();or.get("/",Re((n,e)=>{let t=he(),r=mt(t,T),o=Array.from(Object.values(r.tests));e.status(200).json(o)}));or.post("/",Re(async(n,e)=>{let t;try{t=Yu.parse(n.body)}catch(c){e.status(400).json({error:`Invalid request body: ${c}`});return}try{uo(t.name)}catch(c){e.status(400).json({error:c.message});return}let o={id:GA(),name:t.name,baseUrl:t.baseUrl,schemaVersion:Tt,advanced:{disableAICaching:!1,browserType:t.browserType??"Chromium",viewport:t.viewport??Ot},retries:0,steps:[]};t.environment&&(o.envs=[{name:t.environment,default:!0}]);let i=he(),s=zc.join(i.rootDir,i.config.testCreationDir??""),a=await pf({test:o,name:t.name,folder:s}),l={...o,relativeFilePath:zc.relative(i.rootDir,a)};e.status(201).json(l)}));or.get("/:testPath",Re(async(n,e)=>{let{testPath:t}=n.params;if(!t){e.status(400).json({error:"Missing testPath in url path."});return}let r=he(),o=mt(r,T),i;try{i=await Us(zc.join(r.rootDir,t),Ae,o),e.status(200).json(i)}catch(s){e.status(400).send({error:s.message});return}(async()=>{try{let{stepsToSave:s,moduleUpdates:a}=await Nt({steps:i.steps});a.forEach(l=>{nc(l.moduleId,{...l,schemaVersion:Tt},o)}),Jo(t,{schemaVersion:Tt,steps:s},r)}catch(s){Ae.error({err:s},"Failed to save migrated test to disk after initial fetch")}})()}));or.patch("/:testPath/metadata",Re(async(n,e)=>{if(!n.params.testPath){e.status(400).json({error:"Missing testPath in url path."});return}let t;try{t=Ku.parse(n.body)}catch(r){e.status(400).json({error:`Invalid request body: ${r}`});return}Jo(n.params.testPath,t,he()),e.status(201).json({message:"ok"})}));or.patch("/:testPath",Re(async(n,e)=>{let{testPath:t}=n.params;if(!t){e.status(400).json({error:"Missing testPath in url path."});return}let r;try{r=qu.parse(n.body)}catch(d){e.status(400).json({error:`Invalid request body: ${d}`});return}let o=he(),i=mt(o,T),s;try{s=Fs(t,o)}catch(d){e.status(400).json({error:`Existing test file on disk is invalid: ${d}`});return}let{stepsToSave:a,moduleUpdates:l,cachesToSave:c}=await Nt({steps:r.steps,cacheCreationParams:{testId:s.id,orgId:fi()}});await new Xe({apiKey:vg(),baseUrl:oa()}).updateStepCaches({entries:c,testId:s.id}),l.forEach(d=>{nc(d.moduleId,{...d,schemaVersion:r.schemaVersion},i)}),Jo(t,{steps:a,schemaVersion:r.schemaVersion},o),e.status(201).json({message:"ok"})}));or.patch("/:testPath/environments",Re(async(n,e)=>{let{testPath:t}=n.params;if(!t){e.status(400).json({error:"Missing testPath in url path."});return}let r;try{r=Xu.parse(n.body)}catch(o){e.status(400).json({error:`Invalid request body: ${o}`});return}Jo(t,{envs:r.defaultEnv?[{name:r.defaultEnv,default:!0}]:[]},he()),e.status(201).json({message:"ok"})}));var Ng=or;var gi=class{async prepareGoldenScreenshotForComparison(e,t,r){return await new no(he(),!1).prepareGoldenScreenshotForComparison(e,t,r)}};async function Dg(n){let{momenticServerUrl:e,apiKey:t,serverPort:r,appPort:o,staticDir:i,devicePixelRatio:s,version:a}=n;xg(a),e&&Sg(e),Ae.debug(n,"Initializing desktop server");let l=await bg(t);Ae.debug({orgId:l},"Checking API key successful");let c=XA(i,r),u=`http://localhost:${r}`;T.info(`Desktop server is running at ${u}`),await new Promise(v=>{c.listen(r,()=>{Ae.info(`Desktop server is running at ${u}`),v()})});let m={type:"API_KEY",baseUrl:oa(),apiKey:t},p=new $r(m),f=new Xe(m),h=new sa(f,fi()),g=new Or(f,fi()),y=new gi;cf({baseServer:c,generatorFactory:async()=>p,storage:h,debugDataStorage:g,logger:Ae,devicePixelRatio:s,authorization:m,visualDiffScreenshotStorage:y})}var kg="25mb";function XA(n,e){let t=_g();t.use(VA()),t.use(Mg.json({limit:kg})),t.use(Mg.urlencoded({extended:!1,limit:kg}));let r=YA();if(r.use("/tests",Ng),r.use("/modules",Og),r.use("/environments",Cg),r.use("/projects",Lg),r.use("/labels",Rg),t.use("/api",r),t.use((i,s,a)=>{i.path!=="/healthcheck"&&Ae.debug({url:i.url,path:i.path,query:i.query,method:i.method,body:i.body,headers:i.rawHeaders,client:i.ip},"Received desktop-server request"),s.on("close",()=>{s.statusCode>=400&&Ae.error({url:i.url,method:i.method,statusCode:s.statusCode},"Request completed in error")}),a()}),t.use((i,s,a,l)=>{if(i instanceof Error&&i.message.includes("BadRequestError: request aborted")){a.status(400).send("Client disconnected");return}Ae.error({stack:i.stack,msg:i.message,err:i,url:s.url,method:s.method},"Unhandled exception leading to 500 on desktop-server"),T.error(`Oh no! We seem to have hit an unexpected snag \u{1F61E}. Please contact Momentic Support with the following error: ${i.message}`),a.status(500).send("Internal Server Error")}),n){let i=_g.static(n);t.use("/",i),t.use("*",i)}let o=JA.createServer(t);return o.once("error",i=>{"code"in i&&i.code==="EADDRINUSE"?T.error(qA`Port ${e} is already in use by another process. Please close the other process and try again.
2607
+ ${r.map(o=>o.configFilePath)}`);if(r.length===0)throw new Error("No valid Momentic project file available.");return r[0]}function LA(n){let e=PA(n);if(!e||!e.projects||!e.projects.length)return;let t=e.projects.map(i=>(i.endsWith("/")||(i+="/"),`${i}*${Qr}`)),r=Zr(t,{absolute:!1,cwd:Ic(),dotRelative:!1,maxDepth:Rc,nodir:!0}),o=[];for(let i of r){let s=Nn.join(Ic(),i),a=Pc(s);a&&o.push({configFilePath:s,config:a,rootDir:hg(s)})}return o}function Oc(n){if(n){n=Nn.resolve(n);let t=Pc(n);if(!t)throw new Error("No valid Momentic project file available.");return[{config:t,configFilePath:n,rootDir:Nn.dirname(n)}]}if(bA(mg)){let t=LA(mg);if(t)return t}return OA()}function eo(n,e){let t=fg.stringify(n);xA(e,t)}import to from"fs";import Lc from"path";import{z as Nc}from"zod";var NA=Nc.object({width:Nc.number(),height:Nc.number()}),no=class{defaultGoldenScreenshotDir;regenerateGoldenFiles;constructor(e,t){let r=Lc.join(e.rootDir,e.config.defaultGoldenFileDir??"golden/visual-diff");this.defaultGoldenScreenshotDir=r,this.regenerateGoldenFiles=t}async prepareGoldenScreenshotForComparison(e,t,r){if(t.screenshot?.data?.startsWith("https://")){let s=await fetch(t.screenshot.data);return{buffer:Buffer.from(await s.arrayBuffer()),width:t.screenshot.width,height:t.screenshot.height}}let o=t.screenshot?.data;o||(o=Lc.join(this.defaultGoldenScreenshotDir,`${t.id}.jpg`));let i=`${o}.metadata.json`;if(this.regenerateGoldenFiles)return to.mkdirSync(Lc.dirname(o),{recursive:!0}),to.writeFileSync(o,r.buffer),to.writeFileSync(i,JSON.stringify({width:r.width,height:r.height})),{buffer:Buffer.from(r.buffer),width:r.width,height:r.height};if(to.existsSync(o)){let s=to.readFileSync(o),a=NA.parse(JSON.parse(to.readFileSync(i,"utf-8")));return{buffer:s,width:a.width,height:a.height}}else throw new R("UserConfigurationError",`Cannot execute visual diff without a saved baseline screenshot at ${o}`)}};import MA from"fs";import yg from"micromatch";import _A from"path";var kA=new Es(10,60*1e3),Dc="https://api.momentic.ai",_c,Mc,Sg=n=>{Dc=n},oa=()=>Dc,wg=(n,e)=>{_c=n,Mc?.abort(),Mc=new AbortController;let t=Mc.signal,r=_A.basename(n.configFilePath);MA.watch(n.rootDir,{signal:t,persistent:!1,recursive:!0},(o,i)=>{i&&(i!==r&&n.config.include&&!yg.isMatch(i,n.config.include)||i!==r&&yg.isMatch(i,(n.config.exclude??[]).concat(is))||(kA.increment("setLocalProject")?T.error(`A file change under the ${n.rootDir} directory has caused Momentic to reload its configuration more than 10 times in the last minute. Please avoid making rapid changes to files in this directory as this may cause performance issues.`):_c=e(n.configFilePath)))})},he=()=>_c,ro,kc,bg=async n=>{if(ro)return ro;let e=new Xe({baseUrl:Dc,apiKey:n});try{return ro=await e.getOrgId(),kc=n,ro}catch(t){throw new Error(`Error checking API key against server: ${t}`)}},fi=()=>{if(!ro)throw new Error("Your organization ID appears invalid. Please contact Momentic support.");return ro},vg=()=>{if(!kc)throw new Error("Your API key appears invalid. Please contact Momentic support.");return kc};import Tg,{multistream as DA}from"pino";import FA from"pino-pretty";var Fc=new Map,UA=!1,Uc=class n{consoleLogger;ddClientToken;hostname;bindingAttributes;excludeAttributesInConsoleLogs;excludeTimestamps;disableConsoleLogs;site="https://http-intake.logs.us5.datadoghq.com/api/v2/logs";constructor({bindings:e,clientToken:t,hostname:r,excludeAttributesInConsoleLogs:o,excludeTimestamps:i,disableConsoleLogs:s}){this.ddClientToken=t,this.hostname=r,this.excludeAttributesInConsoleLogs=o,this.excludeTimestamps=i,this.disableConsoleLogs=s,this.bindingAttributes={...e,env:"staging"};let a={base:o?{}:this.bindingAttributes,errorKey:"err",level:"debug",timestamp:!i};this.consoleLogger=UA?Tg(a):Tg(a,DA([{stream:FA({colorize:!0})}]))}child(e){return new n({clientToken:this.ddClientToken,bindings:{...this.bindingAttributes,...e},hostname:this.hostname,excludeAttributesInConsoleLogs:this.excludeAttributesInConsoleLogs,disableConsoleLogs:this.disableConsoleLogs})}flush(e){this.disableConsoleLogs||this.consoleLogger.flush(e)}log(e,t,r,...o){if(t&&r===void 0&&(r=`${t}`,t={}),this.disableConsoleLogs||this.consoleLogger[e](e==="error"?t:{testId:t.testId,runId:t.runId},r,...o),typeof t=="object"&&t&&"err"in t&&t.err instanceof Error){let s={};for(let a of Object.getOwnPropertyNames(t.err))s[a]=t.err[a];s.name=t.err.name,t.err=s}let i=Object.assign({},this.bindingAttributes,t&&typeof t=="object"?t:{});o.length>0&&(i.args=o),(async()=>{try{let s=await fetch(this.site,{method:"POST",headers:{Accept:"application/json","Content-Type":"application/json","DD-API-KEY":this.ddClientToken},body:JSON.stringify([{ddsource:this.bindingAttributes.app,hostname:this.hostname??"vercel",service:"momentic",message:{message:r||"",...i,level:e}}])});if(!s.ok)throw new Error(`Failed to log to Datadog: ${s.statusText})}`)}catch(s){this.disableConsoleLogs||this.consoleLogger.warn({obj:t,msg:r,args:o,err:s},"Failed to log to Datadog")}})()}debug(e,t,...r){this.log("debug",e,t,...r)}info(e,t,...r){this.log("info",e,t,...r)}warn(e,t,...r){this.log("warn",e,t,...r)}error(e,t,...r){this.log("error",e,t,...r)}bindings(){return this.bindingAttributes}addBinding(e,t){this.bindingAttributes[e]=t}setMinLevel(e){this.consoleLogger.level=e}enableConsoleLogs(){this.disableConsoleLogs=!1}},ia=({app:n,clientToken:e,hostname:t,excludeAttributesInConsoleLogs:r,excludeTimestamps:o,disableConsoleLogs:i})=>{if(!process.env.DD_CLIENT_TOKEN&&!process.env.NEXT_PUBLIC_DD_CLIENT_TOKEN&&!e)throw new Error("Missing DD_CLIENT_TOKEN");return Fc.has(n)||Fc.set(n,new Uc({bindings:{app:n},hostname:t,clientToken:e||process.env.NEXT_PUBLIC_DD_CLIENT_TOKEN||process.env.DD_CLIENT_TOKEN,excludeAttributesInConsoleLogs:r,excludeTimestamps:o,disableConsoleLogs:i})),Fc.get(n)};import{hostname as zA}from"os";var Ae=ia({app:"desktop-server",clientToken:"pubcfd7516a5c0ba852b42675cd97bee027",hostname:zA(),excludeAttributesInConsoleLogs:!0,excludeTimestamps:!0,disableConsoleLogs:!0}),xg=n=>{Ae.addBinding("version",n)};function Re(n){return function(...e){let t=e[e.length-1],r=n(...e);Promise.resolve(r).catch(t)}}var Eg=BA();Eg.get("/",Re((n,e)=>{let t=hf(he(),Ae);e.status(200).json(t)}));var Cg=Eg;import{Router as $A}from"express";var sa=class extends Pr{constructor(t,r){super(t,r);this.client=t;this.orgId=r}async getOrgId(t){return this.orgId}async fetchTestMetadata(t,r,o){let i=he(),a=mt(i,o).tests[t];if(a)return Fs(a.relativePath,i)}async fetchApiTestMetadata(t,r,o){throw new Error("API tests are not available in the desktop app")}async fetchEnvironment(t,r,o){let i=he();return Xo(r,i,o)}};var Ag=$A();Ag.get("/",Re((n,e)=>{let t=he(),r=mt(t,T),o=new Set;r?.tests&&Object.values(r.tests).forEach(s=>{s.labels?.forEach(a=>o.add(a))});let i=Array.from(o).sort();e.status(200).json(i)}));var Rg=Ag;import{Router as jA}from"express";import Ig from"fs";import Pg from"path";var aa=jA();aa.get("/",Re(async(n,e)=>{let t=mt(he(),T),o=(await uf(t,Ae)).filter(i=>i.enabled??!0);e.status(200).json(o)}));aa.post("/",Re(async(n,e)=>{let t;try{t=Ju.parse(n.body)}catch(s){e.status(400).json({error:`Invalid request body: ${s}`});return}try{uo(t.name)}catch(s){e.status(400).json({error:`Invalid module name: ${s}`});return}let r=he(),o=Pg.join(r.rootDir,r.config.moduleCreationDir??Pg.dirname(t.testFilePath));if(!Ig.existsSync(o)||!Ig.statSync(o).isDirectory()){e.status(400).json({error:`The folder configured for module creation '${o}' does not exist.`});return}let i=await df({...t,folder:o});e.status(201).json(i)}));aa.get("/:moduleId",Re(async(n,e)=>{if(!n.params.moduleId){e.status(400).json({error:"Missing moduleId in url path."});return}let t=mt(he(),T),r=t.modules[n.params.moduleId];if(!r){e.status(404).json({error:"Module not found."});return}try{let o=await rc(r,t,T);e.json(o)}catch(o){e.status(400).json({err:o})}}));var Og=aa;import{Router as HA}from"express";var la=HA();la.get("/",Re((n,e)=>{let t=Oc().map(r=>({name:r.config.name,configFilePath:r.configFilePath}));e.status(200).json(t)}));la.get("/current",Re((n,e)=>{let t=he(),r={name:t.config.name,configFilePath:t.configFilePath};e.status(200).json(r)}));la.post("/set",Re((n,e)=>{let t;try{t=Zu.parse(n.body)}catch(r){e.status(400).json({error:`Invalid request body: ${r}`});return}try{let r=Mn({configFilePath:t.configFilePath});wg(r,o=>Mn({configFilePath:o}))}catch(r){e.status(400).json({error:`Error setting project: ${r}`});return}e.sendStatus(204)}));var Lg=la;import{Router as WA}from"express";import zc from"path";import{v4 as GA}from"uuid";var or=WA();or.get("/",Re((n,e)=>{let t=he(),r=mt(t,T),o=Array.from(Object.values(r.tests));e.status(200).json(o)}));or.post("/",Re(async(n,e)=>{let t;try{t=Yu.parse(n.body)}catch(c){e.status(400).json({error:`Invalid request body: ${c}`});return}try{uo(t.name)}catch(c){e.status(400).json({error:c.message});return}let o={id:GA(),name:t.name,baseUrl:t.baseUrl,schemaVersion:Tt,advanced:{disableAICaching:!1,disableFailureRecovery:!0,browserType:t.browserType??"Chromium",viewport:t.viewport??Ot},retries:0,steps:[]};t.environment&&(o.envs=[{name:t.environment,default:!0}]);let i=he(),s=zc.join(i.rootDir,i.config.testCreationDir??""),a=await pf({test:o,name:t.name,folder:s}),l={...o,relativeFilePath:zc.relative(i.rootDir,a)};e.status(201).json(l)}));or.get("/:testPath",Re(async(n,e)=>{let{testPath:t}=n.params;if(!t){e.status(400).json({error:"Missing testPath in url path."});return}let r=he(),o=mt(r,T),i;try{i=await Us(zc.join(r.rootDir,t),Ae,o),e.status(200).json(i)}catch(s){e.status(400).send({error:s.message});return}(async()=>{try{let{stepsToSave:s,moduleUpdates:a}=await Nt({steps:i.steps});a.forEach(l=>{nc(l.moduleId,{...l,schemaVersion:Tt},o)}),Jo(t,{schemaVersion:Tt,steps:s},r)}catch(s){Ae.error({err:s},"Failed to save migrated test to disk after initial fetch")}})()}));or.patch("/:testPath/metadata",Re(async(n,e)=>{if(!n.params.testPath){e.status(400).json({error:"Missing testPath in url path."});return}let t;try{t=Ku.parse(n.body)}catch(r){e.status(400).json({error:`Invalid request body: ${r}`});return}Jo(n.params.testPath,t,he()),e.status(201).json({message:"ok"})}));or.patch("/:testPath",Re(async(n,e)=>{let{testPath:t}=n.params;if(!t){e.status(400).json({error:"Missing testPath in url path."});return}let r;try{r=qu.parse(n.body)}catch(d){e.status(400).json({error:`Invalid request body: ${d}`});return}let o=he(),i=mt(o,T),s;try{s=Fs(t,o)}catch(d){e.status(400).json({error:`Existing test file on disk is invalid: ${d}`});return}let{stepsToSave:a,moduleUpdates:l,cachesToSave:c}=await Nt({steps:r.steps,cacheCreationParams:{testId:s.id,orgId:fi()}});await new Xe({apiKey:vg(),baseUrl:oa()}).updateStepCaches({entries:c,testId:s.id}),l.forEach(d=>{nc(d.moduleId,{...d,schemaVersion:r.schemaVersion},i)}),Jo(t,{steps:a,schemaVersion:r.schemaVersion},o),e.status(201).json({message:"ok"})}));or.patch("/:testPath/environments",Re(async(n,e)=>{let{testPath:t}=n.params;if(!t){e.status(400).json({error:"Missing testPath in url path."});return}let r;try{r=Xu.parse(n.body)}catch(o){e.status(400).json({error:`Invalid request body: ${o}`});return}Jo(t,{envs:r.defaultEnv?[{name:r.defaultEnv,default:!0}]:[]},he()),e.status(201).json({message:"ok"})}));var Ng=or;var gi=class{async prepareGoldenScreenshotForComparison(e,t,r){return await new no(he(),!1).prepareGoldenScreenshotForComparison(e,t,r)}};async function Dg(n){let{momenticServerUrl:e,apiKey:t,serverPort:r,appPort:o,staticDir:i,devicePixelRatio:s,version:a}=n;xg(a),e&&Sg(e),Ae.debug(n,"Initializing desktop server");let l=await bg(t);Ae.debug({orgId:l},"Checking API key successful");let c=XA(i,r),u=`http://localhost:${r}`;T.info(`Desktop server is running at ${u}`),await new Promise(v=>{c.listen(r,()=>{Ae.info(`Desktop server is running at ${u}`),v()})});let m={type:"API_KEY",baseUrl:oa(),apiKey:t},p=new $r(m),f=new Xe(m),h=new sa(f,fi()),g=new Or(f,fi()),y=new gi;cf({baseServer:c,generatorFactory:async()=>p,storage:h,debugDataStorage:g,logger:Ae,devicePixelRatio:s,authorization:m,visualDiffScreenshotStorage:y})}var kg="25mb";function XA(n,e){let t=_g();t.use(VA()),t.use(Mg.json({limit:kg})),t.use(Mg.urlencoded({extended:!1,limit:kg}));let r=YA();if(r.use("/tests",Ng),r.use("/modules",Og),r.use("/environments",Cg),r.use("/projects",Lg),r.use("/labels",Rg),t.use("/api",r),t.use((i,s,a)=>{i.path!=="/healthcheck"&&Ae.debug({url:i.url,path:i.path,query:i.query,method:i.method,body:i.body,headers:i.rawHeaders,client:i.ip},"Received desktop-server request"),s.on("close",()=>{s.statusCode>=400&&Ae.error({url:i.url,method:i.method,statusCode:s.statusCode},"Request completed in error")}),a()}),t.use((i,s,a,l)=>{if(i instanceof Error&&i.message.includes("BadRequestError: request aborted")){a.status(400).send("Client disconnected");return}Ae.error({stack:i.stack,msg:i.message,err:i,url:s.url,method:s.method},"Unhandled exception leading to 500 on desktop-server"),T.error(`Oh no! We seem to have hit an unexpected snag \u{1F61E}. Please contact Momentic Support with the following error: ${i.message}`),a.status(500).send("Internal Server Error")}),n){let i=_g.static(n);t.use("/",i),t.use("*",i)}let o=JA.createServer(t);return o.once("error",i=>{"code"in i&&i.code==="EADDRINUSE"?T.error(qA`Port ${e} is already in use by another process. Please close the other process and try again.
2608
2608
  Using Bash on MacOS or Linux:
2609
2609
  lsof -t -i :58888 | xargs kill -9
2610
2610
 
2611
2611
  Using Command Prompt on Windows:
2612
2612
  for /f "tokens=5" %a in ('netstat -ano ^| findstr :58888') do taskkill /PID %a /F
2613
- `):console.error("An unexpected server error occurred:",i.message)}),o}KA.setMaxListeners(50);process.on("warning",n=>{Ae.warn({err:n},`Node warning received on desktop-server: ${n.message}`)});process.on("uncaughtException",n=>{Ae.error({err:n},"Uncaught exception leading to exit on desktop-server"),T.error(`Oh no! The Momentic desktop app encountered a fatal error \u{1F61E}. Error logs: ${n.message}`)});process.on("unhandledRejection",(n,e)=>{Ae.error({reason:`${n}`,promise:`${e}`,stack:n?.stack},"Uncaught exception leading to exit on desktop-server (promise rejection)"),T.error(`Oh no! The Momentic desktop app encountered an asynchronous error \u{1F61E}. Error logs: ${n}`)});import ZR from"events";import Py from"fs";import QR from"open";import xa from"path";import{fileURLToPath as eI}from"url";import{existsSync as uR,mkdirSync as pR,statSync as mR}from"fs";import{dirname as hR}from"path";import $g from"readline/promises";import{execSync as ZA}from"child_process";import{platform as QA}from"os";function Bc(){return Fg()?(T.info("Setting device pixel ratio to 2 automatically since a Mac OS Retina screen was detected."),T.info("If you are using a low pixel-density monitor, you should manually set --pixel-ratio to 1 to avoid incorrect viewport calculations."),T.info("Confirm your device's pixel-ratio at https://www.mydevice.io."),2):(T.info("Setting device pixel ratio to 1."),T.info("If you are using Momentic on a high-pixel density (HiDPI) monitor, relaunch with the --pixel-ratio option to avoid incorrect viewport calculations"),T.info("Confirm your device's pixel-ratio at https://www.mydevice.io."),1)}function Fg(){return QA()==="darwin"&&ZA("system_profiler SPDisplaysDataType").toString().includes("Retina")}function $c(n){Fg()&&n===1&&(T.warn("If you are using Momentic on a Retina screen, relaunch with the --pixel-ratio option to avoid incorrect viewport calculations."),T.warn("Confirm your device's pixel-ratio at https://www.mydevice.io."))}import eR from"@actions/exec";import tR from"@actions/io";import nR from"quote";import rR from"string-argv";async function Ug(n,e=!0){let t=rR(n),r=await tR.which(t[0],!0),o=t.slice(1),i=eR.exec(nR(r),o,{delay:100});if(e)return i}import{existsSync as oR,statSync as iR}from"fs";var jc=!!process.env.CI||!process.stdout.isTTY;function yi(n){try{return oR(n)&&iR(n).isDirectory()}catch(e){return T.error({err:e},`Error reading path ${n} during directory existence check`),!1}}import sR from"csv-parser";import{createReadStream as aR}from"fs";function Hc(n){return new Promise((e,t)=>{let r=[];aR(n).pipe(sR()).on("data",o=>r.push(o)).on("end",()=>e(r)).on("error",o=>t(o))})}import ca from"semver";import{z as da}from"zod";var Si="1.0.43",lR="https://registry.npmjs.org/momentic",cR=da.object({versions:da.record(da.string(),da.unknown()).optional()});async function zg(n){if(!Si){n.warn("Unable to check CLI version because CLI_VERSION is not set");return}let e;for(let r=0;r<2;r++)try{let o=await H(fetch(lR),{milliseconds:2e3});if(!o.ok)throw new Error(`Got error status code ${o.statusText}`);let i=await o.json();e=cR.parse(i).versions;break}catch(o){n.warn({err:o},"Failed to fetch npm registry data")}if(!e){n.warn("Failed to fetch npm registry data. Skipping version check.");return}let t;for(let r of Object.keys(e))ca.valid(r)&&(!t||ca.gt(r,t))&&ca.gt(r,Si)&&ca.lt(r,"2.0.0")&&!r.includes("alpha")&&(t=r);t&&(T.warn(`Update available: v${Si} -> v${t}`),T.warn("This version may be missing critical fixes, features, and security updates."),T.warn(`Run "npx momentic@${t} -V" to update`))}import{hostname as dR}from"os";var j=ia({app:"cli",clientToken:"pub7eb923f18fb3f1d42ac5eba8c5ea13a5",hostname:dR(),excludeAttributesInConsoleLogs:!0,excludeTimestamps:!0,disableConsoleLogs:!0}).child({version:"1.0.43"});var Wc=!1,jg=(()=>{try{return mR("/.dockerenv"),!0}catch{return!1}})();async function ht(n,e){if(jc||Wc||jg)return!0;j.flush(),await new Promise(s=>setTimeout(s,500));let t=$g.createInterface({input:process.stdin,output:process.stdout}),r=n.split("."),o;if(r.length===1)o=n;else{let s=`${r.slice(0,r.length-1).join(".").trim()}.`;e?T.warn(s):T.log(s),o=r[r.length-1].trim()}let i=await t.question(`${o} ('y' for yes / n for no / 'A' to accept all) `);return t.close(),i==="A"?(Wc=!0,setTimeout(()=>{Wc=!1},3e3),!0):i.toLowerCase()==="y"}async function Gc(n){let e=hR(n);return yi(e)?uR(n)?ht(`File '${Bg(n)}' already exists. Overwrite existing content?`,!0):!0:await ht(`Directory '${Bg(e)}' doesn't exist. Create it now?`,!0)?(pR(e,{recursive:!0}),!0):!1}function Bg(n){return n.replace(/(\s+)/g,"\\$1")}async function Hg(n,e){if(jc||jg)return e;let t=$g.createInterface({input:process.stdin,output:process.stdout}),r=await t.question(`${n} `);return t.close(),r.trim()||e}import{cloneDeep as fR}from"lodash-es";async function ua({client:n,skipPrompts:e,project:t}){let r=await n.getAllEnvironments(),o=fR(t.config);o.environments||(o.environments=[]);for(let i of r){let s=o.environments?.find(a=>a.name===i.name);if(s)!e&&!await ht(`Environment ${i.name} already exists in the project configuration file. Would you like to overwrite its variables?`)&&process.exit(1),s.baseUrl=i.variables[pe],delete i.variables[pe],s.envVariables=i.variables;else{let a=i.variables[pe];delete i.variables[pe],o.environments.push({name:i.name,baseUrl:a,envVariables:i.variables})}}eo(o,t.configFilePath),T.success(`Pulled ${r.length} environments successfully! Please make sure to commit any changes to your project configuration file.`)}import{createHash as Wg}from"crypto";import Gg from"fs";async function qg({testsToFetch:n,client:e,all:t,yes:r}){let{tests:o,modules:i}=await e.getTestYAMLExport({paths:n,all:t}),s=0;for(let[l,c]of Object.entries(o)){let u=Vg(l,me.TEST);!r&&!await Gc(u)||(s+=1,Gg.writeFileSync(u,c,"utf-8"),j.info({checksum:Wg("md5").update(c).digest("hex")},`Wrote '${u}'`))}let a=0;for(let[l,c]of Object.entries(i)){let u=Vg(l,me.MODULE);!r&&!await Gc(u)||(a+=1,Gg.writeFileSync(u,c,"utf-8"),j.info({checksum:Wg("md5").update(c).digest("hex")},`Wrote '${u}'`))}s===0?T.success("Pulled 0 tests."):T.success(`Pulled ${s} test${s>1?"s":""}${a?` and ${a} module${a>1?"s":""}`:""}!`)}function Vg(n,e){switch(e){case me.TEST:return`${Pe(n)}.${nn.TEST}`;case me.MODULE:return`${Pe(n)}.${nn.MODULE}`;default:throw new Error(`Unknown entity type ${e}`)}}async function Kg(n){let{project:e,client:t,skipPrompts:r}=n;T.info("Welcome to the Momentic Cloud importer wizard! \u{1F636}\u200D\u{1F32B}\uFE0F"),T.info("Importing environments from Momentic Cloud."),T.info(`This command will overwrite all local environment configuration in ${e.configFilePath} with environments from Momentic Cloud.`),await ht("Are you sure you want to proceed?",!0)||(T.info("Aborting..."),process.exit(1)),await ua({client:t,project:e,skipPrompts:r}),T.success(`Successfully imported environments from Momentic Cloud. We recommend pulling secrets out of ${e.configFilePath} into .env files or dynamically set environment variables for security.`),T.info("Importing tests and modules from Momentic Cloud."),await qg({testsToFetch:[],client:t,all:!0,yes:r}),T.success("Successfully imported tests and modules from Momentic Cloud. You can move them to the desired location in your project. We recommend committing these files to version control so you can share them with team members and run Momentic tests in CI.")}import ft from"fs";import ir from"path";import gR from"yaml";function Yg(){yi("momentic")||(T.error(`The migration command should be ran from the v0 root Momentic directory, which should contain a folder called 'momentic'. No folder named 'momentic' was found in the current working directory (${process.cwd()}).`),process.exit(1));let n={name:"default",include:hi,environments:[]};T.info("Migrating environments");let e=Jg(["momentic/environments"],yR);for(let r of e){let o=gR.parse(ft.readFileSync(r,"utf-8"));try{let i=Oi.parse(o),s=i.variables[pe]??"";delete i.variables[pe],n.environments?.push({name:i.name,baseUrl:s,envVariables:i.variables})}catch(i){T.error(`${r} failed to parse as a valid environment file.`),T.error(i),process.exit(1)}}T.info("Migrating tests");let t=oc("./momentic",T);for(let r of t){let o=ir.join(...r.fullPathSegments),i=ir.join(ir.dirname(o),`${r.fileName.slice(0,-5)}.test.yaml`);T.info(`Moving test ${o} to ${i}`),ft.renameSync(o,i)}if(yi("momentic/modules")){T.info("Migrating modules");for(let r of ft.readdirSync("./momentic/modules")){if(!r.endsWith(".yaml"))continue;let o=ir.resolve(ir.join("./momentic/modules",r));if(!ft.readFileSync(o,"utf-8").includes("schemaVersion")){T.warn(`Skipping file ${o} since it does not have valid Momentic module contents`);continue}let s=`${o.slice(0,-5)}.module.yaml`;T.info(`Moving module ${o} to ${s}`),ft.renameSync(o,s)}}return T.info("Writing new project configuration file"),eo(n,"momentic.config.yaml"),ft.rmSync("./momentic/environments",{recursive:!0,force:!0}),ft.rmSync("./momentic/fixtures",{recursive:!0,force:!0}),T.success("Migration succeeded!"),T.info("Going forward:"),T.info(` - You can store test and module files anywhere under the project root (${process.cwd()})`),T.info(" - Environment details and other common options are tracked in the root momentic.config.yaml file"),n}function Jg(n,e,t=new Set){for(let r of n){let o=ir.resolve(r),i=!1;try{i=ft.existsSync(o)&&ft.statSync(o).isDirectory()}catch(s){T.error({err:s},`Error reading path ${o} during collect paths`)}if(o&&i){let s=ft.readdirSync(o).map(a=>ir.join(o,a));Jg(s,e,t);continue}if(o.endsWith(".yaml")){try{if(!ft.existsSync(o)||!ft.statSync(o).isFile()){T.warn(`File not found or unreadable: ${o}`);continue}}catch(s){T.error({err:s},`Error reading file ${o} during collect paths`);continue}if(!e(o))continue;t.add(o)}}return t}function yR(n){return n.endsWith(".yaml")?ft.readFileSync(n,"utf8").includes("momentic/environment")?!0:(T.warn(`Skipping YAML that is not a Momentic environment: ${n}`),!1):!1}import{Argument as pa,Option as be}from"@commander-js/extra-typings";import{validateHeaderValue as SR}from"http";import{cpus as Xg}from"os";import{parse as wR}from"yaml";import{z as F}from"zod";var ma=58888,qc=30*60*1e3,sr=new be("--api-key <key>","API key for authentication. If not supplied, attempts to read the MOMENTIC_API_KEY env var."),oo=new be("--server <server>","Momentic server to use. Leave unchanged unless using Momentic on-premise."),ar=new be("-y, --yes","Skip all confirmation prompts."),Kc=new be("-w, --wait","Wait for tests to finish running before exiting. Only applicable when running tests remotely").implies({remote:!0}),Yc=new be("--wait-timeout <waitTimeout>",`The maximum number of seconds to wait for tests to complete. Only applicable when the --wait option is specified. Defaults to ${qc/1e3} seconds.`),ha=new be("--custom-headers <customHeaders...>","Specify custom headers in the form HEADER=VALUE to be sent with each request during the test. Multiple entries can be provided."),Jc=new be("--no-report","Skip reporting test results to Momentic Cloud when running with the --local flag.").implies({local:!0}),Zg=new be("--reporter <reporter>","Output report files in a standardized format to a local directory. See the --reporter-dir flag for information on the output directory.").choices(Object.values(Ji)),Qg=new be("--reporter-dir <reporterDir>","Output directory to store report files. Relative paths are resolved relative to the project root, which is defined by the detected momentic.config.yaml. Defaults to 'reports' if unset."),ey=new be("--include <includePatterns...>","Only include tests that match the provided regex patterns. Multiple patterns can be provided. The patterns will be matched against the test file paths and the pattern only needs to match a part of the path for the test to be included."),ty=new be("--exclude <excludePatterns...>","The inverted version of --include: a test that matches any of the provided exclusion patterns will be excluded from running."),Xc=new be("--pixel-ratio <pixelRatio>","Device pixel ratio of your screen or monitor. Mac OS Retina displays and machines marketed as 'HiDPI' should set this to 2. Visit https://www.mydevice.io/ to find your device's pixel ratio."),ny=new be("--port <port>",`Port to run the app on. Defaults to ${ma}.`),Zc=new be("--input-csv <inputCsv>","Path to a CSV file on disk where each row represents a set of inputs that will be made available to all tests that are ran. The first line of the CSV must be the input names."),fa=new be("--env <env>","Name of the environment to use when running tests."),ga=new be("--url-override <urlOverride>","Fully qualified url (e.g. https://www.google.com) to start all tests from. Overrides any default starting url set from the test or environment."),ry=new be("--shard-index <shardIndex>","The index of the shard to run tests for. Defaults to 1.").default(1).argParser(n=>parseInt(n,10)),wi=new be("-c, --config <configPath>","Absolute or relative path to a Momentic configuration file (*.momentic.config.yaml)"),oy=new be("-f, --filter <filter>","Run tests within the project that has a name equal to the filter provided. This option cannot be used together with file path or directory arguments, but substring matches are allowed."),iy=new be("--shard-count <shardCount>","The number of shards that tests are being run on. Defaults to 1.").default(1).argParser(n=>parseInt(n,10)),sy=new pa("<tests...>",`One or more test paths to queue on Momentic Cloud.
2613
+ `):console.error("An unexpected server error occurred:",i.message)}),o}KA.setMaxListeners(50);process.on("warning",n=>{Ae.warn({err:n},`Node warning received on desktop-server: ${n.message}`)});process.on("uncaughtException",n=>{Ae.error({err:n},"Uncaught exception leading to exit on desktop-server"),T.error(`Oh no! The Momentic desktop app encountered a fatal error \u{1F61E}. Error logs: ${n.message}`)});process.on("unhandledRejection",(n,e)=>{Ae.error({reason:`${n}`,promise:`${e}`,stack:n?.stack},"Uncaught exception leading to exit on desktop-server (promise rejection)"),T.error(`Oh no! The Momentic desktop app encountered an asynchronous error \u{1F61E}. Error logs: ${n}`)});import ZR from"events";import Py from"fs";import QR from"open";import xa from"path";import{fileURLToPath as eI}from"url";import{existsSync as uR,mkdirSync as pR,statSync as mR}from"fs";import{dirname as hR}from"path";import $g from"readline/promises";import{execSync as ZA}from"child_process";import{platform as QA}from"os";function Bc(){return Fg()?(T.info("Setting device pixel ratio to 2 automatically since a Mac OS Retina screen was detected."),T.info("If you are using a low pixel-density monitor, you should manually set --pixel-ratio to 1 to avoid incorrect viewport calculations."),T.info("Confirm your device's pixel-ratio at https://www.mydevice.io."),2):(T.info("Setting device pixel ratio to 1."),T.info("If you are using Momentic on a high-pixel density (HiDPI) monitor, relaunch with the --pixel-ratio option to avoid incorrect viewport calculations"),T.info("Confirm your device's pixel-ratio at https://www.mydevice.io."),1)}function Fg(){return QA()==="darwin"&&ZA("system_profiler SPDisplaysDataType").toString().includes("Retina")}function $c(n){Fg()&&n===1&&(T.warn("If you are using Momentic on a Retina screen, relaunch with the --pixel-ratio option to avoid incorrect viewport calculations."),T.warn("Confirm your device's pixel-ratio at https://www.mydevice.io."))}import eR from"@actions/exec";import tR from"@actions/io";import nR from"quote";import rR from"string-argv";async function Ug(n,e=!0){let t=rR(n),r=await tR.which(t[0],!0),o=t.slice(1),i=eR.exec(nR(r),o,{delay:100});if(e)return i}import{existsSync as oR,statSync as iR}from"fs";var jc=!!process.env.CI||!process.stdout.isTTY;function yi(n){try{return oR(n)&&iR(n).isDirectory()}catch(e){return T.error({err:e},`Error reading path ${n} during directory existence check`),!1}}import sR from"csv-parser";import{createReadStream as aR}from"fs";function Hc(n){return new Promise((e,t)=>{let r=[];aR(n).pipe(sR()).on("data",o=>r.push(o)).on("end",()=>e(r)).on("error",o=>t(o))})}import ca from"semver";import{z as da}from"zod";var Si="1.0.44",lR="https://registry.npmjs.org/momentic",cR=da.object({versions:da.record(da.string(),da.unknown()).optional()});async function zg(n){if(!Si){n.warn("Unable to check CLI version because CLI_VERSION is not set");return}let e;for(let r=0;r<2;r++)try{let o=await H(fetch(lR),{milliseconds:2e3});if(!o.ok)throw new Error(`Got error status code ${o.statusText}`);let i=await o.json();e=cR.parse(i).versions;break}catch(o){n.warn({err:o},"Failed to fetch npm registry data")}if(!e){n.warn("Failed to fetch npm registry data. Skipping version check.");return}let t;for(let r of Object.keys(e))ca.valid(r)&&(!t||ca.gt(r,t))&&ca.gt(r,Si)&&ca.lt(r,"2.0.0")&&!r.includes("alpha")&&(t=r);t&&(T.warn(`Update available: v${Si} -> v${t}`),T.warn("This version may be missing critical fixes, features, and security updates."),T.warn(`Run "npx momentic@${t} -V" to update`))}import{hostname as dR}from"os";var j=ia({app:"cli",clientToken:"pub7eb923f18fb3f1d42ac5eba8c5ea13a5",hostname:dR(),excludeAttributesInConsoleLogs:!0,excludeTimestamps:!0,disableConsoleLogs:!0}).child({version:"1.0.44"});var Wc=!1,jg=(()=>{try{return mR("/.dockerenv"),!0}catch{return!1}})();async function ht(n,e){if(jc||Wc||jg)return!0;j.flush(),await new Promise(s=>setTimeout(s,500));let t=$g.createInterface({input:process.stdin,output:process.stdout}),r=n.split("."),o;if(r.length===1)o=n;else{let s=`${r.slice(0,r.length-1).join(".").trim()}.`;e?T.warn(s):T.log(s),o=r[r.length-1].trim()}let i=await t.question(`${o} ('y' for yes / n for no / 'A' to accept all) `);return t.close(),i==="A"?(Wc=!0,setTimeout(()=>{Wc=!1},3e3),!0):i.toLowerCase()==="y"}async function Gc(n){let e=hR(n);return yi(e)?uR(n)?ht(`File '${Bg(n)}' already exists. Overwrite existing content?`,!0):!0:await ht(`Directory '${Bg(e)}' doesn't exist. Create it now?`,!0)?(pR(e,{recursive:!0}),!0):!1}function Bg(n){return n.replace(/(\s+)/g,"\\$1")}async function Hg(n,e){if(jc||jg)return e;let t=$g.createInterface({input:process.stdin,output:process.stdout}),r=await t.question(`${n} `);return t.close(),r.trim()||e}import{cloneDeep as fR}from"lodash-es";async function ua({client:n,skipPrompts:e,project:t}){let r=await n.getAllEnvironments(),o=fR(t.config);o.environments||(o.environments=[]);for(let i of r){let s=o.environments?.find(a=>a.name===i.name);if(s)!e&&!await ht(`Environment ${i.name} already exists in the project configuration file. Would you like to overwrite its variables?`)&&process.exit(1),s.baseUrl=i.variables[pe],delete i.variables[pe],s.envVariables=i.variables;else{let a=i.variables[pe];delete i.variables[pe],o.environments.push({name:i.name,baseUrl:a,envVariables:i.variables})}}eo(o,t.configFilePath),T.success(`Pulled ${r.length} environments successfully! Please make sure to commit any changes to your project configuration file.`)}import{createHash as Wg}from"crypto";import Gg from"fs";async function qg({testsToFetch:n,client:e,all:t,yes:r}){let{tests:o,modules:i}=await e.getTestYAMLExport({paths:n,all:t}),s=0;for(let[l,c]of Object.entries(o)){let u=Vg(l,me.TEST);!r&&!await Gc(u)||(s+=1,Gg.writeFileSync(u,c,"utf-8"),j.info({checksum:Wg("md5").update(c).digest("hex")},`Wrote '${u}'`))}let a=0;for(let[l,c]of Object.entries(i)){let u=Vg(l,me.MODULE);!r&&!await Gc(u)||(a+=1,Gg.writeFileSync(u,c,"utf-8"),j.info({checksum:Wg("md5").update(c).digest("hex")},`Wrote '${u}'`))}s===0?T.success("Pulled 0 tests."):T.success(`Pulled ${s} test${s>1?"s":""}${a?` and ${a} module${a>1?"s":""}`:""}!`)}function Vg(n,e){switch(e){case me.TEST:return`${Pe(n)}.${nn.TEST}`;case me.MODULE:return`${Pe(n)}.${nn.MODULE}`;default:throw new Error(`Unknown entity type ${e}`)}}async function Kg(n){let{project:e,client:t,skipPrompts:r}=n;T.info("Welcome to the Momentic Cloud importer wizard! \u{1F636}\u200D\u{1F32B}\uFE0F"),T.info("Importing environments from Momentic Cloud."),T.info(`This command will overwrite all local environment configuration in ${e.configFilePath} with environments from Momentic Cloud.`),await ht("Are you sure you want to proceed?",!0)||(T.info("Aborting..."),process.exit(1)),await ua({client:t,project:e,skipPrompts:r}),T.success(`Successfully imported environments from Momentic Cloud. We recommend pulling secrets out of ${e.configFilePath} into .env files or dynamically set environment variables for security.`),T.info("Importing tests and modules from Momentic Cloud."),await qg({testsToFetch:[],client:t,all:!0,yes:r}),T.success("Successfully imported tests and modules from Momentic Cloud. You can move them to the desired location in your project. We recommend committing these files to version control so you can share them with team members and run Momentic tests in CI.")}import ft from"fs";import ir from"path";import gR from"yaml";function Yg(){yi("momentic")||(T.error(`The migration command should be ran from the v0 root Momentic directory, which should contain a folder called 'momentic'. No folder named 'momentic' was found in the current working directory (${process.cwd()}).`),process.exit(1));let n={name:"default",include:hi,environments:[]};T.info("Migrating environments");let e=Jg(["momentic/environments"],yR);for(let r of e){let o=gR.parse(ft.readFileSync(r,"utf-8"));try{let i=Oi.parse(o),s=i.variables[pe]??"";delete i.variables[pe],n.environments?.push({name:i.name,baseUrl:s,envVariables:i.variables})}catch(i){T.error(`${r} failed to parse as a valid environment file.`),T.error(i),process.exit(1)}}T.info("Migrating tests");let t=oc("./momentic",T);for(let r of t){let o=ir.join(...r.fullPathSegments),i=ir.join(ir.dirname(o),`${r.fileName.slice(0,-5)}.test.yaml`);T.info(`Moving test ${o} to ${i}`),ft.renameSync(o,i)}if(yi("momentic/modules")){T.info("Migrating modules");for(let r of ft.readdirSync("./momentic/modules")){if(!r.endsWith(".yaml"))continue;let o=ir.resolve(ir.join("./momentic/modules",r));if(!ft.readFileSync(o,"utf-8").includes("schemaVersion")){T.warn(`Skipping file ${o} since it does not have valid Momentic module contents`);continue}let s=`${o.slice(0,-5)}.module.yaml`;T.info(`Moving module ${o} to ${s}`),ft.renameSync(o,s)}}return T.info("Writing new project configuration file"),eo(n,"momentic.config.yaml"),ft.rmSync("./momentic/environments",{recursive:!0,force:!0}),ft.rmSync("./momentic/fixtures",{recursive:!0,force:!0}),T.success("Migration succeeded!"),T.info("Going forward:"),T.info(` - You can store test and module files anywhere under the project root (${process.cwd()})`),T.info(" - Environment details and other common options are tracked in the root momentic.config.yaml file"),n}function Jg(n,e,t=new Set){for(let r of n){let o=ir.resolve(r),i=!1;try{i=ft.existsSync(o)&&ft.statSync(o).isDirectory()}catch(s){T.error({err:s},`Error reading path ${o} during collect paths`)}if(o&&i){let s=ft.readdirSync(o).map(a=>ir.join(o,a));Jg(s,e,t);continue}if(o.endsWith(".yaml")){try{if(!ft.existsSync(o)||!ft.statSync(o).isFile()){T.warn(`File not found or unreadable: ${o}`);continue}}catch(s){T.error({err:s},`Error reading file ${o} during collect paths`);continue}if(!e(o))continue;t.add(o)}}return t}function yR(n){return n.endsWith(".yaml")?ft.readFileSync(n,"utf8").includes("momentic/environment")?!0:(T.warn(`Skipping YAML that is not a Momentic environment: ${n}`),!1):!1}import{Argument as pa,Option as be}from"@commander-js/extra-typings";import{validateHeaderValue as SR}from"http";import{cpus as Xg}from"os";import{parse as wR}from"yaml";import{z as F}from"zod";var ma=58888,qc=30*60*1e3,sr=new be("--api-key <key>","API key for authentication. If not supplied, attempts to read the MOMENTIC_API_KEY env var."),oo=new be("--server <server>","Momentic server to use. Leave unchanged unless using Momentic on-premise."),ar=new be("-y, --yes","Skip all confirmation prompts."),Kc=new be("-w, --wait","Wait for tests to finish running before exiting. Only applicable when running tests remotely").implies({remote:!0}),Yc=new be("--wait-timeout <waitTimeout>",`The maximum number of seconds to wait for tests to complete. Only applicable when the --wait option is specified. Defaults to ${qc/1e3} seconds.`),ha=new be("--custom-headers <customHeaders...>","Specify custom headers in the form HEADER=VALUE to be sent with each request during the test. Multiple entries can be provided."),Jc=new be("--no-report","Skip reporting test results to Momentic Cloud when running with the --local flag.").implies({local:!0}),Zg=new be("--reporter <reporter>","Output report files in a standardized format to a local directory. See the --reporter-dir flag for information on the output directory.").choices(Object.values(Ji)),Qg=new be("--reporter-dir <reporterDir>","Output directory to store report files. Relative paths are resolved relative to the project root, which is defined by the detected momentic.config.yaml. Defaults to 'reports' if unset."),ey=new be("--include <includePatterns...>","Only include tests that match the provided regex patterns. Multiple patterns can be provided. The patterns will be matched against the test file paths and the pattern only needs to match a part of the path for the test to be included."),ty=new be("--exclude <excludePatterns...>","The inverted version of --include: a test that matches any of the provided exclusion patterns will be excluded from running."),Xc=new be("--pixel-ratio <pixelRatio>","Device pixel ratio of your screen or monitor. Mac OS Retina displays and machines marketed as 'HiDPI' should set this to 2. Visit https://www.mydevice.io/ to find your device's pixel ratio."),ny=new be("--port <port>",`Port to run the app on. Defaults to ${ma}.`),Zc=new be("--input-csv <inputCsv>","Path to a CSV file on disk where each row represents a set of inputs that will be made available to all tests that are ran. The first line of the CSV must be the input names."),fa=new be("--env <env>","Name of the environment to use when running tests."),ga=new be("--url-override <urlOverride>","Fully qualified url (e.g. https://www.google.com) to start all tests from. Overrides any default starting url set from the test or environment."),ry=new be("--shard-index <shardIndex>","The index of the shard to run tests for. Defaults to 1.").default(1).argParser(n=>parseInt(n,10)),wi=new be("-c, --config <configPath>","Absolute or relative path to a Momentic configuration file (*.momentic.config.yaml)"),oy=new be("-f, --filter <filter>","Run tests within the project that has a name equal to the filter provided. This option cannot be used together with file path or directory arguments, but substring matches are allowed."),iy=new be("--shard-count <shardCount>","The number of shards that tests are being run on. Defaults to 1.").default(1).argParser(n=>parseInt(n,10)),sy=new pa("<tests...>",`One or more test paths to queue on Momentic Cloud.
2614
2614
 
2615
2615
  A test path is a lowercased version of your test name where spaces are replaced with dashes: 'npx momentic@latest pull hello-world'.`),ay=new pa("<tests...>","One or more test file path or folders that exist on the local machine: 'npx momentic@latest run hello-world.test.yaml'.").argOptional(),ly=new pa("<suites...>",`One or more suite paths that exist on Momentic Cloud.
2616
2616
 
@@ -2626,6 +2626,6 @@ ${n.map(d=>` - ${d}`).join(`
2626
2626
  `)}`),Object.values(e.tests).forEach(d=>{n.some(m=>d.relativePath.includes(m))&&a.add(d.fullFilePath)}))}else{!r&&!await ht("No test paths or substrings were provided. Do you want to run all tests?")&&(T.error("Cancelled by user."),process.exit(1));let c=Object.values(e.tests);T.info(`Reading all ${c.length} tests in the project from local disk.`),c.forEach(u=>{a.add(u.fullFilePath)})}for(let c of a){let u=id.relative(t.rootDir,c);o&&!o.some(d=>new RegExp(d).test(u))&&a.delete(c),i&&i.some(d=>new RegExp(d).test(u))&&a.delete(c)}let l=Array.from(a).map(async c=>{try{let u=await Us(c,j,e);if($R.gt(u.schemaVersion,Tt)&&T.warn(`Test ${c} has schema version ${u.schemaVersion}, which is greater than what is currently supported by this SDK. Please update your momentic package version to avoid unexpected behavior.`),s&&s.length>0){let d=u.labels||[];if(!s.some(p=>d.includes(p)))return null}return{...u,fullFilePath:c,relativeFilePath:id.relative(t.rootDir,c)}}catch(u){T.error(`Failed to read and resolve test at '${c}': ${u}`),process.exit(1)}});return Promise.all(l).then(zR)}import{diff as jR}from"deep-object-diff";import{cloneDeep as sd}from"lodash-es";import{debounce as HR}from"ts-debounce";import{v4 as Ay}from"uuid";async function Cy({orgId:n,codeEvalTools:e,logger:t,outputDefinitions:r,testContext:o}){let i={};for(let s of r){let{name:a,value:l}=s;i[a]=await Mt({orgId:n,s:l,localTools:e,logger:t,context:o})}return i}async function Ry(n){let e=new Date,{testDefinition:t}=n;try{return await WR(n)}catch(r){return T.error(`Fatal error running test: ${r.message}`),{parameters:n,failureReason:"UnknownError",failureDetails:{errorMessage:r.message,errorStack:r.stack},status:"FAILED",attempts:0,test:t,filePath:t.relativeFilePath,startedAt:e,finishedAt:new Date,outputs:{}}}}async function WR({testDefinition:n,project:e,apiClient:t,billingReporter:r,generator:o,orgId:i,retriesOverride:s,noReport:a,envName:l,urlOverride:c,devicePixelRatio:u,customHeaders:d,testInputs:m,regenerateGoldenFiles:p,logUpdate:f}){let h=new Date,g={envName:l,urlOverride:c,customHeaders:d,testInputs:m},y=new Pr(t,i),v=new no(e,p),x=new Or(t,i),b=new vn({httpClient:new Vt({baseUrl:t.baseUrl,apiKey:t.apiKey})});try{await y.resolveStepCacheEntries({organizationId:i,testId:n.id,steps:n.steps,schemaVersion:n.schemaVersion,logger:j})}catch(B){throw j.error({err:B},"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 an error, please contact Momentic Support with the following error: ${B}`)}if(!l){for(let B of n.envs??[])if(B.default){l=B.name;break}}let S,C={};if(l){try{S=Xo(l,e,j)}catch(B){let P=`Failed to resolve environment ${l} for test ${n.name}: ${B}`;throw new Error(P)}C=S.variables}let I=n.baseUrl;if(c)I=c;else if(!I){let B=C[pe];typeof B=="string"&&(I=B)}if(!I){let B=`Cannot run test with no base URL and no ${pe} variable defined in its environment`;throw new Error(B)}let O;if(a)O=Ay();else try{O=(await t.createRun({testId:n.id,testName:n.name,trigger:"CLI",resolvedBaseUrl:I,schemaVersion:n.schemaVersion})).id}catch(B){throw j.error({err:B,testId:n.id},"Error creating run on Momentic Cloud"),new Error(`Error creating run on Momentic Cloud. Please ensure Momentic is accessible from your environment.
2627
2627
  If you believe this is an error, please contact Momentic Support with the following error message: ${B}`)}let L=j.child({testId:n.id,runId:O,orgId:i}),U=async B=>{if(!a)try{await t.updateRun(O,B)}catch(P){L.warn({err:P},`Failed to update run status for test ${O}. You may see stale data on the Momentic Cloud Server.`)}},z,M=Math.max(s??n.retries,0),te=[];for(let B=0;B<=M;B++){let P=Ay(),se=sd(n);if(!a)try{P=(await t.createRunAttempt(O)).id}catch(ve){throw j.error({err:ve,testId:se.id,runId:O},"Error creating run attempt on Momentic Cloud"),new Error("Error creating run attempt on Momentic Cloud. Please ensure Momentic is accessible from your environment or pass the --no-report flag.")}B!==0&&f("RETRYING",`(attempt ${B+1}/${M+1})`);let De=async ve=>{if(!a)try{await t.updateRunAttempt(O,P,ve)}catch(lt){L.warn({err:lt},`Failed to update run attempt for attempt ${P}. You may see stale data on the Momentic Cloud Server.`)}};try{await U({status:"RUNNING",attempts:B+1});let{controller:ve,context:lt}=await GR({baseUrl:I,envName:l,apiClient:t,devicePixelRatio:u,logger:L,storageClient:y,codeEvalTools:b,test:se,generator:o,orgId:i,variables:C,customHeaders:d,testInputs:m,localBrowserConfigFromEnv:S?.browser,visualDiffScreenshotStorage:v});z=await VR({logger:L,storageClient:y,billingReporter:r,debugDataClient:x,codeEvalTools:b,apiClient:t,test:se,orgId:i,runId:O,context:lt,controller:ve,noReport:a}),await De({status:z.status,finishedAt:new Date}),te.unshift(z.status);let ae=await Cy({orgId:i,codeEvalTools:b,logger:L,outputDefinitions:n.outputs??[],testContext:lt});if(z.status!=="FAILED")return await U({status:z.status,finishedAt:new Date,flake:mu(te)}),{...z,parameters:g,runId:O,test:se,filePath:se.relativeFilePath,startedAt:h,finishedAt:new Date,attempts:B+1,baseUrl:I,outputs:ae};let J=z.failedStepResult,N=J?.message||"Unknown failure";if(B<M){L.warn({errResult:J},`Test '${se.name}' failed attempt ${B+1} of ${M+1}, retrying...`);continue}L.error({errResult:J},`Test '${se.name}' failed after all exhausting ${M+1} attempts: ${N}
2628
2628
  `),await U({status:"FAILED",failureReason:J?.failureReason,finishedAt:new Date});let Ie={errorMessage:N},et=J?.failureReason??Vu(N)??"UnknownError";return await U({status:"FAILED",finishedAt:new Date,failureDetails:Ie,failureReason:et}),{...z,parameters:g,runId:O,failureDetails:Ie,failureReason:et,test:se,filePath:se.relativeFilePath,startedAt:h,finishedAt:new Date,attempts:B+1,baseUrl:I,outputs:ae}}catch(ve){let lt=`Encountered fatal platform error while running test '${se.name}': ${ve}`;L.error({err:ve},lt),T.error(lt);let ae={errorMessage:ve.message,errStack:ve.stack},J={status:"FAILED",failureDetails:ae,failureReason:"InternalPlatformError",finishedAt:new Date};return await Promise.all([De(J),U(J)]),{...J,parameters:g,runId:O,test:se,filePath:se.relativeFilePath,startedAt:h,finishedAt:new Date,attempts:B+1,baseUrl:I,outputs:{}}}}throw new Error("This code should not be reachable")}async function GR({baseUrl:n,envName:e,devicePixelRatio:t,apiClient:r,test:o,storageClient:i,codeEvalTools:s,generator:a,orgId:l,variables:c,logger:u,customHeaders:d,testInputs:m,localBrowserConfigFromEnv:p,visualDiffScreenshotStorage:f}){let h={...p,...po.parse(o.advanced)};d&&(h.extraHeaders={...h.extraHeaders??{},...d});let g=await _r.init(l),y={baseUrl:r.baseUrl,apiKey:r.apiKey};h.browserType==="Google Chrome"&&await cr(["chrome"]);let v;try{v=await Jt.init({baseUrl:n,logger:u,userBrowserSettings:h,storage:i,featureFlagStore:g,enricher:new er(y),timeout:h.pageLoadTimeoutMs,contextArgs:{viewport:o.advanced.viewport??Ot,deviceScaleFactor:t}})}catch(S){let C=S.message;if(C.includes("Executable doesn't exist")||C.includes("install your dependencies"))T.error("The headless browser used by Momentic is not installed correctly. Re-installing the necessary dependencies before starting the test. If this issue persists, pleases contact Momentic Support."),await cr(Qc,!0),v=await Jt.init({baseUrl:n,logger:u,userBrowserSettings:h,storage:i,featureFlagStore:g,enricher:new er(y),timeout:h.pageLoadTimeoutMs,contextArgs:{viewport:o.advanced.viewport??Ot,deviceScaleFactor:t}});else throw S}let x=new Br({browser:v,generator:a,config:Ms,logger:u,orgId:l,storage:i,flagStore:g,localCodeEvalTools:s,visualDiffScreenshotStorage:f}),b=new xt({baseUrl:n,currentUrl:x.browser.url(),variablesFromEnvironment:c,envName:e});return o.parameters&&await Promise.all(o.parameters.map(async S=>{let{name:C,defaultValue:I,required:O}=S,L=m?.[C];O&&L===void 0&&(T.error(`Required parameter '${C}' is required by test '${o.name}' but not provided`),process.exit(1));let U=await Mt({orgId:l,s:L??I,localTools:s,logger:u,context:xt.dummyContext(b.getEnvName())});b.setMomenticSystemVariable(C,U)})),{controller:x,context:b}}async function VR({storageClient:n,debugDataClient:e,apiClient:t,billingReporter:r,codeEvalTools:o,test:i,orgId:s,runId:a,context:l,controller:c,noReport:u,logger:d}){j.info(`Running test '${i.name}' locally${u?"":` and reporting results to https://app.momentic.ai/runs/${a}`}`);let m=sd(i.steps),p=async S=>{try{if(S.results){let C=sd(S.results);ls(C,j),S.results=C}await t.updateRun(a,S)}catch(C){d.warn({err:C},"Failed to update run data. You may see stale data on the Momentic Cloud Server.")}},f=HR(async S=>{u||await p(S)},1e4,{maxWait:3e4}),h=async S=>{try{await f(S)}catch{}},g={controller:c,storage:n,debugDataStorage:e,billingReporter:r,context:l,logger:d,codeEvalTools:o},y={orgId:s,runId:a,testMetadata:i,steps:i.steps};return await ws({fixtures:g,inputs:y,options:{collectDebugData:!0,reinitializeBrowser:!0,disableHealing:!0},callbacks:{step:{},test:{onTestComplete:async()=>{await Promise.all([c.browser.cleanup(),r.reportBillableEvent(d,"test-run",{eventId:a})])},onSaveScreenshot:async S=>{if(u)return"";let{key:C}=await t.uploadScreenshot({screenshot:S.toString("base64")});return C},onUpdateRun:S=>{h(S)},onSaveFinalRunResults:async S=>{f.cancel(),await p(S)},onProposedTestSteps:async S=>t.uploadProposedSteps(S,d),onTestSuccess:async S=>{let C=jR(m,S);if(Object.keys(C).length===0){d.debug("No changes to test steps after success");return}d.debug({changes:C},"Updating steps post-run success in worker");try{let{cachesToSave:I}=await Nt({steps:S,cacheCreationParams:{testId:i.id,orgId:s}});await t.updateStepCaches({testId:i.id,entries:I})}catch(I){d.error({err:I},"Failed to save step caches after successful execution. This is not critical, but can impact future performance.")}}}}})}async function Iy(n){let{tests:e,yes:t,start:r,waitOn:o,client:i,billingReporter:s,project:a,report:l,retriesOverride:c,urlOverride:u,envName:d,orgId:m,devicePixelRatio:p,customHeaders:f,testInputMatrix:h,reporter:g,include:y,exclude:v,labels:x,reporterDir:b="reports",waitOnTimeout:S=60,parallel:C=1,shardIndex:I=1,shardCount:O=1,regenerateGoldenFiles:L}=n;r&&(j.info({orgId:m},`Executing start command: ${r}`),await Ug(r,!1)),o&&(j.info({orgId:m},`Waiting for url: ${o} with timeout: ${S} seconds.`),await KR({resources:[o],interval:2500,timeout:S*1e3,headers:{Accept:"*/*"},followRedirect:!0,verbose:!1,log:!0,strictSSL:!1}));let U=new $r({baseUrl:i.baseUrl,apiKey:i.apiKey}),z=mt(a,T),M=await Ey({tests:e,momenticFiles:z,yes:t,project:a,include:y,exclude:v,labels:x}),te=[];M.forEach((J,N)=>{h?h.forEach((Ie,et)=>{te.push({testIndex:N,inputs:Ie,inputIndex:et})}):te.push({testIndex:N,inputs:void 0,inputIndex:void 0})}),O&&O>1&&(te=YR(te,I,O));let B=`Running ${te.length} tests with ${C} workers`;j.info({allTestsToRunWithInputs:te,shardCount:O,shardIndex:I,orgId:m},B),T.dimmed(B),te.forEach(J=>{T.dimmed(` - ${[M[J.testIndex].relativeFilePath]}${typeof J.inputIndex=="number"?` with input set ${J.inputIndex}`:""}`)}),T.log("");let P=[],se=Date.now(),De=new Set,ve=()=>{let J=i.getAppUrl();return io({results:P,startTime:se,onFailed:Ie=>{va(Ie,Ie.filePath)},getDisplayLine:Ie=>{let et=` - ${Ie.filePath}`;return l&&Ie.runId&&(et+=` (${J}/runs/${Ie.runId})`),et},entity:"test"})},lt=()=>{T.warn("SIGINT received. Stopping tests and printing the existing results..."),ve(),process.exit()};process.on("SIGINT",lt);let ae={};for(let J=0;J<te.length;J++){let N=Object.values(ae);N.length===C&&await Promise.race(N.map(vi=>vi.promise));let Ie=te[J],et=`test-${J}`;ae[et]={done:!1,promise:(async({testIndex:vi,inputs:ad})=>{let lo=M[vi];De.add({testIndex:vi,inputs:ad});let Ly=lo.relativeFilePath.includes("..")?lo.fullFilePath:lo.relativeFilePath,Ti=(He,ld)=>{He=He.toUpperCase();let en=He;He.includes("FAIL")?en=ao.bgRed.white(" FAILED "):He.includes("PASS")?en=ao.bgGreen.white(" PASSED "):He.includes("START")?en=ao.bgBlue.white("STARTING"):He.includes("CANCEL")?en=ao.bgYellow.white(" CANCEL "):He.includes("RETRY")?en=ao.bgYellow.white("RETRYING"):He.includes("RUN")||He.includes("PROG")?en=ao.bgMagenta.white("PROGRESS"):j.warn(`Unknown status tried to be logged in run test locally: ${He}`),qR||(en=`[${en}]`),T.log(`${en} ${Ly} ${ld?`${ld} `:""}(${De.size}/${te.length})`)};Ti("START");let Ny=setInterval(()=>Ti("RUN"),5*60*1e3);try{let He=await Ry({testDefinition:lo,project:a,testInputs:ad,orgId:m,devicePixelRatio:p,apiClient:i,billingReporter:s,generator:U,retriesOverride:c,urlOverride:u,envName:d,noReport:!l,customHeaders:f,regenerateGoldenFiles:L,logUpdate:Ti});Ti(He.status),P.push(He)}catch(He){T.error(`Encountered unexpected fatal error when running test '${lo.name}': ${He.message}`)}finally{clearInterval(Ny),ae[et].done=!0,delete ae[et]}})(Ie)}}return await Promise.allSettled(Object.values(ae).map(J=>J.promise)),process.off("SIGINT",lt),g&&await xy(g,{suiteName:`on-demand-suite-${se}`,startedAt:new Date(se),finishedAt:new Date,runs:P},b??"reports"),ve()}function YR(n,e,t){if(t>n.length&&(T.warn(`Shard count ${t} is greater than the number of tests ${n.length}! Some workers won't have any tests to run.`),t=Math.max(t,n.length),e>t))return[];let r=Math.floor((e-1)*(n.length/t)),o=Math.floor(e*(n.length/t));return n.sort().filter((s,a)=>a>=r&&a<o)}Ca||j.warn("Sentry is not enabled in this environment due to unsupported node version");await zg(j);var Pt=new JR;Pt.name("momentic").description("Momentic CLI").version(Si||"unknown");Pt.command("install-browsers").option("-f, --force","Force reinstallation even if the browser executables already exist on disk.").argument("[browsers...]","Browsers to install",["chromium"]).action(async(n,e)=>{await cr(py(n),e.force)});Pt.addOption(new Qt("--log-level <level>").choices(["debug","info","warn","error"]).default("info")).on("option:log-level",n=>{j.setMinLevel(n.toLowerCase()),T.setMinLevel(n.toLowerCase())});Pt.addOption(new Qt("--verbose","enable verbose logging")).on("option:verbose",()=>{j.enableConsoleLogs(),T.setMinLevel(0)});Pt.command("check-config").addOption(wi).action(async n=>{Mn({configFilePath:n.config})});var tI=Pt.command("migrate").description("Migrate and upgrade tooling");tI.command("v0-v1").addOption(ar).addOption(sr).action(async n=>{let e=await lr(n);if(!e.yes&&!await ht("This command will migrate and then delete your previous Momentic files. All members of your team should transition to the V1 CLI at the same time. Please backup your local directory for safety before proceeding. Continue?",!0)&&process.exit(1),!Yg().environments?.length&&await ht("In the V1 CLI, all environment configuration should be committed to a central `momentic.config.yaml` file, which you should commit to your source control repository. Sensitive data can be managed through `.env` files or by injecting the secret into the environment and then referencing them in `envVariables` with ${VAR} syntax. Would you like to pull the latest environments from Momentic Cloud into your `momentic.config.yaml` file?",!0)){let{apiKey:r,server:o}=e,i=Mn({}),s=new Xe({baseUrl:o,apiKey:r,logger:j});await ua({client:s,project:i,skipPrompts:e.yes}),T.success("Successfully imported environments from Momentic Cloud.")}});Pt.command("import-from-cloud").addOption(sr).addOption(oo).addOption(wi).addOption(ar).action(async n=>{let e=await lr(n),{apiKey:t,server:r,config:o,yes:i}=e,s=Mn({configFilePath:o}),a=new Xe({baseUrl:r,apiKey:t,logger:j});await Kg({client:a,project:s,skipPrompts:i}),process.exit(0)});Pt.command("init").description("Initialize an empty Momentic project in the current working directory").addOption(new Qt("--name <name>","Name of the project")).action(async n=>{T.info(`Welcome to the Momentic project setup wizard! \u{1F680}
2629
- `),T.info("This wizard will help you bootstrap a new Momentic project. If need to import existing assets from Momentic Cloud, you can call the 'import-from-cloud' command after initialization."),Py.existsSync(Qr)&&(T.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 t={name:n.name??await Hg("Choose an identifier for your project, such as a service, product, or team name (default: 'app'):","app"),include:hi};eo(t,Qr),T.success(`Initialized Momentic project file at ${xa.resolve(Qr)}`)});Pt.command("app").addOption(sr).addOption(oo).addOption(ar).addOption(Xc).addOption(ny).addOption(wi).action(async n=>{let e=await lr(n),{apiKey:t,port:r=ma,yes:o,server:i,pixelRatio:s}=e,a=new Xe({baseUrl:i,apiKey:t,logger:j}),l=await ed({client:a,skipPrompts:o,installBrowsers:!0});kr.capture({event:"local app started",distinctId:l,properties:{organizationId:l}});let c=eI(import.meta.url),u=xa.dirname(c),d=xa.resolve(u,"..","static"),m=xa.resolve(u,"..","assets"),p=s??Bc();$c(p),co(),await Dg({momenticServerUrl:i,apiKey:t,serverPort:r,appPort:r,staticDir:d,assetsDir:m,devicePixelRatio:p,version:"1.0.43"});let f=`http://localhost:${r}`;await QR(f)});var Oy=Pt.command("queue").description("Queue tests or suites to run on Momentic Cloud");Oy.command("suites").description("Run one or more suites on Momentic Cloud").addOption(sr).addOption(oo).addOption(Kc).addOption(Yc).addOption(ar).addArgument(ly).addOption(ga).addOption(fa).addOption(ha).action(async(n,e)=>{let{apiKey:t,server:r,wait:o,waitTimeout:i,env:s,urlOverride:a,customHeaders:l}=await lr(e),c=new Xe({baseUrl:r,apiKey:t,logger:j});(!n||!Array.isArray(n)||!n.length)&&(T.error("Must pass at least one suite to run."),process.exit(1));let u=await c.getOrgId();kr.capture({event:"queue suites remotely",distinctId:u,properties:{organizationId:u,numSuites:n.length}}),await gy({client:c,orgId:u,wait:o,suitePaths:n,waitTimeout:i,env:s,urlOverride:a,customHeaders:ya(l)})});Oy.command("tests").description("Run one or more tests on Momentic Cloud").addOption(sr).addOption(oo).addOption(ar).addOption(ha).addOption(Zc).addOption(ga).addOption(fa).addOption(Kc).addOption(Yc).addArgument(sy).action(async(n,e)=>{let t=await lr(e),{all:r,apiKey:o,customHeaders:i,env:s,server:a,inputCsv:l,urlOverride:c,wait:u,waitTimeout:d,yes:m}=t,p=ya(i);for(let y of n)(y.endsWith(".yaml")||Py.existsSync(y))&&T.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 f=new Xe({baseUrl:a,apiKey:o,logger:j}),h=await f.getOrgId();kr.capture({event:"queue tests remotely",distinctId:h,properties:{organizationId:h,numTests:n.length}});let g;l&&(g=await Hc(l)),await yy({client:f,orgId:h,tests:n,all:r,customHeaders:p,env:s,urlOverride:c,wait:u,waitTimeout:d,testInputMatrix:g,yes:m}),process.exit(0)});var nI=Pt.command("run").alias("test").description("Run tests on the local machine");nI.addOption(sr).addOption(oo).addOption(wi).addOption(oy).addOption(ar).addOption(ha).addOption(Zc).addOption(fa).addOption(ga).addOption(Jc).addOption(Xc).addOption(new Qt("--start <start>","Arbitrary setup command that will run before Momentic steps begin.")).addOption(new Qt("--wait-on <waitOn>","URL to wait to become accessible before Momentic tests begin.")).addOption(new Qt("--wait-on-timeout <waitOnTimeout>","Max time in seconds to wait for the --wait-on URL to become accessible.")).addOption(new Qt("--retries <retries>","Number of retries to attempt when running tests locally. Defaults to each test's own retry configuration.")).addOption(new Qt("-p, --parallel <parallel>","When running with the --local flag, the number of tests to run in parallel. Defaults to 1.")).addOption(new Qt("--labels <labels...>","Only run tests with the specified label(s).")).addOption(new Qt("--update-golden-files","Update locally stored golden files for steps that this is enabled for.")).addOption(Jc).addOption(Zg).addOption(Qg).addOption(ry).addOption(iy).addOption(ey).addOption(ty).addArgument(ay).action(async(n,e)=>{let t=await lr(e),r=ya(t.customHeaders),o=Mn({configFilePath:t.config,nameFilter:t.filter}),i=new Xe({baseUrl:t.server,apiKey:t.apiKey,logger:j}),s=new us(i),a;t.inputCsv&&(a=await Hc(t.inputCsv));let l=await ed({client:i,skipPrompts:t.yes,installBrowsers:!0});kr.capture({event:"run tests locally",distinctId:l,properties:{organizationId:l}});let c=t.pixelRatio??Bc();$c(c);try{(await Iy({...t,retriesOverride:t.retries,devicePixelRatio:c,tests:n,project:o,client:i,billingReporter:s,customHeaders:r,envName:t.env,orgId:l,testInputMatrix:a,regenerateGoldenFiles:t.updateGoldenFiles})).failed>0?process.exit(1):process.exit(0)}catch(u){T.error("Failed to run tests locally. Please check the error message below or run with the --verbose flag."),T.error(u),process.exit(1)}});async function rI(){try{await Pt.parseAsync(process.argv),co()}catch(n){let e={};try{e.playwrightVersion=XR("npx playwright --version").toString()}catch(t){j.error({err:t},"Error fetching debug information")}j.error({err:n,debugInfo:e},"Uncaught error in CLI"),j.flush(),Ea(n,e),T.error(n),co(),process.exit(1)}}ZR.setMaxListeners(50);process.on("warning",n=>{j.warn({err:n},`Node warning received on CLI: ${n.message}`)});rI();
2629
+ `),T.info("This wizard will help you bootstrap a new Momentic project. If need to import existing assets from Momentic Cloud, you can call the 'import-from-cloud' command after initialization."),Py.existsSync(Qr)&&(T.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 t={name:n.name??await Hg("Choose an identifier for your project, such as a service, product, or team name (default: 'app'):","app"),include:hi};eo(t,Qr),T.success(`Initialized Momentic project file at ${xa.resolve(Qr)}`)});Pt.command("app").addOption(sr).addOption(oo).addOption(ar).addOption(Xc).addOption(ny).addOption(wi).action(async n=>{let e=await lr(n),{apiKey:t,port:r=ma,yes:o,server:i,pixelRatio:s}=e,a=new Xe({baseUrl:i,apiKey:t,logger:j}),l=await ed({client:a,skipPrompts:o,installBrowsers:!0});kr.capture({event:"local app started",distinctId:l,properties:{organizationId:l}});let c=eI(import.meta.url),u=xa.dirname(c),d=xa.resolve(u,"..","static"),m=xa.resolve(u,"..","assets"),p=s??Bc();$c(p),co(),await Dg({momenticServerUrl:i,apiKey:t,serverPort:r,appPort:r,staticDir:d,assetsDir:m,devicePixelRatio:p,version:"1.0.44"});let f=`http://localhost:${r}`;await QR(f)});var Oy=Pt.command("queue").description("Queue tests or suites to run on Momentic Cloud");Oy.command("suites").description("Run one or more suites on Momentic Cloud").addOption(sr).addOption(oo).addOption(Kc).addOption(Yc).addOption(ar).addArgument(ly).addOption(ga).addOption(fa).addOption(ha).action(async(n,e)=>{let{apiKey:t,server:r,wait:o,waitTimeout:i,env:s,urlOverride:a,customHeaders:l}=await lr(e),c=new Xe({baseUrl:r,apiKey:t,logger:j});(!n||!Array.isArray(n)||!n.length)&&(T.error("Must pass at least one suite to run."),process.exit(1));let u=await c.getOrgId();kr.capture({event:"queue suites remotely",distinctId:u,properties:{organizationId:u,numSuites:n.length}}),await gy({client:c,orgId:u,wait:o,suitePaths:n,waitTimeout:i,env:s,urlOverride:a,customHeaders:ya(l)})});Oy.command("tests").description("Run one or more tests on Momentic Cloud").addOption(sr).addOption(oo).addOption(ar).addOption(ha).addOption(Zc).addOption(ga).addOption(fa).addOption(Kc).addOption(Yc).addArgument(sy).action(async(n,e)=>{let t=await lr(e),{all:r,apiKey:o,customHeaders:i,env:s,server:a,inputCsv:l,urlOverride:c,wait:u,waitTimeout:d,yes:m}=t,p=ya(i);for(let y of n)(y.endsWith(".yaml")||Py.existsSync(y))&&T.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 f=new Xe({baseUrl:a,apiKey:o,logger:j}),h=await f.getOrgId();kr.capture({event:"queue tests remotely",distinctId:h,properties:{organizationId:h,numTests:n.length}});let g;l&&(g=await Hc(l)),await yy({client:f,orgId:h,tests:n,all:r,customHeaders:p,env:s,urlOverride:c,wait:u,waitTimeout:d,testInputMatrix:g,yes:m}),process.exit(0)});var nI=Pt.command("run").alias("test").description("Run tests on the local machine");nI.addOption(sr).addOption(oo).addOption(wi).addOption(oy).addOption(ar).addOption(ha).addOption(Zc).addOption(fa).addOption(ga).addOption(Jc).addOption(Xc).addOption(new Qt("--start <start>","Arbitrary setup command that will run before Momentic steps begin.")).addOption(new Qt("--wait-on <waitOn>","URL to wait to become accessible before Momentic tests begin.")).addOption(new Qt("--wait-on-timeout <waitOnTimeout>","Max time in seconds to wait for the --wait-on URL to become accessible.")).addOption(new Qt("--retries <retries>","Number of retries to attempt when running tests locally. Defaults to each test's own retry configuration.")).addOption(new Qt("-p, --parallel <parallel>","When running with the --local flag, the number of tests to run in parallel. Defaults to 1.")).addOption(new Qt("--labels <labels...>","Only run tests with the specified label(s).")).addOption(new Qt("--update-golden-files","Update locally stored golden files for steps that this is enabled for.")).addOption(Jc).addOption(Zg).addOption(Qg).addOption(ry).addOption(iy).addOption(ey).addOption(ty).addArgument(ay).action(async(n,e)=>{let t=await lr(e),r=ya(t.customHeaders),o=Mn({configFilePath:t.config,nameFilter:t.filter}),i=new Xe({baseUrl:t.server,apiKey:t.apiKey,logger:j}),s=new us(i),a;t.inputCsv&&(a=await Hc(t.inputCsv));let l=await ed({client:i,skipPrompts:t.yes,installBrowsers:!0});kr.capture({event:"run tests locally",distinctId:l,properties:{organizationId:l}});let c=t.pixelRatio??Bc();$c(c);try{(await Iy({...t,retriesOverride:t.retries,devicePixelRatio:c,tests:n,project:o,client:i,billingReporter:s,customHeaders:r,envName:t.env,orgId:l,testInputMatrix:a,regenerateGoldenFiles:t.updateGoldenFiles})).failed>0?process.exit(1):process.exit(0)}catch(u){T.error("Failed to run tests locally. Please check the error message below or run with the --verbose flag."),T.error(u),process.exit(1)}});async function rI(){try{await Pt.parseAsync(process.argv),co()}catch(n){let e={};try{e.playwrightVersion=XR("npx playwright --version").toString()}catch(t){j.error({err:t},"Error fetching debug information")}j.error({err:n,debugInfo:e},"Uncaught error in CLI"),j.flush(),Ea(n,e),T.error(n),co(),process.exit(1)}}ZR.setMaxListeners(50);process.on("warning",n=>{j.warn({err:n},`Node warning received on CLI: ${n.message}`)});rI();
2630
2630
  //# sourceMappingURL=cli.js.map
2631
- //# debugId=b7717b2d-47b9-50d6-93f5-7ce14d2edde3
2631
+ //# debugId=904cac85-fa3c-5af8-a93b-644e0eaba702