momentic 2.7.0 → 2.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="1e5befb8-ee07-5f92-8630-a43fb91645f1")}catch(e){}}();
3
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="0ba158ab-7de7-5b11-865d-75f20a411592")}catch(e){}}();
4
4
  var JT=Object.create;var Zu=Object.defineProperty;var XT=Object.getOwnPropertyDescriptor;var QT=Object.getOwnPropertyNames;var ZT=Object.getPrototypeOf,eE=Object.prototype.hasOwnProperty;var em=(n,e)=>()=>(e||n((e={exports:{}}).exports,e),e.exports);var tE=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of QT(e))!eE.call(n,o)&&o!==t&&Zu(n,o,{get:()=>e[o],enumerable:!(r=XT(e,o))||r.enumerable});return n};var nE=(n,e,t)=>(t=n!=null?JT(ZT(n)):{},tE(e||!n||!n.__esModule?Zu(t,"default",{value:n,enumerable:!0}):t,n));var hS=em((z3,mS)=>{"use strict";mS.exports=pS;function pS(n,e,t){n instanceof RegExp&&(n=dS(n,t)),e instanceof RegExp&&(e=dS(e,t));var r=uS(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 dS(n,e){var t=e.match(n);return t?t[0]:null}pS.range=uS;function uS(n,e,t){var r,o,i,a,s,l=t.indexOf(n),c=t.indexOf(e,l+1),d=l;if(l>=0&&c>0){if(n===e)return[l,c];for(r=[],i=t.length;d>=0&&!s;)d==l?(r.push(d),l=t.indexOf(n,d+1)):r.length==1?s=[r.pop(),c]:(o=r.pop(),o<i&&(i=o,a=c),c=t.indexOf(e,d+1)),d=l<c&&l>=0?l:c;r.length&&(s=[i,a])}return s}});var TS=em((H3,vS)=>{"use strict";var gS=hS();vS.exports=ZA;var fS="\0SLASH"+Math.random()+"\0",SS="\0OPEN"+Math.random()+"\0",Hd="\0CLOSE"+Math.random()+"\0",yS="\0COMMA"+Math.random()+"\0",bS="\0PERIOD"+Math.random()+"\0";function zd(n){return parseInt(n,10)==n?parseInt(n,10):n.charCodeAt(0)}function XA(n){return n.split("\\\\").join(fS).split("\\{").join(SS).split("\\}").join(Hd).split("\\,").join(yS).split("\\.").join(bS)}function QA(n){return n.split(fS).join("\\").split(SS).join("{").split(Hd).join("}").split(yS).join(",").split(bS).join(".")}function wS(n){if(!n)return[""];var e=[],t=gS("{","}",n);if(!t)return n.split(",");var r=t.pre,o=t.body,i=t.post,a=r.split(",");a[a.length-1]+="{"+o+"}";var s=wS(i);return i.length&&(a[a.length-1]+=s.shift(),a.push.apply(a,s)),e.push.apply(e,a),e}function ZA(n){return n?(n.substr(0,2)==="{}"&&(n="\\{\\}"+n.substr(2)),fa(XA(n),!0).map(QA)):[]}function eI(n){return"{"+n+"}"}function tI(n){return/^-?0\d/.test(n)}function nI(n,e){return n<=e}function rI(n,e){return n>=e}function fa(n,e){var t=[],r=gS("{","}",n);if(!r)return[n];var o=r.pre,i=r.post.length?fa(r.post,!1):[""];if(/\$$/.test(r.pre))for(var a=0;a<i.length;a++){var s=o+"{"+r.body+"}"+i[a];t.push(s)}else{var l=/^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(r.body),c=/^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(r.body),d=l||c,p=r.body.indexOf(",")>=0;if(!d&&!p)return r.post.match(/,.*\}/)?(n=r.pre+"{"+r.body+Hd+r.post,fa(n)):[n];var u;if(d)u=r.body.split(/\.\./);else if(u=wS(r.body),u.length===1&&(u=fa(u[0],!1).map(eI),u.length===1))return i.map(function(W){return r.pre+u[0]+W});var m;if(d){var h=zd(u[0]),g=zd(u[1]),f=Math.max(u[0].length,u[1].length),S=u.length==3?Math.abs(zd(u[2])):1,w=nI,T=g<h;T&&(S*=-1,w=rI);var y=u.some(tI);m=[];for(var E=h;w(E,g);E+=S){var x;if(c)x=String.fromCharCode(E),x==="\\"&&(x="");else if(x=String(E),y){var A=f-x.length;if(A>0){var k=new Array(A+1).join("0");E<0?x="-"+k+x.slice(1):x=k+x}}m.push(x)}}else{m=[];for(var L=0;L<u.length;L++)m.push.apply(m,fa(u[L],!1))}for(var L=0;L<m.length;L++)for(var a=0;a<i.length;a++){var s=o+m[L]+i[a];(!e||d||s)&&t.push(s)}}return t}});var Mi=(n,e)=>{},Tc=!1;try{let n=await import("@sentry/node");Mi=n.captureException,n.init({dsn:"https://89e980855f7b9c6e56fc6c7e7143888b@o4506426201800704.ingest.us.sentry.io/4508343221354497",environment:"production",release:process.env.SENTRY_RELEASE_NAME,tracesSampleRate:0}),Tc=!0}catch{}import{Command as A_,Option as Bt}from"@commander-js/extra-typings";import{execSync as I_}from"child_process";import Iv from"body-parser";import ck from"cors";import dk from"dedent";import pk from"events";import Pv,{Router as uk}from"express";import{diff as KA}from"deep-object-diff";import un from"fs";import Zr from"path";import{diff as wA}from"deep-object-diff";import{z as tm}from"zod";var z_=tm.object({input:tm.string()});import{z as Ye}from"zod";var $_=Ye.object({srcs:Ye.array(Ye.string()),urls:Ye.array(Ye.string()),desiredSrc:Ye.string().optional(),desiredUrl:Ye.string().optional()}),nm=Ye.object({srcRegex:Ye.string().optional(),urlRegex:Ye.string().optional()}),rm=Ye.object({x:Ye.number(),y:Ye.number(),correlation:Ye.number()}),G_=Ye.object({searchImageBase64String:Ye.string(),pageImageBase64String:Ye.string(),id:Ye.string().uuid(),timeoutMs:Ye.number().max(1e4).min(0).optional()});import{z as _}from"zod";import*as F from"zod";function Ce(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}}Ce(F);var rr=(s=>(s.AI="AI",s.AI_HEALED="AI_HEALED",s.CLICK_TO_FIND="CLICK_TO_FIND",s.XY_PERCENT="XY_PERCENT",s.RECORDING="RECORDING",s.USER_CSS_SELECTOR="USER_CSS_SELECTOR",s.HEURISTIC_HEALED="HEURISTIC_HEALED",s))(rr||{}),rE=F.object({mPathSelectorTokens:F.string().array(),frameSrcRegex:F.string().optional(),frameUrlRegex:F.string().optional(),indices:F.number().array()}),Ec=F.object({result:F.number(),traceId:F.string()}).array(),Ni=F.object({type:F.literal("GCS_TRACES"),traces:Ec}),Ir=F.object({id:F.number().int(),dataMomenticId:F.number().int().optional(),selector:F.string().optional(),hybridSelector:F.object({textContent:F.string().nullish(),attributes:F.record(F.string(),F.string()),tagName:F.string(),expandShadowRoot:F.boolean().optional(),classNames:F.string().array(),nthChild:F.number()}).array().optional(),generatedSelectors:F.string().array().optional(),role:F.string().optional(),name:F.string().optional(),numChildren:F.number().optional(),content:F.string().optional(),pathFromRoot:F.string().optional(),serializedForm:F.string().optional(),nodeOnlySerializedForm:F.string().optional(),serializedHtml:F.string().optional().describe("pruned html including 1 neighbor and 1 layer of children. value for text inputs pruned."),nodeOnlySerializedHtml:F.string().optional().describe("outerHtml of the element without any children. value for text inputs pruned."),screenshotUrl:F.string().url().optional(),boundingBox:F.object({x:F.number().optional(),y:F.number().optional(),width:F.number(),height:F.number()}).describe("css pixel bounding box").optional(),frameCache:rE.optional(),inputDescription:F.string().optional().describe("the description that generated this cache"),targetSource:F.nativeEnum(rr).optional(),targetUpdateTime:F.string().optional(),targetUpdateLoggerTags:F.record(F.string(),F.string()).optional(),memory:Ni.optional()}).openapi({ref:"ElementTargetCache"});function om(n){return!!(n.name||n.role||n.content||n.serializedForm||n.serializedHtml||n.screenshotUrl)}var oE=F.object({type:F.literal("description"),elementDescriptor:F.string(),a11yData:Ir.optional().describe("DEPRECATED: new a11y cache is stored in DB and resolved into the 'cache' field")}).openapi({ref:"DescriptionTarget"}),iE=F.object({x:F.number(),y:F.number()}),aE=F.object({type:F.literal("coordinates"),pixels:iE}).openapi({ref:"CoordinatesTarget"});function or(n){return n.type==="description"}function En(n){return n.type==="coordinates"}var pt=F.discriminatedUnion("type",[oE,aE]).openapi({ref:"ElementTarget"});function xc(n){if(!n)return!1;switch(n.type){case"description":return!!n.elementDescriptor}return!0}function ut(n){if(!n)return"";switch(n.type){case"description":return n.elementDescriptor;case"coordinates":return`x: ${n.pixels.x}, y: ${n.pixels.y}`}}import{v4 as be}from"uuid";import*as v from"zod";import{z as fe}from"zod";import{z as wo}from"zod";var Cc=wo.object({result:wo.boolean(),traceId:wo.string()}).array(),Rc=wo.object({type:wo.literal("GCS_TRACES"),traces:Cc}),im=wo.object({memory:Rc.optional()});var Xa=class{async resolveStepCacheEntries(){}async saveStepCacheEntries(){}};Ce(fe);var am=fe.object({plan:fe.string().optional(),evidence:fe.string().optional(),thoughts:fe.string(),result:fe.boolean(),relevantElements:fe.array(fe.number()).optional(),updatedMemory:Cc.optional()}),vo=(o=>(o.CONTAINS="CONTAINS",o.STARTS_WITH="STARTS_WITH",o.EQUALS="EQUALS",o.EXISTS="EXISTS",o))(vo||{});var sE=fe.object({type:fe.literal("ELEMENT_CONTENT"),negated:fe.boolean().optional(),operation:fe.nativeEnum(vo),value:fe.string()}).openapi({ref:"ElementContentAssertion"}),lE=fe.object({type:fe.literal("ELEMENT_ATTRIBUTE"),negated:fe.boolean().optional(),operation:fe.nativeEnum(vo),attr:fe.string(),value:fe.string()}).openapi({ref:"ElementAttributeValueAssertion"}),To=(o=>(o.EXISTS="EXISTS",o.VISIBLE="VISIBLE",o.ENABLED="ENABLED",o.EDITABLE="EDITABLE",o))(To||{}),cE=fe.object({type:fe.literal("ELEMENT_EXISTENCE"),negated:fe.boolean().optional(),condition:fe.nativeEnum(To).describe("Treated as the element exists AND is also ...")}).openapi({ref:"ElementExistenceAssertion"}),sm=fe.discriminatedUnion("type",[sE,lE,cE]).openapi({ref:"ManualElementAssertion"});var dE=fe.object({type:fe.literal("CONTENT"),negated:fe.boolean().optional(),value:fe.string()}).openapi({ref:"PageContentAssertion"}),lm=fe.discriminatedUnion("type",[dE]).openapi({ref:"ManualPageAssertion"});import{z as le}from"zod";var Qa=le.object({url:le.string(),method:le.union([le.literal("GET"),le.literal("POST"),le.literal("PUT"),le.literal("DELETE"),le.literal("PATCH")]),headers:le.record(le.string(),le.string()).optional(),params:le.record(le.string(),le.string()).optional(),body:le.string().optional(),timeout:le.number().int().optional().describe("Max seconds to wait for the request to complete")}),cm=le.object({url:le.string(),headers:le.record(le.string(),le.string()).optional(),query:le.string(),variables:le.record(le.string(),le.string()).optional(),timeout:le.number().int().optional().describe("Max seconds to wait for the request to complete")}),Za=le.object({code:le.string(),fragment:le.boolean().optional(),environment:le.union([le.literal("NODE"),le.literal("BROWSER")]).optional().describe("default NODE"),timeout:le.number().int().max(60).optional().describe("Max seconds for the code to complete")});var Ue=(H=>(H.AI_EXTRACT="AI_EXTRACT",H.AI_ASSERTION="AI_ASSERTION",H.AUTH_LOAD="AUTH_LOAD",H.AUTH_SAVE="AUTH_SAVE",H.BLUR="BLUR",H.CAPTCHA="CAPTCHA",H.CLICK="CLICK",H.COOKIE="COOKIE",H.COPY="COPY",H.DIALOG="DIALOG",H.DRAG="DRAG",H.ELEMENT_CHECK="ELEMENT_CHECK",H.FILE_UPLOAD="FILE_UPLOAD",H.FOCUS="FOCUS",H.GO_BACK="GO_BACK",H.GO_FORWARD="GO_FORWARD",H.HOVER="HOVER",H.JAVASCRIPT="JAVASCRIPT",H.LOCAL_STORAGE="LOCAL_STORAGE",H.MOUSE_DRAG="MOUSE_DRAG",H.NAVIGATE="NAVIGATE",H.NEW_TAB="NEW_TAB",H.PAGE_CHECK="PAGE_CHECK",H.PASTE="PASTE",H.PRESS="PRESS",H.KEY_DOWN="KEY_DOWN",H.KEY_UP="KEY_UP",H.REFRESH="REFRESH",H.REQUEST="REQUEST",H.GRAPHQL_REQUEST="GRAPHQL_REQUEST",H.SCROLL_DOWN="SCROLL_DOWN",H.SCROLL_UP="SCROLL_UP",H.SCROLL_LEFT="SCROLL_LEFT",H.SCROLL_RIGHT="SCROLL_RIGHT",H.SELECT_OPTION="SELECT_OPTION",H.SWITCH_TAB="TAB",H.TYPE="TYPE",H.VISUAL_DIFF="VISUAL_DIFF",H.WAIT="WAIT",H.WAIT_FOR_URL="WAIT_FOR_URL",H.REGISTER_REQUEST_LISTENER="REGISTER_REQUEST_LISTENER",H.AWAIT_LISTENER="AWAIT_LISTENER",H.RECORD_REQUESTS="RECORD_REQUESTS",H.GET_RECORDED_REQUESTS="GET_RECORDED_REQUESTS",H.SET_HEADER="SET_HEADER",H.SUCCESS="SUCCESS",H))(Ue||{});Ce(v);var V=v.object({thoughts:v.string().optional(),id:v.string().uuid().describe("unique identifier to this step, used for step cache")}),Gt=v.object({useSelector:v.boolean().optional(),force:v.boolean().optional(),disableCache:v.boolean().optional().describe("disable element caching for this step"),iframeUrl:v.string().optional().describe("url or url regex for the iframe")}).openapi({ref:"CommonTargetingOptions"}),xn=v.object({target:Ir}).optional().openapi({ref:"SingleTargetCache"}),es=v.object({loadTimeout:v.number().int().max(60).optional().describe("Max seconds for the page to load")}),pE=V.merge(es).merge(v.object({type:v.literal("NAVIGATE"),url:v.string()})).openapi({ref:"NavigateCommand"}),ts=Gt.merge(v.object({cache:xn})),Eo=V.merge(ts.merge(v.object({target:pt.optional(),type:v.literal("SCROLL_UP"),deltaY:v.number().optional()}))).openapi({ref:"ScrollUpCommand"}),xo=V.merge(ts.merge(v.object({target:pt.optional(),type:v.literal("SCROLL_DOWN"),deltaY:v.number().optional()}))).openapi({ref:"ScrollDownCommand"}),Co=V.merge(ts.merge(v.object({target:pt.optional(),type:v.literal("SCROLL_LEFT"),deltaX:v.number().optional()}))).openapi({ref:"ScrollLeftCommand"}),Ro=V.merge(ts.merge(v.object({target:pt.optional(),type:v.literal("SCROLL_RIGHT"),deltaX:v.number().optional()}))).openapi({ref:"ScrollRightCommand"}),SD=v.discriminatedUnion("type",[Eo,xo,Co,Ro]).openapi({ref:"AllScrollCommands"}),uE=V.merge(v.object({type:v.literal("DIALOG"),action:v.union([v.literal("ACCEPT"),v.literal("DISMISS")])})).openapi({ref:"DialogCommand"}),mE=V.merge(v.object({type:v.literal("WAIT"),delay:v.number()})).openapi({ref:"WaitCommand"}),hE=v.discriminatedUnion("type",[v.object({type:v.literal("SUBSTRING"),url:v.string()}),v.object({type:v.literal("GLOB"),glob:v.string()}),v.object({type:v.literal("REGEX"),regex:v.string()})]),gE=v.object({caseInsensitive:v.boolean().optional().describe("Whether to ignore case when matching the URL"),negated:v.boolean().optional().describe("Wait for the URL to NOT match the provided matcher instead."),timeout:v.number().int().optional().describe("Max seconds to wait for the URL to match")}),fE=V.extend({type:v.literal("WAIT_FOR_URL"),matcher:hE}).merge(gE).openapi({ref:"WaitUrlCommand"}),SE=V.merge(es).merge(v.object({type:v.literal("REFRESH")})).openapi({ref:"RefreshCommand"}),yE=V.merge(v.object({type:v.literal("GO_BACK")})).openapi({ref:"GoBackCommand"}),bE=V.merge(v.object({type:v.literal("GO_FORWARD")})).openapi({ref:"GoForwardCommand"}),wE=V.extend({type:v.literal("AUTH_SAVE")}).openapi({ref:"AuthSaveCommand"}),vE=V.extend({type:v.literal("AUTH_LOAD"),storageState:v.string().describe("JSON string auth state. Leave blank or set to the empty string to clear all existing authentication.")}).openapi({ref:"AuthLoadCommand"}),Ic=V.merge(Gt).extend({type:v.literal("CAPTCHA")}).openapi({ref:"CaptchaCommand"}),TE=V.extend({type:v.literal("COPY"),value:v.string()}).openapi({ref:"CopyCommand"}),EE=V.extend({type:v.literal("PASTE")}).openapi({ref:"PasteCommand"}),xE=V.merge(Za).extend({type:v.literal("JAVASCRIPT")}).openapi({ref:"JavaScriptCommand"}),_i=V.merge(Gt).extend({type:v.literal("CLICK"),target:pt,doubleClick:v.boolean().optional(),rightClick:v.boolean().optional(),waitForDownload:v.boolean().optional().describe("Wait for the click to trigger a file download and for the file download to complete."),delayMs:v.number().optional(),downloadTimeoutMs:v.number().optional(),cache:xn,relativePosition:v.object({x:v.number(),y:v.number()}).optional()}).openapi({ref:"ClickCommand"}),Di=V.merge(Gt).merge(v.object({type:v.literal("DRAG"),fromTarget:pt,toTarget:pt,steps:v.number().optional(),hoverSeconds:v.number().optional().describe("Seconds to hover the object before dropping"),cache:v.object({fromTarget:Ir.optional(),toTarget:Ir.optional()}).optional()})).openapi({ref:"DragCommand"}),Fi=V.merge(Gt).merge(v.object({type:v.literal("MOUSE_DRAG"),target:pt.optional(),deltaX:v.string().describe("pixels to move horizontally, can be template"),deltaY:v.string().describe("pixels to move vertically, can be template"),steps:v.number().optional(),cache:xn})).openapi({ref:"MouseDragCommand"}),Ui=V.merge(Gt).merge(v.object({type:v.literal("HOVER"),target:pt,cache:xn})).openapi({ref:"HoverCommand"}),Bi=V.merge(Gt).merge(v.object({type:v.literal("FOCUS"),target:pt,cache:xn})).openapi({ref:"FocusCommand"}),zi=V.merge(Gt).extend({type:v.literal("BLUR"),target:pt.optional(),cache:xn}).openapi({ref:"BlurCommand"}),CE=v.object({type:v.literal("URL"),url:v.string()}).describe("Accessible link to the file, either public http or local file://").openapi({ref:"UrlSource"}),RE=v.object({type:v.literal("USER_FILE"),name:v.string()}).describe("Accessible link to the file, references the google cloud file").openapi({ref:"UploadedFileSource"}),AE=V.extend({type:v.literal("FILE_UPLOAD"),fileSource:v.discriminatedUnion("type",[CE,RE]),filename:v.string().optional()}).openapi({ref:"FileUploadCommand"}),IE=v.discriminatedUnion("type",[v.object({type:v.literal("VALUE"),value:v.string()}),v.object({type:v.literal("LABEL"),label:v.string()}),v.object({type:v.literal("INDEX"),index:v.coerce.string()})]),Hi=V.merge(Gt).extend({type:v.literal("SELECT_OPTION"),target:pt,cache:xn,choice:IE.describe("new field for selecting options, optional for backcompat")}).openapi({ref:"SelectOptionCommand"}),Pc=v.union([v.literal("MULTIMODAL"),v.literal("VISION_ONLY")]),ns=V.merge(v.object({type:v.literal("AI_ASSERTION"),assertion:v.string(),disableCache:v.boolean().optional(),iframeUrl:v.string().optional(),contextChoice:Pc.optional(),timeout:v.number().int().optional().describe("Max seconds to wait for assertion to be true"),cache:im.optional()})).openapi({ref:"AIAssertionCommand"}),Cn=5,Lc=600,ji=V.merge(Gt).extend({type:v.literal("ELEMENT_CHECK"),target:pt,assertion:sm,cache:xn,timeout:v.number().int().min(0).max(Lc).optional().describe("max seconds to wait for the assertion to be true")}).openapi({ref:"ElementAssertionCommand"}),PE=V.extend({type:v.literal("PAGE_CHECK"),assertion:lm,iframeUrl:v.string().optional().describe("url or url regex for the iframe"),timeout:v.number().int().min(0).max(Lc).optional().describe("max seconds to wait for the assertion to be true")}).openapi({ref:"PageAssertionCommand"}),LE=V.merge(v.object({type:v.literal("AI_EXTRACT"),goal:v.string(),schema:v.string().optional(),envKey:v.string().optional(),disableCache:v.boolean().optional(),iframeUrl:v.string().optional()})).openapi({ref:"AIExtractCommand"}),OE=v.object({clearContent:v.boolean().optional(),forceClearContent:v.boolean().optional(),delay:v.number().min(0).max(1e3).optional().describe("Delay between each press in milliseconds."),force:v.boolean().optional(),pressEnter:v.boolean().optional()}),dm=25,$i=V.merge(Gt).merge(OE).extend({type:v.literal("TYPE"),target:pt.optional(),value:v.string(),cache:xn}).openapi({ref:"TypeCommand"}),ME=V.merge(v.object({type:v.literal("PRESS"),value:v.string(),repeat:v.number().optional(),convertMeta:v.boolean().optional(),delayMs:v.number().optional()})).openapi({ref:"PressCommand"}),NE=V.merge(v.object({type:v.literal("KEY_DOWN"),value:v.string(),convertMeta:v.boolean().optional()})).openapi({ref:"KeyDownCommand"}),kE=V.merge(v.object({type:v.literal("KEY_UP"),value:v.string(),convertMeta:v.boolean().optional()})).openapi({ref:"KeyUpCommand"}),_E=v.object({type:v.literal("SUBSTRING"),substring:v.string()}),DE=v.object({type:v.literal("REGEX"),pattern:v.string()}),FE=v.object({type:v.literal("INDEX"),index:v.coerce.string()}),UE=v.discriminatedUnion("type",[_E,DE,FE]),BE=V.merge(es).merge(v.object({type:v.literal("TAB"),action:UE})).openapi({ref:"TabCommand"}),zE=V.merge(es).merge(v.object({type:v.literal("NEW_TAB"),url:v.string()})).openapi({ref:"NewTabCommand"}),HE=V.merge(v.object({type:v.literal("COOKIE"),value:v.string()})).openapi({ref:"CookieCommand"}),jE=V.merge(v.object({type:v.literal("LOCAL_STORAGE"),key:v.string(),value:v.string()})).openapi({ref:"LocalStorageCommand"}),$E=V.extend({type:v.literal("REQUEST")}).merge(Qa).openapi({ref:"RequestCommand"}),GE=V.extend({type:v.literal("GRAPHQL_REQUEST")}).merge(cm).openapi({ref:"GraphQLRequestCommand"}),WE=V.merge(v.object({type:v.literal("SUCCESS"),condition:ns.optional()})).openapi({ref:"SuccessCommand"}),VE=V.merge(v.object({type:v.literal("FAILURE")})).openapi({ref:"FailureCommand"}),qE=v.object({data:v.string().describe("location at which to find a jpg"),width:v.number(),height:v.number()}),Gi=V.merge(Gt).merge(v.object({type:v.literal("VISUAL_DIFF"),threshold:v.number().optional().describe("default 0.1"),target:pt.optional(),screenshot:qE.optional(),cache:xn})).openapi({ref:"VisualDiffCommand"}),KE=V.merge(v.object({type:v.literal("REGISTER_REQUEST_LISTENER"),pattern:v.string(),key:v.string()})).openapi({ref:"RegisterRequestListenerCommand"}),YE=V.merge(v.object({type:v.literal("AWAIT_LISTENER"),key:v.string(),timeout:v.number().optional().describe("timeout")})).openapi({ref:"WaitForListenerCommand"}),JE=V.merge(v.object({type:v.literal("RECORD_REQUESTS"),pattern:v.string(),key:v.string()})).openapi({ref:"RecordRequestsCommand"}),XE=V.merge(v.object({type:v.literal("GET_RECORDED_REQUESTS"),key:v.string()})).openapi({ref:"GetRecordedRequestsCommand"}),QE=V.merge(v.object({type:v.literal("SET_HEADER"),name:v.string(),value:v.string(),urlPattern:v.string().optional().describe("URL pattern to match")})).openapi({ref:"SetHeaderCommand"}),pm=v.discriminatedUnion("type",[_i,$i,ME,NE,kE,Hi,pE,xo,Eo,ns,Ui,mE,WE]),ZE=v.discriminatedUnion("type",[LE,vE,wE,Ic,HE,TE,uE,Di,ji,AE,yE,bE,xE,jE,Fi,zE,PE,EE,SE,$E,GE,Co,Ro,BE,Gi,Bi,zi,fE,KE,YE,JE,XE,QE]),Ao=v.discriminatedUnion("type",[...pm.options,...ZE.options]).openapi({ref:"Command"}),rs=v.discriminatedUnion("type",[...pm.options,VE]);function Un(n){let e;switch(n){case"PASTE":case"AUTH_SAVE":case"VISUAL_DIFF":case"SUCCESS":case"SCROLL_DOWN":case"SCROLL_UP":case"SCROLL_LEFT":case"SCROLL_RIGHT":case"CAPTCHA":case"GO_BACK":case"GO_FORWARD":case"REFRESH":e={id:be(),type:n};break;case"AUTH_LOAD":{e={id:be(),type:n,storageState:""};break}case"AI_EXTRACT":e={id:be(),type:n,goal:""};break;case"DIALOG":e={id:be(),type:n,action:"DISMISS"};break;case"DRAG":e={id:be(),type:n,fromTarget:{type:"description",elementDescriptor:""},toTarget:{type:"description",elementDescriptor:""}};break;case"MOUSE_DRAG":e={id:be(),type:n,deltaX:"0",deltaY:"0",steps:1};break;case"WAIT_FOR_URL":e={id:be(),type:n,matcher:{type:"SUBSTRING",url:""}};break;case"WAIT":e={id:be(),type:n,delay:1};break;case"BLUR":e={id:be(),type:n};break;case"HOVER":case"FOCUS":case"CLICK":e={id:be(),type:n,target:{type:"description",elementDescriptor:""}};break;case"COOKIE":case"PRESS":case"COPY":case"TYPE":e={id:be(),type:n,value:"",clearContent:!0};break;case"KEY_DOWN":case"KEY_UP":e={id:be(),type:n,value:""};break;case"SELECT_OPTION":e={id:be(),type:n,target:{type:"description",elementDescriptor:""},choice:{type:"VALUE",value:""}};break;case"NAVIGATE":case"NEW_TAB":return{id:be(),type:n,url:""};case"TAB":e={id:be(),type:n,action:{type:"SUBSTRING",substring:""}};break;case"REQUEST":e={id:be(),type:n,url:"",method:"GET"};break;case"GRAPHQL_REQUEST":e={id:be(),type:n,url:"",query:""};break;case"LOCAL_STORAGE":e={id:be(),type:n,key:"",value:""};break;case"JAVASCRIPT":e={id:be(),type:n,code:""};break;case"AI_ASSERTION":e={id:be(),type:n,assertion:""};break;case"FILE_UPLOAD":{e={id:be(),type:n,fileSource:{type:"URL",url:""}};break}case"ELEMENT_CHECK":{e={id:be(),type:n,target:{type:"description",elementDescriptor:""},assertion:{type:"ELEMENT_EXISTENCE",condition:"EXISTS"}};break}case"PAGE_CHECK":{e={id:be(),type:n,assertion:{type:"CONTENT",value:""}};break}case"REGISTER_REQUEST_LISTENER":{e={id:be(),type:n,pattern:"",key:""};break}case"AWAIT_LISTENER":{e={id:be(),type:n,key:""};break}case"RECORD_REQUESTS":{e={id:be(),type:n,pattern:"",key:""};break}case"GET_RECORDED_REQUESTS":{e={id:be(),type:n,key:""};break}case"SET_HEADER":{e={id:be(),type:n,name:"",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}function um(n){switch(n.type){case"BLUR":case"CLICK":case"DRAG":case"FOCUS":case"HOVER":case"MOUSE_DRAG":case"PRESS":case"KEY_DOWN":case"KEY_UP":case"SCROLL_DOWN":case"SCROLL_UP":case"SCROLL_LEFT":case"SCROLL_RIGHT":case"TYPE":return!0;case"AUTH_LOAD":case"AUTH_SAVE":case"AWAIT_LISTENER":case"SUCCESS":case"AI_ASSERTION":case"AI_EXTRACT":case"CAPTCHA":case"COOKIE":case"COPY":case"DIALOG":case"ELEMENT_CHECK":case"FILE_UPLOAD":case"GET_RECORDED_REQUESTS":case"GO_BACK":case"GO_FORWARD":case"GRAPHQL_REQUEST":case"JAVASCRIPT":case"LOCAL_STORAGE":case"NAVIGATE":case"NEW_TAB":case"PASTE":case"PAGE_CHECK":case"RECORD_REQUESTS":case"REGISTER_REQUEST_LISTENER":case"REFRESH":case"REQUEST":case"SELECT_OPTION":case"SET_HEADER":case"TAB":case"VISUAL_DIFF":case"WAIT":case"WAIT_FOR_URL":return!1;default:return(t=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(n)}}import{z as ex}from"zod";var TD=ex.discriminatedUnion("type",[zi,Ic,_i,Di,Bi,Ui,Fi,Eo,xo,Co,Ro,Hi,$i,Gi,ji]);function mm(n){return["AI_ASSERTION","ELEMENT_CHECK","PAGE_CHECK"].includes(n)}import{z as tx}from"zod";var Tt={type:!0,cache:!0},Pr=tx.discriminatedUnion("type",[ns.pick(Tt),zi.pick(Tt),_i.pick(Tt),Di.pick(Tt),ji.pick(Tt),Bi.pick(Tt),Ui.pick(Tt),Fi.pick(Tt),Eo.pick(Tt),xo.pick(Tt),Co.pick(Tt),Ro.pick(Tt),Hi.pick(Tt),$i.pick(Tt),Gi.pick(Tt)]),Oc=Object.values(Ue).filter(n=>Pr.options.some(e=>e.shape.type.safeParse(n).success));Ao.options.forEach(n=>{if("target"in n.shape&&!Oc.includes(n.shape.type.value))throw new Error(`Command ${n.shape.type.value} has a target but no cache`)});import{z as Nc}from"zod";import{z as Mc}from"zod";import{z as Io}from"zod";var It=Io.object({index:Io.number().optional().describe("global index within a test (in-order traversal)"),id:Io.string(),skipped:Io.boolean().optional(),envKey:Io.string().optional().describe("key in the environment to save the result of this step to"),aiSuggested:Io.boolean().optional()});Ce(Mc);var Pt=It.extend({type:Mc.literal("PRESET_ACTION"),command:Ao,skipped:Mc.boolean().optional()}).openapi({ref:"PresetAction"});Ce(Nc);var Lr=It.extend({type:Nc.literal("AI_ACTION"),text:Nc.string(),steps:Pt.array().optional()}).openapi({ref:"AIAction"});import{z as ie}from"zod";var nx=ie.object({cacheKey:ie.string(),cacheExpiryMs:ie.number()}),kc=It.extend({id:ie.string().uuid().describe("ID of the module step itself. Used to 'namespace' step cache entries."),inputs:ie.record(ie.string()).optional(),cacheConfig:nx.optional()}),Bn=kc.extend({type:ie.literal("MODULE"),moduleId:ie.string().uuid()}),rx=ie.union([Bn.pick({type:!0,moduleId:!0}),ie.record(ie.unknown())]),ox=ie.object({type:ie.literal("URL_REGEX"),regex:ie.string()}),ix=ie.object({type:ie.literal("PAGE_CHECK"),substring:ie.string()}),_c=ie.object({cacheInvalidation:ie.discriminatedUnion("type",[ix,ox]).optional()}),Lt=ie.object({moduleId:ie.string().uuid(),name:ie.string(),description:ie.string().nullish(),enabled:ie.boolean().nullish(),parameters:ie.string().array().nullish(),defaultParameters:ie.record(ie.string(),ie.string()).nullish(),parameterEnums:ie.record(ie.string(),ie.string().array()).nullish(),defaultCacheKey:ie.string().nullish(),defaultCacheTtl:ie.number().nullish(),defaultCacheAllInvocations:ie.boolean().nullish(),autoAuth:ie.boolean().nullish(),advanced:_c.nullish()});import{z as at}from"zod";import{z as Dc}from"zod";Ce(Dc);var Po=It.extend({type:Dc.literal("AI_ACTION_DYNAMIC"),text:Dc.string()}).openapi({ref:"AIActionDynamic"});import{z as hm}from"zod";var Fc=It.extend({type:hm.literal("CONDITIONAL"),skipped:hm.boolean().optional()});import{z as os}from"zod";var ax=os.object({type:os.literal("url"),url:os.string()}),Wi=It.extend({type:os.literal("IFRAME"),identifier:ax});import{z as Wt}from"zod";var Uc=(r=>(r.ALWAYS="ALWAYS",r.ON_FAILURE="ON_FAILURE",r.ON_ACTION_FAILURE="ON_ACTION_FAILURE",r))(Uc||{});var sx=Wt.discriminatedUnion("type",[Wt.object({type:Wt.literal("NAVIGATE_URL"),url:Wt.string().url()}),Wt.object({type:Wt.literal("GO_TO_SECTION_START")})]),lx=Wt.object({trigger:Wt.nativeEnum(Uc).optional(),attempts:Wt.number().int().optional(),restartBehavior:sx}),Vi=It.extend({type:Wt.literal("SECTION"),description:Wt.string().describe("user provided goal of what the section should accomplish"),plan:Wt.string().array().optional(),autohealingConfig:lx.optional()});var gm=Lt.merge(kc).extend({type:at.literal("RESOLVED_MODULE"),steps:at.lazy(()=>Le.array())}),Bc=Lt.extend({steps:at.lazy(()=>Le.array())}),zc=Wi.extend({steps:at.lazy(()=>we.array())}),cx=Wi.extend({steps:at.lazy(()=>Le.array())}),Hc=Vi.extend({steps:at.lazy(()=>we.array())}),dx=Vi.extend({steps:at.lazy(()=>Le.array())}),Or=Fc.extend({blocks:at.object({assertion:at.lazy(()=>Pt),steps:at.lazy(()=>we.array())}).array(),elseSteps:at.lazy(()=>we.array().optional())}),px=Fc.extend({blocks:at.object({assertion:at.lazy(()=>Pt),steps:at.lazy(()=>Le.array())}).array(),elseSteps:at.lazy(()=>Le.array().optional())}),we=at.discriminatedUnion("type",[Pt,Lr,Po,Bn,Or,zc,Hc]),Le=at.discriminatedUnion("type",[Pt,Lr,Po,gm,px,cx,dx]);import{z as Vt}from"zod";var ux=Vt.object({steps:we.array(),beforeSteps:we.array().nullish(),afterSteps:we.array().nullish()}),Lo=Vt.object({steps:Le.array(),beforeSteps:Le.array().nullish(),afterSteps:Le.array().nullish()}),Mr=Vt.object({steps:Vt.record(Vt.string(),Vt.unknown()).array(),beforeSteps:Vt.record(Vt.string(),Vt.unknown()).array().nullish(),afterSteps:Vt.record(Vt.string(),Vt.unknown()).array().nullish()});var Oe="1.0.20";import{z as ir}from"zod";var jc=ir.object({key:ir.string(),testId:ir.string().optional(),moduleId:ir.string().optional(),organizationId:ir.string(),value:Pr}),$c=jc.extend({uniqueKey:ir.string()}),HF=ir.record(ir.string(),$c);var fm=_.object({phrase:_.string()}),Gc=_.object({thoughts:_.string().optional(),result:_.union([_.literal("NOT_FOUND"),_.string(),_.number(),_.array(_.unknown()),_.record(_.unknown(),_.unknown()),_.unknown()])}),E0=_.object({text:_.string()}),Sm=_.object({thoughts:_.string(),review:_.string().optional(),id:_.number().int(),updatedMemory:Ec.optional()}),is=(u=>(u.NO_DESCRIPTION_PROVIDED="NO_DESCRIPTION_PROVIDED",u.FEW_WORDS="FEW_WORDS",u.STYLE_TAG="STYLE_TAG",u.TYPE_IN_DESCRIPTION="TYPE_IN_DESCRIPTION",u.HARDCODED_ATTRIBUTE="HARDCODED_ATTRIBUTE",u.NONE="NONE",u.AMBIGUOUS_DESCRIPTION="AMBIGUOUS_DESCRIPTION",u.AMBIGUOUS_ASSERTION="AMBIGUOUS_ASSERTION",u.PREFER_PAGE_CHECK="PREFER_PAGE_CHECK",u.PREFER_ASSERTION="PREFER_ASSERTION",u.HTML_ELEMENTS="HTML_ELEMENTS",u.MULTIPLE_ELEMENTS_DESCRIPTION="MULTIPLE_ELEMENTS_DESCRIPTION",u))(is||{});var ym=_.object({thoughts:_.string(),category:_.nativeEnum(is)}),mx=_.discriminatedUnion("op",[_.object({op:_.literal("replace"),path:_.string(),value:_.string()}),_.object({op:_.literal("add"),path:_.string(),value:_.string()}),_.object({op:_.literal("remove"),path:_.string()})]),x0=_.object({thoughts:_.string(),patches:mx.array()}),bm=[_.literal("add"),_.literal("replace"),_.literal("remove")],hx=_.object({op:_.union(bm),path:_.string(),value:Le.optional()}),wm=_.object({patches:hx.array(),thoughts:_.string()});var gx=_.object({thoughts:_.string(),op:_.union(bm),value:_.union([_.null(),Le])}),vm=_.object({reasoning:_.string(),scenario:_.string(),patch:gx.or(_.null())}),C0=_.object({thoughts:_.string(),evaluation:_.number().min(1).max(10)}),R0=_.object({observations:_.string(),reasoning:_.string(),command:rs});var Wc=_.object({summary:_.string(),reasoning:_.string(),evaluation:_.discriminatedUnion("type",[_.object({type:_.literal("DONE")}),_.object({type:_.literal("RIGHT_TRACK")}),_.object({type:_.literal("WRONG_TRACK"),feedback:_.string()}),_.object({type:_.literal("IMPOSSIBLE")})])});import{z as N}from"zod";import*as Q from"zod";var M0=Q.object({thoughts:Q.string().optional().describe("only provided if a description was provided"),target:Ir.optional().describe("only provided if a description was provided"),pageState:Q.string().optional().describe("serialized a11y tree, only provided if a description was provided"),options:Q.object({label:Q.string(),value:Q.string()}).array().optional().describe("list of options, provided for <select> elements only"),screenshot:Q.object({data:Q.string(),height:Q.number().int(),width:Q.number().int()}).optional().describe("only provided if returnScreenshot is true")}),as=Q.union([Q.literal("ELEMENT_CHECK"),Q.literal("NEGATED_CHECK"),Q.literal("NEGATED_ELEMENT_VISIBLE_CHECK"),Q.literal("SELECT_OPTION"),Q.literal("TYPE")]);function Nr(n){if(!("useSelector"in n&&n.useSelector)){if(n.type==="SELECT_OPTION")return"SELECT_OPTION";if(n.type==="TYPE")return"TYPE";if(n.type==="ELEMENT_CHECK"&&n.assertion.type==="ELEMENT_EXISTENCE"&&n.assertion.condition==="EXISTS"&&n.assertion.negated)return"NEGATED_CHECK";if(n.type==="ELEMENT_CHECK"&&n.assertion.type==="ELEMENT_EXISTENCE"&&n.assertion.condition==="VISIBLE"&&n.assertion.negated)return"NEGATED_ELEMENT_VISIBLE_CHECK";if(n.type==="ELEMENT_CHECK")return"ELEMENT_CHECK"}}var qi=(a=>(a.USER_SELECTOR="USER_SELECTOR",a.CSS_SELECTOR="CSS_SELECTOR",a.HYBRID_SELECTOR="HYBRID_SELECTOR",a.HTML_DISTANCE="HTML_DISTANCE",a.TEMPLATE_MATCHING="TEMPLATE_MATCHING",a.AUTO_FRAME="AUTO_FRAME",a))(qi||{}),Oo=Q.object({matched:Q.boolean(),reason:Q.string().optional().describe("Human understandable description"),logs:Q.string().array().optional().describe("Logs for debugging")}),fx=Oo.extend({type:Q.literal("USER_SELECTOR")}),Sx=Oo.extend({type:Q.literal("CSS_SELECTOR"),selectors:Q.string().array()}),yx=Oo.extend({type:Q.literal("HYBRID_SELECTOR")}),bx=Oo.extend({type:Q.literal("HTML_DISTANCE"),distance:Q.number().optional(),closestElement:Q.string().optional(),savedElement:Q.string().optional()}),wx=Oo.extend({type:Q.literal("TEMPLATE_MATCHING"),elementImageUrl:Q.string().url()}),vx=Oo.extend({type:Q.literal("AUTO_FRAME"),logs:Q.string().array().optional()}),Tm=Q.discriminatedUnion("type",[fx,Sx,yx,bx,wx,vx]);import{z as Zi}from"zod";import{z as $C}from"zod";import*as J from"zod";import{cloneDeep as Ji}from"lodash-es";var Tx=n=>{let e=Em(n,0);if(e===void 0||!xx(n[e]))return;let t=Em(n,e+1);if(t!==void 0)return Cx(n,e,t)},xm=Tx,Em=(n,e)=>{for(let t=e;t<n.length;t+=1){let r=n[t];if(!Ex(r))return t}},Ex=n=>n===" "||n===" "||n===`
5
5
  `||n==="\r",xx=n=>n==="{"||n==="[",Cx=(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 Rx(r);if(r===void 0)r=i;else if(r[0]===i)r+=i;else return}},Rx=n=>n===void 0?0:n[0]===" "?n.length:n;var Cm=(n,e)=>{let t=Vc(n,"toPrecision",e,e);return t===void 0?Vc(n,"toExponential",e,e):t},Vc=(n,e,t,r)=>{let i=n[e](r).replace(Ax,"$1").replace(Ix,"$1");return i.length<=t?i:r===1?void 0:Vc(n,e,t,r-1)},Ax=/(e)\+/iu,Ix=/\.?0*($|e)/iu;var Am=(n,e)=>{if(typeof n!="string")throw new TypeError(`Input must be a JSON string: ${n}`);Px(e)},Px=n=>{if(Lx(n),n<0)throw new TypeError(`"maxSize" argument must be positive: ${n}`);if(n<Rm)throw new TypeError(`"maxSize" argument must be at least ${Rm}: ${n}`)},Lx=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}`)},Rm=7;var ss=(n,e,t)=>{let r=Pm(e,t);return Im(n,e,r)},Im=(n,e,t)=>{if(t>=e)return t;let r=n[t];return r>=Bx&&r<=zx?Im(n,e,t+1):t},ls=(n,e,t)=>{if(t===void 0)return t;let r=Pm(e,t);return Ox(n,r)},Ox=(n,e)=>Mx(n,e)?e-3:Nx(n,e)?e-2:kx(n,e)?e-1:e,Mx=(n,e)=>e>=3&&n[e-3]>=_x&&n[e-3]<=Dx,Nx=(n,e)=>e>=2&&n[e-2]>=Fx,kx=(n,e)=>e>=1&&n[e-1]>=Ux,Pm=(n,e)=>e<0||Object.is(e,-0)?Math.max(n+e,0):e,_x=240,Dx=244,Fx=224,Ux=194,Bx=128,zx=191;var Lm=(n,e,t)=>{let r=globalThis.Buffer.from(n),o=ss(r,r.length,e),i=ls(r,r.length,t);return o===0&&i>=r.length?r.toString():r.toString("utf8",o,i)};var Om=/[\uD800-\uDFFF]/gu,Mm="\uFFFD";var cs=n=>Hx(n)?n.replace(Om,Mm):n,Hx=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 Yc=({input:n,targetByteCount:e,firstStartSurrogate:t,lastStartSurrogate:r,firstEndSurrogate:o,lastEndSurrogate:i,increment:a,canBacktrack:s,shift:l,charIndexInit:c})=>{let d=c,p=d,u=0;for(;u<e;d+=a){p=d;let h=n.charCodeAt(d);if(Number.isNaN(h))break;if(h<=127){u+=1;continue}if(h<=2047){u+=2;continue}if(u+=3,h<t||h>r)continue;let g=n.charCodeAt(d+a);Number.isNaN(g)||g<o||g>i||(u+=1,d+=a)}return(s&&u>e?p:d)+l};var Jc=(n,e,t)=>e<0||Object.is(e,-0)?qx(n,e,t):Vx(n,e,t),Vx=(n,e,t)=>Yc({input:n,targetByteCount:e,firstStartSurrogate:55296,lastStartSurrogate:56319,firstEndSurrogate:56320,lastEndSurrogate:57343,increment:1,canBacktrack:t,shift:0,charIndexInit:0}),qx=(n,e,t)=>Yc({input:n,targetByteCount:-e,firstStartSurrogate:56320,lastStartSurrogate:57343,firstEndSurrogate:55296,lastEndSurrogate:56319,increment:-1,canBacktrack:!t,shift:1,charIndexInit:n.length-1});var ds=(n,e,t)=>{let r=Jc(n,e,!1),o=Kx(n,t),i=r===0&&o===void 0?n:n.slice(r,o);return cs(i)},Kx=(n,e)=>{if(e===void 0)return e;let t=Jc(n,e,!0);return t===n.length?void 0:t};var km=(n,e,t)=>{let{textEncoder:r,textDecoder:o}=Yx(),i=Jx(n),{written:a}=r.encodeInto(n,i),s=ss(i,a,e),l=ls(i,a,t),c=l===void 0?a:Math.min(l,a),d=i.subarray(s,c);return o.decode(d)},Yx=()=>(Xc===void 0&&(Xc=new globalThis.TextEncoder,Nm=new globalThis.TextDecoder("utf8",{fatal:!1})),{textEncoder:Xc,textDecoder:Nm}),Xc,Nm,Jx=n=>{let e=n.length*3;return e>Xx?new Uint8Array(e):((ps===void 0||ps.length<e)&&(ps=new Uint8Array(e)),ps)},Xx=1e5,ps;var _m=(n,e)=>{if(e===void 0)return e;let t=Qc(n,e);return t>=n.length*Dm?void 0:t},Qc=(n,e)=>e<=n.length*-Dm?0:e,Dm=4;var Fm=(n,e,t)=>{if(typeof n!="string")throw new TypeError(`First argument must be a string: ${n}`);Qx(e),Zx(t)},Qx=n=>{if(n===void 0)throw new TypeError("Second argument is required.");Um("Second",n)},Zx=n=>{n!==void 0&&Um("Third",n)},Um=(n,e)=>{if(!Number.isInteger(e))throw new TypeError(`${n} argument must be an integer: ${e}`)};var Bm=n=>{let e=!0,t=0;for(let r=0;r<Zc;r+=1){let o=eC(n,r);o<=127||(e&&(e=!1),o>2047&&(t+=1))}return{asciiOnly:e,longCharsPercentage:t/Zc}},eC=(n,e)=>{let t=Zc-1,r=1-(t-e)/t,o=Math.round(r*(n.length-1));return n.charCodeAt(o)},Zc=50;var tC=(n,e,t)=>{if(Fm(n,e,t),n==="")return n;let r=Qc(n,e),o=_m(n,t);return o===void 0&&Object.is(r,0)?cs(n):nC(n,r,o)},zm=tC,nC=(n,e,t)=>{if(n.length<=rC)return ds(n,e,t);let{asciiOnly:r,longCharsPercentage:o}=Bm(n);return r?iC(n,e,t):o>=oC?ds(n,e,t):Hm(n,e,t)},rC=200,oC=.4,iC=(n,e,t)=>"Buffer"in globalThis&&"from"in globalThis.Buffer?Lm(n,e,t):Hm(n,e,t),Hm=(n,e,t)=>"TextEncoder"in globalThis?km(n,e,t):ds(n,e,t);var $m=(n,e)=>{let t=JSON.stringify(n),r=lC(t),o=zm(r,0,e-jm.length-Ki.length*2),a=`${aC(o)}${jm}`;return cC(a)},aC=n=>n.replace(sC,""),sC=/(\\|\\u[0-9a-fA-F]{0,3})$/u,lC=n=>n.slice(Ki.length,-Ki.length),cC=n=>`${Ki}${n}${Ki}`,Ki='"',jm="...";var Gm=n=>globalThis.Buffer.byteLength(n);var ed=n=>{let e=n.length,t=e;for(let r=0;r<e;r+=1){let o=n.charCodeAt(r);if(o<=dC)continue;if(o<=pC){t+=1;continue}if(t+=2,o<uC||o>mC)continue;let i=n.charCodeAt(r+1);i<hC||i>gC||(r+=1)}return t},dC=127,pC=2047,uC=55296,mC=56319,hC=56320,gC=57343;var Wm=()=>fC.bind(void 0,new TextEncoder),fC=(n,e)=>{let t=SC(e);return n.encodeInto(e,t).written},SC=n=>{let e=n.length*3;return e>yC?new Uint8Array(e):((us===void 0||us.length<e)&&(us=new Uint8Array(e)),us)},yC=1e5,us;var wC=()=>"Buffer"in globalThis&&"byteLength"in globalThis.Buffer?Gm:"TextEncoder"in globalThis?vC.bind(void 0,Wm()):ed,vC=(n,e)=>e.length<100?ed(e):n(e),Vm=wC();var qm=n=>{if(n===null)return TC;if(n===!0)return EC;if(n===!1)return xC;let e=typeof n;return e==="object"?CC:e==="number"?JSON.stringify(n).length:td(n)},TC=4,EC=4,xC=5,CC=2,td=n=>Vm(JSON.stringify(n));var ms=({size:n,increment:e,maxSize:t,truncatedProps:r,path:o,value:i})=>{let a=n+e,s=a>t;return s?{size:n,stop:s,truncatedProps:[...r,{path:o,value:i}]}:{size:a,stop:s,truncatedProps:r}},Ym=n=>qm(n),Jm=(n,e,t)=>{let r=Qm({empty:n,indent:e,depth:t,keySpaceSize:0}),o=Zm(n);return r+o},Xm=({key:n,empty:e,indent:t,depth:r})=>{let o=Qm({empty:e,indent:t,depth:r,keySpaceSize:1}),i=td(n),a=Zm(e);return o+i+RC+a},RC=1,Qm=({empty:n,indent:e,depth:t,keySpaceSize:r})=>{if(e===void 0)return 0;let o=Km+e*(t+1),i=n?Km+e*t:0;return r+o+i},Km=1,Zm=n=>n?0:AC,AC=1;var hs=({parent:n,truncatedProps:e,path:t,increment:r,maxSize:o,key:i,empty:a,size:s,truncateValue:l,indent:c,depth:d})=>{let p=n[i],u=[...t,i],{size:m,stop:h,truncatedProps:g}=ms({size:s,increment:r,maxSize:o,truncatedProps:e,path:u,value:p});return h?{empty:a,size:m,truncatedProps:g}:IC({value:p,truncatedProps:e,path:u,maxSize:o,empty:a,size:s,newSize:m,truncateValue:l,indent:c,depth:d})},IC=({value:n,truncatedProps:e,path:t,maxSize:r,empty:o,size:i,newSize:a,truncateValue:s,indent:l,depth:c})=>{let{value:d,size:p,truncatedProps:u}=s({value:n,truncatedProps:e,path:t,size:a,maxSize:r,indent:l,depth:c+1});return d===void 0?{empty:o,size:i,truncatedProps:u}:{empty:!1,size:p,value:d,truncatedProps:u}};var eh=({array:n,truncatedProps:e,path:t,size:r,maxSize:o,truncateValue:i,indent:a,depth:s})=>{let l=[],c={empty:!0,size:r,truncatedProps:e};for(let d=0;d<n.length;d+=1){let p=Jm(c.empty,a,s);c=hs({parent:n,truncatedProps:c.truncatedProps,path:t,increment:p,maxSize:o,key:d,empty:c.empty,size:c.size,truncateValue:i,indent:a,depth:s}),c.value!==void 0&&l.push(c.value)}return{value:l,size:c.size,truncatedProps:c.truncatedProps}};var th=({object:n,truncatedProps:e,path:t,size:r,maxSize:o,truncateValue:i,indent:a,depth:s})=>{let l={},c={empty:!0,size:r,truncatedProps:e};for(let d in n){let p=Xm({key:d,empty:c.empty,indent:a,depth:s});c=hs({parent:n,truncatedProps:c.truncatedProps,path:t,increment:p,maxSize:o,key:d,empty:c.empty,size:c.size,truncateValue:i,indent:a,depth:s}),c.value!==void 0&&(l[d]=c.value)}return{value:l,size:c.size,truncatedProps:c.truncatedProps}};var gs=({value:n,truncatedProps:e,path:t,size:r,maxSize:o,indent:i,depth:a})=>{let s=Ym(n),{size:l,stop:c,truncatedProps:d}=ms({size:r,increment:s,maxSize:o,truncatedProps:e,path:t,value:n});return c?{value:void 0,size:l,truncatedProps:d}:PC({value:n,truncatedProps:d,path:t,size:l,maxSize:o,indent:i,depth:a})},PC=({value:n,truncatedProps:e,path:t,size:r,maxSize:o,indent:i,depth:a})=>typeof n!="object"||n===null?{value:n,size:r,truncatedProps:e}:Array.isArray(n)?eh({array:n,truncatedProps:e,path:t,size:r,maxSize:o,truncateValue:gs,indent:i,depth:a}):th({object:n,truncatedProps:e,path:t,size:r,maxSize:o,truncateValue:gs,indent:i,depth:a});var LC=(n,e)=>{Am(n,e);let t=OC(n),r=MC(n),{value:o,truncatedProps:i}=gs({value:r,truncatedProps:[],path:[],size:0,maxSize:e,indent:t,depth:0});return{jsonString:NC({newValue:o,value:r,maxSize:e,indent:t}),truncatedProps:i}},Mo=LC,OC=n=>{let e=xm(n);return typeof e=="string"?e.length:e},MC=n=>{try{return JSON.parse(n)}catch(e){throw new TypeError(`Invalid JSON string: "${n}"
@@ -46,7 +46,7 @@ globstar while`,e,u,t,m,h),this.matchOne(e.slice(u),t.slice(m),r))return this.de
46
46
  First test path: ${u}
47
47
 
48
48
  Second test path: ${o}`)}t.tests[p.id]={type:ve.TEST,name:p.name,id:p.id,description:p.description??void 0,labels:p.labels,...d};return}catch(p){r.warn(`Skipping file '${o}' because it is missing Momentic test metadata: ${p}`);return}case ve.MODULE:try{let p=Lt.parse(a);t.modules[p.moduleId]={type:ve.MODULE,name:p.name,id:p.moduleId,description:p.description??void 0,...d};let u=d.fileName.replace(".module.yaml","");!ly&&Ie(p.name)!==u&&r.warn(`The module with ID ${p.moduleId} has a name (${p.name}) that does not match its file name (${u}). We recommend renaming the module or the file to be consistent to avoid confusion and issues with module resolution.`);return}catch(p){r.warn(`Skipping file '${o}' because it is missing Momentic module metadata: ${p}`);return}default:r.warn(`Unsupported file type ${l}, skipping...`);return}}var ni="momentic.config.yaml",cy="momentic.workspace.yaml",OP=Te.object({projects:Te.string().array().describe("list of glob patterns to find project (momentic.config.yaml) files")}),MP=Te.union([Te.string(),Te.object({fromFile:Te.string(),json:Te.boolean().optional()})]),NP=Te.object({name:lp,baseUrl:Te.string(),envFile:Te.string().optional().describe("path to a file on disk to read environment variables from. can be relative to project root or absolute."),envVariables:Te.record(Te.string(),MP).optional(),inheritFromShell:Te.boolean().optional().describe("inherit all environment variables from the shell - might be noisy"),browser:kr.optional()}),kP=Te.object({postSave:Te.string().optional()}),_P=Te.object({name:lp,include:Te.string().array().optional().describe("list of glob patterns that match momentic files (optional)"),exclude:Te.string().array().optional().describe("opposite of include, takes precedence over include"),goldenFileDir:Te.string().optional(),reporterDir:Te.string().optional(),outputDir:Te.string().optional(),retries:Te.number().optional().describe("number of retries per test"),parallel:Te.number().optional().describe("degree of parallelism"),environments:Te.array(NP).optional(),gitMainBranch:Te.string().optional(),gitProtectedBranches:Te.string().array().optional(),ai:Id.optional(),browser:kr.extend({disableSecondaryCacheResolution:Te.boolean().optional()}).optional(),advanced:yg.optional(),hooks:kP.optional()});function uy(n,e){let t;try{t=IP(n,"utf-8")}catch(o){b.warn(`Could not read possible Momentic ${e} file at ${n}: ${o}`);return}let r;try{if(r=py.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){b.warn(`Possible Momentic ${e} file at ${n} does not parse as valid YAML: ${o}`);return}return r}function pp(n){let e=uy(n,"project configuration");if(e!==void 0)try{return _P.parse(e)}catch(t){b.warn(`Possible Momentic project configuration file at ${n} does not adhere to the required schema: ${t}`);return}}function DP(n){let e=uy(n,"workspace configuration");if(e!==void 0)try{return OP.parse(e)}catch(t){b.warn(`Possible Momentic workspace configuration file at ${n} does not adhere to the required schema: ${t}`);return}}function FP(){let n=[],e=dp(),t=ro.parse(e).root,r=15,o=0;for(;o<r;){o++;let i=ro.basename(e);if(Hs.includes(i))return b.warn(`Stopping search for Momentic projects since the current directory name (${i}) is likely a system artifact folder.`),n;for(let a of PP(e))if(a.endsWith(ni)){let s=ro.join(e,a),l=pp(s);l&&n.push({configFilePath:s,config:l,rootDir:dy(s)})}if(n.length)return n;if(e=ro.dirname(e),e===t)break}return n}function jt(n={}){let{configFilePath:e,nameFilter:t}=n,r=up(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:
49
- ${r.map(o=>o.configFilePath)}`);if(r.length===0)throw new Error("No valid Momentic project file available.");return b.debug(`Found valid project configuration at ${r[0].configFilePath}`),r[0]}function UP(n){let e=DP(n);if(!e||!e.projects||!e.projects.length)return;let t=e.projects.map(i=>(i.endsWith("/")||(i+="/"),`${i}*${ni}`)),r=ti(t,{absolute:!1,cwd:dp(),dotRelative:!1,maxDepth:cp,nodir:!0}),o=[];for(let i of r){let a=ro.join(dp(),i),s=pp(a);s&&o.push({configFilePath:a,config:s,rootDir:dy(a)})}return o}function up(n){if(n){n=ro.resolve(n);let t=pp(n);return t||(console.error(`No valid Momentic project file found at ${n}.`),process.exit(1)),[{config:t,configFilePath:n,rootDir:ro.dirname(n)}]}if(AP(cy)){let t=UP(cy);if(t)return t}return FP()}function ri(n,e){let t=py.stringify(n);LP(e,t)}import oi from"fs";import mp from"path";import{z as hp}from"zod";var my="golden/visual-diff",hy="reports",gy="test-results";var BP=hp.object({width:hp.number(),height:hp.number()}),ii=class{defaultGoldenScreenshotDir;regenerateGoldenFiles;constructor(e,t){let r=mp.join(e.rootDir,e.config.goldenFileDir??my);this.defaultGoldenScreenshotDir=r,this.regenerateGoldenFiles=t}async prepareGoldenScreenshotForComparison(e,t,r){if(t.screenshot?.data?.startsWith("https://")){let a=await fetch(t.screenshot.data);return{buffer:Buffer.from(await a.arrayBuffer()),width:t.screenshot.width,height:t.screenshot.height}}let o=t.screenshot?.data;o||(o=mp.join(this.defaultGoldenScreenshotDir,`${t.id}.jpg`));let i=`${o}.metadata.json`;if(this.regenerateGoldenFiles)return oi.mkdirSync(mp.dirname(o),{recursive:!0}),oi.writeFileSync(o,r.buffer),oi.writeFileSync(i,JSON.stringify({width:r.width,height:r.height})),{buffer:Buffer.from(r.buffer),width:r.width,height:r.height};if(oi.existsSync(o)){let a=oi.readFileSync(o),s=BP.parse(JSON.parse(oi.readFileSync(i,"utf-8")));return{buffer:a,width:s.width,height:s.height}}else throw new R("UserConfigurationError",`Cannot execute visual diff without a saved baseline screenshot at ${o}`)}};var ai=class{flags;constructor(e){this.flags={auto_expand_iframes:e.browser?.autoExpandIframes??!1,rag_v2:e.ai?.aiPageFiltering??!1,faker_constant_seed:e.advanced?.fakerConstantSeed??!1,disable_secondary_cache_resolution:e.browser?.disableSecondaryCacheResolution??!1,show_zero_opacity_elements:e.browser?.showZeroOpacityElements??!1,global_locator_redirect:e.browser?.globalLocatorRedirect??!1,visual_actions:e.browser?.visualActions??!1,mini_model_initial_assertion:!1,mini_model_initial_locator:!1,show_test_plans:!1,icon_knowledge_base:!1,disable_clickhouse_caches:!1,disable_clickhouse_last_updated_endpoint:!1}}isBooleanFlagEnabled(e){return this.flags[e]}getAllFlags(){return{...this.flags}}getFlagPayload(e){}async refresh(){}};import zP from"simple-git";var Ee=zP();function vl(n){if(n.startsWith("git@")){let e=n.split(":");if(e.length===2){let t=e[1].replace(".git","").split("/");if(t.length===2){let r=t[0],o=t[1];return`${r}/${o}`}}}else if(n.startsWith("http")||n.startsWith("https")){let t=new URL(n).pathname.split("/").filter(Boolean);if(t.length>=2){let r=t[0],o=t[1].replace(".git","");return`${r}/${o}`}}}async function xe(n,e){try{return(await e).trim()}catch(t){n.error({err:t},"Failed to run git command");return}}function HP(){if(process.env.GITHUB_ACTION)return"GithubActions";if(process.env.GITLAB_CI)return"GitlabCI";if(process.env.CIRCLECI)return"CircleCI";if(process.env.BUILDKITE)return"Buildkite";if(process.env["System.CollectionUri"]?.includes("azure"))return"AzureDevOps";if(process.env.PROJECT_ID&&process.env.BUILD_ID)return"GCPCloudBuild"}async function jP(n){let[e,t,r,o]=await Promise.all([xe(n,Ee.show(["--no-patch","--format=%ci"])),xe(n,Ee.listRemote(["--get-url","origin"])),xe(n,Ee.show(["-s","--pretty=%B"])),xe(n,Ee.show(["-s","--pretty=%an"]))]);return{gitCommitSha:process.env.GITHUB_SHA,gitCommitShaShort:process.env.GITHUB_SHA?.slice(0,6),gitCommitTimestamp:e?new Date(e):void 0,gitBranchName:process.env.GITHUB_HEAD_REF||process.env.GITHUB_REF_NAME,gitOriginUrl:t,gitCommitMessage:r,gitCommitAuthorName:o,githubRepository:process.env.GITHUB_REPOSITORY,pipelineId:`${process.env.GITHUB_RUN_ID}:${process.env.GITHUB_RUN_ATTEMPT}`}}async function $P(n){let[e,t,r]=await Promise.all([xe(n,Ee.listRemote(["--get-url","origin"])),xe(n,Ee.show(["-s","--pretty=%B"])),xe(n,Ee.show(["-s","--pretty=%an"]))]);return{gitCommitSha:process.env.CI_COMMIT_SHA,gitCommitShaShort:process.env.CI_COMMIT_SHORT_SHA,gitCommitTimestamp:process.env.CI_COMMIT_TIMESTAMP?new Date(process.env.CI_COMMIT_TIMESTAMP):void 0,gitBranchName:process.env.CI_COMMIT_BRANCH||process.env.CI_COMMIT_REF_NAME,gitOriginUrl:e,gitCommitMessage:t,gitCommitAuthorName:r,gitlabProjectPath:process.env.CI_SERVER_HOST,pipelineId:`${process.env.CI_PIPELINE_ID}:${process.env.CI_JOB_ID}`}}async function GP(n){let[e,t,r,o]=await Promise.all([xe(n,Ee.show(["--no-patch","--format=%ci"])),xe(n,Ee.listRemote(["--get-url","origin"])),xe(n,Ee.show(["-s","--pretty=%B"])),xe(n,Ee.show(["-s","--pretty=%an"]))]),i=t?.includes("github.com"),a=t?.includes("gitlab.com"),s=t?vl(t):void 0;return{gitCommitSha:process.env.CIRCLE_SHA1,gitCommitShaShort:process.env.CIRCLE_SHA1?.slice(0,6),gitCommitTimestamp:e?new Date(e):void 0,gitBranchName:process.env.CIRCLE_BRANCH,gitOriginUrl:process.env.CIRCLE_REPOSITORY_URL,gitCommitMessage:r,gitCommitAuthorName:o,githubRepository:i?s:void 0,gitlabProjectPath:a?s:void 0,pipelineId:`${process.env.CIRCLE_WORKFLOW_ID}:${process.env.CIRCLE_WORKFLOW_JOB_ID}`}}async function WP(n){let[e,t,r]=await Promise.all([xe(n,Ee.show(["--no-patch","--format=%ci"])),xe(n,Ee.show(["-s","--pretty=%B"])),xe(n,Ee.show(["-s","--pretty=%an"]))]),o=process.env.BUILDKITE_REPO,i=o?.includes("github.com"),a=o?.includes("gitlab.com"),s=o?vl(o):void 0;return{gitCommitSha:process.env.BUILDKITE_COMMIT,gitCommitShaShort:process.env.BUILDKITE_COMMIT?.slice(0,6),gitCommitTimestamp:e?new Date(e):void 0,gitBranchName:process.env.BUILDKITE_BRANCH,gitOriginUrl:o,gitCommitMessage:t,gitCommitAuthorName:r,githubRepository:i?s:void 0,gitlabProjectPath:a?s:void 0,pipelineId:`${process.env.BUILDKITE_PIPELINE_ID}:${process.env.BUILDKITE_BUILD_ID}:${process.env.BUILDKITE_JOB_ID}`}}async function VP(n){let[e,t,r]=await Promise.all([xe(n,Ee.show(["--no-patch","--format=%ci"])),xe(n,Ee.show(["-s","--pretty=%B"])),xe(n,Ee.show(["-s","--pretty=%an"]))]),o=process.env["Build.Repository.Uri"],i=o?.includes("github.com"),a=o?.includes("gitlab.com"),s=o?vl(o):void 0;return{gitCommitSha:process.env["Build.SourceVersion"],gitCommitShaShort:process.env["Build.SourceVersion"]?.slice(0,6),gitCommitTimestamp:e?new Date(e):void 0,gitBranchName:process.env["Build.SourceBranchName"],gitOriginUrl:o,gitCommitMessage:t,gitCommitAuthorName:r,githubRepository:i?s:void 0,gitlabProjectPath:a?s:void 0,pipelineId:`${process.env["System.JobId"]}:${process.env["System.JobAttempt"]}`}}async function qP(n,e){let[t,r,o,i,a,s,l,c]=await Promise.all([xe(n,Ee.revparse(["HEAD"])),xe(n,Ee.revparse(["--short","HEAD"])),xe(n,Ee.revparse(["--abbrev-ref","HEAD"])),xe(n,Ee.listRemote(["--get-url","origin"])),xe(n,Ee.show(["--no-patch","--format=%ci"])),xe(n,Ee.show(["-s","--pretty=%B"])),xe(n,Ee.show(["-s","--pretty=%an"])),e?xe(n,Ee.raw(["merge-base","--fork-point",e])):Promise.resolve(void 0)]),d=c?await xe(n,Ee.show(["--no-patch","--format=%ci",c])):void 0,p=i?.includes("github.com"),u=i?.includes("gitlab.com"),m=i?vl(i):void 0;return{gitCommitSha:t,gitCommitShaShort:r,gitBranchName:o,gitOriginUrl:i,gitCommitTimestamp:a?new Date(a):void 0,gitCommitMessage:s,gitCommitAuthorName:l,lastCommitOnMainSha:c,lastCommitOnMainTimestamp:d?new Date(d):void 0,githubRepository:p?m:void 0,gitlabProjectPath:u?m:void 0,pipelineId:void 0}}async function KP(){let n=process.env._HEAD_REPO_URL;return{gitCommitSha:process.env.COMMIT_SHA,gitCommitShaShort:process.env.COMMIT_SHA?.slice(0,6),gitBranchName:process.env.BRANCH_NAME,gitOriginUrl:n?process.env._HEAD_REPO_URL:void 0,gitCommitTimestamp:void 0,gitCommitMessage:void 0,gitCommitAuthorName:void 0,githubRepository:n?process.env.REPO_FULL_NAME:void 0,gitlabProjectPath:n?void 0:process.env.REPO_FULL_NAME,pipelineId:`${process.env.PROJECT_ID}:${process.env.BUILD_ID}`}}async function YP(n){let e=n.config.gitProtectedBranches??[];return n.config.gitMainBranch&&e.push(n.config.gitMainBranch),{gitMainBranch:n.config.gitMainBranch,gitProtectedBranches:e}}async function JP(n,e){let t=HP();if(!t)return qP(n,e);switch(t){case"GithubActions":return jP(n);case"GitlabCI":return $P(n);case"CircleCI":return GP(n);case"Buildkite":return WP(n);case"AzureDevOps":return VP(n);case"GCPCloudBuild":return KP()}}async function XP(n,e,t,r){let o=r;if(!r.gitCommitSha)return o;if(r.gitMainBranch&&(!o.lastCommitOnMainSha||!o.lastCommitOnMainTimestamp)){let i=await e.getMergeBaseCommitFromGitlab(t,r.gitMainBranch,r.gitCommitSha);o={...o,lastCommitOnMainSha:i.sha,lastCommitOnMainTimestamp:i.committer.date}}if(!o.gitCommitTimestamp||!o.gitCommitAuthorName||!o.gitCommitMessage||!o.gitCommitAuthorName){let i=await e.getCommitFromGitlab(t,r.gitCommitSha);i&&(o={...o,gitCommitTimestamp:o.gitCommitTimestamp??i.committer.date,gitCommitAuthorName:o.gitCommitAuthorName??i.author.name,gitCommitMessage:o.gitCommitMessage??i.message})}return o}async function QP(n,e,t,r,o){let i=o;if(!o.gitCommitSha)return i;if(o.gitMainBranch&&(!i.lastCommitOnMainSha||!i.lastCommitOnMainTimestamp)){let a=await e.getMergeBaseCommitFromGithub(t,r,o.gitMainBranch,o.gitCommitSha);i={...i,lastCommitOnMainSha:a.sha,lastCommitOnMainTimestamp:a.committer.date}}if(!i.gitCommitTimestamp||!i.gitCommitAuthorName||!i.gitCommitMessage||!i.gitCommitAuthorName){let a=await e.getCommitFromGithub(t,r,o.gitCommitSha);a&&(i={...i,gitCommitTimestamp:i.gitCommitTimestamp??a.committer.date,gitCommitAuthorName:i.gitCommitAuthorName??a.author.name,gitCommitMessage:i.gitCommitMessage??a.message})}return i}async function ZP(n,e,t){try{if(t.githubRepository){let[r,o]=t.githubRepository.split("/");return QP(n,e,r,o,t)}else if(t.gitlabProjectPath)return XP(n,e,t.gitlabProjectPath,t)}catch(r){n.warn({err:r},"Failed to get remote git metadata")}return t}async function si(n,e,t){let r=await YP(t),o=await JP(n,r.gitMainBranch),i={...r,...o},a=await ZP(n,e,i);return{...r,...o,...a}}import mk from"http";import{z as Sp}from"zod";var z="v1",Na="2.7.0";var gr=class extends Error{constructor(e){super(e),this.name="TimeoutError"}};var fy=n=>{let e=n.reason===void 0?new DOMException("This operation was aborted.","AbortError"):n.reason;return e instanceof Error?e:new DOMException(e,"AbortError")};function B(n,e){let{milliseconds:t,fallback:r,message:o,customTimers:i={setTimeout,clearTimeout}}=e,a,s;if(typeof t!="number"||Math.sign(t)!==1)throw new TypeError(`Expected \`milliseconds\` to be a positive number, got \`${t}\``);return new Promise((l,c)=>{if(e.signal){let{signal:p}=e;if(p.aborted)return c(fy(p));s=()=>c(fy(p)),p.addEventListener("abort",s)}let d=()=>{if(r)try{l(r())}catch(p){c(p)}else{typeof n.cancel=="function"&&Promise.resolve().then(()=>n.cancel()).catch(()=>{});let p=o instanceof Error?o:new gr(o??`Promise timed out after ${t}ms`);c(p)}};a=i.setTimeout(d,t),Promise.resolve(n).then(p=>l(p)).catch(p=>c(p))}).finally(()=>{i.clearTimeout(a),e.signal&&s&&e.signal.removeEventListener("abort",s)})}var Tl=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 a=this.userActions.get(o)?.filter(s=>r-s<=this.windowMs)??[];a.length>0?this.userActions.set(o,a):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)}};var gp=["ability","able","aboard","about","above","accept","accident","according","account","accurate","acres","across","act","action","active","activity","actual","actually","add","addition","additional","adjective","adult","adventure","advice","affect","afraid","after","afternoon","again","against","age","ago","agree","ahead","aid","air","airplane","alike","alive","all","allow","almost","alone","along","aloud","alphabet","already","also","although","am","among","amount","ancient","angle","angry","animal","announced","another","answer","ants","any","anybody","anyone","anything","anyway","anywhere","apart","apartment","appearance","apple","applied","appropriate","are","area","arm","army","around","arrange","arrangement","arrive","arrow","art","article","as","aside","ask","asleep","at","ate","atmosphere","atom","atomic","attached","attack","attempt","attention","audience","author","automobile","available","average","avoid","aware","away","baby","back","bad","badly","bag","balance","ball","balloon","band","bank","bar","bare","bark","barn","base","baseball","basic","basis","basket","bat","battle","be","bean","bear","beat","beautiful","beauty","became","because","become","becoming","bee","been","before","began","beginning","begun","behavior","behind","being","believed","bell","belong","below","belt","bend","beneath","bent","beside","best","bet","better","between","beyond","bicycle","bigger","biggest","bill","birds","birth","birthday","bit","bite","black","blank","blanket","blew","blind","block","blood","blow","blue","board","boat","body","bone","book","border","born","both","bottle","bottom","bound","bow","bowl","box","boy","brain","branch","brass","brave","bread","break","breakfast","breath","breathe","breathing","breeze","brick","bridge","brief","bright","bring","broad","broke","broken","brother","brought","brown","brush","buffalo","build","building","built","buried","burn","burst","bus","bush","business","busy","but","butter","buy","by","cabin","cage","cake","call","calm","came","camera","camp","can","canal","cannot","cap","capital","captain","captured","car","carbon","card","care","careful","carefully","carried","carry","case","cast","castle","cat","catch","cattle","caught","cause","cave","cell","cent","center","central","century","certain","certainly","chain","chair","chamber","chance","change","changing","chapter","character","characteristic","charge","chart","check","cheese","chemical","chest","chicken","chief","child","children","choice","choose","chose","chosen","church","circle","circus","citizen","city","class","classroom","claws","clay","clean","clear","clearly","climate","climb","clock","close","closely","closer","cloth","clothes","clothing","cloud","club","coach","coal","coast","coat","coffee","cold","collect","college","colony","color","column","combination","combine","come","comfortable","coming","command","common","community","company","compare","compass","complete","completely","complex","composed","composition","compound","concerned","condition","congress","connected","consider","consist","consonant","constantly","construction","contain","continent","continued","contrast","control","conversation","cook","cookies","cool","copper","copy","corn","corner","correct","correctly","cost","cotton","could","count","country","couple","courage","course","court","cover","cow","cowboy","crack","cream","create","creature","crew","crop","cross","crowd","cry","cup","curious","current","curve","customs","cut","cutting","daily","damage","dance","danger","dangerous","dark","darkness","date","daughter","dawn","day","dead","deal","dear","death","decide","declared","deep","deeply","deer","definition","degree","depend","depth","describe","desert","design","desk","detail","determine","develop","development","diagram","diameter","did","die","differ","difference","different","difficult","difficulty","dig","dinner","direct","direction","directly","dirt","dirty","disappear","discover","discovery","discuss","discussion","disease","dish","distance","distant","divide","division","do","doctor","does","dog","doing","doll","dollar","done","donkey","door","dot","double","doubt","down","dozen","draw","drawn","dream","dress","drew","dried","drink","drive","driven","driver","driving","drop","dropped","drove","dry","duck","due","dug","dull","during","dust","duty","each","eager","ear","earlier","early","earn","earth","easier","easily","east","easy","eat","eaten","edge","education","effect","effort","egg","eight","either","electric","electricity","element","elephant","eleven","else","empty","end","enemy","energy","engine","engineer","enjoy","enough","enter","entire","entirely","environment","equal","equally","equator","equipment","escape","especially","essential","establish","even","evening","event","eventually","ever","every","everybody","everyone","everything","everywhere","evidence","exact","exactly","examine","example","excellent","except","exchange","excited","excitement","exciting","exclaimed","exercise","exist","expect","experience","experiment","explain","explanation","explore","express","expression","extra","eye","face","facing","fact","factor","factory","failed","fair","fairly","fall","fallen","familiar","family","famous","far","farm","farmer","farther","fast","fastened","faster","fat","father","favorite","fear","feathers","feature","fed","feed","feel","feet","fell","fellow","felt","fence","few","fewer","field","fierce","fifteen","fifth","fifty","fight","fighting","figure","fill","film","final","finally","find","fine","finest","finger","finish","fire","fireplace","firm","first","fish","five","fix","flag","flame","flat","flew","flies","flight","floating","floor","flow","flower","fly","fog","folks","follow","food","foot","football","for","force","foreign","forest","forget","forgot","forgotten","form","former","fort","forth","forty","forward","fought","found","four","fourth","fox","frame","free","freedom","frequently","fresh","friend","friendly","frighten","frog","from","front","frozen","fruit","fuel","full","fully","fun","function","funny","fur","furniture","further","future","gain","game","garage","garden","gas","gasoline","gate","gather","gave","general","generally","gentle","gently","get","getting","giant","gift","girl","give","given","giving","glad","glass","globe","go","goes","gold","golden","gone","good","goose","got","government","grabbed","grade","gradually","grain","grandfather","grandmother","graph","grass","gravity","gray","great","greater","greatest","greatly","green","grew","ground","group","grow","grown","growth","guard","guess","guide","gulf","gun","habit","had","hair","half","halfway","hall","hand","handle","handsome","hang","happen","happened","happily","happy","harbor","hard","harder","hardly","has","hat","have","having","hay","he","headed","heading","health","heard","hearing","heart","heat","heavy","height","held","hello","help","helpful","her","herd","here","herself","hidden","hide","high","higher","highest","highway","hill","him","himself","his","history","hit","hold","hole","hollow","home","honor","hope","horn","horse","hospital","hot","hour","house","how","however","huge","human","hundred","hung","hungry","hunt","hunter","hurried","hurry","hurt","husband","ice","idea","identity","if","ill","image","imagine","immediately","importance","important","impossible","improve","in","inch","include","including","income","increase","indeed","independent","indicate","individual","industrial","industry","influence","information","inside","instance","instant","instead","instrument","interest","interior","into","introduced","invented","involved","iron","is","island","it","its","itself","jack","jar","jet","job","join","joined","journey","joy","judge","jump","jungle","just","keep","kept","key","kids","kill","kind","kitchen","knew","knife","know","knowledge","known","label","labor","lack","lady","laid","lake","lamp","land","language","large","larger","largest","last","late","later","laugh","law","lay","layers","lead","leader","leaf","learn","least","leather","leave","leaving","led","left","leg","length","lesson","let","letter","level","library","lie","life","lift","light","like","likely","limited","line","lion","lips","liquid","list","listen","little","live","living","load","local","locate","location","log","lonely","long","longer","look","loose","lose","loss","lost","lot","loud","love","lovely","low","lower","luck","lucky","lunch","lungs","lying","machine","machinery","mad","made","magic","magnet","mail","main","mainly","major","make","making","man","managed","manner","manufacturing","many","map","mark","market","married","mass","massage","master","material","mathematics","matter","may","maybe","me","meal","mean","means","meant","measure","meat","medicine","meet","melted","member","memory","men","mental","merely","met","metal","method","mice","middle","might","mighty","mile","military","milk","mill","mind","mine","minerals","minute","mirror","missing","mission","mistake","mix","mixture","model","modern","molecular","moment","money","monkey","month","mood","moon","more","morning","most","mostly","mother","motion","motor","mountain","mouse","mouth","move","movement","movie","moving","mud","muscle","music","musical","must","my","myself","mysterious","nails","name","nation","national","native","natural","naturally","nature","near","nearby","nearer","nearest","nearly","necessary","neck","needed","needle","needs","negative","neighbor","neighborhood","nervous","nest","never","new","news","newspaper","next","nice","night","nine","no","nobody","nodded","noise","none","noon","nor","north","nose","not","note","noted","nothing","notice","noun","now","number","numeral","nuts","object","observe","obtain","occasionally","occur","ocean","of","off","offer","office","officer","official","oil","old","older","oldest","on","once","one","only","onto","open","operation","opinion","opportunity","opposite","or","orange","orbit","order","ordinary","organization","organized","origin","original","other","ought","our","ourselves","out","outer","outline","outside","over","own","owner","oxygen","pack","package","page","paid","pain","paint","pair","palace","pale","pan","paper","paragraph","parallel","parent","park","part","particles","particular","particularly","partly","parts","party","pass","passage","past","path","pattern","pay","peace","pen","pencil","people","per","percent","perfect","perfectly","perhaps","period","person","personal","pet","phrase","physical","piano","pick","picture","pictured","pie","piece","pig","pile","pilot","pine","pink","pipe","pitch","place","plain","plan","plane","planet","planned","planning","plant","plastic","plate","plates","play","pleasant","please","pleasure","plenty","plural","plus","pocket","poem","poet","poetry","point","pole","police","policeman","political","pond","pony","pool","poor","popular","population","porch","port","position","positive","possible","possibly","post","pot","potatoes","pound","pour","powder","power","powerful","practical","practice","prepare","present","president","press","pressure","pretty","prevent","previous","price","pride","primitive","principal","principle","printed","private","prize","probably","problem","process","produce","product","production","program","progress","promised","proper","properly","property","protection","proud","prove","provide","public","pull","pupil","pure","purple","purpose","push","put","putting","quarter","queen","question","quick","quickly","quiet","quietly","quite","rabbit","race","radio","railroad","rain","raise","ran","ranch","range","rapidly","rate","rather","raw","rays","reach","read","reader","ready","real","realize","rear","reason","recall","receive","recent","recently","recognize","record","red","refer","refused","region","regular","related","relationship","religious","remain","remarkable","remember","remove","repeat","replace","replied","report","represent","require","research","respect","rest","result","return","review","rhyme","rhythm","rice","rich","ride","riding","right","ring","rise","rising","river","road","roar","rock","rocket","rocky","rod","roll","roof","room","root","rope","rose","rough","round","route","row","rubbed","rubber","rule","ruler","run","running","rush","sad","saddle","safe","safety","said","sail","sale","salmon","salt","same","sand","sang","sat","satellites","satisfied","save","saved","saw","say","scale","scared","scene","school","science","scientific","scientist","score","screen","sea","search","season","seat","second","secret","section","see","seed","seeing","seems","seen","seldom","select","selection","sell","send","sense","sent","sentence","separate","series","serious","serve","service","sets","setting","settle","settlers","seven","several","shade","shadow","shake","shaking","shall","shallow","shape","share","sharp","she","sheep","sheet","shelf","shells","shelter","shine","shinning","ship","shirt","shoe","shoot","shop","shore","short","shorter","shot","should","shoulder","shout","show","shown","shut","sick","sides","sight","sign","signal","silence","silent","silk","silly","silver","similar","simple","simplest","simply","since","sing","single","sink","sister","sit","sitting","situation","six","size","skill","skin","sky","slabs","slave","sleep","slept","slide","slight","slightly","slip","slipped","slope","slow","slowly","small","smaller","smallest","smell","smile","smoke","smooth","snake","snow","so","soap","social","society","soft","softly","soil","solar","sold","soldier","solid","solution","solve","some","somebody","somehow","someone","something","sometime","somewhere","son","song","soon","sort","sound","source","south","southern","space","speak","special","species","specific","speech","speed","spell","spend","spent","spider","spin","spirit","spite","split","spoken","sport","spread","spring","square","stage","stairs","stand","standard","star","stared","start","state","statement","station","stay","steady","steam","steel","steep","stems","step","stepped","stick","stiff","still","stock","stomach","stone","stood","stop","stopped","store","storm","story","stove","straight","strange","stranger","straw","stream","street","strength","stretch","strike","string","strip","strong","stronger","struck","structure","struggle","stuck","student","studied","studying","subject","substance","success","successful","such","sudden","suddenly","sugar","suggest","suit","sum","summer","sun","sunlight","supper","supply","support","suppose","sure","surface","surprise","surrounded","swam","sweet","swept","swim","swimming","swing","swung","syllable","symbol","system","table","tail","take","taken","tales","talk","tall","tank","tape","task","taste","taught","tax","tea","teach","teacher","team","tears","teeth","telephone","television","tell","temperature","ten","tent","term","terrible","test","than","thank","that","thee","them","themselves","then","theory","there","therefore","these","they","thick","thin","thing","think","third","thirty","this","those","thou","though","thought","thousand","thread","three","threw","throat","through","throughout","throw","thrown","thumb","thus","thy","tide","tie","tight","tightly","till","time","tin","tiny","tip","tired","title","to","tobacco","today","together","told","tomorrow","tone","tongue","tonight","too","took","tool","top","topic","torn","total","touch","toward","tower","town","toy","trace","track","trade","traffic","trail","train","transportation","trap","travel","treated","tree","triangle","tribe","trick","tried","trip","troops","tropical","trouble","truck","trunk","truth","try","tube","tune","turn","twelve","twenty","twice","two","type","typical","uncle","under","underline","understanding","unhappy","union","unit","universe","unknown","unless","until","unusual","up","upon","upper","upward","us","use","useful","using","usual","usually","valley","valuable","value","vapor","variety","various","vast","vegetable","verb","vertical","very","vessels","victory","view","village","visit","visitor","voice","volume","vote","vowel","voyage","wagon","wait","walk","wall","want","war","warm","warn","was","wash","waste","watch","water","wave","way","we","weak","wealth","wear","weather","week","weigh","weight","welcome","well","went","were","west","western","wet","whale","what","whatever","wheat","wheel","when","whenever","where","wherever","whether","which","while","whispered","whistle","white","who","whole","whom","whose","why","wide","widely","wife","wild","will","willing","win","wind","window","wing","winter","wire","wise","wish","with","within","without","wolf","women","won","wonder","wonderful","wood","wooden","wool","word","wore","work","worker","world","worried","worry","worse","worth","would","wrapped","write","writer","writing","written","wrong","wrote","yard","year","yellow","yes","yesterday","yet","you","young","younger","your","yourself","youth","zero","zebra","zipper","zoo","zulu"];function Sy(n){return new Array(n).fill(0).map(()=>gp[Math.floor(Math.random()*gp.length)]).join("-")}var eL=9e4,tL=3,nL=1500,rL=15e3,Sn=class extends Error{status;rawError;constructor(e,t,r,o={}){super(r,o),this.status=e,this.rawError=t}};async function oL(n){return n.text().then(e=>{try{return JSON.parse(e).error}catch{return e}})}var fp=class{baseUrl;logger;constructor(e){this.baseUrl=e.baseUrl,this.logger=e.logger}getHeaders(){let e={"Content-Type":"application/json"};return Na&&(e[bg]=Na),e}async sendRequest(e,t){let{retries:r=tL,requestTimeoutMs:o=eL,initialRetryDelayMs:i=nL,maxRetryDelayMs:a=rL}=t,s=r,l=r,c,d={path:e,baseUrl:this.baseUrl,method:t.method};for(;s>0;)try{return s--,await this.sendSingleRequestHelper(e,t,o)}catch(p){if(c=p,p instanceof Sn&&p.status>=400&&p.status<500)throw p;if(p instanceof Error&&p.name==="AbortError"&&(c=new gr),s===0)throw c;let u=l-s,m=Math.min(i*Math.pow(2,u-1),a);await new Promise(h=>setTimeout(h,m))}throw this.logger.warn({...d,err:c},"Got fatal error response from Momentic server"),c}async sendSingleRequestHelper(e,t,r){let o={path:e,baseUrl:this.baseUrl,method:t.method},i=new AbortController,a=setTimeout(()=>i.abort(),r),s=()=>i.abort();t.signal&&t.signal.addEventListener("abort",s);let l={...this.getHeaders(),...t.extraHeaders};try{let c=await fetch(`${this.baseUrl}${e}`,{method:t.method,body:t.body?JSON.stringify(t.body):void 0,headers:l,signal:i.signal});if(!c.ok){let p=await oL(c);throw new Sn(c.status,p,`Request to ${t.method} ${e} failed with status ${c.status}: ${p}`)}let d;if(c.status===204)d={};else{let p=await c.text();try{d=JSON.parse(p)}catch{d=p}}return this.logger&&!t.noLog&&d&&this.logger.debug({result:d,status:c.status,...o},"Got response from Momentic server"),d}finally{clearTimeout(a),t.signal&&t.signal.removeEventListener("abort",s)}}},Dt=class extends fp{apiKey;constructor(e){super(e),this.apiKey=e.apiKey}getHeaders(){return{...super.getHeaders(),Authorization:`Bearer ${this.apiKey}`}}};var ct=class extends Dt{constructor(e){super(e)}getAppUrl(){return this.baseUrl.replace(/\/\/api/,"//app")}async getAuthInfo(){let e=await this.sendRequest(`/${z}/auth/check`,{method:"GET",noLog:!0,retries:10,requestTimeoutMs:5e3});return Bg.parse(e)}async bulkGetRunStatus(e){let t=await this.sendRequest(`/${z}/runs/status`,{method:"POST",body:e,noLog:!0,retries:3,requestTimeoutMs:1e4});return _g.parse(t)}async getTestYAMLExport(e){let t=await this.sendRequest(`/${z}/tests/export`,{method:"POST",body:e,retries:3,requestTimeoutMs:3e4});return Lg.parse(t)}async updateStepCaches(e,t){await this.sendRequest(`/${z}/cache`,{method:"PATCH",body:e,extraHeaders:t,retries:3,requestTimeoutMs:1e4,initialRetryDelayMs:3e3})}async getStepCacheForTest(e,t){let r=await this.sendRequest(`/${z}/cache`,{method:"POST",body:e,extraHeaders:t,retries:10,requestTimeoutMs:3e4,initialRetryDelayMs:3e3});return Og.parse(r)}async queueTests(e){let t=await this.sendRequest(`/${z}/tests/queue`,{method:"POST",body:e,retries:3,requestTimeoutMs:1e4});return Pg.parse(t)}async uploadScreenshot(e){let t=await this.sendRequest(`/${z}/screenshots`,{method:"POST",body:e,noLog:!0,retries:3,requestTimeoutMs:5e3});return Ug.parse(t)}async getAllEnvironments(){let e=await this.sendRequest(`/${z}/environments`,{method:"GET",retries:3,requestTimeoutMs:5e3});return zg.parse(e)}async acquireCacheLock(e,t){let r=await this.sendRequest(`/${z}/result-cache/lock`,{method:"POST",body:e,signal:t,retries:3,requestTimeoutMs:3e4});return qg.parse(r)}async releaseCacheLock(e){await this.sendRequest(`/${z}/result-cache/lock`,{method:"DELETE",body:{key:e},retries:3,requestTimeoutMs:5e3})}async deleteCacheResult(e){await this.sendRequest(`/${z}/result-cache/entry`,{method:"DELETE",body:e,retries:3,requestTimeoutMs:5e3})}async setCacheResult(e){await this.sendRequest(`/${z}/result-cache/entry`,{method:"PATCH",body:e,retries:3,requestTimeoutMs:5e3})}async getCacheResult(e){try{return await this.sendRequest(`/${z}/result-cache/entry`,{method:"POST",body:e,retries:3,requestTimeoutMs:5e3})}catch(t){if(t instanceof Error&&t.message.includes("404"))return null;throw t}}async queueSuiteRuns(e){let t=await this.sendRequest(`/${z}/suites/queue`,{method:"POST",body:e,retries:3,requestTimeoutMs:5e3});return Hg.parse(t)}async bulkGetRunGroupStatus(e){let t={runGroupIds:e},r=await this.sendRequest(`/${z}/run-groups/status`,{method:"POST",body:t,noLog:!0,retries:3,requestTimeoutMs:5e3});return Sh.array().parse(r)}async uploadProposedSteps(e,t){try{await this.sendRequest(`/${z}/test-fragments/`,{method:"POST",body:e,retries:3,requestTimeoutMs:1e4})}catch(r){t.error({err:r},"Failed to upload proposed steps")}}async uploadSnapshotScreenshot(e,t,r){try{await this.sendRequest(`/${z}/snapshots/${t}/screenshot`,{method:"POST",body:r,noLog:!0,retries:3,requestTimeoutMs:1e4})}catch(o){e.error({err:o},"Failed to upload screenshot")}}async generateConsoleLogsForRunAttemptUploadUrl(e,t,r){let o=await this.sendRequest(`/${z}/runs/${t}/attempts/${r}/console-logs`,{method:"POST",noLog:!0,retries:3,requestTimeoutMs:5e3});return sa.parse(o)}async generateNetworkLogsForRunAttemptUploadUrl(e,t,r){let o=await this.sendRequest(`/${z}/runs/${t}/attempts/${r}/network-logs`,{method:"POST",noLog:!0,retries:3,requestTimeoutMs:1e4});return sa.parse(o)}async generateHtmlSnapshotUploadUrl(e,t){let r=await this.sendRequest(`/${z}/snapshots/${t}/html`,{method:"POST",noLog:!0,retries:3,requestTimeoutMs:1e4});return sa.parse(r)}async reportBillableEvents(e,t){try{await this.sendRequest(`/${z}/billing/events`,{method:"POST",body:t,noLog:!0,retries:10,requestTimeoutMs:1e4})}catch(r){e.error({err:r},"Failed to report billable event")}}async fetchTestFragment(e){let t=await this.sendRequest(`/${z}/test-fragments/${e}`,{method:"GET",noLog:!0,retries:3,requestTimeoutMs:1e4});return jg.parse(t)}async patchTestFragment(e,t){await this.sendRequest(`/${z}/test-fragments/${e}`,{method:"PATCH",body:t,retries:3,requestTimeoutMs:1e4})}async getPastTestResults(e,t){let r=await this.sendRequest(`/${z}/results/tests/${e}`,{method:"POST",body:t,retries:3,requestTimeoutMs:1e4});return $g.parse(r)}async generateTestResultsUploadUrl(){let e=await this.sendRequest(`/${z}/results/uploads`,{method:"POST",noLog:!0,retries:3,requestTimeoutMs:1e4});return Gg.parse(e)}async startProcessingResultsUpload(e,t){let r=await this.sendRequest(`/${z}/results/uploads/${e}/process`,{method:"POST",noLog:!0,body:t,retries:3,requestTimeoutMs:1e4});return Wg.parse(r)}async fetchIconKnowledgeBase(e){try{let t=await this.sendRequest(`/${z}/knowledge-base/icons`,{method:"GET",noLog:!0,retries:3,requestTimeoutMs:5e3});return Zg.parse(t)}catch(t){return e.error({err:t},"Failed to fetch icon knowledge base"),null}}async saveNewIcons(e,t){try{await this.sendRequest(`/${z}/knowledge-base/icons`,{method:"POST",body:e,noLog:!0,retries:3,requestTimeoutMs:5e3})}catch(r){t.error({err:r},"Failed to save new icons to icon knowledge base")}}async getMergeBaseCommitFromGithub(e,t,r,o){let i=new URLSearchParams;i.set("base",r),i.set("head",o);let a=await this.sendRequest(`/${z}/git/github/${e}/${t}/merge-base-commit?${i.toString()}`,{method:"GET",noLog:!0,retries:3,requestTimeoutMs:1e4});return la.parse(a)}async getCommitFromGithub(e,t,r){let o=await this.sendRequest(`/${z}/git/github/${e}/${t}/commits/${r}`,{method:"GET",noLog:!0,retries:3,requestTimeoutMs:1e4});return la.parse(o)}async getMergeBaseCommitFromGitlab(e,t,r){let o=new URLSearchParams;o.set("base",t),o.set("head",r);let i=await this.sendRequest(`/${z}/git/gitlab/${e}/merge-base-commit?${o.toString()}`,{method:"GET",noLog:!0,retries:3,requestTimeoutMs:5e3});return la.parse(i)}async getCommitFromGitlab(e,t){let r=await this.sendRequest(`/${z}/git/gitlab/${e}/commits/${t}`,{method:"GET",noLog:!0,retries:3,requestTimeoutMs:1e4});return la.parse(r)}async getAgentConfig(){let e=await this.sendRequest(`/${z}/web-agent/agent-config`,{method:"GET",noLog:!0,retries:3,requestTimeoutMs:5e3});return Sp.record(Sp.string(),Sp.string()).parse(e)}};import{randomUUID as yy}from"crypto";var El=class{apiClient;constructor(e){this.apiClient=e}async reportBillableEvent(e,t,r){try{return await this.apiClient.reportBillableEvents(e,[{event:t,timestamp:new Date().toISOString(),transactionId:r?.eventId??yy(),properties:yd({},r)}])}catch(o){e.error({err:o},"Failed to report billable event")}}async reportCreditsUsed(e,t,r,o){if(r)try{return await this.apiClient.reportBillableEvents(e,[{event:"credits-used",timestamp:new Date().toISOString(),transactionId:o?.eventId??yy(),properties:yd({creditsUsed:r,usedBy:t},o)}])}catch(i){e.error({err:i},"Failed to report credits used")}}};function li(n,e,t){return fetch(n,{method:"PUT",body:t,headers:{"Content-Type":e}})}var xl=class{constructor(e){this.client=e}async storeConsoleLogsForRunAttempt(e,t,r,o){try{let i=JSON.stringify(o),{uploadUrl:a}=await this.client.generateConsoleLogsForRunAttemptUploadUrl(e,t,r),s=await li(a,"application/json",i);if(!s.ok)throw new Error(`Failed to upload network logs: ${s.statusText}`)}catch(i){e.error({err:i},"Failed to upload console logs")}}async storeNetworkLogsForRunAttempt(e,t,r,o){let i=JSON.stringify(o);try{let{uploadUrl:a}=await this.client.generateNetworkLogsForRunAttemptUploadUrl(e,t,r),s=await li(a,"application/json",i);if(!s.ok)throw new Error(`Failed to upload network logs: ${s.statusText}`)}catch(a){e.error({err:a},"Failed to upload network logs")}}async storeHtmlSnapshot(e,t,r){try{let{uploadUrl:o}=await this.client.generateHtmlSnapshotUploadUrl(e,t),i=await li(o,"text/html",r);if(!i.ok)throw new Error(`Failed to upload network logs: ${i.statusText}`)}catch(o){e.error({err:o},"Failed to upload html snapshot")}}async storeScreenshot(e,t,r){try{await this.client.uploadSnapshotScreenshot(e,t,{screenshot:r.toString("base64")})}catch(o){e.error({err:o},"Failed to upload screenshot")}}async storeA11yTreeSnapshot(e,t,r){return Promise.resolve()}async getConsoleLogsForRunAttempt(e,t,r){}async getNetworkLogsForRunAttempt(e,t,r){}async getHtmlSnapshot(e,t){}async getA11yTreeSnapshot(e,t){}async getScreenshot(e,t){}};var ci=class{constructor(e,t){this.client=e;this.orgId=t}async acquireCacheLock(e,t){return this.client.acquireCacheLock(e,t)}async uploadScreenshot(e){return(await this.client.uploadScreenshot({screenshot:e.toString("base64")})).key}async releaseCacheLock(e){return this.client.releaseCacheLock(e)}async deleteCacheResult(e){return this.client.deleteCacheResult(e)}async setCacheResult(e){return this.client.setCacheResult(e)}async getCacheResult(e){return this.client.getCacheResult(e)}fetchIconKnowledgeBase(e){return this.client.fetchIconKnowledgeBase(e)}saveNewIcons(e,t){return this.client.saveNewIcons(e,t)}};import{Faker as iL,en as aL}from"@faker-js/faker";var di="v1",fr=class{httpClient;fakerInstance;type="API_CLIENT";sms={send:this.sendSms.bind(this),fetchLatest:this.fetchLatestSms.bind(this)};email={send:this.sendEmail.bind(this),fetchLatest:this.fetchLatestEmail.bind(this),fetchAll:this.fetchAllEmails.bind(this)};ai={generate:this.sendAiGenerate.bind(this)};constructor(e){this.httpClient=e.httpClient,e.fakerSeed&&(this.fakerInstance=new iL({locale:aL}),this.fakerInstance.seed(e.fakerSeed))}async sendAiGenerate(e){let t=typeof e=="string"?{input:e}:e;return this.httpClient.sendRequest(`/${di}/tools/ai/generate`,{method:"POST",body:t}).catch(r=>{throw r instanceof Sn?new Error(r.rawError):new Error(`Failed to send AI generation: ${r.message}`)})}async sendSms(e){return this.httpClient.sendRequest(`/${di}/tools/sms/send`,{method:"POST",body:e}).then(()=>{}).catch(t=>{throw t instanceof Sn?new Error(t.rawError):new Error(`Failed to send sms: ${t.message}`)})}async fetchLatestSms(e){return this.httpClient.sendRequest(`/${di}/tools/sms/fetchLatest`,{method:"POST",body:e}).catch(t=>{throw t instanceof Sn?new Error(t.rawError):t})}async sendEmail(e){return this.httpClient.sendRequest(`/${di}/tools/email/send`,{method:"POST",body:e}).then(()=>{}).catch(t=>{throw t instanceof Sn?new Error(t.rawError):new Error(`Failed to send email: ${t.message}`)})}async fetchAllEmails(e){return this.httpClient.sendRequest(`/${di}/tools/email/fetchAll`,{method:"POST",body:e}).catch(t=>{throw t instanceof Sn?new Error(t.rawError):new Error(`Failed to fetch all emails: ${t.message}`)})}async fetchLatestEmail(e){return this.httpClient.sendRequest(`/${di}/tools/email/fetchLatest`,{method:"POST",body:e}).catch(t=>{throw t instanceof Sn?new Error(t.rawError):new Error(`Failed to fetch latest emails: ${t.message}`)})}};import{z as sL}from"zod";var pi=class extends Dt{agentConfig;constructor(e,t){super(t),this.agentConfig=e}async rankChunksWithAi(e,t){let r={...e,loggerTags:t.loggerTags},o=await this.sendRequest(`/${z}/web-agent/recommend-chunks-ai`,{method:"POST",body:r,signal:t.abortSignal});return Eh.parse(o)}async rankChunksWithRag(e,t){let r=await this.sendRequest(`/${z}/web-agent/recommend-chunks`,{method:"POST",body:{cliVersion:Na,...e},signal:t.abortSignal});return Th.parse(r)}async getScreenshotFromS3(e){let t=await this.sendRequest(`/${z}/s3/visual-diff-screenshot`,{method:"POST",body:{url:e}});return sL.string().parse(t)}async getElementLocation(e,t){let r={...e,disableCache:t.disableCache,loggerTags:t.loggerTags,useMemory:t.useMemory,agentConfigVersion:this.agentConfig?.locator},o=await this.sendRequest(`/${z}/web-agent/locate-element`,{method:"POST",body:r,signal:t.abortSignal});return Ag.parse(o)}async getAssertionResult(e,t){let r={...e,disableCache:!!t.disableCache,useConsensus:!!t.useConsensus,attemptNumber:t.attemptNumber,loggerTags:t.loggerTags,useMemory:t.useMemory,agentConfigVersion:this.agentConfig?.locator},o=await this.sendRequest(`/${z}/web-agent/assertion`,{method:"POST",body:r,signal:t.abortSignal});return Pd.parse(o)}async getLintStepResult(e,t){let r={...e,disableCache:!!t.disableCache,loggerTags:t.loggerTags},o=await this.sendRequest(`/${z}/web-agent/lint/step`,{method:"POST",body:r,signal:t.abortSignal});return Rg.parse(o)}async getVisualAssertionResult(e,t){let r={...e,disableCache:!!t.disableCache,useConsensus:!!t.useConsensus,loggerTags:t.loggerTags},o=await this.sendRequest(`/${z}/web-agent/visual-assertion`,{method:"POST",body:r,signal:t.abortSignal});return Pd.parse(o)}async getAiActionCommand(e,t){let r=await this.sendRequest(`/${z}/web-agent/next-command-dynamic`,{method:"POST",body:{...e,disableCache:t.disableCache,loggerTags:t.loggerTags},signal:t.abortSignal});return Cg.parse(r)}async getMultiturnAiActionCommand(e,t){return await this.sendRequest(`/${z}/web-agent/ai-action/next-command`,{method:"POST",body:{...e,disableCache:t.disableCache,loggerTags:t.loggerTags},signal:t.abortSignal})}async getMultiturnAiActionEvaluation(e,t){let r=await this.sendRequest(`/${z}/web-agent/ai-action/evaluate`,{method:"POST",body:{...e,disableCache:t.disableCache,loggerTags:t.loggerTags},signal:t.abortSignal});return Wc.parse(r)}async getReverseMappedDescription(e,t){let r=await this.sendRequest(`/${z}/web-agent/reverse-mapped-description`,{method:"POST",body:{...e,disableCache:t.disableCache,loggerTags:t.loggerTags},signal:t.abortSignal});return Ig.parse(r)}async getTextExtraction(e,t){let r={...e,disableCache:t.disableCache,loggerTags:t.loggerTags},o=await this.sendRequest(`/${z}/web-agent/text-extraction`,{method:"POST",body:r,signal:t.abortSignal});return Gc.parse(o)}async getTestResultClassification(e,t){let r=await this.sendRequest(`/${z}/web-agent/result-classification`,{method:"POST",body:{...e,loggerTags:t.loggerTags},signal:t.abortSignal});return rd.parse(r)}async getExtractedKeywords(e,t){let r=await this.sendRequest(`/${z}/web-agent/extract-keywords`,{method:"POST",body:{goal:e,disableCache:t.disableCache,context:e},signal:t.abortSignal});return Mh.parse(r)}async getAutohealingProposal(e,t){let r=await this.sendRequest(`/${z}/web-agent/autoheal-section`,{method:"POST",body:{...e,loggerTags:t.loggerTags},signal:t.abortSignal});return wm.parse(r)}async getFailureRecoveryProposal(e,t){let r=await this.sendRequest(`/${z}/web-agent/failure-recovery`,{method:"POST",body:{...e,loggerTags:t.loggerTags},signal:t.abortSignal});return vm.parse(r)}async getIframeRegex(e,t){let r=await this.sendRequest(`/${z}/web-agent/iframe-regex`,{method:"POST",body:e,signal:t.abortSignal});return nm.parse(r)}};var ui=class extends Dt{generator;constructor(e,t){super(e),this.generator=t}async runTemplateMatching(e,t={}){let r=await this.sendRequest(`/${z}/web-agent/template-matching`,{method:"POST",body:e,signal:t?.signal});return rm.parse(r)}async constructIframeRegex(e,t={}){return this.generator.getIframeRegex(e,{abortSignal:t.signal})}};var Cl=class{constructor(e){this.client=e}async uploadResultsArchive(e,t){let{uploadUrl:r,id:o}=await this.client.generateTestResultsUploadUrl(),i=await li(r,"application/zip",t);if(!i.ok)throw new Error(`Failed to upload test results: ${await i.text()}`);let{runGroupId:a}=await this.client.startProcessingResultsUpload(o,{runGroupId:e});return a}};function mi({orgId:n,client:e,gitMetadata:t,alwaysSaveCache:r,noCache:o}){return o?new Xa:new yp(n,e,t,r)}var yp=class{constructor(e,t,{gitMainBranch:r,gitBranchName:o,gitProtectedBranches:i,gitCommitTimestamp:a,lastCommitOnMainSha:s,lastCommitOnMainTimestamp:l},c){this.orgId=e;this.client=t;this.cacheHeaders={},r&&(this.cacheHeaders[wg]=r),o&&(this.cacheHeaders[vg]=o),a&&(this.cacheHeaders[Tg]=a.toISOString()),s&&(this.cacheHeaders[Eg]=s),l&&(this.cacheHeaders[xg]=l.toISOString()),c?this.writeCaches=!0:o?this.writeCaches=!i.includes(o):this.writeCaches=!0}cacheHeaders;writeCaches;async saveStepCacheEntries({entries:e,testId:t,logger:r}){if(!this.writeCaches){r.debug("Skipping cache storage because branch is protected");return}try{await this.client.updateStepCaches({entries:e,testId:t},this.cacheHeaders)}catch(o){r.error({err:o},"Failed to save step cache entries")}}async resolveStepCacheEntries(e){let{steps:t,beforeSteps:r,afterSteps:o}=e.stepLists,i=await this.client.getStepCacheForTest({testId:e.testId,steps:t,schemaVersion:e.schemaVersion},this.cacheHeaders);if(!this.writeCaches){e.logger.debug("Skipping cache last used at update because branch is protected");return}for(let s of[t,r,o])s&&Ho({steps:s,stepCacheEntries:i,logger:e.logger});let{cachesToSave:a}=await gt({stepLists:e.stepLists,cacheCreationParams:{testId:e.testId,orgId:this.orgId}});this.client.updateStepCaches({entries:a,testId:e.testId},this.cacheHeaders)}};import hk from"path";import{Server as UN}from"socket.io";import{cloneDeep as lL}from"lodash-es";var cL={showOverlay:!1},bp=class{sessions=new Map;sessionCountByIp=new Map;getCurrentConnectionsByIp(e){return this.sessionCountByIp.get(e)??0}getCurrentSessionsByIp(){return Object.fromEntries(this.sessionCountByIp)}reserveCapacityByIp(e){e&&this.sessionCountByIp.set(e,(this.sessionCountByIp.get(e)??0)+1)}releaseCapacityByIp(e){e&&this.sessionCountByIp.set(e,Math.max(this.getCurrentConnectionsByIp(e)-1,0))}registerSession({controller:e,context:t,cleanup:r,clientIp:o,sessionId:i}){return this.sessions.set(i,{controller:e,context:t,cleanup:r,clientIp:o,browserBehavior:lL(cL)}),i}removeSession(e,t){(async()=>{let o=this.sessions.get(e);if(!o)return;this.releaseCapacityByIp(o.clientIp);let{controller:i}=o;try{i.setClosed(),await i.browser.cleanup()}catch(a){t.error({err:a},"Error cleaning up browser in global state manager")}try{await o.cleanup?.()}catch(a){t.error({err:a},"Error running cleanup function in global state manager")}this.sessions.delete(e)})()}getSession(e){return this.sessions.get(e)}},X=new bp;function by(n,e,t){let r=Date.now(),o=Date.now(),i,a,s,l,c=!1,d=async(h,g)=>{if(!h.closed&&!h.isInPageLoad)try{let f=s;s=void 0;let S=h.url(),w=g.toEditorDisplayCopy();JSON.stringify(w)===JSON.stringify(i)&&S===l&&r>o||(n.emit("browserState",{logsPerPage:f?.logsPerPage,harPages:f?.harPages,harEntries:f?.harEntries,viewport:h.getViewport(),url:S,iframeSrcUrls:a??[],context:w,isInPageLoad:h.isInPageLoad}),r=Date.now()),l=S,i=w}catch(f){if(!n.connected)return;let S=f instanceof Error?f.message:`${f}`;if(S.includes("Frame was detached")||S.includes("Not attached to an active page")||S.includes("browser has been closed")||S.includes("UserInfrastructureError"))return;t.error({err:f,sessionId:e},"Error grabbing browser state")}},p=setInterval(()=>{let h=X.getSession(e),g=h?.controller?.browser;if(!g||g.closed){t.debug("Clearing browser state socket cron due to the browser being closed"),clearInterval(p);return}d(g,h.context)},1e3),u=(h,g)=>!!(JSON.stringify(h)!==JSON.stringify(a)||g.logsPerPage.some(f=>f.length>0)||g.harPages&&Object.keys(g.harPages).length>0||g.harEntries&&Object.keys(g.harEntries).length>0),m=setInterval(async()=>{let g=X.getSession(e)?.controller?.browser;if(!g||g.closed){clearInterval(m);return}else if(c)return;c=!0;try{let f=await g.getAllFrameUrls(),S=g.retrieveAndClearDebugData();u(f,S)&&(a=f,s=S,o=Date.now())}catch(f){t.warn({err:f},"Failed to fetch extended details")}finally{c=!1}},2500);return{timers:[p,m]}}var Sr={};var dL=n=>()=>{let{sessionId:e}=n.metadata;Sr[e]?.abort?.abort()},wy={event:"cancelApiTest",createHandler:dL};import{CookieJar as PL}from"tough-cookie";import{randomUUID as yL}from"crypto";import{faker as pL}from"@faker-js/faker";import uL from"assert";import mL from"axios";import hL from"moment";import*as gL from"otpauth";import fL from"pg";async function vy(n){let e;try{e=new URL(n.url).hostname}catch{}let t=[];return n.headers.getSetCookie()?.forEach(r=>{let o=_s(r,e);t.push(...o)}),t}var SL=Object.getPrototypeOf(async function(){}).constructor;async function Ty(n,e,t){let r=e.code;e.options.fragment&&(r=`return ${e.code}`);let{env:o}=e.bindings,i=e.tools,a={},s=(f,S)=>{o[f]=S,a[f]=S},l={},c=(f,S)=>{o[f]=S,l[f]=S},d;r.includes("Octokit")&&(d=(await import("@octokit/rest")).Octokit);let p;r.includes("createAppAuth")&&(p=(await import("@octokit/auth-app")).createAppAuth);let u=async()=>await Promise.resolve(new SL("axios","moment","faker","assert","pg","Octokit","createAppAuth","OTPAuth","extractCookiesFromResponse","env","setVariable","setPersistentVariable","sendSms","waitForLatestSms","email","sms","ai",r)(mL,hL,i.fakerInstance??pL,uL,fL,d,p,gL,vy,o,s,c,S=>i.sms.send(S),S=>i.sms.fetchLatest(S),i.email,i.sms,i.ai)),m=!0,h,g;try{h=await B(u(),{milliseconds:e.options.timeoutMs,message:`Timeout of ${e.options.timeoutMs}ms exceeded for code execution`,signal:e.signal})}catch(f){t.error({err:f,env:o,evalCode:r},`[${n}] Error executing code: ${f}`),m=!1,f instanceof gr?g=`Timeout of ${e.options.timeoutMs}ms exceeded for code execution`:g=f instanceof Error?f.message:`${f}`}return{result:h,variableUpdates:a,persistentVariableUpdates:l,success:m,error:g}}async function Ey({code:n,fragment:e,context:t,localTools:r,logger:o,signal:i,timeoutMs:a=sr}){let s=yL(),l=await Ty(s,{code:n,options:{fragment:e,timeoutMs:a},bindings:t.toObjectCopy(),tools:r,signal:i},o);return b.debug(`[${s}] Got execution result: ${JSON.stringify(l)}`),l}import{createHmac as bL,randomUUID as wL}from"crypto";import vL from"fetch-retry";var TL=vL(global.fetch,{retries:3,retryOn:function(n,e,t){return!!(e!==null||t&&t.status>=500)},retryDelay:function(n){return Math.pow(2,n)*500}}),xy=process.env.GCP_JS_EVAL_FUNCTION_ENDPOINT,Cy=process.env.MOMENTIC_LAMBDA_AUTH_SECRET;async function Ry({orgId:n,code:e,fragment:t,context:r,timeoutMs:o=sr,retries:i=2,signal:a,logger:s}){if(!xy)throw new Error("GCP_JS_EVAL_FUNCTION_ENDPOINT environment variable not set");let l,c,d=0;if(!Cy)throw new Error("Missing lambda auth secret.");let p=bL("sha256",Cy).update(n).digest("hex");for(;d<=i;){d++,a?.throwIfAborted();let m={id:wL(),orgId:n,momenticLambdaAuthHash:p,code:e,fragment:t,state:r.toObjectCopy(),timeoutMs:o};try{if(l=await B(TL(xy,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(m)}),{milliseconds:o,message:`Timeout of ${o}ms exceeded for code execution`,signal:a}),!l)throw new Error("Got empty response from code evaluation server");if(!l.ok)throw new Error(`Code evaluation server returned error code ${l.status}`);c=void 0;break}catch(h){c=h}}if(c)throw s.error({err:c},"Failed to evaluate code remotely"),c;if(!l)throw new Error(`An unexpected code evaluation error occurred${c?`: ${c}`:""}`);let u;try{u=zh.parse(await l.json())}catch(m){throw new Error(`Code evaluation server returned invalid response: ${m}`)}if(u.error)throw new Error(`Code evaluation error: ${u.error}`);return u}async function Kn(n){let e;if(process.env.GCP_JS_EVAL_FUNCTION_ENDPOINT)e=await Ry(n);else if(n.localTools)e=await Ey({...n,localTools:n.localTools});else throw new Error("No code evaluation environment available");if(e.error){let t=`Failed to evaluate code:
49
+ ${r.map(o=>o.configFilePath)}`);if(r.length===0)throw new Error("No valid Momentic project file available.");return b.debug(`Found valid project configuration at ${r[0].configFilePath}`),r[0]}function UP(n){let e=DP(n);if(!e||!e.projects||!e.projects.length)return;let t=e.projects.map(i=>(i.endsWith("/")||(i+="/"),`${i}*${ni}`)),r=ti(t,{absolute:!1,cwd:dp(),dotRelative:!1,maxDepth:cp,nodir:!0}),o=[];for(let i of r){let a=ro.join(dp(),i),s=pp(a);s&&o.push({configFilePath:a,config:s,rootDir:dy(a)})}return o}function up(n){if(n){n=ro.resolve(n);let t=pp(n);return t||(console.error(`No valid Momentic project file found at ${n}.`),process.exit(1)),[{config:t,configFilePath:n,rootDir:ro.dirname(n)}]}if(AP(cy)){let t=UP(cy);if(t)return t}return FP()}function ri(n,e){let t=py.stringify(n);LP(e,t)}import oi from"fs";import mp from"path";import{z as hp}from"zod";var my="golden/visual-diff",hy="reports",gy="test-results";var BP=hp.object({width:hp.number(),height:hp.number()}),ii=class{defaultGoldenScreenshotDir;regenerateGoldenFiles;constructor(e,t){let r=mp.join(e.rootDir,e.config.goldenFileDir??my);this.defaultGoldenScreenshotDir=r,this.regenerateGoldenFiles=t}async prepareGoldenScreenshotForComparison(e,t,r){if(t.screenshot?.data?.startsWith("https://")){let a=await fetch(t.screenshot.data);return{buffer:Buffer.from(await a.arrayBuffer()),width:t.screenshot.width,height:t.screenshot.height}}let o=t.screenshot?.data;o||(o=mp.join(this.defaultGoldenScreenshotDir,`${t.id}.jpg`));let i=`${o}.metadata.json`;if(this.regenerateGoldenFiles)return oi.mkdirSync(mp.dirname(o),{recursive:!0}),oi.writeFileSync(o,r.buffer),oi.writeFileSync(i,JSON.stringify({width:r.width,height:r.height})),{buffer:Buffer.from(r.buffer),width:r.width,height:r.height};if(oi.existsSync(o)){let a=oi.readFileSync(o),s=BP.parse(JSON.parse(oi.readFileSync(i,"utf-8")));return{buffer:a,width:s.width,height:s.height}}else throw new R("UserConfigurationError",`Cannot execute visual diff without a saved baseline screenshot at ${o}`)}};var ai=class{flags;constructor(e){this.flags={auto_expand_iframes:e.browser?.autoExpandIframes??!1,rag_v2:e.ai?.aiPageFiltering??!1,faker_constant_seed:e.advanced?.fakerConstantSeed??!1,disable_secondary_cache_resolution:e.browser?.disableSecondaryCacheResolution??!1,show_zero_opacity_elements:e.browser?.showZeroOpacityElements??!1,global_locator_redirect:e.browser?.globalLocatorRedirect??!1,visual_actions:e.browser?.visualActions??!1,mini_model_initial_assertion:!1,mini_model_initial_locator:!1,show_test_plans:!1,icon_knowledge_base:!1,disable_clickhouse_caches:!1,disable_clickhouse_last_updated_endpoint:!1}}isBooleanFlagEnabled(e){return this.flags[e]}getAllFlags(){return{...this.flags}}getFlagPayload(e){}async refresh(){}};import zP from"simple-git";var Ee=zP();function vl(n){if(n.startsWith("git@")){let e=n.split(":");if(e.length===2){let t=e[1].replace(".git","").split("/");if(t.length===2){let r=t[0],o=t[1];return`${r}/${o}`}}}else if(n.startsWith("http")||n.startsWith("https")){let t=new URL(n).pathname.split("/").filter(Boolean);if(t.length>=2){let r=t[0],o=t[1].replace(".git","");return`${r}/${o}`}}}async function xe(n,e){try{return(await e).trim()}catch(t){n.error({err:t},"Failed to run git command");return}}function HP(){if(process.env.GITHUB_ACTION)return"GithubActions";if(process.env.GITLAB_CI)return"GitlabCI";if(process.env.CIRCLECI)return"CircleCI";if(process.env.BUILDKITE)return"Buildkite";if(process.env["System.CollectionUri"]?.includes("azure"))return"AzureDevOps";if(process.env.PROJECT_ID&&process.env.BUILD_ID)return"GCPCloudBuild"}async function jP(n){let[e,t,r,o]=await Promise.all([xe(n,Ee.show(["--no-patch","--format=%ci"])),xe(n,Ee.listRemote(["--get-url","origin"])),xe(n,Ee.show(["-s","--pretty=%B"])),xe(n,Ee.show(["-s","--pretty=%an"]))]);return{gitCommitSha:process.env.GITHUB_SHA,gitCommitShaShort:process.env.GITHUB_SHA?.slice(0,6),gitCommitTimestamp:e?new Date(e):void 0,gitBranchName:process.env.GITHUB_HEAD_REF||process.env.GITHUB_REF_NAME,gitOriginUrl:t,gitCommitMessage:r,gitCommitAuthorName:o,githubRepository:process.env.GITHUB_REPOSITORY,pipelineId:`${process.env.GITHUB_RUN_ID}:${process.env.GITHUB_RUN_ATTEMPT}`}}async function $P(n){let[e,t,r]=await Promise.all([xe(n,Ee.listRemote(["--get-url","origin"])),xe(n,Ee.show(["-s","--pretty=%B"])),xe(n,Ee.show(["-s","--pretty=%an"]))]);return{gitCommitSha:process.env.CI_COMMIT_SHA,gitCommitShaShort:process.env.CI_COMMIT_SHORT_SHA,gitCommitTimestamp:process.env.CI_COMMIT_TIMESTAMP?new Date(process.env.CI_COMMIT_TIMESTAMP):void 0,gitBranchName:process.env.CI_COMMIT_BRANCH||process.env.CI_COMMIT_REF_NAME,gitOriginUrl:e,gitCommitMessage:t,gitCommitAuthorName:r,gitlabProjectPath:process.env.CI_PROJECT_PATH,pipelineId:`${process.env.CI_PIPELINE_ID}:${process.env.CI_JOB_ID}`}}async function GP(n){let[e,t,r,o]=await Promise.all([xe(n,Ee.show(["--no-patch","--format=%ci"])),xe(n,Ee.listRemote(["--get-url","origin"])),xe(n,Ee.show(["-s","--pretty=%B"])),xe(n,Ee.show(["-s","--pretty=%an"]))]),i=t?.includes("github.com"),a=t?.includes("gitlab.com"),s=t?vl(t):void 0;return{gitCommitSha:process.env.CIRCLE_SHA1,gitCommitShaShort:process.env.CIRCLE_SHA1?.slice(0,6),gitCommitTimestamp:e?new Date(e):void 0,gitBranchName:process.env.CIRCLE_BRANCH,gitOriginUrl:process.env.CIRCLE_REPOSITORY_URL,gitCommitMessage:r,gitCommitAuthorName:o,githubRepository:i?s:void 0,gitlabProjectPath:a?s:void 0,pipelineId:`${process.env.CIRCLE_WORKFLOW_ID}:${process.env.CIRCLE_WORKFLOW_JOB_ID}`}}async function WP(n){let[e,t,r]=await Promise.all([xe(n,Ee.show(["--no-patch","--format=%ci"])),xe(n,Ee.show(["-s","--pretty=%B"])),xe(n,Ee.show(["-s","--pretty=%an"]))]),o=process.env.BUILDKITE_REPO,i=o?.includes("github.com"),a=o?.includes("gitlab.com"),s=o?vl(o):void 0;return{gitCommitSha:process.env.BUILDKITE_COMMIT,gitCommitShaShort:process.env.BUILDKITE_COMMIT?.slice(0,6),gitCommitTimestamp:e?new Date(e):void 0,gitBranchName:process.env.BUILDKITE_BRANCH,gitOriginUrl:o,gitCommitMessage:t,gitCommitAuthorName:r,githubRepository:i?s:void 0,gitlabProjectPath:a?s:void 0,pipelineId:`${process.env.BUILDKITE_PIPELINE_ID}:${process.env.BUILDKITE_BUILD_ID}:${process.env.BUILDKITE_JOB_ID}`}}async function VP(n){let[e,t,r]=await Promise.all([xe(n,Ee.show(["--no-patch","--format=%ci"])),xe(n,Ee.show(["-s","--pretty=%B"])),xe(n,Ee.show(["-s","--pretty=%an"]))]),o=process.env["Build.Repository.Uri"],i=o?.includes("github.com"),a=o?.includes("gitlab.com"),s=o?vl(o):void 0;return{gitCommitSha:process.env["Build.SourceVersion"],gitCommitShaShort:process.env["Build.SourceVersion"]?.slice(0,6),gitCommitTimestamp:e?new Date(e):void 0,gitBranchName:process.env["Build.SourceBranchName"],gitOriginUrl:o,gitCommitMessage:t,gitCommitAuthorName:r,githubRepository:i?s:void 0,gitlabProjectPath:a?s:void 0,pipelineId:`${process.env["System.JobId"]}:${process.env["System.JobAttempt"]}`}}async function qP(n,e){let[t,r,o,i,a,s,l,c]=await Promise.all([xe(n,Ee.revparse(["HEAD"])),xe(n,Ee.revparse(["--short","HEAD"])),xe(n,Ee.revparse(["--abbrev-ref","HEAD"])),xe(n,Ee.listRemote(["--get-url","origin"])),xe(n,Ee.show(["--no-patch","--format=%ci"])),xe(n,Ee.show(["-s","--pretty=%B"])),xe(n,Ee.show(["-s","--pretty=%an"])),e?xe(n,Ee.raw(["merge-base","--fork-point",e])):Promise.resolve(void 0)]),d=c?await xe(n,Ee.show(["--no-patch","--format=%ci",c])):void 0,p=i?.includes("github.com"),u=i?.includes("gitlab.com"),m=i?vl(i):void 0;return{gitCommitSha:t,gitCommitShaShort:r,gitBranchName:o,gitOriginUrl:i,gitCommitTimestamp:a?new Date(a):void 0,gitCommitMessage:s,gitCommitAuthorName:l,lastCommitOnMainSha:c,lastCommitOnMainTimestamp:d?new Date(d):void 0,githubRepository:p?m:void 0,gitlabProjectPath:u?m:void 0,pipelineId:void 0}}async function KP(){let n=process.env._HEAD_REPO_URL;return{gitCommitSha:process.env.COMMIT_SHA,gitCommitShaShort:process.env.COMMIT_SHA?.slice(0,6),gitBranchName:process.env.BRANCH_NAME,gitOriginUrl:n?process.env._HEAD_REPO_URL:void 0,gitCommitTimestamp:void 0,gitCommitMessage:void 0,gitCommitAuthorName:void 0,githubRepository:n?process.env.REPO_FULL_NAME:void 0,gitlabProjectPath:n?void 0:process.env.REPO_FULL_NAME,pipelineId:`${process.env.PROJECT_ID}:${process.env.BUILD_ID}`}}async function YP(n){let e=n.config.gitProtectedBranches??[];return n.config.gitMainBranch&&e.push(n.config.gitMainBranch),{gitMainBranch:n.config.gitMainBranch,gitProtectedBranches:e}}async function JP(n,e){let t=HP();if(!t)return qP(n,e);switch(t){case"GithubActions":return jP(n);case"GitlabCI":return $P(n);case"CircleCI":return GP(n);case"Buildkite":return WP(n);case"AzureDevOps":return VP(n);case"GCPCloudBuild":return KP()}}async function XP(n,e,t,r){let o=r;if(!r.gitCommitSha)return o;if(r.gitMainBranch&&(!o.lastCommitOnMainSha||!o.lastCommitOnMainTimestamp)){let i=await e.getMergeBaseCommitFromGitlab(t,r.gitMainBranch,r.gitCommitSha);o={...o,lastCommitOnMainSha:i.sha,lastCommitOnMainTimestamp:i.committer.date}}if(!o.gitCommitTimestamp||!o.gitCommitAuthorName||!o.gitCommitMessage||!o.gitCommitAuthorName){let i=await e.getCommitFromGitlab(t,r.gitCommitSha);i&&(o={...o,gitCommitTimestamp:o.gitCommitTimestamp??i.committer.date,gitCommitAuthorName:o.gitCommitAuthorName??i.author.name,gitCommitMessage:o.gitCommitMessage??i.message})}return o}async function QP(n,e,t,r,o){let i=o;if(!o.gitCommitSha)return i;if(o.gitMainBranch&&(!i.lastCommitOnMainSha||!i.lastCommitOnMainTimestamp)){let a=await e.getMergeBaseCommitFromGithub(t,r,o.gitMainBranch,o.gitCommitSha);i={...i,lastCommitOnMainSha:a.sha,lastCommitOnMainTimestamp:a.committer.date}}if(!i.gitCommitTimestamp||!i.gitCommitAuthorName||!i.gitCommitMessage||!i.gitCommitAuthorName){let a=await e.getCommitFromGithub(t,r,o.gitCommitSha);a&&(i={...i,gitCommitTimestamp:i.gitCommitTimestamp??a.committer.date,gitCommitAuthorName:i.gitCommitAuthorName??a.author.name,gitCommitMessage:i.gitCommitMessage??a.message})}return i}async function ZP(n,e,t){try{if(t.githubRepository){let[r,o]=t.githubRepository.split("/");return await QP(n,e,r,o,t)}else if(t.gitlabProjectPath)return await XP(n,e,t.gitlabProjectPath,t)}catch(r){n.warn({err:r},"Failed to get remote git metadata")}return t}async function si(n,e,t){let r=await YP(t),o=await JP(n,r.gitMainBranch),i={...r,...o},a=await ZP(n,e,i);return{...r,...o,...a}}import mk from"http";import{z as Sp}from"zod";var z="v1",Na="2.7.1";var gr=class extends Error{constructor(e){super(e),this.name="TimeoutError"}};var fy=n=>{let e=n.reason===void 0?new DOMException("This operation was aborted.","AbortError"):n.reason;return e instanceof Error?e:new DOMException(e,"AbortError")};function B(n,e){let{milliseconds:t,fallback:r,message:o,customTimers:i={setTimeout,clearTimeout}}=e,a,s;if(typeof t!="number"||Math.sign(t)!==1)throw new TypeError(`Expected \`milliseconds\` to be a positive number, got \`${t}\``);return new Promise((l,c)=>{if(e.signal){let{signal:p}=e;if(p.aborted)return c(fy(p));s=()=>c(fy(p)),p.addEventListener("abort",s)}let d=()=>{if(r)try{l(r())}catch(p){c(p)}else{typeof n.cancel=="function"&&Promise.resolve().then(()=>n.cancel()).catch(()=>{});let p=o instanceof Error?o:new gr(o??`Promise timed out after ${t}ms`);c(p)}};a=i.setTimeout(d,t),Promise.resolve(n).then(p=>l(p)).catch(p=>c(p))}).finally(()=>{i.clearTimeout(a),e.signal&&s&&e.signal.removeEventListener("abort",s)})}var Tl=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 a=this.userActions.get(o)?.filter(s=>r-s<=this.windowMs)??[];a.length>0?this.userActions.set(o,a):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)}};var gp=["ability","able","aboard","about","above","accept","accident","according","account","accurate","acres","across","act","action","active","activity","actual","actually","add","addition","additional","adjective","adult","adventure","advice","affect","afraid","after","afternoon","again","against","age","ago","agree","ahead","aid","air","airplane","alike","alive","all","allow","almost","alone","along","aloud","alphabet","already","also","although","am","among","amount","ancient","angle","angry","animal","announced","another","answer","ants","any","anybody","anyone","anything","anyway","anywhere","apart","apartment","appearance","apple","applied","appropriate","are","area","arm","army","around","arrange","arrangement","arrive","arrow","art","article","as","aside","ask","asleep","at","ate","atmosphere","atom","atomic","attached","attack","attempt","attention","audience","author","automobile","available","average","avoid","aware","away","baby","back","bad","badly","bag","balance","ball","balloon","band","bank","bar","bare","bark","barn","base","baseball","basic","basis","basket","bat","battle","be","bean","bear","beat","beautiful","beauty","became","because","become","becoming","bee","been","before","began","beginning","begun","behavior","behind","being","believed","bell","belong","below","belt","bend","beneath","bent","beside","best","bet","better","between","beyond","bicycle","bigger","biggest","bill","birds","birth","birthday","bit","bite","black","blank","blanket","blew","blind","block","blood","blow","blue","board","boat","body","bone","book","border","born","both","bottle","bottom","bound","bow","bowl","box","boy","brain","branch","brass","brave","bread","break","breakfast","breath","breathe","breathing","breeze","brick","bridge","brief","bright","bring","broad","broke","broken","brother","brought","brown","brush","buffalo","build","building","built","buried","burn","burst","bus","bush","business","busy","but","butter","buy","by","cabin","cage","cake","call","calm","came","camera","camp","can","canal","cannot","cap","capital","captain","captured","car","carbon","card","care","careful","carefully","carried","carry","case","cast","castle","cat","catch","cattle","caught","cause","cave","cell","cent","center","central","century","certain","certainly","chain","chair","chamber","chance","change","changing","chapter","character","characteristic","charge","chart","check","cheese","chemical","chest","chicken","chief","child","children","choice","choose","chose","chosen","church","circle","circus","citizen","city","class","classroom","claws","clay","clean","clear","clearly","climate","climb","clock","close","closely","closer","cloth","clothes","clothing","cloud","club","coach","coal","coast","coat","coffee","cold","collect","college","colony","color","column","combination","combine","come","comfortable","coming","command","common","community","company","compare","compass","complete","completely","complex","composed","composition","compound","concerned","condition","congress","connected","consider","consist","consonant","constantly","construction","contain","continent","continued","contrast","control","conversation","cook","cookies","cool","copper","copy","corn","corner","correct","correctly","cost","cotton","could","count","country","couple","courage","course","court","cover","cow","cowboy","crack","cream","create","creature","crew","crop","cross","crowd","cry","cup","curious","current","curve","customs","cut","cutting","daily","damage","dance","danger","dangerous","dark","darkness","date","daughter","dawn","day","dead","deal","dear","death","decide","declared","deep","deeply","deer","definition","degree","depend","depth","describe","desert","design","desk","detail","determine","develop","development","diagram","diameter","did","die","differ","difference","different","difficult","difficulty","dig","dinner","direct","direction","directly","dirt","dirty","disappear","discover","discovery","discuss","discussion","disease","dish","distance","distant","divide","division","do","doctor","does","dog","doing","doll","dollar","done","donkey","door","dot","double","doubt","down","dozen","draw","drawn","dream","dress","drew","dried","drink","drive","driven","driver","driving","drop","dropped","drove","dry","duck","due","dug","dull","during","dust","duty","each","eager","ear","earlier","early","earn","earth","easier","easily","east","easy","eat","eaten","edge","education","effect","effort","egg","eight","either","electric","electricity","element","elephant","eleven","else","empty","end","enemy","energy","engine","engineer","enjoy","enough","enter","entire","entirely","environment","equal","equally","equator","equipment","escape","especially","essential","establish","even","evening","event","eventually","ever","every","everybody","everyone","everything","everywhere","evidence","exact","exactly","examine","example","excellent","except","exchange","excited","excitement","exciting","exclaimed","exercise","exist","expect","experience","experiment","explain","explanation","explore","express","expression","extra","eye","face","facing","fact","factor","factory","failed","fair","fairly","fall","fallen","familiar","family","famous","far","farm","farmer","farther","fast","fastened","faster","fat","father","favorite","fear","feathers","feature","fed","feed","feel","feet","fell","fellow","felt","fence","few","fewer","field","fierce","fifteen","fifth","fifty","fight","fighting","figure","fill","film","final","finally","find","fine","finest","finger","finish","fire","fireplace","firm","first","fish","five","fix","flag","flame","flat","flew","flies","flight","floating","floor","flow","flower","fly","fog","folks","follow","food","foot","football","for","force","foreign","forest","forget","forgot","forgotten","form","former","fort","forth","forty","forward","fought","found","four","fourth","fox","frame","free","freedom","frequently","fresh","friend","friendly","frighten","frog","from","front","frozen","fruit","fuel","full","fully","fun","function","funny","fur","furniture","further","future","gain","game","garage","garden","gas","gasoline","gate","gather","gave","general","generally","gentle","gently","get","getting","giant","gift","girl","give","given","giving","glad","glass","globe","go","goes","gold","golden","gone","good","goose","got","government","grabbed","grade","gradually","grain","grandfather","grandmother","graph","grass","gravity","gray","great","greater","greatest","greatly","green","grew","ground","group","grow","grown","growth","guard","guess","guide","gulf","gun","habit","had","hair","half","halfway","hall","hand","handle","handsome","hang","happen","happened","happily","happy","harbor","hard","harder","hardly","has","hat","have","having","hay","he","headed","heading","health","heard","hearing","heart","heat","heavy","height","held","hello","help","helpful","her","herd","here","herself","hidden","hide","high","higher","highest","highway","hill","him","himself","his","history","hit","hold","hole","hollow","home","honor","hope","horn","horse","hospital","hot","hour","house","how","however","huge","human","hundred","hung","hungry","hunt","hunter","hurried","hurry","hurt","husband","ice","idea","identity","if","ill","image","imagine","immediately","importance","important","impossible","improve","in","inch","include","including","income","increase","indeed","independent","indicate","individual","industrial","industry","influence","information","inside","instance","instant","instead","instrument","interest","interior","into","introduced","invented","involved","iron","is","island","it","its","itself","jack","jar","jet","job","join","joined","journey","joy","judge","jump","jungle","just","keep","kept","key","kids","kill","kind","kitchen","knew","knife","know","knowledge","known","label","labor","lack","lady","laid","lake","lamp","land","language","large","larger","largest","last","late","later","laugh","law","lay","layers","lead","leader","leaf","learn","least","leather","leave","leaving","led","left","leg","length","lesson","let","letter","level","library","lie","life","lift","light","like","likely","limited","line","lion","lips","liquid","list","listen","little","live","living","load","local","locate","location","log","lonely","long","longer","look","loose","lose","loss","lost","lot","loud","love","lovely","low","lower","luck","lucky","lunch","lungs","lying","machine","machinery","mad","made","magic","magnet","mail","main","mainly","major","make","making","man","managed","manner","manufacturing","many","map","mark","market","married","mass","massage","master","material","mathematics","matter","may","maybe","me","meal","mean","means","meant","measure","meat","medicine","meet","melted","member","memory","men","mental","merely","met","metal","method","mice","middle","might","mighty","mile","military","milk","mill","mind","mine","minerals","minute","mirror","missing","mission","mistake","mix","mixture","model","modern","molecular","moment","money","monkey","month","mood","moon","more","morning","most","mostly","mother","motion","motor","mountain","mouse","mouth","move","movement","movie","moving","mud","muscle","music","musical","must","my","myself","mysterious","nails","name","nation","national","native","natural","naturally","nature","near","nearby","nearer","nearest","nearly","necessary","neck","needed","needle","needs","negative","neighbor","neighborhood","nervous","nest","never","new","news","newspaper","next","nice","night","nine","no","nobody","nodded","noise","none","noon","nor","north","nose","not","note","noted","nothing","notice","noun","now","number","numeral","nuts","object","observe","obtain","occasionally","occur","ocean","of","off","offer","office","officer","official","oil","old","older","oldest","on","once","one","only","onto","open","operation","opinion","opportunity","opposite","or","orange","orbit","order","ordinary","organization","organized","origin","original","other","ought","our","ourselves","out","outer","outline","outside","over","own","owner","oxygen","pack","package","page","paid","pain","paint","pair","palace","pale","pan","paper","paragraph","parallel","parent","park","part","particles","particular","particularly","partly","parts","party","pass","passage","past","path","pattern","pay","peace","pen","pencil","people","per","percent","perfect","perfectly","perhaps","period","person","personal","pet","phrase","physical","piano","pick","picture","pictured","pie","piece","pig","pile","pilot","pine","pink","pipe","pitch","place","plain","plan","plane","planet","planned","planning","plant","plastic","plate","plates","play","pleasant","please","pleasure","plenty","plural","plus","pocket","poem","poet","poetry","point","pole","police","policeman","political","pond","pony","pool","poor","popular","population","porch","port","position","positive","possible","possibly","post","pot","potatoes","pound","pour","powder","power","powerful","practical","practice","prepare","present","president","press","pressure","pretty","prevent","previous","price","pride","primitive","principal","principle","printed","private","prize","probably","problem","process","produce","product","production","program","progress","promised","proper","properly","property","protection","proud","prove","provide","public","pull","pupil","pure","purple","purpose","push","put","putting","quarter","queen","question","quick","quickly","quiet","quietly","quite","rabbit","race","radio","railroad","rain","raise","ran","ranch","range","rapidly","rate","rather","raw","rays","reach","read","reader","ready","real","realize","rear","reason","recall","receive","recent","recently","recognize","record","red","refer","refused","region","regular","related","relationship","religious","remain","remarkable","remember","remove","repeat","replace","replied","report","represent","require","research","respect","rest","result","return","review","rhyme","rhythm","rice","rich","ride","riding","right","ring","rise","rising","river","road","roar","rock","rocket","rocky","rod","roll","roof","room","root","rope","rose","rough","round","route","row","rubbed","rubber","rule","ruler","run","running","rush","sad","saddle","safe","safety","said","sail","sale","salmon","salt","same","sand","sang","sat","satellites","satisfied","save","saved","saw","say","scale","scared","scene","school","science","scientific","scientist","score","screen","sea","search","season","seat","second","secret","section","see","seed","seeing","seems","seen","seldom","select","selection","sell","send","sense","sent","sentence","separate","series","serious","serve","service","sets","setting","settle","settlers","seven","several","shade","shadow","shake","shaking","shall","shallow","shape","share","sharp","she","sheep","sheet","shelf","shells","shelter","shine","shinning","ship","shirt","shoe","shoot","shop","shore","short","shorter","shot","should","shoulder","shout","show","shown","shut","sick","sides","sight","sign","signal","silence","silent","silk","silly","silver","similar","simple","simplest","simply","since","sing","single","sink","sister","sit","sitting","situation","six","size","skill","skin","sky","slabs","slave","sleep","slept","slide","slight","slightly","slip","slipped","slope","slow","slowly","small","smaller","smallest","smell","smile","smoke","smooth","snake","snow","so","soap","social","society","soft","softly","soil","solar","sold","soldier","solid","solution","solve","some","somebody","somehow","someone","something","sometime","somewhere","son","song","soon","sort","sound","source","south","southern","space","speak","special","species","specific","speech","speed","spell","spend","spent","spider","spin","spirit","spite","split","spoken","sport","spread","spring","square","stage","stairs","stand","standard","star","stared","start","state","statement","station","stay","steady","steam","steel","steep","stems","step","stepped","stick","stiff","still","stock","stomach","stone","stood","stop","stopped","store","storm","story","stove","straight","strange","stranger","straw","stream","street","strength","stretch","strike","string","strip","strong","stronger","struck","structure","struggle","stuck","student","studied","studying","subject","substance","success","successful","such","sudden","suddenly","sugar","suggest","suit","sum","summer","sun","sunlight","supper","supply","support","suppose","sure","surface","surprise","surrounded","swam","sweet","swept","swim","swimming","swing","swung","syllable","symbol","system","table","tail","take","taken","tales","talk","tall","tank","tape","task","taste","taught","tax","tea","teach","teacher","team","tears","teeth","telephone","television","tell","temperature","ten","tent","term","terrible","test","than","thank","that","thee","them","themselves","then","theory","there","therefore","these","they","thick","thin","thing","think","third","thirty","this","those","thou","though","thought","thousand","thread","three","threw","throat","through","throughout","throw","thrown","thumb","thus","thy","tide","tie","tight","tightly","till","time","tin","tiny","tip","tired","title","to","tobacco","today","together","told","tomorrow","tone","tongue","tonight","too","took","tool","top","topic","torn","total","touch","toward","tower","town","toy","trace","track","trade","traffic","trail","train","transportation","trap","travel","treated","tree","triangle","tribe","trick","tried","trip","troops","tropical","trouble","truck","trunk","truth","try","tube","tune","turn","twelve","twenty","twice","two","type","typical","uncle","under","underline","understanding","unhappy","union","unit","universe","unknown","unless","until","unusual","up","upon","upper","upward","us","use","useful","using","usual","usually","valley","valuable","value","vapor","variety","various","vast","vegetable","verb","vertical","very","vessels","victory","view","village","visit","visitor","voice","volume","vote","vowel","voyage","wagon","wait","walk","wall","want","war","warm","warn","was","wash","waste","watch","water","wave","way","we","weak","wealth","wear","weather","week","weigh","weight","welcome","well","went","were","west","western","wet","whale","what","whatever","wheat","wheel","when","whenever","where","wherever","whether","which","while","whispered","whistle","white","who","whole","whom","whose","why","wide","widely","wife","wild","will","willing","win","wind","window","wing","winter","wire","wise","wish","with","within","without","wolf","women","won","wonder","wonderful","wood","wooden","wool","word","wore","work","worker","world","worried","worry","worse","worth","would","wrapped","write","writer","writing","written","wrong","wrote","yard","year","yellow","yes","yesterday","yet","you","young","younger","your","yourself","youth","zero","zebra","zipper","zoo","zulu"];function Sy(n){return new Array(n).fill(0).map(()=>gp[Math.floor(Math.random()*gp.length)]).join("-")}var eL=9e4,tL=3,nL=1500,rL=15e3,Sn=class extends Error{status;rawError;constructor(e,t,r,o={}){super(r,o),this.status=e,this.rawError=t}};async function oL(n){return n.text().then(e=>{try{return JSON.parse(e).error}catch{return e}})}var fp=class{baseUrl;logger;constructor(e){this.baseUrl=e.baseUrl,this.logger=e.logger}getHeaders(){let e={"Content-Type":"application/json"};return Na&&(e[bg]=Na),e}async sendRequest(e,t){let{retries:r=tL,requestTimeoutMs:o=eL,initialRetryDelayMs:i=nL,maxRetryDelayMs:a=rL}=t,s=r,l=r,c,d={path:e,baseUrl:this.baseUrl,method:t.method};for(;s>0;)try{return s--,await this.sendSingleRequestHelper(e,t,o)}catch(p){if(c=p,p instanceof Sn&&p.status>=400&&p.status<500)throw p;if(p instanceof Error&&p.name==="AbortError"&&(c=new gr),s===0)throw c;let u=l-s,m=Math.min(i*Math.pow(2,u-1),a);await new Promise(h=>setTimeout(h,m))}throw this.logger.warn({...d,err:c},"Got fatal error response from Momentic server"),c}async sendSingleRequestHelper(e,t,r){let o={path:e,baseUrl:this.baseUrl,method:t.method},i=new AbortController,a=setTimeout(()=>i.abort(),r),s=()=>i.abort();t.signal&&t.signal.addEventListener("abort",s);let l={...this.getHeaders(),...t.extraHeaders};try{let c=await fetch(`${this.baseUrl}${e}`,{method:t.method,body:t.body?JSON.stringify(t.body):void 0,headers:l,signal:i.signal});if(!c.ok){let p=await oL(c);throw new Sn(c.status,p,`Request to ${t.method} ${e} failed with status ${c.status}: ${p}`)}let d;if(c.status===204)d={};else{let p=await c.text();try{d=JSON.parse(p)}catch{d=p}}return this.logger&&!t.noLog&&d&&this.logger.debug({result:d,status:c.status,...o},"Got response from Momentic server"),d}finally{clearTimeout(a),t.signal&&t.signal.removeEventListener("abort",s)}}},Dt=class extends fp{apiKey;constructor(e){super(e),this.apiKey=e.apiKey}getHeaders(){return{...super.getHeaders(),Authorization:`Bearer ${this.apiKey}`}}};var ct=class extends Dt{constructor(e){super(e)}getAppUrl(){return this.baseUrl.replace(/\/\/api/,"//app")}async getAuthInfo(){let e=await this.sendRequest(`/${z}/auth/check`,{method:"GET",noLog:!0,retries:10,requestTimeoutMs:5e3});return Bg.parse(e)}async bulkGetRunStatus(e){let t=await this.sendRequest(`/${z}/runs/status`,{method:"POST",body:e,noLog:!0,retries:3,requestTimeoutMs:1e4});return _g.parse(t)}async getTestYAMLExport(e){let t=await this.sendRequest(`/${z}/tests/export`,{method:"POST",body:e,retries:3,requestTimeoutMs:3e4});return Lg.parse(t)}async updateStepCaches(e,t){await this.sendRequest(`/${z}/cache`,{method:"PATCH",body:e,extraHeaders:t,retries:3,requestTimeoutMs:1e4,initialRetryDelayMs:3e3})}async getStepCacheForTest(e,t){let r=await this.sendRequest(`/${z}/cache`,{method:"POST",body:e,extraHeaders:t,retries:10,requestTimeoutMs:3e4,initialRetryDelayMs:3e3});return Og.parse(r)}async queueTests(e){let t=await this.sendRequest(`/${z}/tests/queue`,{method:"POST",body:e,retries:3,requestTimeoutMs:1e4});return Pg.parse(t)}async uploadScreenshot(e){let t=await this.sendRequest(`/${z}/screenshots`,{method:"POST",body:e,noLog:!0,retries:3,requestTimeoutMs:5e3});return Ug.parse(t)}async getAllEnvironments(){let e=await this.sendRequest(`/${z}/environments`,{method:"GET",retries:3,requestTimeoutMs:5e3});return zg.parse(e)}async acquireCacheLock(e,t){let r=await this.sendRequest(`/${z}/result-cache/lock`,{method:"POST",body:e,signal:t,retries:3,requestTimeoutMs:3e4});return qg.parse(r)}async releaseCacheLock(e){await this.sendRequest(`/${z}/result-cache/lock`,{method:"DELETE",body:{key:e},retries:3,requestTimeoutMs:5e3})}async deleteCacheResult(e){await this.sendRequest(`/${z}/result-cache/entry`,{method:"DELETE",body:e,retries:3,requestTimeoutMs:5e3})}async setCacheResult(e){await this.sendRequest(`/${z}/result-cache/entry`,{method:"PATCH",body:e,retries:3,requestTimeoutMs:5e3})}async getCacheResult(e){try{return await this.sendRequest(`/${z}/result-cache/entry`,{method:"POST",body:e,retries:3,requestTimeoutMs:5e3})}catch(t){if(t instanceof Error&&t.message.includes("404"))return null;throw t}}async queueSuiteRuns(e){let t=await this.sendRequest(`/${z}/suites/queue`,{method:"POST",body:e,retries:3,requestTimeoutMs:5e3});return Hg.parse(t)}async bulkGetRunGroupStatus(e){let t={runGroupIds:e},r=await this.sendRequest(`/${z}/run-groups/status`,{method:"POST",body:t,noLog:!0,retries:3,requestTimeoutMs:5e3});return Sh.array().parse(r)}async uploadProposedSteps(e,t){try{await this.sendRequest(`/${z}/test-fragments/`,{method:"POST",body:e,retries:3,requestTimeoutMs:1e4})}catch(r){t.error({err:r},"Failed to upload proposed steps")}}async uploadSnapshotScreenshot(e,t,r){try{await this.sendRequest(`/${z}/snapshots/${t}/screenshot`,{method:"POST",body:r,noLog:!0,retries:3,requestTimeoutMs:1e4})}catch(o){e.error({err:o},"Failed to upload screenshot")}}async generateConsoleLogsForRunAttemptUploadUrl(e,t,r){let o=await this.sendRequest(`/${z}/runs/${t}/attempts/${r}/console-logs`,{method:"POST",noLog:!0,retries:3,requestTimeoutMs:5e3});return sa.parse(o)}async generateNetworkLogsForRunAttemptUploadUrl(e,t,r){let o=await this.sendRequest(`/${z}/runs/${t}/attempts/${r}/network-logs`,{method:"POST",noLog:!0,retries:3,requestTimeoutMs:1e4});return sa.parse(o)}async generateHtmlSnapshotUploadUrl(e,t){let r=await this.sendRequest(`/${z}/snapshots/${t}/html`,{method:"POST",noLog:!0,retries:3,requestTimeoutMs:1e4});return sa.parse(r)}async reportBillableEvents(e,t){try{await this.sendRequest(`/${z}/billing/events`,{method:"POST",body:t,noLog:!0,retries:10,requestTimeoutMs:1e4})}catch(r){e.error({err:r},"Failed to report billable event")}}async fetchTestFragment(e){let t=await this.sendRequest(`/${z}/test-fragments/${e}`,{method:"GET",noLog:!0,retries:3,requestTimeoutMs:1e4});return jg.parse(t)}async patchTestFragment(e,t){await this.sendRequest(`/${z}/test-fragments/${e}`,{method:"PATCH",body:t,retries:3,requestTimeoutMs:1e4})}async getPastTestResults(e,t){let r=await this.sendRequest(`/${z}/results/tests/${e}`,{method:"POST",body:t,retries:3,requestTimeoutMs:1e4});return $g.parse(r)}async generateTestResultsUploadUrl(){let e=await this.sendRequest(`/${z}/results/uploads`,{method:"POST",noLog:!0,retries:3,requestTimeoutMs:1e4});return Gg.parse(e)}async startProcessingResultsUpload(e,t){let r=await this.sendRequest(`/${z}/results/uploads/${e}/process`,{method:"POST",noLog:!0,body:t,retries:3,requestTimeoutMs:1e4});return Wg.parse(r)}async fetchIconKnowledgeBase(e){try{let t=await this.sendRequest(`/${z}/knowledge-base/icons`,{method:"GET",noLog:!0,retries:3,requestTimeoutMs:5e3});return Zg.parse(t)}catch(t){return e.error({err:t},"Failed to fetch icon knowledge base"),null}}async saveNewIcons(e,t){try{await this.sendRequest(`/${z}/knowledge-base/icons`,{method:"POST",body:e,noLog:!0,retries:3,requestTimeoutMs:5e3})}catch(r){t.error({err:r},"Failed to save new icons to icon knowledge base")}}async getMergeBaseCommitFromGithub(e,t,r,o){let i=new URLSearchParams;i.set("base",r),i.set("head",o);let a=await this.sendRequest(`/${z}/git/github/${e}/${t}/merge-base-commit?${i.toString()}`,{method:"GET",noLog:!0,retries:3,requestTimeoutMs:1e4});return la.parse(a)}async getCommitFromGithub(e,t,r){let o=await this.sendRequest(`/${z}/git/github/${e}/${t}/commits/${r}`,{method:"GET",noLog:!0,retries:3,requestTimeoutMs:1e4});return la.parse(o)}async getMergeBaseCommitFromGitlab(e,t,r){let o=new URLSearchParams;o.set("base",t),o.set("head",r);let i=await this.sendRequest(`/${z}/git/gitlab/${e}/merge-base-commit?${o.toString()}`,{method:"GET",noLog:!0,retries:3,requestTimeoutMs:5e3});return la.parse(i)}async getCommitFromGitlab(e,t){let r=await this.sendRequest(`/${z}/git/gitlab/${e}/commits/${t}`,{method:"GET",noLog:!0,retries:3,requestTimeoutMs:1e4});return la.parse(r)}async getAgentConfig(){let e=await this.sendRequest(`/${z}/web-agent/agent-config`,{method:"GET",noLog:!0,retries:3,requestTimeoutMs:5e3});return Sp.record(Sp.string(),Sp.string()).parse(e)}};import{randomUUID as yy}from"crypto";var El=class{apiClient;constructor(e){this.apiClient=e}async reportBillableEvent(e,t,r){try{return await this.apiClient.reportBillableEvents(e,[{event:t,timestamp:new Date().toISOString(),transactionId:r?.eventId??yy(),properties:yd({},r)}])}catch(o){e.error({err:o},"Failed to report billable event")}}async reportCreditsUsed(e,t,r,o){if(r)try{return await this.apiClient.reportBillableEvents(e,[{event:"credits-used",timestamp:new Date().toISOString(),transactionId:o?.eventId??yy(),properties:yd({creditsUsed:r,usedBy:t},o)}])}catch(i){e.error({err:i},"Failed to report credits used")}}};function li(n,e,t){return fetch(n,{method:"PUT",body:t,headers:{"Content-Type":e}})}var xl=class{constructor(e){this.client=e}async storeConsoleLogsForRunAttempt(e,t,r,o){try{let i=JSON.stringify(o),{uploadUrl:a}=await this.client.generateConsoleLogsForRunAttemptUploadUrl(e,t,r),s=await li(a,"application/json",i);if(!s.ok)throw new Error(`Failed to upload network logs: ${s.statusText}`)}catch(i){e.error({err:i},"Failed to upload console logs")}}async storeNetworkLogsForRunAttempt(e,t,r,o){let i=JSON.stringify(o);try{let{uploadUrl:a}=await this.client.generateNetworkLogsForRunAttemptUploadUrl(e,t,r),s=await li(a,"application/json",i);if(!s.ok)throw new Error(`Failed to upload network logs: ${s.statusText}`)}catch(a){e.error({err:a},"Failed to upload network logs")}}async storeHtmlSnapshot(e,t,r){try{let{uploadUrl:o}=await this.client.generateHtmlSnapshotUploadUrl(e,t),i=await li(o,"text/html",r);if(!i.ok)throw new Error(`Failed to upload network logs: ${i.statusText}`)}catch(o){e.error({err:o},"Failed to upload html snapshot")}}async storeScreenshot(e,t,r){try{await this.client.uploadSnapshotScreenshot(e,t,{screenshot:r.toString("base64")})}catch(o){e.error({err:o},"Failed to upload screenshot")}}async storeA11yTreeSnapshot(e,t,r){return Promise.resolve()}async getConsoleLogsForRunAttempt(e,t,r){}async getNetworkLogsForRunAttempt(e,t,r){}async getHtmlSnapshot(e,t){}async getA11yTreeSnapshot(e,t){}async getScreenshot(e,t){}};var ci=class{constructor(e,t){this.client=e;this.orgId=t}async acquireCacheLock(e,t){return this.client.acquireCacheLock(e,t)}async uploadScreenshot(e){return(await this.client.uploadScreenshot({screenshot:e.toString("base64")})).key}async releaseCacheLock(e){return this.client.releaseCacheLock(e)}async deleteCacheResult(e){return this.client.deleteCacheResult(e)}async setCacheResult(e){return this.client.setCacheResult(e)}async getCacheResult(e){return this.client.getCacheResult(e)}fetchIconKnowledgeBase(e){return this.client.fetchIconKnowledgeBase(e)}saveNewIcons(e,t){return this.client.saveNewIcons(e,t)}};import{Faker as iL,en as aL}from"@faker-js/faker";var di="v1",fr=class{httpClient;fakerInstance;type="API_CLIENT";sms={send:this.sendSms.bind(this),fetchLatest:this.fetchLatestSms.bind(this)};email={send:this.sendEmail.bind(this),fetchLatest:this.fetchLatestEmail.bind(this),fetchAll:this.fetchAllEmails.bind(this)};ai={generate:this.sendAiGenerate.bind(this)};constructor(e){this.httpClient=e.httpClient,e.fakerSeed&&(this.fakerInstance=new iL({locale:aL}),this.fakerInstance.seed(e.fakerSeed))}async sendAiGenerate(e){let t=typeof e=="string"?{input:e}:e;return this.httpClient.sendRequest(`/${di}/tools/ai/generate`,{method:"POST",body:t}).catch(r=>{throw r instanceof Sn?new Error(r.rawError):new Error(`Failed to send AI generation: ${r.message}`)})}async sendSms(e){return this.httpClient.sendRequest(`/${di}/tools/sms/send`,{method:"POST",body:e}).then(()=>{}).catch(t=>{throw t instanceof Sn?new Error(t.rawError):new Error(`Failed to send sms: ${t.message}`)})}async fetchLatestSms(e){return this.httpClient.sendRequest(`/${di}/tools/sms/fetchLatest`,{method:"POST",body:e}).catch(t=>{throw t instanceof Sn?new Error(t.rawError):t})}async sendEmail(e){return this.httpClient.sendRequest(`/${di}/tools/email/send`,{method:"POST",body:e}).then(()=>{}).catch(t=>{throw t instanceof Sn?new Error(t.rawError):new Error(`Failed to send email: ${t.message}`)})}async fetchAllEmails(e){return this.httpClient.sendRequest(`/${di}/tools/email/fetchAll`,{method:"POST",body:e}).catch(t=>{throw t instanceof Sn?new Error(t.rawError):new Error(`Failed to fetch all emails: ${t.message}`)})}async fetchLatestEmail(e){return this.httpClient.sendRequest(`/${di}/tools/email/fetchLatest`,{method:"POST",body:e}).catch(t=>{throw t instanceof Sn?new Error(t.rawError):new Error(`Failed to fetch latest emails: ${t.message}`)})}};import{z as sL}from"zod";var pi=class extends Dt{agentConfig;constructor(e,t){super(t),this.agentConfig=e}async rankChunksWithAi(e,t){let r={...e,loggerTags:t.loggerTags},o=await this.sendRequest(`/${z}/web-agent/recommend-chunks-ai`,{method:"POST",body:r,signal:t.abortSignal});return Eh.parse(o)}async rankChunksWithRag(e,t){let r=await this.sendRequest(`/${z}/web-agent/recommend-chunks`,{method:"POST",body:{cliVersion:Na,...e},signal:t.abortSignal});return Th.parse(r)}async getScreenshotFromS3(e){let t=await this.sendRequest(`/${z}/s3/visual-diff-screenshot`,{method:"POST",body:{url:e}});return sL.string().parse(t)}async getElementLocation(e,t){let r={...e,disableCache:t.disableCache,loggerTags:t.loggerTags,useMemory:t.useMemory,agentConfigVersion:this.agentConfig?.locator},o=await this.sendRequest(`/${z}/web-agent/locate-element`,{method:"POST",body:r,signal:t.abortSignal});return Ag.parse(o)}async getAssertionResult(e,t){let r={...e,disableCache:!!t.disableCache,useConsensus:!!t.useConsensus,attemptNumber:t.attemptNumber,loggerTags:t.loggerTags,useMemory:t.useMemory,agentConfigVersion:this.agentConfig?.locator},o=await this.sendRequest(`/${z}/web-agent/assertion`,{method:"POST",body:r,signal:t.abortSignal});return Pd.parse(o)}async getLintStepResult(e,t){let r={...e,disableCache:!!t.disableCache,loggerTags:t.loggerTags},o=await this.sendRequest(`/${z}/web-agent/lint/step`,{method:"POST",body:r,signal:t.abortSignal});return Rg.parse(o)}async getVisualAssertionResult(e,t){let r={...e,disableCache:!!t.disableCache,useConsensus:!!t.useConsensus,loggerTags:t.loggerTags},o=await this.sendRequest(`/${z}/web-agent/visual-assertion`,{method:"POST",body:r,signal:t.abortSignal});return Pd.parse(o)}async getAiActionCommand(e,t){let r=await this.sendRequest(`/${z}/web-agent/next-command-dynamic`,{method:"POST",body:{...e,disableCache:t.disableCache,loggerTags:t.loggerTags},signal:t.abortSignal});return Cg.parse(r)}async getMultiturnAiActionCommand(e,t){return await this.sendRequest(`/${z}/web-agent/ai-action/next-command`,{method:"POST",body:{...e,disableCache:t.disableCache,loggerTags:t.loggerTags},signal:t.abortSignal})}async getMultiturnAiActionEvaluation(e,t){let r=await this.sendRequest(`/${z}/web-agent/ai-action/evaluate`,{method:"POST",body:{...e,disableCache:t.disableCache,loggerTags:t.loggerTags},signal:t.abortSignal});return Wc.parse(r)}async getReverseMappedDescription(e,t){let r=await this.sendRequest(`/${z}/web-agent/reverse-mapped-description`,{method:"POST",body:{...e,disableCache:t.disableCache,loggerTags:t.loggerTags},signal:t.abortSignal});return Ig.parse(r)}async getTextExtraction(e,t){let r={...e,disableCache:t.disableCache,loggerTags:t.loggerTags},o=await this.sendRequest(`/${z}/web-agent/text-extraction`,{method:"POST",body:r,signal:t.abortSignal});return Gc.parse(o)}async getTestResultClassification(e,t){let r=await this.sendRequest(`/${z}/web-agent/result-classification`,{method:"POST",body:{...e,loggerTags:t.loggerTags},signal:t.abortSignal});return rd.parse(r)}async getExtractedKeywords(e,t){let r=await this.sendRequest(`/${z}/web-agent/extract-keywords`,{method:"POST",body:{goal:e,disableCache:t.disableCache,context:e},signal:t.abortSignal});return Mh.parse(r)}async getAutohealingProposal(e,t){let r=await this.sendRequest(`/${z}/web-agent/autoheal-section`,{method:"POST",body:{...e,loggerTags:t.loggerTags},signal:t.abortSignal});return wm.parse(r)}async getFailureRecoveryProposal(e,t){let r=await this.sendRequest(`/${z}/web-agent/failure-recovery`,{method:"POST",body:{...e,loggerTags:t.loggerTags},signal:t.abortSignal});return vm.parse(r)}async getIframeRegex(e,t){let r=await this.sendRequest(`/${z}/web-agent/iframe-regex`,{method:"POST",body:e,signal:t.abortSignal});return nm.parse(r)}};var ui=class extends Dt{generator;constructor(e,t){super(e),this.generator=t}async runTemplateMatching(e,t={}){let r=await this.sendRequest(`/${z}/web-agent/template-matching`,{method:"POST",body:e,signal:t?.signal});return rm.parse(r)}async constructIframeRegex(e,t={}){return this.generator.getIframeRegex(e,{abortSignal:t.signal})}};var Cl=class{constructor(e){this.client=e}async uploadResultsArchive(e,t){let{uploadUrl:r,id:o}=await this.client.generateTestResultsUploadUrl(),i=await li(r,"application/zip",t);if(!i.ok)throw new Error(`Failed to upload test results: ${await i.text()}`);let{runGroupId:a}=await this.client.startProcessingResultsUpload(o,{runGroupId:e});return a}};function mi({orgId:n,client:e,gitMetadata:t,alwaysSaveCache:r,noCache:o}){return o?new Xa:new yp(n,e,t,r)}var yp=class{constructor(e,t,{gitMainBranch:r,gitBranchName:o,gitProtectedBranches:i,gitCommitTimestamp:a,lastCommitOnMainSha:s,lastCommitOnMainTimestamp:l},c){this.orgId=e;this.client=t;this.cacheHeaders={},r&&(this.cacheHeaders[wg]=r),o&&(this.cacheHeaders[vg]=o),a&&(this.cacheHeaders[Tg]=a.toISOString()),s&&(this.cacheHeaders[Eg]=s),l&&(this.cacheHeaders[xg]=l.toISOString()),c?this.writeCaches=!0:o?this.writeCaches=!i.includes(o):this.writeCaches=!0}cacheHeaders;writeCaches;async saveStepCacheEntries({entries:e,testId:t,logger:r}){if(!this.writeCaches){r.debug("Skipping cache storage because branch is protected");return}try{await this.client.updateStepCaches({entries:e,testId:t},this.cacheHeaders)}catch(o){r.error({err:o},"Failed to save step cache entries")}}async resolveStepCacheEntries(e){let{steps:t,beforeSteps:r,afterSteps:o}=e.stepLists,i=await this.client.getStepCacheForTest({testId:e.testId,steps:t,schemaVersion:e.schemaVersion},this.cacheHeaders);if(!this.writeCaches){e.logger.debug("Skipping cache last used at update because branch is protected");return}for(let s of[t,r,o])s&&Ho({steps:s,stepCacheEntries:i,logger:e.logger});let{cachesToSave:a}=await gt({stepLists:e.stepLists,cacheCreationParams:{testId:e.testId,orgId:this.orgId}});this.client.updateStepCaches({entries:a,testId:e.testId},this.cacheHeaders)}};import hk from"path";import{Server as UN}from"socket.io";import{cloneDeep as lL}from"lodash-es";var cL={showOverlay:!1},bp=class{sessions=new Map;sessionCountByIp=new Map;getCurrentConnectionsByIp(e){return this.sessionCountByIp.get(e)??0}getCurrentSessionsByIp(){return Object.fromEntries(this.sessionCountByIp)}reserveCapacityByIp(e){e&&this.sessionCountByIp.set(e,(this.sessionCountByIp.get(e)??0)+1)}releaseCapacityByIp(e){e&&this.sessionCountByIp.set(e,Math.max(this.getCurrentConnectionsByIp(e)-1,0))}registerSession({controller:e,context:t,cleanup:r,clientIp:o,sessionId:i}){return this.sessions.set(i,{controller:e,context:t,cleanup:r,clientIp:o,browserBehavior:lL(cL)}),i}removeSession(e,t){(async()=>{let o=this.sessions.get(e);if(!o)return;this.releaseCapacityByIp(o.clientIp);let{controller:i}=o;try{i.setClosed(),await i.browser.cleanup()}catch(a){t.error({err:a},"Error cleaning up browser in global state manager")}try{await o.cleanup?.()}catch(a){t.error({err:a},"Error running cleanup function in global state manager")}this.sessions.delete(e)})()}getSession(e){return this.sessions.get(e)}},X=new bp;function by(n,e,t){let r=Date.now(),o=Date.now(),i,a,s,l,c=!1,d=async(h,g)=>{if(!h.closed&&!h.isInPageLoad)try{let f=s;s=void 0;let S=h.url(),w=g.toEditorDisplayCopy();JSON.stringify(w)===JSON.stringify(i)&&S===l&&r>o||(n.emit("browserState",{logsPerPage:f?.logsPerPage,harPages:f?.harPages,harEntries:f?.harEntries,viewport:h.getViewport(),url:S,iframeSrcUrls:a??[],context:w,isInPageLoad:h.isInPageLoad}),r=Date.now()),l=S,i=w}catch(f){if(!n.connected)return;let S=f instanceof Error?f.message:`${f}`;if(S.includes("Frame was detached")||S.includes("Not attached to an active page")||S.includes("browser has been closed")||S.includes("UserInfrastructureError"))return;t.error({err:f,sessionId:e},"Error grabbing browser state")}},p=setInterval(()=>{let h=X.getSession(e),g=h?.controller?.browser;if(!g||g.closed){t.debug("Clearing browser state socket cron due to the browser being closed"),clearInterval(p);return}d(g,h.context)},1e3),u=(h,g)=>!!(JSON.stringify(h)!==JSON.stringify(a)||g.logsPerPage.some(f=>f.length>0)||g.harPages&&Object.keys(g.harPages).length>0||g.harEntries&&Object.keys(g.harEntries).length>0),m=setInterval(async()=>{let g=X.getSession(e)?.controller?.browser;if(!g||g.closed){clearInterval(m);return}else if(c)return;c=!0;try{let f=await g.getAllFrameUrls(),S=g.retrieveAndClearDebugData();u(f,S)&&(a=f,s=S,o=Date.now())}catch(f){t.warn({err:f},"Failed to fetch extended details")}finally{c=!1}},2500);return{timers:[p,m]}}var Sr={};var dL=n=>()=>{let{sessionId:e}=n.metadata;Sr[e]?.abort?.abort()},wy={event:"cancelApiTest",createHandler:dL};import{CookieJar as PL}from"tough-cookie";import{randomUUID as yL}from"crypto";import{faker as pL}from"@faker-js/faker";import uL from"assert";import mL from"axios";import hL from"moment";import*as gL from"otpauth";import fL from"pg";async function vy(n){let e;try{e=new URL(n.url).hostname}catch{}let t=[];return n.headers.getSetCookie()?.forEach(r=>{let o=_s(r,e);t.push(...o)}),t}var SL=Object.getPrototypeOf(async function(){}).constructor;async function Ty(n,e,t){let r=e.code;e.options.fragment&&(r=`return ${e.code}`);let{env:o}=e.bindings,i=e.tools,a={},s=(f,S)=>{o[f]=S,a[f]=S},l={},c=(f,S)=>{o[f]=S,l[f]=S},d;r.includes("Octokit")&&(d=(await import("@octokit/rest")).Octokit);let p;r.includes("createAppAuth")&&(p=(await import("@octokit/auth-app")).createAppAuth);let u=async()=>await Promise.resolve(new SL("axios","moment","faker","assert","pg","Octokit","createAppAuth","OTPAuth","extractCookiesFromResponse","env","setVariable","setPersistentVariable","sendSms","waitForLatestSms","email","sms","ai",r)(mL,hL,i.fakerInstance??pL,uL,fL,d,p,gL,vy,o,s,c,S=>i.sms.send(S),S=>i.sms.fetchLatest(S),i.email,i.sms,i.ai)),m=!0,h,g;try{h=await B(u(),{milliseconds:e.options.timeoutMs,message:`Timeout of ${e.options.timeoutMs}ms exceeded for code execution`,signal:e.signal})}catch(f){t.error({err:f,env:o,evalCode:r},`[${n}] Error executing code: ${f}`),m=!1,f instanceof gr?g=`Timeout of ${e.options.timeoutMs}ms exceeded for code execution`:g=f instanceof Error?f.message:`${f}`}return{result:h,variableUpdates:a,persistentVariableUpdates:l,success:m,error:g}}async function Ey({code:n,fragment:e,context:t,localTools:r,logger:o,signal:i,timeoutMs:a=sr}){let s=yL(),l=await Ty(s,{code:n,options:{fragment:e,timeoutMs:a},bindings:t.toObjectCopy(),tools:r,signal:i},o);return b.debug(`[${s}] Got execution result: ${JSON.stringify(l)}`),l}import{createHmac as bL,randomUUID as wL}from"crypto";import vL from"fetch-retry";var TL=vL(global.fetch,{retries:3,retryOn:function(n,e,t){return!!(e!==null||t&&t.status>=500)},retryDelay:function(n){return Math.pow(2,n)*500}}),xy=process.env.GCP_JS_EVAL_FUNCTION_ENDPOINT,Cy=process.env.MOMENTIC_LAMBDA_AUTH_SECRET;async function Ry({orgId:n,code:e,fragment:t,context:r,timeoutMs:o=sr,retries:i=2,signal:a,logger:s}){if(!xy)throw new Error("GCP_JS_EVAL_FUNCTION_ENDPOINT environment variable not set");let l,c,d=0;if(!Cy)throw new Error("Missing lambda auth secret.");let p=bL("sha256",Cy).update(n).digest("hex");for(;d<=i;){d++,a?.throwIfAborted();let m={id:wL(),orgId:n,momenticLambdaAuthHash:p,code:e,fragment:t,state:r.toObjectCopy(),timeoutMs:o};try{if(l=await B(TL(xy,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(m)}),{milliseconds:o,message:`Timeout of ${o}ms exceeded for code execution`,signal:a}),!l)throw new Error("Got empty response from code evaluation server");if(!l.ok)throw new Error(`Code evaluation server returned error code ${l.status}`);c=void 0;break}catch(h){c=h}}if(c)throw s.error({err:c},"Failed to evaluate code remotely"),c;if(!l)throw new Error(`An unexpected code evaluation error occurred${c?`: ${c}`:""}`);let u;try{u=zh.parse(await l.json())}catch(m){throw new Error(`Code evaluation server returned invalid response: ${m}`)}if(u.error)throw new Error(`Code evaluation error: ${u.error}`);return u}async function Kn(n){let e;if(process.env.GCP_JS_EVAL_FUNCTION_ENDPOINT)e=await Ry(n);else if(n.localTools)e=await Ey({...n,localTools:n.localTools});else throw new Error("No code evaluation environment available");if(e.error){let t=`Failed to evaluate code:
50
50
  ${e.error}
51
51
  Code received:
52
52
  ${n.code}`;throw n.logger.error({err:e.error,code:n.code,env:n.context.toObjectCopy()},t),new Error(t)}if(e.variableUpdates)for(let[t,r]of Object.entries(e.variableUpdates))n.context.setVariable(t,r);if(e.persistentVariableUpdates&&Object.keys(e.persistentVariableUpdates).length>0){await n.callbacks?.onPersistentVariableUpdates?.(e.persistentVariableUpdates);for(let[t,r]of Object.entries(e.persistentVariableUpdates))n.context.setVariable(t,r)}return e.result}import{set as EL}from"lodash-es";async function $t(n){let{orgId:e,s:t,context:r,logger:o,signal:i,flagStore:a,retries:s=2,timeoutMs:l=sr,allowUndefined:c=!1}=n,d=/{{(.*?)}}/g,p=t.matchAll(d),u=t;for(let m of p){if(m.length<2)continue;let h=m[1].trim(),g;try{g=await Kn({orgId:e,code:h,fragment:!0,context:r,timeoutMs:l,logger:o,retries:s,localTools:n.localTools,signal:i,flagStore:a})}catch(S){throw o.error({err:S,value:t},"Error evaluating template string"),S}if(g===void 0&&!c)throw new R("UserConfigurationError",`Template fragment '${h}' evaluated to undefined. Please ensure that the variable name is spelled correctly and it is only referenced after being assigned a value.`);let f=typeof g=="string"?g:`${g}`;f=f.replaceAll(/\$/g,"$$$$"),u=u.replace(m[0],f)}return u}async function hi(n){return Ay(n)}async function Ay({obj:n,bannedKeys:e,allowList:t,context:r,prefixPath:o=[],replacements:i=[],...a}){for(let s in n){if(e.includes(s))continue;let l=!1;if(t)if(t.includes(s))l=!0;else continue;let c=n[s],d=[...o,s];if(typeof c=="string"&&c.includes("{{")){let p=await $t({s:c,context:r,...a});if(c===p)continue;i.push({path:d,original:c}),n[s]=p}else typeof c=="object"&&c!==null&&!Array.isArray(c)&&await Ay({obj:c,bannedKeys:e,context:r,prefixPath:d,replacements:i,allowList:l?void 0:t,...a})}return i}function Iy(n,e){for(let{path:t,original:r}of e)EL(n,t,r)}import xL from"fetch-retry";var N6=process.env.MAILINATOR_API_KEY,k6=xL(global.fetch,{retryOn:function(n,e,t){return n>3?!1:!!(e!==null||t&&t.status>=400)},retryDelay:function(n){return 500}});import RL from"fetch-cookie";import{cloneDeep as AL}from"lodash-es";var CL=3e4;async function Rl({command:n,logger:e,baseUrl:t,fetchImplementation:r=fetch}){let o=n.timeout??CL/1e3,i=Object.fromEntries(Object.entries(n.headers||{}).filter(([m,h])=>m&&h)),a=new URLSearchParams;Object.entries(n.params||{}).filter(([m,h])=>m&&h).forEach(([m,h])=>{a.append(m,h)});let s=a.toString(),l;if(jo(n.url)&&(l=n.url),t&&$o(n.url,t)&&(l=new URL(n.url,t).toString()),!l)throw new R("ActionFailureError",`Invalid URL: ${n.url}`);e.debug({url:l,searchParams:s,headers:i,body:n.body,method:n.method},"Making HTTP request");let d=await B((async()=>{let m=s?`${l}?${s}`:l;try{return await r(m,{headers:i,method:n.method,body:n.body})}catch(h){throw e.error({err:h},"Failed to make HTTP request"),new Error(`Failed to make HTTP request: ${h}`)}})(),{milliseconds:o*1e3,fallback:()=>{throw new R("ActionFailureError",`Fetch request timed out after ${o} seconds`)}});if(!d.ok){let m;try{m=await d.text()}catch(h){m=`Failed to read response body: ${h}`}throw new R("ActionFailureError",`Fetch request failed with status ${d.status}: ${m}`)}let p={};d.headers.forEach((m,h)=>{p[h]=m});let u={status:d.status,headers:p};if(d.headers.get("content-type")?.includes("json"))try{u.json=await d.json()}catch{}else d.headers.get("content-type")?.includes("text")&&(u.text=await d.text());return u}async function Py(n){let{fixtures:e,inputs:t}=n,{context:r}=e,{orgId:o,step:i}=t,a=AL(i);await hi({obj:a,orgId:o,bannedKeys:["code"],...e});let s=await IL(n);return a.envKey&&s.data&&r.setVariable(a.envKey,s.data),s}async function IL(n){let{fixtures:e,inputs:t}=n,{step:r,orgId:o,baseUrl:i}=t,{cookieJar:a}=e,s=new Date;switch(r.type){case"JAVASCRIPT":{let c=await Kn({code:r.code,orgId:o,fragment:!!r.fragment,timeoutMs:r.timeout?r.timeout*1e3:void 0,...e});try{JSON.stringify(c)}catch(d){return{...r,startedAt:s,finishedAt:new Date,status:"FAILED",message:`JavaScript return value is not serializable: ${d instanceof Error?d.message:`${d}`}`}}return{...r,startedAt:s,finishedAt:new Date,message:"JavaScript code executed successfully",status:"SUCCESS",data:c}}case"REQUEST":{let c=RL(fetch,a),d=await Rl({command:r,logger:e.logger,baseUrl:i,fetchImplementation:c});return{...r,startedAt:s,finishedAt:new Date,status:"SUCCESS",message:"Request executed successfully",data:d}}default:return(c=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(r)}}async function Ly(n){let{inputs:e,fixtures:t,callbacks:r}=n,{signal:o}=t,{steps:i,orgId:a,baseUrl:s}=e,{test:l,step:c}=r,d={startedAt:new Date,status:"RUNNING",results:[]},p=d.results,u=new PL,m={cookieJar:u,...t};for(let h of i){let g=new Date;c.onStarted?.(h.id);let f;try{o?.throwIfAborted(),f=await Py({inputs:{step:h,baseUrl:s,orgId:a},fixtures:m})}catch(S){o?.aborted?f={...h,startedAt:g,finishedAt:new Date,status:"CANCELLED",message:"Step cancelled by user."}:f={...h,startedAt:g,finishedAt:new Date,status:"FAILED",message:`Step failed: ${S instanceof Error?S.message:`${S}`}`}}if(p.push(f),c.onFinished?.({result:f,cookies:Fs(u,new URL(s).hostname)}),l.updateAttemptProgress?.({results:p}),f.status!=="SUCCESS"){d.status=f.status==="CANCELLED"?"CANCELLED":"FAILED";break}}return d.status==="RUNNING"&&(d.status="PASSED"),d.finishedAt=new Date,l.onFinished?.(),d}async function Oy(n){let{socket:e,storageFactory:t}=n,r=n.socket.id,{testId:o}=e.handshake.query;if(typeof o!="string")throw new Error(`Received invalid test ID that does not parse as a string: ${o}`);let i=await n.getOrgId({type:"api-test",testId:o}),a=await t(i),{baseUrl:s,envName:l,testName:c,environmentVariables:d}=await wp({testId:o,orgId:i,logger:n.logger,storage:a,authorization:n.authorization}),p={type:"api-test",orgId:await n.getOrgId({type:"api-test",testId:o}),testId:o,sessionId:r,latestContext:new Ot({baseUrl:s||"",currentUrl:s||"",variablesFromEnvironment:d,envName:l,testName:c})};return Sr[r]=p,p}async function wp({testId:n,logger:e,storage:t,authorization:r}){let o=await t.fetchApiTestMetadata(n,e);if(!o)throw new Error(`Failed to fetch API test metadata for test ID: ${n}`);let i;r?.type==="API_KEY"&&(i=new fr({httpClient:new Dt({...r,logger:e}),fakerSeed:void 0}));let a=o.envs?.find(d=>d.default),s;a&&(s=await t.fetchEnvironment(a.name,e));let l=o.baseUrl||s?.variables?.[We];if(!l)throw new Error("Base URL is empty in both API test options and the configured environment");let c={...s?.variables};return{baseUrl:l,envName:s?.name,testName:o.name,environmentVariables:c,localCodeEvalTools:i}}var LL=n=>async(e,t)=>{let{steps:r}=e,{authorization:o,metadata:i,socket:a,logger:s,flagStoreFactory:l,storageFactory:c}=n,{orgId:d,testId:p,sessionId:u}=i,m=s.child({testId:p,orgId:d,sessionId:u}),h=Sr[u];if(!h)throw new Error(`No api testing session with id ${u} could be found. Please reconnect and try again.`);let g=new AbortController;h.abort=g;let f=h.latestContext,S=await c(d),{localCodeEvalTools:w,baseUrl:T}=await wp({testId:p,orgId:d,logger:m,storage:S,authorization:o}),y={context:f,logger:m,localTools:w,signal:g.signal,flagStore:await l(d)},A=await Ly({inputs:{steps:r,orgId:d,baseUrl:T},fixtures:y,callbacks:{test:{onFinished:()=>{a.emit("apiTestFinished")}},step:{onStarted:k=>{a.emit("apiStepStarted",k)},onFinished:k=>{a.emit("apiStepFinished",k)}}}});t({result:A})},My={event:"executeApiTest",createHandler:LL};var OL=({metadata:n,logger:e})=>{let{sessionId:t}=n;return async()=>{e.info({sessionId:t},"Cancel event received");let r=X.getSession(t);if(!r)throw new Error("No active session found");try{r.controller.setClosed()}catch{}}},Ny={event:"cancel",createHandler:OL};var ML=({metadata:n,logger:e})=>{let{sessionId:t}=n;return async(r,o)=>{let i=X.getSession(t);if(!i)throw new Error("No active session found");i.controller.setOpen();let a=i.controller.browser;try{let l=(await a.getBrowserState({skipWait:!0})).serialize();e.debug({a11yTree:l},"Fetched a11y tree from the browser"),o({a11yTree:l})}catch(s){e.error({err:s},"Error fetching a11y tree from the browser"),o({err:s.message})}}},ky={event:"fetchA11yTree",createHandler:ML};var NL=({metadata:n,logger:e})=>{let{sessionId:t}=n;return async(r,o)=>{let i=X.getSession(t);if(!i)throw new Error("No active session found");i.controller.setOpen();let a=i.controller.browser;try{let s=await a.html();o({html:s})}catch(s){e.error({err:s},"Error fetching DOM from the browser"),s.name==="TimeoutError"?o({err:"Timed out fetching DOM tree. This page may be too large for Momentic to process."}):o({err:s.message})}}},_y={event:"fetchDom",createHandler:NL};var kL=({metadata:n,logger:e})=>{let{sessionId:t,type:r}=n;return o=>{e.info({sessionId:t,reason:o},`Disconnect event received (${o})`),r==="e2e"?X.removeSession(t,e):r==="api-test"&&delete Sr[t]}},Dy={event:"disconnect",createHandler:kL};function rn(n){let{result:e,nestedResults:t}=n;if(!n.nestedResults.length)return;let{firstMetadata:r,lastMetadata:o}=_L(t);DL(e,r,o);let i=[...n.asyncTasks];n.asyncTasks.push((async()=>{try{await FL(i,e,r,o)}catch(a){n.logger.error({result:n.result,err:a},"Error hoisting scalar result metadata")}})())}function _L(n){let e=n[0],t;for(;;){switch(e.type){case"PRESET_ACTION":{t=e;break}case"CONDITIONAL":if(e.assertion){t=e;break}break;case"AI_ACTION_DYNAMIC":case"AI_ACTION":case"MODULE":case"SECTION":case"IFRAME":if(!e.results.length){t=e;break}e=e.results[e.results.length-1];break;default:return(a=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(e)}if(t)break}let r=n[n.length-1],o;for(;;){switch(r.type){case"PRESET_ACTION":{o=r;break}case"AI_ACTION_DYNAMIC":case"CONDITIONAL":case"AI_ACTION":case"MODULE":case"SECTION":case"IFRAME":if(!r.results.length){o=r;break}r=r.results[r.results.length-1];break;default:return(a=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(r)}if(o)break}return{firstMetadata:t,lastMetadata:o}}function DL(n,e,t){e&&(n.beforeUrl=e.beforeUrl),t&&(n.afterUrl=t.afterUrl,n.data=t.data,t.status!=="SUCCESS"&&(n.message=t.message))}async function FL(n,e,t,r){await Promise.allSettled(n),t&&(e.beforeSnapshot=t.beforeSnapshot),r&&(e.afterSnapshot=r.afterSnapshot)}import ka from"os";import UL from"v8";var Fy,Ln,BL=ka.platform(),zL=ka.cpus().map(n=>({model:n.model,speed:n.speed}));function Uy(n){let e=()=>{try{let t=!1,r=HL(),o=jL();r.freeMemory<1e6&&(t=!0);let i=UL.getHeapStatistics(),a=i.used_heap_size,s=i.heap_size_limit;a/s>.9&&(t=!0),t?n.warn({memory:r,cpu:o,heapStats:i},"Critical resource usage metrics detected"):n.debug({memory:r,cpu:o},"Got machine resource usage metrics")}catch{}};return e(),{interval:setInterval(e,1e4),cpuMetadata:zL,platform:BL}}function HL(){let n=ka.totalmem(),e=ka.freemem(),t=n-e;return{totalMemory:n,freeMemory:e,usedMemory:t}}function jL(){let n=ka.cpus(),e=Date.now(),t={measurementTime:e,user:0,nice:0,sys:0,idle:0,irq:0,total:0};for(let o of n)t.user+=o.times.user,t.nice+=o.times.nice,t.sys+=o.times.sys,t.idle+=o.times.idle,t.irq+=o.times.irq;if(t.total=t.user+t.nice+t.sys+t.idle+t.irq,!Ln)return Ln=t,null;let r={user:t.user-Ln.user,nice:t.nice-Ln.nice,sys:t.sys-Ln.sys,idle:t.idle-Ln.idle,irq:t.irq-Ln.irq,total:t.total-Ln.total};return Fy={measurementTime:e,intervalMs:e-Ln.measurementTime,user:r.user/r.total*100,nice:r.nice/r.total*100,sys:r.sys/r.total*100,idle:r.idle/r.total*100,irq:r.irq/r.total*100,total:100-r.idle/r.total*100},Ln=t,Fy}import{hostname as qL}from"os";async function zy(n){let{command:e,tracer:t,timeoutMs:r,targetingWrapper:o,disableCache:i,fixtures:a}=n,{logger:s,abortSignal:l}=a;if(e.target&&!or(e.target))throw new Error("Element assertion with x/y is not supported yet");let c=e.assertion.type==="ELEMENT_EXISTENCE"&&e.assertion.negated&&(e.assertion.condition==="EXISTS"||e.assertion.condition==="VISIBLE"),d=Date.now(),p=0,u,m=500;for(;p<2||Date.now()-d<r;){p++,p>1&&await Z(m,l),l?.throwIfAborted();try{let{newTarget:h,elementInteractedDisplayString:g,result:f}=await o({ctx:a.ctx,tracer:t,command:e,target:e.target,cache:e.cache?.target,action:async S=>$L(S.locator,n),options:{...e,disableCache:i,disableGlobalLocatorRedirect:!0,source:Nr(e)}});if(u={success:f.success,data:f.data,err:f.err,newTarget:h,elementInteractedDisplayString:g},!f.success){u=f,m=Math.min(m*2,1e4);continue}return u}catch(h){if(l?.throwIfAborted(),c)return{success:!0,thoughts:`The element described does not exist on the page: ${h.message}`};if(s.warn({err:h},"Element assertion ended in error, retrying..."),!(h instanceof R)||h.reason!="ActionFailureError")throw h;u={success:!1,err:h}}}if(!u)throw new Error(`Failed to evaluate manual element assertion in ${r}ms.`);return u}async function $L(n,{command:e,fixtures:t}){let r=e.assertion;await t.browser.highlight(n);let o=!0,i,a;switch(r.type){case"ELEMENT_CONTENT":{let s=await n.textContent()??"";if(a={elementTextContent:je(s,500,!0)},!By(s,r.value,r.operation,!!r.negated)){let l=r.negated?cr[r.operation]:dr[r.operation];o=!1,i=new R("AssertionFailureError",`The content ${l} '${r.value}': ${s}`)}break}case"ELEMENT_ATTRIBUTE":{a={elementOuterHtml:je(await n.evaluate(l=>l.cloneNode(!1).outerHTML),500,!0)};let s;try{s=await n.getAttribute(r.attr,{timeout:3e3})??""}catch(l){i=new R("AssertionFailureError",`The element does not have an attribute named ${r.attr}: ${l}`),o=!1;break}if(!By(s,r.value,r.operation,!!r.negated)){let l=r.negated?cr[r.operation]:dr[r.operation];o=!1,r.operation==="EXISTS"?i=r.negated?new R("AssertionFailureError",`The attribute ${r.attr} ${l}: ${s}`):new R("AssertionFailureError",`The attribute ${r.attr} ${l}`):i=new R("AssertionFailureError",`The attribute ${r.attr} ${l} '${r.value}': ${s}`)}break}case"ELEMENT_EXISTENCE":{switch(r.condition){case"VISIBLE":{o=await n.evaluate(async(l,c)=>{let d=Date.now();for(;Date.now()-d<c;){let p=l.getBoundingClientRect();if(p.width>0&&p.height>0)return!0;await new Promise(u=>setTimeout(u,250))}return!1},Cn*1e3);break}case"EDITABLE":{o=await n.isEditable({timeout:Cn*1e3});break}case"EXISTS":{o=!0;break}case"ENABLED":{o=await n.isEnabled({timeout:Cn*1e3});break}default:return(l=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(r.condition)}if(o=r.negated?!o:o,!o){let s=r.negated?kd[r.condition]:_d[r.condition];i=new R("AssertionFailureError",`The element ${s}`)}break}}return{success:o,data:a,err:i}}function By(n,e,t,r){let o;switch(t){case"CONTAINS":{o=n.includes(e);break}case"EQUALS":{o=n.trim()===e.trim();break}case"STARTS_WITH":{o=n.trim().startsWith(e);break}case"EXISTS":{o=n.trim().length>0;break}default:return(a=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(t)}return r?!o:o}import{Jimp as GL}from"jimp";async function _a(n,e){let t=await n.screenshot(e),r=await GL.fromBuffer(t);return{buffer:t,width:Math.ceil(r.bitmap.width??0),height:Math.ceil(r.bitmap.height??0)}}import{Jimp as Hy}from"jimp";import vp from"jpeg-js";import WL from"pixelmatch";async function jy({ctx:n,tracer:e,command:t,disableCache:r,browser:o,targetingWrapper:i,logger:a,screenshotStorage:s}){if(t.target&&!or(t.target))throw new Error("Visual Diff with x/y is not supported yet");await o.waitForDOMStability({logger:a});let l={clearHighlights:!0,hideCaret:!0},c;t.target?.elementDescriptor?c=(await i({ctx:n,tracer:e,command:t,target:t.target,cache:t.cache?.target??t.target?.a11yData,action:async q=>_a(o,{locator:q.locator,...l}),options:{...t,disableCache:r,disableGlobalLocatorRedirect:!0}})).result:c=await _a(o,l);let d=await s.prepareGoldenScreenshotForComparison(a,t,c);if((c.height!==d.height||c.width!==d.width)&&a.debug({currHeight:c.height,currWidth:c.width,savedHeight:d.height,savedWidth:d.width},"Mismatched before and after visual diff screenshot sizes"),Math.abs(c.height-d.height)>10||Math.abs(c.width-d.width)>10){let W=`${c.width}x${c.height}`,q=`${d.width}x${d.height}`;return{fail:!0,thoughts:`Current screenshot (${W}) does not match saved screenshot dimensions (${q}) - did you change the size of the target or the viewport?`,beforeScreenshotOverride:d.buffer,afterScreenshotOverride:c.buffer,succeedImmediately:!1,urlAfterCommand:o.url()}}let p=await Hy.fromBuffer(c.buffer),u={width:c.width,height:c.height},m=await Hy.fromBuffer(d.buffer),h={width:d.width,height:d.height},g,f=u.width*u.height,S=h.width*h.height,w=Math.abs(u.height-h.height),T=Math.abs(u.width-h.width);if(f>S){let W=p.cover({w:h.width,h:h.height});c.buffer=await W.getBuffer("image/jpeg"),g="current",c.width=h.width,c.height=h.height}else if(S>f){let W=m.cover({w:u.width,h:u.height});d.buffer=await W.getBuffer("image/jpeg"),g="saved"}let y={data:Buffer.alloc(c.width*c.height*4),width:c.width,height:c.height},E=t.threshold??.1,A=WL(vp.decode(d.buffer).data,vp.decode(c.buffer).data,y.data,c.width,c.height,{threshold:E,diffColorAlt:[0,255,0]})/(c.width*c.height)*100,k=A>E*100,L=`Visual diff of ${A.toFixed(2)}% detected, which is ${k?"over":"under"} the threshold of ${E*100}%.`;if(g&&(L+=` The ${g} screenshot was cropped since it was taller by ${w} pixels and wider by ${T} pixels.`),k)throw new R("ActionFailureError",L);return{fail:k,thoughts:L,beforeScreenshotOverride:c.buffer,afterScreenshotOverride:vp.encode(y,75).data,succeedImmediately:!1,urlAfterCommand:o.url()}}var VL=5e3;async function Al({timeout:n=Cn,...e}){let t=Date.now(),r=n*1e3,o=r+1e4,i,a=0,s=500;for(;a-t<r;){if(Date.now()-t>o){e.logger.warn("Exceeded max system timeout for page assertion, exiting...");break}e.signal.throwIfAborted();let l=Date.now();i=await $y(e),a=Date.now();let c=a-l;if(c>1e3&&e.logger.warn({pageAssertDuration:c},"Page assertion took longer than expected"),!i.success)await Z(s,e.signal),s=Math.min(Math.floor(s*1.5),VL);else return i}return i=await $y(e),i}async function $y({assertion:n,browser:e,flagStore:t}){switch(n.type){case"CONTENT":{let o,i=!1,a;try{let s;if(t.isBooleanFlagEnabled("auto_expand_iframes")){let l=await e.evaluateFunctionInAllFrames(Gy,{value:n.value,negated:!!n.negated,returnHtml:!1});i=n.negated?l.every(c=>c.evaluation):l.some(c=>c.evaluation),s=l.find(c=>c.pageHtml)?.pageHtml}else({evaluation:i,pageHtml:s}=await e.evaluateFunctionInPage(Gy,{value:n.value,negated:!!n.negated,returnHtml:!0},"checking page content"));if(!i){let l=n.negated?cr.CONTAINS:dr.CONTAINS;a=new R("AssertionFailureError",`The page ${l} '${n.value}'.`),o=s}}catch(s){a=new R("AssertionFailureError",`Failed to evaluate page content assertion: ${s instanceof Error?s.message:`${s}`}`)}return{success:i,err:a,data:i||!o?void 0:{pageContent:o}}}default:return(o=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(n.type)}}function Gy({value:n,negated:e,returnHtml:t}){let r=document.documentElement.outerHTML,o=r.includes(n)===!e;return r.length>1e4&&(r=r.slice(0,1e4)+"...TRUNCATED"),{evaluation:o,pageHtml:!o&&t?r:void 0}}var Tp=async n=>{let{step:e,resolvedInputs:t}=n.moduleParams,{logger:r,context:o,storage:i,codeEvalTools:a,controller:s}=n.fixtures,l=s.browser,{orgId:c,runId:d}=n.inputs,p=s.executeAbortController.signal;Object.keys(t).length>0&&(o.setInputs(t),r.debug({inputs:t,moduleId:e.moduleId},"Set module inputs"));let u,m=!1,h,g;if(e.cacheConfig||e.defaultCacheAllInvocations){let f=e.cacheConfig?.cacheKey||e.defaultCacheKey||"",S=await $t({orgId:c,s:f,context:o,logger:r,localTools:a,signal:p,flagStore:s.flagStore});g={orgId:c,cacheKeys:[S,...Object.entries(t).map(([T,y])=>`${T}:${y}`)]},r.debug({original:f,keyParams:g},"Module cache key params");let w=Date.now();for(;Date.now()-w<Sg;){p?.throwIfAborted();let T=await i.getCacheResult(g);if(T){r.debug({cacheResult:T},"Got result from module execution cache"),u=Il(e,t,"SUCCESS"),u.message="Used cached module result.",u.data=JSON.parse(T),m=!0;break}else r.debug({cacheKey:f,keyParams:g},"No cache result found, continuing with lock acquisition");let y=await i.acquireCacheLock({keyParams:g,clientMetadata:`hostName:${qL()};runId:${d}`},p);if(y.acquired){h=y.keyPrefix,r.info({cacheKeyPrefixIfLockAcquired:h,cacheKey:f,keyParams:g},"Acquired cache lock and proceeding with module execution");break}else r.debug({cacheKeyPrefixIfLockAcquired:h,cacheKey:f,keyParams:g},"Failed to acquire cache lock, retrying...");await Z(2500+Math.random()*1e4,p)}}try{if(!u)u=await KL(n);else if(e.autoAuth){let f=Ds.safeParse(u.data);if(!f.success)throw new R("UserConfigurationError",`Cached authentication module result is not a valid storage state: ${f.error.message}`);r.debug("Automatically loading auth state after cached module result"),await l.loadAuthState(f.data);let S=!1,w=e.advanced?.cacheInvalidation;if(w&&w.type==="PAGE_CHECK"){let T={type:"CONTENT",value:w.substring},y=await Al({timeout:Cn,assertion:T,browser:l,flagStore:s.flagStore,logger:r,signal:p});y.success?r.debug({invalResult:y},"Cached result still valid after page check, continuing..."):(r.info({invalResult:y},"Invalidating cached result due to page check failure"),S=!0)}if(g&&S)return await i.deleteCacheResult(g),Tp(n)}}finally{try{h!==void 0&&!m&&u?.status==="SUCCESS"&&await YL({step:e,result:u,browser:s.browser,cacheKeyPrefix:h,logger:r,storage:i})}finally{h!==void 0&&await i.releaseCacheLock(h)}}return u},KL=async n=>{let{step:e,tracer:t}=n.moduleParams,r=Il(e,n.moduleParams.resolvedInputs,"SUCCESS"),o=await t.startSubSteps(),{status:i,results:a}=await yr(n.work,()=>n.executeStepList({...n,listParams:{steps:e.steps,containerName:`module ('${e.name}')`,tracer:o}}));return r.results=a,r.status=i,r.finishedAt=new Date,rn({asyncTasks:n.work.asyncTasks,nestedResults:a,result:r,logger:n.fixtures.logger}),r};function Il(n,e,t){let r={};return Object.entries(e).forEach(([i,a])=>{r[i]=JSON.stringify(a)}),{type:"MODULE",id:n.id,moduleId:n.moduleId,moduleName:n.name,startedAt:new Date,cacheConfig:n.cacheConfig,inputs:r,results:[],finishedAt:new Date,status:t}}async function Wy({orgId:n,step:e,context:t,logger:r,flagStore:o,codeEvalTools:i,signal:a}){let s={};try{for(let l of e.parameters??[]){let c=e.inputs?.[l]??e.defaultParameters?.[l];if(!c){r.warn(`No value or default found for parameter '${l}' that is required by module '${e.name}'`);continue}s[l]=await Kn({orgId:n,code:c,fragment:!0,context:t,logger:r,localTools:i,signal:a,flagStore:o})}return s}catch(l){throw a?.throwIfAborted(),new R("UserConfigurationError",`Failed to evaluate module inputs: ${l}`)}}async function YL({step:n,result:e,browser:t,cacheKeyPrefix:r,logger:o,storage:i}){let a=n.cacheConfig?.cacheExpiryMs;(!a||a===Kg)&&(a=n.defaultCacheTtl??Yg);let s;n.autoAuth?s=JSON.stringify(await t.saveAuthState()):e.data!==void 0?s=JSON.stringify(e.data):s='""',o.debug({cacheKeyPrefix:r,ttlMs:a,truncatedCacheResultJson:Tf(s)},"Setting module cache result"),await i.setCacheResult({result:s,keyPrefix:r,ttlMs:a})}async function br(n,e,t){let r=new Date;try{return t.throwIfAborted(),await e()}catch(o){let i=new Date,a="FAILED",s;if(t.aborted||o instanceof DOMException&&o.name==="AbortError"?(s="Step aborted by user.",a="CANCELLED"):o instanceof R?s=`${o}`:s=`An unexpected error occurred: ${o.message}`,n.type==="RESOLVED_MODULE"){let l=Il(n,{},"FAILED");return l.message=s,l.startedAt=r,l.finishedAt=i,l}return{...Qs(n),startedAt:r,finishedAt:i,status:a,data:null,message:s,results:[]}}}async function yr(n,e){let t=!1;try{return n&&!n.state.failureRecoveryDisabled&&(n.state.failureRecoveryDisabled=!0,t=!0),await e()}finally{n&&t&&(n.state.failureRecoveryDisabled=void 0)}}import{randomUUID as Vy}from"crypto";import{cloneDeep as XL}from"lodash-es";function Pl(n,e){n.state.healingDetails?n.state.healingDetails.push(e):n.state.healingDetails=[e]}var Ll=async n=>{let{step:e,tracer:t}=n.presetParams,{logger:r,controller:o,context:i,billingReporter:a}=n.fixtures,{collectDebugData:s}=n.options,{testMetadata:l,suiteMetadata:c}=n.inputs,d=e.command.type,p=r.child({commandType:d,stepId:e.id,commandId:e.command.id}),u=ra(e.command);n.work.asyncTasks.push(a.reportCreditsUsed(p,d,u,{testId:l?.id,testName:l?.name,suiteId:c?.id,suiteName:c?.name}));let m=o.browser.url(),h=new Date,g,f=Vy(),S=Vy();if(s)try{g=await o.browser.screenshot({retries:1,clearHighlights:!0,quality:75});let x=await o.browser.getRawCondensedHtml();t.attachBeforeHtmlSnapshot({logger:p,snapshotId:f,html:x}),n.work.asyncTasks.push(n.fixtures.debugDataStorage.storeHtmlSnapshot(p,f,x))}catch(x){p.debug({err:x},"Failed to take before screenshot, continuing...")}let w,T,y,E=Ms();try{let x=await o.executePresetCommand(E,t,e.command,i,l?.advanced.disableAICaching??!1);x.beforeScreenshotOverride&&(g=x.beforeScreenshotOverride),y=x.afterScreenshotOverride;let{proposedStep:A}=QL({work:n.work,step:e,newTargets:x.newTargets,logger:p}),k=new Date,L=o.browser.url();T={beforeUrl:m,afterUrl:L,startedAt:h,finishedAt:k,viewport:o.browser.getViewport(),status:x.fail?"FAILED":"SUCCESS",elementInteracted:x.elementInteracted},w={...e,message:x.thoughts??ZL(x.newTargets)??"Successfully executed preset action.",beforeUrl:m,afterUrl:L,finishedAt:k,startedAt:h,status:x.fail?"FAILED":"SUCCESS",data:x.data,results:[T],details:E.details,proposedStep:A},"assertion"in e.command&&(w.message=x.thoughts||"Assertion passed.")}catch(x){p.error({message:x.message,stack:x.stack},`Failed executing preset step ${Wr(e.command)}`);let A=o.browser.url(),k=new Date,L=x instanceof Error?x.message:`${x}`;x instanceof R&&x.getLastScreenshotBuffer()&&(y=x.getLastScreenshotBuffer()),T={beforeUrl:m,afterUrl:A,startedAt:h,finishedAt:k,viewport:o.browser.getViewport(),status:x instanceof DOMException&&x.name==="AbortError"?"CANCELLED":"FAILED",message:L},w={...e,startedAt:h,finishedAt:k,beforeUrl:m,afterUrl:A,status:x instanceof DOMException&&x.name==="AbortError"?"CANCELLED":"FAILED",message:L,failureReason:x instanceof R?x.reason:void 0,results:[T],details:E.details}}if(s)try{y||(y=await o.browser.screenshot({retries:1,quality:75}));let x=await o.browser.getRawCondensedHtml();t.attachAfterHtmlSnapshot({logger:p,snapshotId:S,html:x}),n.work.asyncTasks.push(n.fixtures.debugDataStorage.storeHtmlSnapshot(p,S,x))}catch(x){p.debug({err:x},"Failed store debug data after step, likely because the page is still loading. This is non-fatal and does not affect the test.")}return T.beforeSnapshot=f,w.beforeSnapshot=f,T.afterSnapshot=S,w.afterSnapshot=S,g&&(t.attachBeforeScreenshot({logger:p,snapshotId:f,screenshot:g}),n.work.asyncTasks.push(n.fixtures.debugDataStorage.storeScreenshot(p,f,g))),y&&(t.attachAfterScreenshot({logger:p,snapshotId:S,screenshot:y}),n.work.asyncTasks.push(n.fixtures.debugDataStorage.storeScreenshot(p,S,y))),w};function QL({work:n,step:e,newTargets:t,logger:r}){if(!t?.length)return{proposedStep:void 0};let o=e.command;gf(o,t,r);let i=t[0]?.description;if(i&&"target"in o&&o.target&&o.target.type==="description"){let a={...o,target:{...o.target,elementDescriptor:i}},s={...XL(e),command:a};return Pl(n,{type:"DESCRIPTION_UPDATE",thoughts:`Updated element description after the original element could not be found on the page. New element location reasoning: ${t[0]?.thoughts}`}),{proposedStep:s}}return{proposedStep:void 0}}function ZL(n){if(n?.length){if(n.length===1&&n[0]?.thoughts)return n[0].thoughts;if(n.length===2&&n.every(e=>e.thoughts))return`Located first element: ${n[0]?.thoughts}
@@ -3917,7 +3917,7 @@ ${a.stack}`),l.status(500).send("Internal Server Error")}),n){let a=Pv.static(n,
3917
3917
  for /f "tokens=5" %a in ('netstat -ano ^| findstr :58888') do taskkill /PID %a /F
3918
3918
  `)}import P_ from"events";import vc from"fs";import L_ from"open";import{cpus as GT}from"os";import wc from"path";import{fileURLToPath as O_}from"url";import kk from"diff-lines";import{gt as _k}from"semver";import{execSync as fk}from"child_process";import{platform as Sk}from"os";function fu(){return Nv()?(b.dimmed("Setting device pixel ratio to 2 automatically since a Mac OS Retina screen was detected."),b.dimmed(`If you are using a low pixel-density monitor, you should manually set --pixel-ratio to 1 to avoid incorrect viewport calculations. Confirm your device's pixel-ratio at https://www.mydevice.io.
3919
3919
  `),2):(b.dimmed("Setting device pixel ratio to 1."),b.dimmed(`If you are using Momentic on a high-pixel density (HiDPI) monitor, relaunch with the --pixel-ratio option to avoid incorrect viewport calculations. Confirm your device's pixel-ratio at https://www.mydevice.io.
3920
- l.`),1)}function Nv(){return Sk()==="darwin"&&fk("system_profiler SPDisplaysDataType").toString().includes("Retina")}function Su(n){Nv()&&n===1&&(b.warn("If you are using Momentic on a Retina screen, relaunch with the --pixel-ratio option to avoid incorrect viewport calculations."),b.warn("Confirm your device's pixel-ratio at https://www.mydevice.io."))}import yk from"@actions/exec";import bk from"@actions/io";import wk from"quote";import vk from"string-argv";async function kv(n,e=!0){let t=vk(n),r=await bk.which(t[0],!0),o=t.slice(1),i=yk.exec(wk(r),o,{delay:100});if(e)return i}import{existsSync as Tk,statSync as Ek}from"fs";var Ga=!!process.env.CI||!!process.env.GITHUB_ACTIONS||!!process.env.GITHUB_RUN_ID||!!process.env.GITLAB_CI||!!process.env.CI_COMMIT_SHA||!!process.env.JENKINS_URL||!!process.env.BUILD_NUMBER||!!process.env.JENKINS_HOME||!!process.env.CIRCLECI||!!process.env.CIRCLE_BUILD_NUM||!!process.env.TRAVIS||!!process.env.TRAVIS_BUILD_NUMBER||!!process.env.BITBUCKET_BUILD_NUMBER||!!process.env.BITBUCKET_COMMIT||!!process.env.CODEBUILD_BUILD_ID||!!process.env.TF_BUILD||!!process.env.BUILD_BUILDID||!!process.env.AGENT_ID||!!process.env.BUILDER_SA_EMAIL||!!process.env.HEROKU_TEST_RUN_ID||!!process.env.CI_NODE_INDEX||!!process.env.TEAMCITY_VERSION||!!process.env.BUILD_VCS_NUMBER||!!process.env.BUILDKITE||!!process.env.BUILDKITE_BUILD_NUMBER||!!process.env.APPVEYOR||!!process.env.APPVEYOR_BUILD_NUMBER||!!process.env.DRONE||!!process.env.DRONE_BUILD_NUMBER||!!process.env.SHIPPABLE||!!process.env.BUILD_URL||!!process.env.SEMAPHORE||!!process.env.SEMAPHORE_EXECUTABLE_UUID||!!process.env.WOODPECKER||!!process.env.CI_BUILD_NUMBER||!!process.env.WERCKER_MAIN_PIPELINE_STARTED||!!process.env.BUDDY_EXECUTION_ID;function _v(n){try{return Tk(n)&&Ek(n).isDirectory()}catch(e){return b.error({err:e},`Error reading path ${n} during directory existence check`),!1}}import xk from"csv-parser";import{createReadStream as Ck}from"fs";function yu(n){return new Promise((e,t)=>{let r=[];Ck(n).pipe(xk()).on("data",o=>r.push(o)).on("end",()=>e(r)).on("error",o=>t(o))})}import tc from"semver";import{z as nc}from"zod";var wn="2.7.0",Rk="https://registry.npmjs.org/momentic",Ak=nc.object({versions:nc.record(nc.string(),nc.unknown()).optional()});async function Dv(n){try{await Ik(n)}catch(e){b.warn({err:e},"Failed to check CLI version against NPM servers")}}async function Ik(n){if(!wn){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 B(fetch(Rk),{milliseconds:5e3});if(!o.ok)throw new Error(`Got error status code ${o.statusText}`);let i=await o.json();e=Ak.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))tc.valid(r)&&(!t||tc.gt(r,t))&&tc.gt(r,wn)&&tc.lt(r,"2.0.0")&&!r.includes("alpha")&&(t=r);t&&(b.warn(`Update available: v${wn} -> v${t}`),b.warn("This version may be missing critical fixes, features, and security updates."),b.warn(`Run "npx momentic@${t} -V" to update`))}import{existsSync as Lk,mkdirSync as Ok,statSync as Mk}from"fs";import{dirname as Nk}from"path";import Uv from"readline/promises";import{hostname as Pk}from"os";var ee=Yl({app:"cli",clientToken:"pub7eb923f18fb3f1d42ac5eba8c5ea13a5",hostname:Pk(),disableConsoleLogs:!0}).child({version:"2.7.0"});var bu=!1,Bv=(()=>{try{return Mk("/.dockerenv"),!0}catch{return!1}})();async function bt(n,e){if(Ga||bu||Bv)return!0;ee.flush(),await new Promise(a=>setTimeout(a,500));let t=Uv.createInterface({input:process.stdin,output:process.stdout}),r=n.split("."),o;if(r.length===1)o=n;else{let a=`${r.slice(0,r.length-1).join(".").trim()}.`;e?b.warn(a):b.log(a),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"?(bu=!0,setTimeout(()=>{bu=!1},3e3),!0):i.toLowerCase()==="y"}async function wu(n){let e=Nk(n);return _v(e)?Lk(n)?bt(`File '${Fv(n)}' already exists. Overwrite existing content?`,!0):!0:await bt(`Directory '${Fv(e)}' doesn't exist. Create it now?`,!0)?(Ok(e,{recursive:!0}),!0):!1}function Fv(n){return n.replace(/(\s+)/g,"\\$1")}async function zv(n,e){if(Ga||Bv)return e;let t=Uv.createInterface({input:process.stdin,output:process.stdout}),r=await t.question(`${n} `);return t.close(),r.trim()||e}async function Hv({test:n,fragment:e,entities:t,client:r,logger:o,yes:i}){_k(e.schemaVersion,Oe)&&(b.error(`This version of the CLI does not support the schema version of the fragment (${e.schemaVersion}). Please update to the latest version of the CLI and retry this command.`),process.exit(1)),hf(e.steps).forEach(g=>{t.modules[g]||(b.error(`The test patch contains a module with id ${g} that could not be found in the current project. This suggests that either this test patch or your local file system may be out of date.`),process.exit(1))}),e.createdAt.getTime()<Date.now()-7*24*60*60*1e3&&!i&&!await bt("The test patch you are applying is more than 7 days old. Are you sure you want to continue?",!0)&&process.exit(1);let s=n.lastModified.getTime();e.createdAt.getTime()+60*60*1e3<s&&!i&&!await bt("The test patch you are applying was created before the test was last updated. Are you sure you want to continue?",!0)&&process.exit(1);let l=eo(n.fullFilePath,o,t),c=l.steps;if(!Array.isArray(c))throw new Error(`Test ${n.fullFilePath} is missing steps array`);let d,p;if(e.schemaVersion!==Oe){let{steps:g,newVersion:f}=await da({metadata:{id:e.id,schemaVersion:e.schemaVersion},steps:e.steps,logger:b});d=f,p=Le.array().parse(g)}else p=Le.array().parse(e.steps);let{stepsToSave:u,moduleUpdates:m}=await gt({stepLists:{steps:p}});u.beforeSteps=l.beforeSteps??void 0,u.afterSteps=l.afterSteps??void 0;let h=kk(JSON.stringify(c,void 0,2),JSON.stringify(u,void 0,2),{n_surrounding:5});b.dimmed("=".repeat(30)),b.dimmed(h),b.dimmed("=".repeat(30)),b.dimmed(""),d&&b.warn(`If this patch is applied, your test will also be automatically upgraded to the latest schema version (${d}). Schema upgrades have no impact on functionality, although you may notice minor differences in the test YAML.`),!i&&!await bt("Do you want to apply this patch?")&&(b.dimmed("Cancelled."),process.exit(1)),Wn({relativeTestPath:n.relativePath,steps:u,schemaVersion:d??e.schemaVersion,project:t.project}),b.success("Patch applied successfully."),await r.patchTestFragment(e.id,{applied:!0,appliedAt:new Date})}import{randomUUID as uo}from"crypto";import{z as iT}from"zod";var Ut=" ".repeat(6);import oT from"chalk";import{Argument as Ci,InvalidArgumentError as Wa,Option as ke}from"@commander-js/extra-typings";import{validateHeaderValue as Dk}from"http";import{z as $v}from"zod";var jv=58888,rc=30*60*1e3;function Jn(n){let e=parseInt(n,10);if(isNaN(e))throw new Wa("Not a number.");return e}function oc(n){if(n===void 0)return;let e={};for(let t of n){let r=t.indexOf("=");if(r===-1)throw new Error(`Header value pair does not contain '=': ${t}`);let o=t.slice(0,r),i=t.slice(r+1);Dk(o,i),e[o]=i}return e}var Xn=new ke("--api-key <key>","Momentic API key").env("MOMENTIC_API_KEY").argParser(n=>{if(!n)throw new Wa("API key is required.");return n}).makeOptionMandatory(),Qn=new ke("--server <server>","Momentic server to use.").default("https://api.momentic.ai").argParser(n=>{try{return $v.string().url().parse(n),n}catch{throw new Wa("Not a valid URL.")}}),Cr=new ke("-y, --yes","Skip all confirmation prompts.").env("CI"),vu=new ke("-w, --wait","Wait for tests to finish running before exiting."),Tu=new ke("--wait-timeout <waitTimeout>",`The maximum number of seconds to wait for tests to complete. Defaults to ${rc/1e3} seconds.`).default(rc/1e3).implies({wait:!0}).argParser(Jn),ic=new ke("--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."),Gv=new ke("--reporter <reporter>","Output report files in a standardized format to a local directory.").choices(Object.values(Os)),Wv=new ke("--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.").default("reports"),Eu=new ke("--output-dir <outputDir>","Output directory to store run artifacts such as screenshots, results, and logs."),Vv=new ke("--upload-results","Upload test results to Momentic Cloud.").default(!1),xu=new ke("--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."),Cu=new ke("--exclude <excludePatterns...>","The inverted version of --include: a test that matches any of the provided exclusion patterns will be excluded from running."),Ru=new ke("--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.").argParser(Jn),qv=new ke("--port <port>",`Port to run the app on. Defaults to ${jv}.`).default(jv).argParser(Jn),Au=new ke("--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."),ac=new ke("--env <env>","Name of the environment to use when running tests."),sc=new ke("--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.").argParser(n=>{try{return $v.string().url().parse(n),n}catch{throw new Wa("Not a valid URL.")}}),Kv=new ke("--shard-index <shardIndex>","The index of the shard to run tests for. Defaults to 1.").default(1).argParser(n=>{let e=Jn(n);if(e<1)throw new Wa("Shard index must be greater than 0.");return e}),Yv=new ke("--shard-count <shardCount>","The number of shards that tests are being run on. Defaults to 1.").default(1).argParser(Jn),vn=new ke("-c, --config <configPath>","Absolute or relative path to a Momentic configuration file."),lc=new ke("-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."),Jv=new ke("--fix","Attempt to fix any issues found."),Iu=new ke("--save-cache","Always save updated step caches after successful test runs. By default, caches are not saved when running on protected branches.").env("CI"),Pu=new ke("--disable-cache","Disable caching of test results."),Xv=new Ci("<tests...>","One or more test paths to queue on Momentic Cloud."),Qv=new Ci("<tests...>","One or more test paths to import from Momentic Cloud.").argOptional(),Lu=new Ci("<tests...>","One or more test file path or folders that exist on the local machine.").argOptional(),Zv=new Ci("<suites...>","One or more suite paths that exist on Momentic Cloud."),eT=new Ci("<resultsPath>","Path to a directory that contains on or more test results archives.").argRequired(),tT=new Ci("<results>","Path to the results archive.").argRequired();async function Ou(n){let e=process.versions.node,t=parseInt(e.split(".")[0]);(isNaN(t)||t<18)&&(b.error(`Node.js version 18 or higher is required to run the CLI. Detected: ${process.versions.node}.`),process.exit(1)),b.debug(`Identified node version ${e}`);let r=await n.client.getAuthInfo();return b.debug("Got auth info from API"),r}import{Console as nT}from"console";import{format as Va}from"util";var Mu=class extends Error{constructor(e,t,r){let o=Error.stackTraceLimit;r&&(Error.stackTraceLimit=Math.max(r,o||10)),super(e),Error.captureStackTrace&&Error.captureStackTrace(this,t),Error.stackTraceLimit=o}},cc=class n extends nT{_buffer=[];_groupDepth=0;Console=nT;constructor(){super({write:e=>(n.write(this._buffer,"log",e),!0)})}static write(e,t,r,o=2){let i=new Mu(void 0,n.write).stack;if(!i)return e;let a=i.split(`
3920
+ l.`),1)}function Nv(){return Sk()==="darwin"&&fk("system_profiler SPDisplaysDataType").toString().includes("Retina")}function Su(n){Nv()&&n===1&&(b.warn("If you are using Momentic on a Retina screen, relaunch with the --pixel-ratio option to avoid incorrect viewport calculations."),b.warn("Confirm your device's pixel-ratio at https://www.mydevice.io."))}import yk from"@actions/exec";import bk from"@actions/io";import wk from"quote";import vk from"string-argv";async function kv(n,e=!0){let t=vk(n),r=await bk.which(t[0],!0),o=t.slice(1),i=yk.exec(wk(r),o,{delay:100});if(e)return i}import{existsSync as Tk,statSync as Ek}from"fs";var Ga=!!process.env.CI||!!process.env.GITHUB_ACTIONS||!!process.env.GITHUB_RUN_ID||!!process.env.GITLAB_CI||!!process.env.CI_COMMIT_SHA||!!process.env.JENKINS_URL||!!process.env.BUILD_NUMBER||!!process.env.JENKINS_HOME||!!process.env.CIRCLECI||!!process.env.CIRCLE_BUILD_NUM||!!process.env.TRAVIS||!!process.env.TRAVIS_BUILD_NUMBER||!!process.env.BITBUCKET_BUILD_NUMBER||!!process.env.BITBUCKET_COMMIT||!!process.env.CODEBUILD_BUILD_ID||!!process.env.TF_BUILD||!!process.env.BUILD_BUILDID||!!process.env.AGENT_ID||!!process.env.BUILDER_SA_EMAIL||!!process.env.HEROKU_TEST_RUN_ID||!!process.env.CI_NODE_INDEX||!!process.env.TEAMCITY_VERSION||!!process.env.BUILD_VCS_NUMBER||!!process.env.BUILDKITE||!!process.env.BUILDKITE_BUILD_NUMBER||!!process.env.APPVEYOR||!!process.env.APPVEYOR_BUILD_NUMBER||!!process.env.DRONE||!!process.env.DRONE_BUILD_NUMBER||!!process.env.SHIPPABLE||!!process.env.BUILD_URL||!!process.env.SEMAPHORE||!!process.env.SEMAPHORE_EXECUTABLE_UUID||!!process.env.WOODPECKER||!!process.env.CI_BUILD_NUMBER||!!process.env.WERCKER_MAIN_PIPELINE_STARTED||!!process.env.BUDDY_EXECUTION_ID;function _v(n){try{return Tk(n)&&Ek(n).isDirectory()}catch(e){return b.error({err:e},`Error reading path ${n} during directory existence check`),!1}}import xk from"csv-parser";import{createReadStream as Ck}from"fs";function yu(n){return new Promise((e,t)=>{let r=[];Ck(n).pipe(xk()).on("data",o=>r.push(o)).on("end",()=>e(r)).on("error",o=>t(o))})}import tc from"semver";import{z as nc}from"zod";var wn="2.7.1",Rk="https://registry.npmjs.org/momentic",Ak=nc.object({versions:nc.record(nc.string(),nc.unknown()).optional()});async function Dv(n){try{await Ik(n)}catch(e){b.warn({err:e},"Failed to check CLI version against NPM servers")}}async function Ik(n){if(!wn){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 B(fetch(Rk),{milliseconds:5e3});if(!o.ok)throw new Error(`Got error status code ${o.statusText}`);let i=await o.json();e=Ak.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))tc.valid(r)&&(!t||tc.gt(r,t))&&tc.gt(r,wn)&&tc.lt(r,"2.0.0")&&!r.includes("alpha")&&(t=r);t&&(b.warn(`Update available: v${wn} -> v${t}`),b.warn("This version may be missing critical fixes, features, and security updates."),b.warn(`Run "npx momentic@${t} -V" to update`))}import{existsSync as Lk,mkdirSync as Ok,statSync as Mk}from"fs";import{dirname as Nk}from"path";import Uv from"readline/promises";import{hostname as Pk}from"os";var ee=Yl({app:"cli",clientToken:"pub7eb923f18fb3f1d42ac5eba8c5ea13a5",hostname:Pk(),disableConsoleLogs:!0}).child({version:"2.7.1"});var bu=!1,Bv=(()=>{try{return Mk("/.dockerenv"),!0}catch{return!1}})();async function bt(n,e){if(Ga||bu||Bv)return!0;ee.flush(),await new Promise(a=>setTimeout(a,500));let t=Uv.createInterface({input:process.stdin,output:process.stdout}),r=n.split("."),o;if(r.length===1)o=n;else{let a=`${r.slice(0,r.length-1).join(".").trim()}.`;e?b.warn(a):b.log(a),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"?(bu=!0,setTimeout(()=>{bu=!1},3e3),!0):i.toLowerCase()==="y"}async function wu(n){let e=Nk(n);return _v(e)?Lk(n)?bt(`File '${Fv(n)}' already exists. Overwrite existing content?`,!0):!0:await bt(`Directory '${Fv(e)}' doesn't exist. Create it now?`,!0)?(Ok(e,{recursive:!0}),!0):!1}function Fv(n){return n.replace(/(\s+)/g,"\\$1")}async function zv(n,e){if(Ga||Bv)return e;let t=Uv.createInterface({input:process.stdin,output:process.stdout}),r=await t.question(`${n} `);return t.close(),r.trim()||e}async function Hv({test:n,fragment:e,entities:t,client:r,logger:o,yes:i}){_k(e.schemaVersion,Oe)&&(b.error(`This version of the CLI does not support the schema version of the fragment (${e.schemaVersion}). Please update to the latest version of the CLI and retry this command.`),process.exit(1)),hf(e.steps).forEach(g=>{t.modules[g]||(b.error(`The test patch contains a module with id ${g} that could not be found in the current project. This suggests that either this test patch or your local file system may be out of date.`),process.exit(1))}),e.createdAt.getTime()<Date.now()-7*24*60*60*1e3&&!i&&!await bt("The test patch you are applying is more than 7 days old. Are you sure you want to continue?",!0)&&process.exit(1);let s=n.lastModified.getTime();e.createdAt.getTime()+60*60*1e3<s&&!i&&!await bt("The test patch you are applying was created before the test was last updated. Are you sure you want to continue?",!0)&&process.exit(1);let l=eo(n.fullFilePath,o,t),c=l.steps;if(!Array.isArray(c))throw new Error(`Test ${n.fullFilePath} is missing steps array`);let d,p;if(e.schemaVersion!==Oe){let{steps:g,newVersion:f}=await da({metadata:{id:e.id,schemaVersion:e.schemaVersion},steps:e.steps,logger:b});d=f,p=Le.array().parse(g)}else p=Le.array().parse(e.steps);let{stepsToSave:u,moduleUpdates:m}=await gt({stepLists:{steps:p}});u.beforeSteps=l.beforeSteps??void 0,u.afterSteps=l.afterSteps??void 0;let h=kk(JSON.stringify(c,void 0,2),JSON.stringify(u,void 0,2),{n_surrounding:5});b.dimmed("=".repeat(30)),b.dimmed(h),b.dimmed("=".repeat(30)),b.dimmed(""),d&&b.warn(`If this patch is applied, your test will also be automatically upgraded to the latest schema version (${d}). Schema upgrades have no impact on functionality, although you may notice minor differences in the test YAML.`),!i&&!await bt("Do you want to apply this patch?")&&(b.dimmed("Cancelled."),process.exit(1)),Wn({relativeTestPath:n.relativePath,steps:u,schemaVersion:d??e.schemaVersion,project:t.project}),b.success("Patch applied successfully."),await r.patchTestFragment(e.id,{applied:!0,appliedAt:new Date})}import{randomUUID as uo}from"crypto";import{z as iT}from"zod";var Ut=" ".repeat(6);import oT from"chalk";import{Argument as Ci,InvalidArgumentError as Wa,Option as ke}from"@commander-js/extra-typings";import{validateHeaderValue as Dk}from"http";import{z as $v}from"zod";var jv=58888,rc=30*60*1e3;function Jn(n){let e=parseInt(n,10);if(isNaN(e))throw new Wa("Not a number.");return e}function oc(n){if(n===void 0)return;let e={};for(let t of n){let r=t.indexOf("=");if(r===-1)throw new Error(`Header value pair does not contain '=': ${t}`);let o=t.slice(0,r),i=t.slice(r+1);Dk(o,i),e[o]=i}return e}var Xn=new ke("--api-key <key>","Momentic API key").env("MOMENTIC_API_KEY").argParser(n=>{if(!n)throw new Wa("API key is required.");return n}).makeOptionMandatory(),Qn=new ke("--server <server>","Momentic server to use.").default("https://api.momentic.ai").argParser(n=>{try{return $v.string().url().parse(n),n}catch{throw new Wa("Not a valid URL.")}}),Cr=new ke("-y, --yes","Skip all confirmation prompts.").env("CI"),vu=new ke("-w, --wait","Wait for tests to finish running before exiting."),Tu=new ke("--wait-timeout <waitTimeout>",`The maximum number of seconds to wait for tests to complete. Defaults to ${rc/1e3} seconds.`).default(rc/1e3).implies({wait:!0}).argParser(Jn),ic=new ke("--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."),Gv=new ke("--reporter <reporter>","Output report files in a standardized format to a local directory.").choices(Object.values(Os)),Wv=new ke("--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.").default("reports"),Eu=new ke("--output-dir <outputDir>","Output directory to store run artifacts such as screenshots, results, and logs."),Vv=new ke("--upload-results","Upload test results to Momentic Cloud.").default(!1),xu=new ke("--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."),Cu=new ke("--exclude <excludePatterns...>","The inverted version of --include: a test that matches any of the provided exclusion patterns will be excluded from running."),Ru=new ke("--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.").argParser(Jn),qv=new ke("--port <port>",`Port to run the app on. Defaults to ${jv}.`).default(jv).argParser(Jn),Au=new ke("--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."),ac=new ke("--env <env>","Name of the environment to use when running tests."),sc=new ke("--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.").argParser(n=>{try{return $v.string().url().parse(n),n}catch{throw new Wa("Not a valid URL.")}}),Kv=new ke("--shard-index <shardIndex>","The index of the shard to run tests for. Defaults to 1.").default(1).argParser(n=>{let e=Jn(n);if(e<1)throw new Wa("Shard index must be greater than 0.");return e}),Yv=new ke("--shard-count <shardCount>","The number of shards that tests are being run on. Defaults to 1.").default(1).argParser(Jn),vn=new ke("-c, --config <configPath>","Absolute or relative path to a Momentic configuration file."),lc=new ke("-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."),Jv=new ke("--fix","Attempt to fix any issues found."),Iu=new ke("--save-cache","Always save updated step caches after successful test runs. By default, caches are not saved when running on protected branches.").env("CI"),Pu=new ke("--disable-cache","Disable caching of test results."),Xv=new Ci("<tests...>","One or more test paths to queue on Momentic Cloud."),Qv=new Ci("<tests...>","One or more test paths to import from Momentic Cloud.").argOptional(),Lu=new Ci("<tests...>","One or more test file path or folders that exist on the local machine.").argOptional(),Zv=new Ci("<suites...>","One or more suite paths that exist on Momentic Cloud."),eT=new Ci("<resultsPath>","Path to a directory that contains on or more test results archives.").argRequired(),tT=new Ci("<results>","Path to the results archive.").argRequired();async function Ou(n){let e=process.versions.node,t=parseInt(e.split(".")[0]);(isNaN(t)||t<18)&&(b.error(`Node.js version 18 or higher is required to run the CLI. Detected: ${process.versions.node}.`),process.exit(1)),b.debug(`Identified node version ${e}`);let r=await n.client.getAuthInfo();return b.debug("Got auth info from API"),r}import{Console as nT}from"console";import{format as Va}from"util";var Mu=class extends Error{constructor(e,t,r){let o=Error.stackTraceLimit;r&&(Error.stackTraceLimit=Math.max(r,o||10)),super(e),Error.captureStackTrace&&Error.captureStackTrace(this,t),Error.stackTraceLimit=o}},cc=class n extends nT{_buffer=[];_groupDepth=0;Console=nT;constructor(){super({write:e=>(n.write(this._buffer,"log",e),!0)})}static write(e,t,r,o=2){let i=new Mu(void 0,n.write).stack;if(!i)return e;let a=i.split(`
3921
3921
  `).slice(o).filter(Boolean).join(`
3922
3922
  `);return e.push({message:r,origin:a,type:t}),e}_log(e,t){n.write(this._buffer,e," ".repeat(this._groupDepth)+t,3)}debug(e,...t){this._log("debug",Va(e,...t))}error(e,...t){this._log("error",Va(e,...t))}info(e,...t){this._log("info",Va(e,...t))}log(e,...t){this._log("log",Va(e,...t))}warn(e,...t){this._log("warn",Va(e,...t))}getBuffer(){return this._buffer.length>0?this._buffer:void 0}};function rT(n){let e=globalThis.console,t=new cc;globalThis.console=t;try{n()}finally{let o=t.getBuffer()?.map(i=>i.message).join(`
3923
3923
  `);process.stderr.write(`${o}
@@ -3935,4 +3935,4 @@ ${n.map(u=>`${Ut}- ${u}`).join(`
3935
3935
  `),b.info("This wizard will help you bootstrap a new Momentic project. If you need to import existing assets from Momentic Cloud, you can call the 'import' command after initialization."),vc.existsSync(ni)&&(b.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 zv("Choose an identifier for your project, such as a service, product, or team name (default: 'app'):","app"),include:sp};ri(t,ni),b.success(`Initialized Momentic project file at ${wc.resolve(ni)}`)});Rt.command("app").addOption(Xn).addOption(Qn).addOption(Cr).addOption(Ru).addOption(qv).addOption(vn).addOption(Iu).addOption(Pu).action(async n=>{let{apiKey:e,port:t,yes:r,server:o,pixelRatio:i,disableCache:a,saveCache:s}=n,l=new ct({baseUrl:o,apiKey:e,logger:ee});await Ou({client:l,skipPrompts:r});let c=O_(import.meta.url),d=wc.dirname(c),p=wc.resolve(d,"..","static"),u=wc.resolve(d,"..","assets"),m=i??fu();Su(m),await Ov({momenticServerUrl:o,apiKey:e,serverPort:t,appPort:t,staticDir:p,assetsDir:u,devicePixelRatio:m,version:wn,noCache:a,alwaysSaveCache:s});let h=`http://localhost:${t}`;await L_(h)});var VT=Rt.command("queue").description("Queue tests or suites to run on Momentic Cloud");VT.command("suites").description("Run one or more suites on Momentic Cloud").addOption(Xn).addOption(Qn).addOption(vu).addOption(Tu).addOption(Cr).addArgument(Zv).addOption(sc).addOption(ac).addOption(ic).action(async(n,e)=>{let{apiKey:t,server:r,wait:o,waitTimeout:i,env:a,urlOverride:s}=e,l=oc(e.customHeaders),c=new ct({baseUrl:r,apiKey:t,logger:ee});(!n||!Array.isArray(n)||!n.length)&&(b.error("Must pass at least one suite to run."),process.exit(1));let{orgId:d}=await c.getAuthInfo();await ET({client:c,orgId:d,wait:o,suitePaths:n,waitTimeout:i,env:a,urlOverride:s,customHeaders:l})});VT.command("tests").description("Run one or more tests on Momentic Cloud").addOption(Xn).addOption(Qn).addOption(Cr).addOption(ic).addOption(Au).addOption(sc).addOption(ac).addOption(new Bt("--all","Run all tests.").default(!1)).addOption(vu).addOption(Tu).addArgument(Xv).action(async(n,e)=>{let{all:t,apiKey:r,env:o,server:i,inputCsv:a,urlOverride:s,wait:l,waitTimeout:c,yes:d}=e,p=oc(e.customHeaders);for(let g of n)(g.endsWith(".yaml")||vc.existsSync(g))&&b.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 u=new ct({baseUrl:i,apiKey:r,logger:ee}),{orgId:m}=await u.getAuthInfo(),h;a&&(h=await yu(a)),await xT({client:u,orgId:m,tests:n,all:t,customHeaders:p,env:o,urlOverride:s,wait:l,waitTimeout:c,testInputMatrix:h,yes:d}),process.exit(0)});var N_=Rt.command("list").description("List test paths");N_.addOption(vn).addOption(lc).addOption(xu).addOption(Cu).addOption(new Bt("--labels <labels...>","Only run tests with the specified label(s).")).addArgument(Lu).action(async(n,e)=>{let t=jt({configFilePath:e.config,nameFilter:e.filter}),r=Se(t,b),o=await gc({tests:n,momenticFiles:r,yes:!0,project:t,include:e.include,exclude:e.exclude,labels:e.labels,logger:gg});b.info(o.map(i=>i.relativeFilePath).join(`
3936
3936
  `)),process.exit(0)});var k_=Rt.command("run").alias("test").description("Run tests on the local machine");k_.addOption(Xn).addOption(Qn).addOption(vn).addOption(lc).addOption(Cr).addOption(ic).addOption(Au).addOption(Iu).addOption(Pu).addOption(ac).addOption(sc).addOption(Ru).addOption(new Bt("--start <start>","Arbitrary setup command that will run before Momentic steps begin.")).addOption(new Bt("--wait-on <waitOn>","URL to wait to become accessible before Momentic tests begin.")).addOption(new Bt("--wait-on-timeout <waitOnTimeout>","Max time in seconds to wait for the --wait-on URL to become accessible.").default(60).argParser(Jn)).addOption(new Bt("--retries <retries>","Number of retries to attempt when running tests locally. Defaults to each test's own retry configuration.").argParser(Jn)).addOption(new Bt("-p, --parallel <parallel>","When running with the --local flag, the number of tests to run in parallel. Defaults to 1.").argParser(Jn)).addOption(new Bt("--labels <labels...>","Only run tests with the specified label(s).")).addOption(new Bt("--update-golden-files","Update locally stored golden files for steps that this is enabled for.").default(!1)).addOption(Gv).addOption(Wv).addOption(Eu).addOption(Vv).addOption(Yv).addOption(Kv).addOption(xu).addOption(Cu).addArgument(Lu).action(async(n,e)=>{if(e.shardIndex>e.shardCount)throw new Error("Shard index cannot be greater than shard count");let t=oc(e.customHeaders),r=jt({configFilePath:e.config,nameFilter:e.filter}),o=r.config.parallel??e.parallel??1;GT().length<o*2&&b.warn(`You requested to run tests in parallel ${o} at a time on a machine with ${GT().length} cores. This may cause performance issues and test failures as Chrome requires at least 2 cores per browser instance.`),b.debug({projectName:r.config.name},"Identified project config");let{errors:i}=await Nu({project:r,fix:!1});i>0&&(b.error(`Found errors in ${i} steps`),b.warn("To fix these errors automatically, run the duplicate-ids check with the --fix flag and then commit the resulting changes"),process.exit(1));let a=new ct({baseUrl:e.server,apiKey:e.apiKey,logger:ee});b.debug("Checking API key and dependencies");let{orgId:s,userId:l}=await Ou({client:a,skipPrompts:e.yes});b.debug("API key check and browser installation complete");let c=new El(a),d=new xl(a),p=e.outputDir??r.config.outputDir,u=e.reporterDir??r.config.reporterDir,m=ee.child({orgId:s,userId:l,cliVersion:wn,trigger:"CLI"}),h=await si(ee,a,r);m.debug(h,"Got local git metadata");let g=new ai(r.config),f=$T.child({org_id:s,user_id:l,cli_version:wn,trigger:"CLI"}),S;e.inputCsv&&(S=await yu(e.inputCsv));let w=e.pixelRatio??fu();Su(w);try{(await UT({...e,parallel:o,retriesOverride:e.retries,devicePixelRatio:w,tests:n,project:r,client:a,debugDataStorage:d,billingReporter:c,analytics:f,flagStore:g,outputDir:p,uploadResults:e.uploadResults,reporterDir:u,customHeaders:t,envName:e.env,orgId:s,testInputMatrix:S,logger:m,regenerateGoldenFiles:e.updateGoldenFiles,gitMetadata:h,alwaysSaveCache:e.saveCache,noCache:e.disableCache})).failed>0?process.exit(1):process.exit(0)}catch(T){b.error("Failed to run tests locally. Please check the error message below or run with the --verbose flag."),b.error(T),process.exit(1)}});var __=Rt.command("apply").description("Apply an operation to local resources");__.command("patch").addOption(Xn).addOption(Qn).addOption(vn).addOption(lc).addOption(Cr).addOption(new Bt("--from <from>","Name or ID of the patch to apply").makeOptionMandatory()).addOption(new Bt("--to <to>","Name or ID of the test to apply the patch to").makeOptionMandatory()).action(async n=>{let{apiKey:e,server:t,config:r,yes:o}=n,i=jt({configFilePath:r}),a=ee,s=new ct({baseUrl:t,apiKey:e,logger:a}),l=Se(i,b),c=l.tests[n.to]??Object.values(l.tests).find(p=>Ie(p.name)===n.to.trim());c||(b.error(`No test matching '${n.to}' could be found in the current project.`),process.exit(1));let d=await s.fetchTestFragment(n.from);await Hv({client:s,test:c,fragment:d,yes:o,entities:l,logger:ee}),process.exit(0)});var qT=Rt.command("results").description("Merge and upload test results.");qT.command("merge").description("Merge test results files.").addOption(Eu).addArgument(eT).action(async(n,e)=>{let{outputDir:t}=e;t||(b.error("Output directory is required."),process.exit(1)),vc.existsSync(n)||(b.warn("Results path does not exist, skipping merge."),process.exit(0)),vc.existsSync(t)&&b.warn(`Output directory ${t} already exists, removing before merging...`),jT(ee,t,n)});qT.command("upload").description("Upload test results to Momentic cloud.").addOption(Xn).addOption(Qn).addArgument(tT).action(async(n,e)=>{let{apiKey:t,server:r}=e,o=ee,i=new ct({baseUrl:r,apiKey:t,logger:o});await bc({consoleLogger:b,resultsPath:n,client:i}),process.exit(0)});async function D_(){Ku("Main program started"),await Dv(ee),Ku("CLI version check complete");try{await Rt.parseAsync(process.argv)}catch(n){let e={};try{e.playwrightVersion=I_("npx playwright --version").toString()}catch(t){ee.error({err:t},"Error fetching debug information")}ee.error({err:n,debugInfo:e},"Uncaught error in CLI"),ee.flush(),Mi(n,e),b.error(n),process.exit(1)}}P_.setMaxListeners(50);process.on("warning",n=>{ee.warn({err:n},`Node warning received on CLI: ${n.message}`)});Ku("CLI parsing setup complete");D_();
3937
3937
  //# sourceMappingURL=cli.js.map
3938
- //# debugId=1e5befb8-ee07-5f92-8630-a43fb91645f1
3938
+ //# debugId=0ba158ab-7de7-5b11-865d-75f20a411592