momentic 2.21.2 → 2.21.3
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 +6 -6
- package/npm-shrinkwrap.json +5 -5
- package/package.json +1 -1
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]="
|
|
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]="e0dde94b-a515-52fa-8ab8-de6b1c9ef5ea")}catch(e){}}();
|
|
4
4
|
var yM=Object.defineProperty;var ot=(r,e)=>()=>(r&&(e=r(r=0)),e);var EM=(r,e)=>{for(var t in e)yM(r,t,{get:e[t],enumerable:!0})};var cA,uA=ot(()=>{"use strict";cA=typeof globalThis=="object"?globalThis:global});var dA=ot(()=>{"use strict";uA()});var pA=ot(()=>{"use strict";dA()});var zn,lg=ot(()=>{"use strict";zn="1.9.0"});function oB(r){var e=new Set([r]),t=new Set,n=r.match(mA);if(!n)return function(){return!1};var o={major:+n[1],minor:+n[2],patch:+n[3],prerelease:n[4]};if(o.prerelease!=null)return function(c){return c===r};function i(s){return t.add(s),!1}function a(s){return e.add(s),!0}return function(c){if(e.has(c))return!0;if(t.has(c))return!1;var l=c.match(mA);if(!l)return i(c);var u={major:+l[1],minor:+l[2],patch:+l[3],prerelease:l[4]};return u.prerelease!=null||o.major!==u.major?i(c):o.major===0?o.minor===u.minor&&o.patch<=u.patch?a(c):i(c):o.minor<=u.minor?a(c):i(c)}}var mA,hA,gA=ot(()=>{"use strict";lg();mA=/^(\d+)\.(\d+)\.(\d+)(-(.+))?$/;hA=oB(zn)});function wa(r,e,t,n){var o;n===void 0&&(n=!1);var i=pl[dl]=(o=pl[dl])!==null&&o!==void 0?o:{version:zn};if(!n&&i[r]){var a=new Error("@opentelemetry/api: Attempted duplicate registration of API: "+r);return t.error(a.stack||a.message),!1}if(i.version!==zn){var a=new Error("@opentelemetry/api: Registration of version v"+i.version+" for "+r+" does not match previously registered API v"+zn);return t.error(a.stack||a.message),!1}return i[r]=e,t.debug("@opentelemetry/api: Registered a global for "+r+" v"+zn+"."),!0}function Gn(r){var e,t,n=(e=pl[dl])===null||e===void 0?void 0:e.version;if(!(!n||!hA(n)))return(t=pl[dl])===null||t===void 0?void 0:t[r]}function Ca(r,e){e.debug("@opentelemetry/api: Unregistering a global for "+r+" v"+zn+".");var t=pl[dl];t&&delete t[r]}var iB,dl,pl,ml=ot(()=>{"use strict";pA();lg();gA();iB=zn.split(".")[0],dl=Symbol.for("opentelemetry.js.api."+iB),pl=cA});function hl(r,e,t){var n=Gn("diag");if(n)return t.unshift(e),n[r].apply(n,sB([],aB(t),!1))}var aB,sB,fA,SA=ot(()=>{"use strict";ml();aB=function(r,e){var t=typeof Symbol=="function"&&r[Symbol.iterator];if(!t)return r;var n=t.call(r),o,i=[],a;try{for(;(e===void 0||e-- >0)&&!(o=n.next()).done;)i.push(o.value)}catch(s){a={error:s}}finally{try{o&&!o.done&&(t=n.return)&&t.call(n)}finally{if(a)throw a.error}}return i},sB=function(r,e,t){if(t||arguments.length===2)for(var n=0,o=e.length,i;n<o;n++)(i||!(n in e))&&(i||(i=Array.prototype.slice.call(e,0,n)),i[n]=e[n]);return r.concat(i||Array.prototype.slice.call(e))},fA=function(){function r(e){this._namespace=e.namespace||"DiagComponentLogger"}return r.prototype.debug=function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];return hl("debug",this._namespace,e)},r.prototype.error=function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];return hl("error",this._namespace,e)},r.prototype.info=function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];return hl("info",this._namespace,e)},r.prototype.warn=function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];return hl("warn",this._namespace,e)},r.prototype.verbose=function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];return hl("verbose",this._namespace,e)},r}()});var Ye,Xu=ot(()=>{"use strict";(function(r){r[r.NONE=0]="NONE",r[r.ERROR=30]="ERROR",r[r.WARN=50]="WARN",r[r.INFO=60]="INFO",r[r.DEBUG=70]="DEBUG",r[r.VERBOSE=80]="VERBOSE",r[r.ALL=9999]="ALL"})(Ye||(Ye={}))});function yA(r,e){r<Ye.NONE?r=Ye.NONE:r>Ye.ALL&&(r=Ye.ALL),e=e||{};function t(n,o){var i=e[n];return typeof i=="function"&&r>=o?i.bind(e):function(){}}return{error:t("error",Ye.ERROR),warn:t("warn",Ye.WARN),info:t("info",Ye.INFO),debug:t("debug",Ye.DEBUG),verbose:t("verbose",Ye.VERBOSE)}}var EA=ot(()=>{"use strict";Xu()});var lB,cB,uB,bn,gl=ot(()=>{"use strict";SA();EA();Xu();ml();lB=function(r,e){var t=typeof Symbol=="function"&&r[Symbol.iterator];if(!t)return r;var n=t.call(r),o,i=[],a;try{for(;(e===void 0||e-- >0)&&!(o=n.next()).done;)i.push(o.value)}catch(s){a={error:s}}finally{try{o&&!o.done&&(t=n.return)&&t.call(n)}finally{if(a)throw a.error}}return i},cB=function(r,e,t){if(t||arguments.length===2)for(var n=0,o=e.length,i;n<o;n++)(i||!(n in e))&&(i||(i=Array.prototype.slice.call(e,0,n)),i[n]=e[n]);return r.concat(i||Array.prototype.slice.call(e))},uB="diag",bn=function(){function r(){function e(o){return function(){for(var i=[],a=0;a<arguments.length;a++)i[a]=arguments[a];var s=Gn("diag");if(s)return s[o].apply(s,cB([],lB(i),!1))}}var t=this,n=function(o,i){var a,s,c;if(i===void 0&&(i={logLevel:Ye.INFO}),o===t){var l=new Error("Cannot use diag as the logger for itself. Please use a DiagLogger implementation like ConsoleDiagLogger or a custom implementation");return t.error((a=l.stack)!==null&&a!==void 0?a:l.message),!1}typeof i=="number"&&(i={logLevel:i});var u=Gn("diag"),d=yA((s=i.logLevel)!==null&&s!==void 0?s:Ye.INFO,o);if(u&&!i.suppressOverrideMessage){var p=(c=new Error().stack)!==null&&c!==void 0?c:"<failed to generate stacktrace>";u.warn("Current logger will be overwritten from "+p),d.warn("Current logger will overwrite one already registered from "+p)}return wa("diag",d,t,!0)};t.setLogger=n,t.disable=function(){Ca(uB,t)},t.createComponentLogger=function(o){return new fA(o)},t.verbose=e("verbose"),t.debug=e("debug"),t.info=e("info"),t.warn=e("warn"),t.error=e("error")}return r.instance=function(){return this._instance||(this._instance=new r),this._instance},r}()});var TA,bA=ot(()=>{"use strict";TA=Symbol("BaggageEntryMetadata")});function cg(r){return typeof r!="string"&&(dB.error("Cannot create baggage metadata from unknown type: "+typeof r),r=""),{__TYPE__:TA,toString:function(){return r}}}var dB,vA=ot(()=>{"use strict";gl();bA();dB=bn.instance()});function ug(r){return Symbol.for(r)}var pB,dg,pg=ot(()=>{"use strict";pB=function(){function r(e){var t=this;t._currentContext=e?new Map(e):new Map,t.getValue=function(n){return t._currentContext.get(n)},t.setValue=function(n,o){var i=new r(t._currentContext);return i._currentContext.set(n,o),i},t.deleteValue=function(n){var o=new r(t._currentContext);return o._currentContext.delete(n),o}}return r}(),dg=new pB});function gg(){return hg}var bi,mB,Ju,hB,gB,fB,SB,mg,yB,EB,TB,hg,bB,vB,RB,AB,wB,CB,xB,fg=ot(()=>{"use strict";bi=function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(n,o){n.__proto__=o}||function(n,o){for(var i in o)Object.prototype.hasOwnProperty.call(o,i)&&(n[i]=o[i])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function n(){this.constructor=e}e.prototype=t===null?Object.create(t):(n.prototype=t.prototype,new n)}}(),mB=function(){function r(){}return r.prototype.createGauge=function(e,t){return vB},r.prototype.createHistogram=function(e,t){return RB},r.prototype.createCounter=function(e,t){return bB},r.prototype.createUpDownCounter=function(e,t){return AB},r.prototype.createObservableGauge=function(e,t){return CB},r.prototype.createObservableCounter=function(e,t){return wB},r.prototype.createObservableUpDownCounter=function(e,t){return xB},r.prototype.addBatchObservableCallback=function(e,t){},r.prototype.removeBatchObservableCallback=function(e){},r}(),Ju=function(){function r(){}return r}(),hB=function(r){bi(e,r);function e(){return r!==null&&r.apply(this,arguments)||this}return e.prototype.add=function(t,n){},e}(Ju),gB=function(r){bi(e,r);function e(){return r!==null&&r.apply(this,arguments)||this}return e.prototype.add=function(t,n){},e}(Ju),fB=function(r){bi(e,r);function e(){return r!==null&&r.apply(this,arguments)||this}return e.prototype.record=function(t,n){},e}(Ju),SB=function(r){bi(e,r);function e(){return r!==null&&r.apply(this,arguments)||this}return e.prototype.record=function(t,n){},e}(Ju),mg=function(){function r(){}return r.prototype.addCallback=function(e){},r.prototype.removeCallback=function(e){},r}(),yB=function(r){bi(e,r);function e(){return r!==null&&r.apply(this,arguments)||this}return e}(mg),EB=function(r){bi(e,r);function e(){return r!==null&&r.apply(this,arguments)||this}return e}(mg),TB=function(r){bi(e,r);function e(){return r!==null&&r.apply(this,arguments)||this}return e}(mg),hg=new mB,bB=new hB,vB=new fB,RB=new SB,AB=new gB,wB=new yB,CB=new EB,xB=new TB});var fr,RA=ot(()=>{"use strict";(function(r){r[r.INT=0]="INT",r[r.DOUBLE=1]="DOUBLE"})(fr||(fr={}))});var _B,IB,AA,wA=ot(()=>{"use strict";pg();_B=function(r,e){var t=typeof Symbol=="function"&&r[Symbol.iterator];if(!t)return r;var n=t.call(r),o,i=[],a;try{for(;(e===void 0||e-- >0)&&!(o=n.next()).done;)i.push(o.value)}catch(s){a={error:s}}finally{try{o&&!o.done&&(t=n.return)&&t.call(n)}finally{if(a)throw a.error}}return i},IB=function(r,e,t){if(t||arguments.length===2)for(var n=0,o=e.length,i;n<o;n++)(i||!(n in e))&&(i||(i=Array.prototype.slice.call(e,0,n)),i[n]=e[n]);return r.concat(i||Array.prototype.slice.call(e))},AA=function(){function r(){}return r.prototype.active=function(){return dg},r.prototype.with=function(e,t,n){for(var o=[],i=3;i<arguments.length;i++)o[i-3]=arguments[i];return t.call.apply(t,IB([n],_B(o),!1))},r.prototype.bind=function(e,t){return t},r.prototype.enable=function(){return this},r.prototype.disable=function(){return this},r}()});var PB,MB,Sg,OB,CA,xA=ot(()=>{"use strict";wA();ml();gl();PB=function(r,e){var t=typeof Symbol=="function"&&r[Symbol.iterator];if(!t)return r;var n=t.call(r),o,i=[],a;try{for(;(e===void 0||e-- >0)&&!(o=n.next()).done;)i.push(o.value)}catch(s){a={error:s}}finally{try{o&&!o.done&&(t=n.return)&&t.call(n)}finally{if(a)throw a.error}}return i},MB=function(r,e,t){if(t||arguments.length===2)for(var n=0,o=e.length,i;n<o;n++)(i||!(n in e))&&(i||(i=Array.prototype.slice.call(e,0,n)),i[n]=e[n]);return r.concat(i||Array.prototype.slice.call(e))},Sg="context",OB=new AA,CA=function(){function r(){}return r.getInstance=function(){return this._instance||(this._instance=new r),this._instance},r.prototype.setGlobalContextManager=function(e){return wa(Sg,e,bn.instance())},r.prototype.active=function(){return this._getContextManager().active()},r.prototype.with=function(e,t,n){for(var o,i=[],a=3;a<arguments.length;a++)i[a-3]=arguments[a];return(o=this._getContextManager()).with.apply(o,MB([e,t,n],PB(i),!1))},r.prototype.bind=function(e,t){return this._getContextManager().bind(e,t)},r.prototype._getContextManager=function(){return Gn(Sg)||OB},r.prototype.disable=function(){this._getContextManager().disable(),Ca(Sg,bn.instance())},r}()});var xa,_A=ot(()=>{"use strict";xA();xa=CA.getInstance()});var $,IA=ot(()=>{"use strict";gl();$=bn.instance()});var LB,PA,MA=ot(()=>{"use strict";fg();LB=function(){function r(){}return r.prototype.getMeter=function(e,t,n){return hg},r}(),PA=new LB});var yg,OA,LA=ot(()=>{"use strict";MA();ml();gl();yg="metrics",OA=function(){function r(){}return r.getInstance=function(){return this._instance||(this._instance=new r),this._instance},r.prototype.setGlobalMeterProvider=function(e){return wa(yg,e,bn.instance())},r.prototype.getMeterProvider=function(){return Gn(yg)||PA},r.prototype.getMeter=function(e,t,n){return this.getMeterProvider().getMeter(e,t,n)},r.prototype.disable=function(){Ca(yg,bn.instance())},r}()});var Qu,NA=ot(()=>{"use strict";LA();Qu=OA.getInstance()});var He=ot(()=>{"use strict";vA();pg();Xu();fg();RA();_A();IA();NA()});var os=(r,e)=>{},zp=!1;try{let r=await import("@sentry/node");os=r.captureException,r.init({dsn:"https://89e980855f7b9c6e56fc6c7e7143888b@o4506426201800704.ingest.us.sentry.io/4508343221354497",environment:"production",release:process.env.SENTRY_RELEASE_NAME,tracesSampleRate:0}),zp=!0}catch{}import{Command as KW,Option as nr}from"@commander-js/extra-typings";import{execSync as YW}from"child_process";import{existsSync as Fk,statSync as Bk}from"fs";import{z as GS}from"zod";var sq=GS.object({input:GS.string()});import{z as Rt}from"zod";var uq=Rt.object({srcs:Rt.array(Rt.string()),urls:Rt.array(Rt.string()),desiredSrc:Rt.string().optional(),desiredUrl:Rt.string().optional()}),jS=Rt.object({srcRegex:Rt.string().optional(),urlRegex:Rt.string().optional()}),VS=Rt.object({x:Rt.number(),y:Rt.number(),correlation:Rt.number()}),dq=Rt.object({searchImageBase64String:Rt.string(),pageImageBase64String:Rt.string(),id:Rt.string().uuid(),timeoutMs:Rt.number().max(1e4).min(0).optional()});import{z as L}from"zod";import*as N from"zod";import{extendZodWithOpenApi as TM}from"zod-openapi";TM(N);var Jn=(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))(Jn||{}),bM=N.object({mPathSelectorTokens:N.string().array(),frameSrcRegex:N.string().optional(),frameUrlRegex:N.string().optional(),indices:N.number().array()}),Gp=N.object({result:N.number(),traceId:N.string()}).array(),ec=N.object({type:N.literal("GCS_TRACES"),traces:Gp}),Xn=(o=>(o.Precise="precise",o.Narrow="narrow",o.Unspecific="broad",o.Irrelevant="irrelevant",o))(Xn||{}),$S=N.object({attributes:N.record(N.string(),N.string()).optional(),text:N.string().optional(),position:N.object({x1:N.number(),y1:N.number(),x2:N.number(),y2:N.number(),tolerance:N.nativeEnum(Xn)}).optional(),shape:N.object({width:N.number(),height:N.number(),tolerance:N.nativeEnum(Xn)}).optional(),boundingBox:N.object({x:N.number(),y:N.number(),width:N.number(),height:N.number()}).optional()}),vM=N.object({selectors:N.string().array(),requirements:$S.optional()}),Qn=N.object({id:N.number().int(),dataMomenticId:N.number().int().optional(),selector:N.string().optional(),hybridSelector:N.object({textContent:N.string().nullish(),attributes:N.record(N.string(),N.string().optional()),tagName:N.string(),expandShadowRoot:N.boolean().optional(),classNames:N.string().array(),nthChild:N.number()}).array().optional(),generatedSelectors:N.string().array().optional(),requirements:$S.optional(),additionalElements:vM.array().optional(),role:N.string().optional(),name:N.string().optional(),numChildren:N.number().optional(),content:N.string().optional(),pathFromRoot:N.string().optional(),serializedHtml:N.string().optional().describe("pruned html including 1 neighbor and 1 layer of children. value for text inputs pruned."),nodeOnlySerializedHtml:N.string().optional().describe("outerHtml of the element without any children. value for text inputs pruned."),screenshotUrl:N.string().url().optional(),boundingBox:N.object({x:N.number().optional(),y:N.number().optional(),width:N.number(),height:N.number()}).describe("css pixel bounding box").optional(),frameCache:bM.optional(),inputDescription:N.string().optional().describe("the description that generated this cache"),targetSource:N.nativeEnum(Jn).optional(),targetUpdateTime:N.string().optional(),targetUpdateLoggerTags:N.record(N.string(),N.string()).optional(),cacheResolutionUpdateSource:N.string().optional(),cacheResolutionUpdateTime:N.string().optional(),cacheResolutionUpdateLoggerTags:N.record(N.string(),N.string()).optional(),memory:ec.optional()}).openapi({ref:"ElementTargetCache"});function tc(r){return!!(r.serializedHtml||r.screenshotUrl||r.generatedSelectors||r.hybridSelector)}var RM=N.object({type:N.literal("description"),elementDescriptor:N.string().describe("Description of the element.")}).openapi({ref:"DescriptionTarget"}),AM=N.object({x:N.number(),y:N.number()}),wM=N.object({type:N.literal("coordinates"),pixels:AM}).openapi({ref:"CoordinatesTarget"});function Zn(r){return r.type==="description"}function on(r){return r.type==="coordinates"}var Ft=N.discriminatedUnion("type",[RM,wM]).openapi({ref:"ElementTarget"});function jp(r){if(!r)return!1;switch(r.type){case"description":return!!r.elementDescriptor}return!0}function Bt(r){if(!r)return"";switch(r.type){case"description":return r.elementDescriptor;case"coordinates":return`x: ${r.pixels.x}, y: ${r.pixels.y}`}}function rc(r){return ec.safeParse(r).success}import{v4 as xe}from"uuid";import*as R from"zod";import{extendZodWithOpenApi as LM}from"zod-openapi";import{z as se}from"zod";import{extendZodWithOpenApi as CM}from"zod-openapi";import{z as as}from"zod";import WS from"zod";var is=WS.object({updatedAt:WS.coerce.date().optional()});var Vp=as.object({result:as.boolean(),traceId:as.string()}).array(),$p=as.object({type:as.literal("GCS_TRACES"),traces:Vp}),Wp=is.extend({memory:$p.optional()});CM(se);var qS=se.object({plan:se.string().optional(),evidence:se.string().optional(),thoughts:se.string(),result:se.boolean(),relevantElements:se.array(se.number()).optional(),updatedMemory:Vp.optional()}),Ln=(o=>(o.CONTAINS="CONTAINS",o.STARTS_WITH="STARTS_WITH",o.EQUALS="EQUALS",o.EXISTS="EXISTS",o))(Ln||{});var xM=se.object({type:se.literal("ELEMENT_NAME"),negated:se.boolean().optional(),operation:se.nativeEnum(Ln),value:se.string()}).openapi({ref:"ElementNameAssertion"}),_M=se.object({type:se.literal("ELEMENT_STYLE"),negated:se.boolean().optional(),operation:se.nativeEnum(Ln),property:se.string(),value:se.string()}).openapi({ref:"ElementStyleAssertion"}),IM=se.object({type:se.literal("ELEMENT_CONTENT"),negated:se.boolean().optional(),operation:se.nativeEnum(Ln),value:se.string()}).openapi({ref:"ElementContentAssertion"}),PM=se.object({type:se.literal("ELEMENT_ATTRIBUTE"),negated:se.boolean().optional(),operation:se.nativeEnum(Ln),attr:se.string(),value:se.string()}).openapi({ref:"ElementAttributeValueAssertion"}),Vo=(i=>(i.EXISTS="EXISTS",i.VISIBLE="VISIBLE",i.ENABLED="ENABLED",i.EDITABLE="EDITABLE",i.FOCUSED="FOCUSED",i))(Vo||{}),MM=se.object({type:se.literal("ELEMENT_EXISTENCE"),negated:se.boolean().optional(),condition:se.nativeEnum(Vo).describe("Treated as the element exists AND is also ...")}).openapi({ref:"ElementExistenceAssertion"}),KS=se.discriminatedUnion("type",[IM,PM,MM,xM,_M]).openapi({ref:"ManualElementAssertion"});var OM=se.object({type:se.literal("CONTENT"),negated:se.boolean().optional(),value:se.string()}).openapi({ref:"PageContentAssertion"}),YS=se.discriminatedUnion("type",[OM]).openapi({ref:"ManualPageAssertion"});import Kt from"zod";var qp=Kt.discriminatedUnion("type",[Kt.object({type:Kt.literal("SUBSTRING"),url:Kt.string()}),Kt.object({type:Kt.literal("GLOB"),glob:Kt.string()}),Kt.object({type:Kt.literal("REGEX"),regex:Kt.string()}),Kt.object({type:Kt.literal("DOMAIN"),domain:Kt.string()})]),ss=Kt.object({urlMatcher:qp,method:Kt.string().optional()});import{z as Ce}from"zod";var Fi=Ce.object({url:Ce.string(),method:Ce.union([Ce.literal("GET"),Ce.literal("POST"),Ce.literal("PUT"),Ce.literal("DELETE"),Ce.literal("PATCH")]),headers:Ce.record(Ce.string(),Ce.string()).optional(),params:Ce.record(Ce.string(),Ce.string()).optional(),body:Ce.string().optional(),timeout:Ce.number().int().optional().describe("Max seconds to wait for the request to complete")}),XS=Ce.object({url:Ce.string(),headers:Ce.record(Ce.string(),Ce.string()).optional(),query:Ce.string(),variables:Ce.string().optional(),timeout:Ce.number().int().optional().describe("Max seconds to wait for the request to complete")}),nc=Ce.object({code:Ce.string(),fragment:Ce.boolean().optional().describe("Agents should not touch this unless explicitly told to"),environment:Ce.union([Ce.literal("NODE"),Ce.literal("BROWSER")]).optional().describe("default NODE, Agents default to using node unless it is necessary to use browser"),timeout:Ce.number().int().max(60).optional().describe("Max seconds for the code to complete")});var Ge=(K=>(K.AI_EXTRACT="AI_EXTRACT",K.AI_ASSERTION="AI_ASSERTION",K.AUTH_LOAD="AUTH_LOAD",K.AUTH_SAVE="AUTH_SAVE",K.BLUR="BLUR",K.CAPTCHA="CAPTCHA",K.CLICK="CLICK",K.COOKIE="COOKIE",K.COPY="COPY",K.DIALOG="DIALOG",K.DRAG="DRAG",K.ELEMENT_CHECK="ELEMENT_CHECK",K.FILE_UPLOAD="FILE_UPLOAD",K.FOCUS="FOCUS",K.GO_BACK="GO_BACK",K.GO_FORWARD="GO_FORWARD",K.HOVER="HOVER",K.JAVASCRIPT="JAVASCRIPT",K.LOCAL_STORAGE="LOCAL_STORAGE",K.MOUSE_DRAG="MOUSE_DRAG",K.NAVIGATE="NAVIGATE",K.NEW_TAB="NEW_TAB",K.PAGE_CHECK="PAGE_CHECK",K.PASTE="PASTE",K.PRESS="PRESS",K.KEY_DOWN="KEY_DOWN",K.KEY_UP="KEY_UP",K.REFRESH="REFRESH",K.REQUEST="REQUEST",K.GRAPHQL_REQUEST="GRAPHQL_REQUEST",K.SCROLL_DOWN="SCROLL_DOWN",K.SCROLL_UP="SCROLL_UP",K.SCROLL_LEFT="SCROLL_LEFT",K.SCROLL_RIGHT="SCROLL_RIGHT",K.SELECT_OPTION="SELECT_OPTION",K.SWITCH_TAB="TAB",K.TYPE="TYPE",K.VISUAL_DIFF="VISUAL_DIFF",K.WAIT="WAIT",K.WAIT_FOR_URL="WAIT_FOR_URL",K.REGISTER_REQUEST_LISTENER="REGISTER_REQUEST_LISTENER",K.AWAIT_LISTENER="AWAIT_LISTENER",K.RECORD_REQUESTS="RECORD_REQUESTS",K.GET_RECORDED_REQUESTS="GET_RECORDED_REQUESTS",K.SET_HEADER="SET_HEADER",K.MOCK_ROUTE="MOCK_ROUTE",K.REMOVE_ROUTE_MOCK="REMOVE_ROUTE_MOCK",K.OFFLINE_MODE="OFFLINE_MODE",K.SUCCESS="SUCCESS",K))(Ge||{});LM(R);var Z=R.object({thoughts:R.string().optional(),id:R.string().uuid().describe("unique identifier to this step, used for step cache")}),Tr=R.object({useSelector:R.boolean().optional(),force:R.boolean().optional(),disableCache:R.boolean().optional().describe("disable element caching for this step"),iframeUrl:R.string().optional().describe("url or url regex for the iframe")}).openapi({ref:"CommonTargetingOptions"}),dr=is.extend({target:Qn}).optional().openapi({ref:"SingleTargetCache"});function JS(r){return dr.safeParse(r).success}var ic=R.object({loadTimeout:R.number().int().max(60).optional().describe("Max seconds for the page to load")}),NM=Z.merge(ic).merge(R.object({type:R.literal("NAVIGATE"),url:R.string()})).openapi({ref:"NavigateCommand"}),ac=Tr.merge(R.object({cache:dr})),Bi=Z.merge(ac.merge(R.object({target:Ft.optional(),type:R.literal("SCROLL_UP"),deltaY:R.number().optional()}))).openapi({ref:"ScrollUpCommand"}),Hi=Z.merge(ac.merge(R.object({target:Ft.optional(),type:R.literal("SCROLL_DOWN"),deltaY:R.number().optional()}))).openapi({ref:"ScrollDownCommand"}),zi=Z.merge(ac.merge(R.object({target:Ft.optional(),type:R.literal("SCROLL_LEFT"),deltaX:R.number().optional()}))).openapi({ref:"ScrollLeftCommand"}),Gi=Z.merge(ac.merge(R.object({target:Ft.optional(),type:R.literal("SCROLL_RIGHT"),deltaX:R.number().optional()}))).openapi({ref:"ScrollRightCommand"}),zq=R.discriminatedUnion("type",[Bi,Hi,zi,Gi]).openapi({ref:"AllScrollCommands"}),DM=Z.merge(R.object({type:R.literal("DIALOG"),action:R.union([R.literal("ACCEPT"),R.literal("DISMISS")])})).openapi({ref:"DialogCommand"}),kM=Z.merge(R.object({type:R.literal("WAIT"),delay:R.number()})).openapi({ref:"WaitCommand"}),UM=R.object({caseInsensitive:R.boolean().optional().describe("Whether to ignore case when matching the URL"),negated:R.boolean().optional().describe("Wait for the URL to NOT match the provided matcher instead."),timeout:R.number().int().optional().describe("Max seconds to wait for the URL to match")}),QS=Z.extend({type:R.literal("WAIT_FOR_URL"),matcher:qp}).merge(UM).openapi({ref:"WaitUrlCommand"}),ZS=Z.merge(ic).merge(R.object({type:R.literal("REFRESH")})).openapi({ref:"RefreshCommand"}),FM=Z.merge(R.object({type:R.literal("GO_BACK")})).openapi({ref:"GoBackCommand"}),ey=Z.merge(R.object({type:R.literal("GO_FORWARD")})).openapi({ref:"GoForwardCommand"}),BM=Z.extend({type:R.literal("AUTH_SAVE")}).openapi({ref:"AuthSaveCommand"}),HM=Z.extend({type:R.literal("AUTH_LOAD"),storageState:R.string().describe("JSON string auth state. Leave blank or set to the empty string to clear all existing authentication.")}).openapi({ref:"AuthLoadCommand"}),Kp=Z.merge(Tr).extend({type:R.literal("CAPTCHA")}).openapi({ref:"CaptchaCommand"}),ty=Z.extend({type:R.literal("COPY"),value:R.string()}).openapi({ref:"CopyCommand"}),ry=Z.extend({type:R.literal("PASTE")}).openapi({ref:"PasteCommand"}),ny=Z.merge(nc).extend({type:R.literal("JAVASCRIPT")}).openapi({ref:"JavaScriptCommand"}),cs=Z.merge(Tr).extend({type:R.literal("CLICK"),target:Ft,doubleClick:R.boolean().optional(),rightClick:R.boolean().optional(),waitForDownload:R.boolean().optional().describe("Wait for the click to trigger a file download and for the file download to complete."),delayMs:R.number().optional(),downloadTimeoutMs:R.number().optional(),cache:dr,relativePosition:R.object({x:R.number(),y:R.number()}).optional()}).openapi({ref:"ClickCommand"}),Yp=is.extend({fromTarget:Qn.optional(),toTarget:Qn.optional()}),ji=Z.merge(Tr).merge(R.object({type:R.literal("DRAG"),fromTarget:Ft,toTarget:Ft,steps:R.number().optional(),hoverSeconds:R.number().optional().describe("Seconds to hover the object before dropping"),cache:Yp.optional()})).openapi({ref:"DragCommand"}),Vi=Z.merge(Tr).merge(R.object({type:R.literal("MOUSE_DRAG"),target:Ft.optional(),deltaX:R.string().describe("pixels to move horizontally, can be template"),deltaY:R.string().describe("pixels to move vertically, can be template"),steps:R.number().optional(),cache:dr})).openapi({ref:"MouseDragCommand"}),us=Z.merge(Tr).merge(R.object({type:R.literal("HOVER"),target:Ft,cache:dr})).openapi({ref:"HoverCommand"}),ds=Z.merge(Tr).merge(R.object({type:R.literal("FOCUS"),target:Ft,cache:dr})).openapi({ref:"FocusCommand"}),ps=Z.merge(Tr).extend({type:R.literal("BLUR"),target:Ft.optional(),cache:dr}).openapi({ref:"BlurCommand"}),zM=R.object({type:R.literal("URL"),url:R.string()}).describe("Accessible link to the file, either public http or local file://").openapi({ref:"UrlSource"}),GM=R.object({type:R.literal("USER_FILE"),name:R.string()}).describe("Accessible link to the file, references the google cloud file").openapi({ref:"UploadedFileSource"}),jM=Z.extend({type:R.literal("FILE_UPLOAD"),fileSource:R.discriminatedUnion("type",[zM,GM]),filename:R.string().optional()}).openapi({ref:"FileUploadCommand"}),Xp=R.discriminatedUnion("type",[R.object({type:R.literal("VALUE"),value:R.string()}),R.object({type:R.literal("LABEL"),label:R.string()}),R.object({type:R.literal("INDEX"),index:R.coerce.string()})]),ms=Z.merge(Tr).extend({type:R.literal("SELECT_OPTION"),target:Ft,cache:dr,choice:Xp.describe("new field for selecting options, optional for backcompat")}).openapi({ref:"SelectOptionCommand"}),Jp=R.union([R.literal("MULTIMODAL"),R.literal("VISION_ONLY")]),sc=Z.merge(R.object({type:R.literal("AI_ASSERTION"),assertion:R.string(),disableCache:R.boolean().optional(),iframeUrl:R.string().optional(),contextChoice:Jp.optional(),timeout:R.number().int().optional().describe("Max seconds to wait for assertion to be true"),cache:Wp.optional()})).openapi({ref:"AIAssertionCommand"}),an=5,Qp=600,$i=Z.merge(Tr).extend({type:R.literal("ELEMENT_CHECK"),target:Ft,assertion:KS,cache:dr.or(Wp).optional(),timeout:R.number().int().min(0).max(Qp).optional().describe("max seconds to wait for the assertion to be true")}).openapi({ref:"ElementAssertionCommand"}),oy=Z.extend({type:R.literal("PAGE_CHECK"),assertion:YS,iframeUrl:R.string().optional().describe("url or url regex for the iframe"),timeout:R.number().int().min(0).max(Qp).optional().describe("max seconds to wait for the assertion to be true")}).openapi({ref:"PageAssertionCommand"}),iy=Z.merge(R.object({type:R.literal("AI_EXTRACT"),goal:R.string(),schema:R.string().optional(),envKey:R.string().optional(),disableCache:R.boolean().optional(),iframeUrl:R.string().optional()})).openapi({ref:"AIExtractCommand"}),VM=R.object({clearContent:R.boolean().optional(),forceClearContent:R.boolean().optional(),delay:R.number().min(0).max(1e3).optional().describe("Delay between each press in milliseconds."),force:R.boolean().optional(),pressEnter:R.boolean().optional(),relativePosition:R.object({x:R.number(),y:R.number()}).optional()}),ay=25,hs=Z.merge(Tr).merge(VM).extend({type:R.literal("TYPE"),target:Ft.optional(),value:R.string(),cache:dr}).openapi({ref:"TypeCommand"}),$M=Z.merge(R.object({type:R.literal("PRESS"),value:R.string(),repeat:R.number().optional(),convertMeta:R.boolean().optional(),delayMs:R.number().optional()})).openapi({ref:"PressCommand"}),WM=Z.merge(R.object({type:R.literal("KEY_DOWN"),value:R.string(),convertMeta:R.boolean().optional()})).openapi({ref:"KeyDownCommand"}),qM=Z.merge(R.object({type:R.literal("KEY_UP"),value:R.string(),convertMeta:R.boolean().optional()})).openapi({ref:"KeyUpCommand"}),KM=R.object({type:R.literal("SUBSTRING"),substring:R.string()}),YM=R.object({type:R.literal("REGEX"),pattern:R.string()}),XM=R.object({type:R.literal("INDEX"),index:R.coerce.string()}),JM=R.discriminatedUnion("type",[KM,YM,XM]),QM=Z.merge(ic).merge(R.object({type:R.literal("TAB"),action:JM})).openapi({ref:"TabCommand"}),sy=Z.merge(ic).merge(R.object({type:R.literal("NEW_TAB"),url:R.string()})).openapi({ref:"NewTabCommand"}),ZM=Z.merge(R.object({type:R.literal("COOKIE"),value:R.string()})).openapi({ref:"CookieCommand"}),ly=Z.merge(R.object({type:R.literal("LOCAL_STORAGE"),key:R.string(),value:R.string()})).openapi({ref:"LocalStorageCommand"}),cy=Z.extend({type:R.literal("REQUEST")}).merge(Fi).openapi({ref:"RequestCommand"}),eO=Z.extend({type:R.literal("GRAPHQL_REQUEST")}).merge(XS).openapi({ref:"GraphQLRequestCommand"}),tO=Z.merge(R.object({type:R.literal("SUCCESS"),condition:sc.optional()})).openapi({ref:"SuccessCommand"}),uy=Z.merge(R.object({type:R.literal("FAILURE")})).openapi({ref:"FailureCommand"}),rO=R.object({data:R.string().describe("location at which to find a jpg"),width:R.number(),height:R.number()}),gs=Z.merge(Tr).merge(R.object({type:R.literal("VISUAL_DIFF"),threshold:R.number().optional().describe("default 0.1"),target:Ft.optional(),screenshot:rO.optional(),cache:dr})).openapi({ref:"VisualDiffCommand"}),nO=Z.merge(R.object({type:R.literal("REGISTER_REQUEST_LISTENER"),requestMatcher:ss,key:R.string()})).openapi({ref:"RegisterRequestListenerCommand"}),oO=Z.merge(R.object({type:R.literal("AWAIT_LISTENER"),key:R.string(),timeout:R.number().optional().describe("timeout")})).openapi({ref:"WaitForListenerCommand"}),iO=Z.merge(R.object({type:R.literal("RECORD_REQUESTS"),requestMatcher:ss,key:R.string()})).openapi({ref:"RecordRequestsCommand"}),aO=Z.merge(R.object({type:R.literal("GET_RECORDED_REQUESTS"),key:R.string()})).openapi({ref:"GetRecordedRequestsCommand"}),sO=Z.merge(R.object({type:R.literal("SET_HEADER"),name:R.string(),value:R.string(),requestMatcher:ss.optional()})).openapi({ref:"SetHeaderCommand"}),lO=Z.merge(R.object({type:R.literal("MOCK_ROUTE"),requestMatcher:ss,responseGenerator:R.string().describe("JavaScript code to generate a response"),fetchOriginalResponse:R.boolean().optional().describe("Whether to fetch the real response and pass it to the response generator. If enabled, the original response will be available as `response` in the code."),key:R.string().optional().describe("Key to reference this mock. This only needs to be set if you plan to remove the mock later in the test.")}).openapi({ref:"MockRouteCommandOptions"})),cO=Z.merge(R.object({type:R.literal("REMOVE_ROUTE_MOCK"),key:R.string().optional().describe("Key of the mock to remove. If not set, all route mocks will be removed.")}).openapi({ref:"RemoveRouteMockCommandOptions"})),uO=Z.merge(R.object({type:R.literal("OFFLINE_MODE"),enable:R.boolean()})).openapi({ref:"OfflineModeCommand"}),dO=R.discriminatedUnion("type",[cs,hs,$M,WM,qM,ms,NM,Hi,Bi,sc,FM,us,kM]),Zp=R.discriminatedUnion("type",[...dO.options,tO]),em=R.discriminatedUnion("type",[...Zp.options,ji,ny,$i,oy,sy,QS,iy,ty,ey,ly,Vi,ry,ZS,cy]),pO=R.discriminatedUnion("type",[iy,HM,BM,Kp,ZM,ty,DM,ji,$i,jM,ey,ny,ly,Vi,sy,oy,ry,ZS,cy,eO,zi,Gi,QM,gs,ds,ps,QS,nO,oO,iO,aO,sO,lO,cO,uO]),Wi=R.discriminatedUnion("type",[...Zp.options,...pO.options]).openapi({ref:"Command"}),lc=R.discriminatedUnion("type",[...Zp.options,uy]),Gq=R.discriminatedUnion("type",[...em.options,uy]);function Nn(r){let e;switch(r){case"PASTE":case"AUTH_SAVE":case"VISUAL_DIFF":case"SUCCESS":case"SCROLL_DOWN":case"SCROLL_UP":case"SCROLL_LEFT":case"SCROLL_RIGHT":case"CAPTCHA":case"GO_BACK":case"GO_FORWARD":case"REFRESH":e={id:xe(),type:r};break;case"AUTH_LOAD":{e={id:xe(),type:r,storageState:""};break}case"AI_EXTRACT":e={id:xe(),type:r,goal:""};break;case"DIALOG":e={id:xe(),type:r,action:"DISMISS"};break;case"DRAG":e={id:xe(),type:r,fromTarget:{type:"description",elementDescriptor:""},toTarget:{type:"description",elementDescriptor:""}};break;case"MOUSE_DRAG":e={id:xe(),type:r,deltaX:"0",deltaY:"0",steps:1};break;case"WAIT_FOR_URL":e={id:xe(),type:r,matcher:{type:"SUBSTRING",url:""}};break;case"WAIT":e={id:xe(),type:r,delay:1};break;case"BLUR":e={id:xe(),type:r};break;case"HOVER":case"FOCUS":case"CLICK":e={id:xe(),type:r,target:{type:"description",elementDescriptor:""}};break;case"COOKIE":case"PRESS":case"COPY":case"TYPE":e={id:xe(),type:r,value:"",clearContent:!0};break;case"KEY_DOWN":case"KEY_UP":e={id:xe(),type:r,value:""};break;case"SELECT_OPTION":e={id:xe(),type:r,target:{type:"description",elementDescriptor:""},choice:{type:"VALUE",value:""}};break;case"NAVIGATE":case"NEW_TAB":return{id:xe(),type:r,url:""};case"TAB":e={id:xe(),type:r,action:{type:"SUBSTRING",substring:""}};break;case"REQUEST":e={id:xe(),type:r,url:"",method:"GET"};break;case"GRAPHQL_REQUEST":e={id:xe(),type:r,url:"",query:""};break;case"LOCAL_STORAGE":e={id:xe(),type:r,key:"",value:""};break;case"JAVASCRIPT":e={id:xe(),type:r,code:""};break;case"AI_ASSERTION":e={id:xe(),type:r,assertion:""};break;case"FILE_UPLOAD":{e={id:xe(),type:r,fileSource:{type:"URL",url:""}};break}case"ELEMENT_CHECK":{e={id:xe(),type:r,target:{type:"description",elementDescriptor:""},assertion:{type:"ELEMENT_EXISTENCE",condition:"EXISTS"}};break}case"PAGE_CHECK":{e={id:xe(),type:r,assertion:{type:"CONTENT",value:""}};break}case"REGISTER_REQUEST_LISTENER":{e={id:xe(),type:r,requestMatcher:{urlMatcher:{type:"REGEX",regex:""}},key:""};break}case"AWAIT_LISTENER":{e={id:xe(),type:r,key:""};break}case"RECORD_REQUESTS":{e={id:xe(),type:r,requestMatcher:{urlMatcher:{type:"REGEX",regex:""}},key:""};break}case"GET_RECORDED_REQUESTS":{e={id:xe(),type:r,key:""};break}case"SET_HEADER":{e={id:xe(),type:r,name:"",value:""};break}case"MOCK_ROUTE":{e={id:xe(),type:r,requestMatcher:{urlMatcher:{type:"REGEX",regex:""}},responseGenerator:""};break}case"REMOVE_ROUTE_MOCK":{e={id:xe(),type:r};break}case"OFFLINE_MODE":{e={id:xe(),type:r,enable:!0};break}default:return(n=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(r)}return e}function dy(r){switch(r.type){case"BLUR":case"CLICK":case"DRAG":case"FOCUS":case"HOVER":case"MOUSE_DRAG":case"PRESS":case"KEY_DOWN":case"KEY_UP":case"SCROLL_DOWN":case"SCROLL_UP":case"SCROLL_LEFT":case"SCROLL_RIGHT":case"TYPE":return!0;case"AUTH_LOAD":case"AUTH_SAVE":case"AWAIT_LISTENER":case"SUCCESS":case"AI_ASSERTION":case"AI_EXTRACT":case"CAPTCHA":case"COOKIE":case"COPY":case"DIALOG":case"ELEMENT_CHECK":case"FILE_UPLOAD":case"GET_RECORDED_REQUESTS":case"GO_BACK":case"GO_FORWARD":case"GRAPHQL_REQUEST":case"JAVASCRIPT":case"LOCAL_STORAGE":case"NAVIGATE":case"NEW_TAB":case"PASTE":case"PAGE_CHECK":case"RECORD_REQUESTS":case"REGISTER_REQUEST_LISTENER":case"REFRESH":case"REQUEST":case"SELECT_OPTION":case"SET_HEADER":case"TAB":case"VISUAL_DIFF":case"WAIT":case"WAIT_FOR_URL":case"OFFLINE_MODE":case"MOCK_ROUTE":case"REMOVE_ROUTE_MOCK":return!1;default:return(t=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(r)}}import{z as mO}from"zod";var qq=mO.discriminatedUnion("type",[ps,Kp,cs,ji,ds,us,Vi,Bi,Hi,zi,Gi,ms,hs,gs,$i]);function py(r){return["AI_ASSERTION","ELEMENT_CHECK","PAGE_CHECK"].includes(r)}import{z as hO}from"zod";import{z as eo}from"zod";function fs(r){return eo.object({key:eo.string(),testId:eo.string().optional(),moduleId:eo.string().optional(),organizationId:eo.string(),value:r})}function Ss(r){return fs(r).extend({uniqueKey:eo.string()})}function cc(r){return eo.record(eo.string(),Ss(r))}var Yt={type:!0,cache:!0},Dn=hO.discriminatedUnion("type",[sc.pick(Yt),ps.pick(Yt),cs.pick(Yt),ji.pick(Yt),$i.pick(Yt),ds.pick(Yt),us.pick(Yt),Vi.pick(Yt),Bi.pick(Yt),Hi.pick(Yt),zi.pick(Yt),Gi.pick(Yt),ms.pick(Yt),hs.pick(Yt),gs.pick(Yt)]),uc=Object.values(Ge).filter(r=>Dn.options.some(e=>e.shape.type.safeParse(r).success));Wi.options.forEach(r=>{if("target"in r.shape&&!uc.includes(r.shape.type.value))throw new Error(`Command ${r.shape.type.value} has a target but no cache`)});function my(r){return uc.includes(r.type)}var hy=fs(Dn),gy=Ss(Dn),t2=cc(Dn);import{v4 as je}from"uuid";import{z as w}from"zod";var Sy=Symbol("Let zodToJsonSchema decide on which parser to use");var fy={name:void 0,$refStrategy:"root",basePath:["#"],effectStrategy:"input",pipeStrategy:"all",dateStrategy:"format:date-time",mapStrategy:"entries",removeAdditionalStrategy:"passthrough",allowedAdditionalProperties:!0,rejectedAdditionalProperties:!1,definitionPath:"definitions",target:"jsonSchema7",strictUnions:!1,definitions:{},errorMessages:!1,markdownDescription:!1,patternStrategy:"escape",applyRegexFlags:!1,emailStrategy:"format:email",base64Strategy:"contentEncoding:base64",nameStrategy:"ref",openAiAnyTypeName:"OpenAiAnyType"},yy=r=>typeof r=="string"?{...fy,name:r}:{...fy,...r};var Ey=r=>{let e=yy(r),t=e.name!==void 0?[...e.basePath,e.definitionPath,e.name]:e.basePath;return{...e,flags:{hasReferencedOpenAiAnyType:!1},currentPath:t,propertyPath:void 0,seen:new Map(Object.entries(e.definitions).map(([n,o])=>[o._def,{def:o._def,path:[...e.basePath,e.definitionPath,n],jsonSchema:void 0}]))}};function tm(r,e,t,n){n?.errorMessages&&t&&(r.errorMessage={...r.errorMessage,[e]:t})}function Se(r,e,t,n,o){r[e]=t,tm(r,e,n,o)}var dc=(r,e)=>{let t=0;for(;t<r.length&&t<e.length&&r[t]===e[t];t++);return[(r.length-t).toString(),...e.slice(t)].join("/")};import{ZodFirstPartyTypeKind as fe}from"zod";function Je(r){if(r.target!=="openAi")return{};let e=[...r.basePath,r.definitionPath,r.openAiAnyTypeName];return r.flags.hasReferencedOpenAiAnyType=!0,{$ref:r.$refStrategy==="relative"?dc(e,r.currentPath):e.join("/")}}import{ZodFirstPartyTypeKind as gO}from"zod";function Ty(r,e){let t={type:"array"};return r.type?._def&&r.type?._def?.typeName!==gO.ZodAny&&(t.items=ee(r.type._def,{...e,currentPath:[...e.currentPath,"items"]})),r.minLength&&Se(t,"minItems",r.minLength.value,r.minLength.message,e),r.maxLength&&Se(t,"maxItems",r.maxLength.value,r.maxLength.message,e),r.exactLength&&(Se(t,"minItems",r.exactLength.value,r.exactLength.message,e),Se(t,"maxItems",r.exactLength.value,r.exactLength.message,e)),t}function by(r,e){let t={type:"integer",format:"int64"};if(!r.checks)return t;for(let n of r.checks)switch(n.kind){case"min":e.target==="jsonSchema7"?n.inclusive?Se(t,"minimum",n.value,n.message,e):Se(t,"exclusiveMinimum",n.value,n.message,e):(n.inclusive||(t.exclusiveMinimum=!0),Se(t,"minimum",n.value,n.message,e));break;case"max":e.target==="jsonSchema7"?n.inclusive?Se(t,"maximum",n.value,n.message,e):Se(t,"exclusiveMaximum",n.value,n.message,e):(n.inclusive||(t.exclusiveMaximum=!0),Se(t,"maximum",n.value,n.message,e));break;case"multipleOf":Se(t,"multipleOf",n.value,n.message,e);break}return t}function vy(){return{type:"boolean"}}function pc(r,e){return ee(r.type._def,e)}var Ry=(r,e)=>ee(r.innerType._def,e);function rm(r,e,t){let n=t??e.dateStrategy;if(Array.isArray(n))return{anyOf:n.map((o,i)=>rm(r,e,o))};switch(n){case"string":case"format:date-time":return{type:"string",format:"date-time"};case"format:date":return{type:"string",format:"date"};case"integer":return fO(r,e)}}var fO=(r,e)=>{let t={type:"integer",format:"unix-time"};if(e.target==="openApi3")return t;for(let n of r.checks)switch(n.kind){case"min":Se(t,"minimum",n.value,n.message,e);break;case"max":Se(t,"maximum",n.value,n.message,e);break}return t};function Ay(r,e){return{...ee(r.innerType._def,e),default:r.defaultValue()}}function wy(r,e){return e.effectStrategy==="input"?ee(r.schema._def,e):Je(e)}function Cy(r){return{type:"string",enum:Array.from(r.values)}}var SO=r=>"type"in r&&r.type==="string"?!1:"allOf"in r;function xy(r,e){let t=[ee(r.left._def,{...e,currentPath:[...e.currentPath,"allOf","0"]}),ee(r.right._def,{...e,currentPath:[...e.currentPath,"allOf","1"]})].filter(i=>!!i),n=e.target==="jsonSchema2019-09"?{unevaluatedProperties:!1}:void 0,o=[];return t.forEach(i=>{if(SO(i))o.push(...i.allOf),i.unevaluatedProperties===void 0&&(n=void 0);else{let a=i;if("additionalProperties"in i&&i.additionalProperties===!1){let{additionalProperties:s,...c}=i;a=c}else n=void 0;o.push(a)}}),o.length?{allOf:o,...n}:void 0}function _y(r,e){let t=typeof r.value;return t!=="bigint"&&t!=="number"&&t!=="boolean"&&t!=="string"?{type:Array.isArray(r.value)?"array":"object"}:e.target==="openApi3"?{type:t==="bigint"?"integer":t,enum:[r.value]}:{type:t==="bigint"?"integer":t,const:r.value}}import{ZodFirstPartyTypeKind as ys}from"zod";var nm,jr={cuid:/^[cC][^\s-]{8,}$/,cuid2:/^[0-9a-z]+$/,ulid:/^[0-9A-HJKMNP-TV-Z]{26}$/,email:/^(?!\.)(?!.*\.\.)([a-zA-Z0-9_'+\-\.]*)[a-zA-Z0-9_+-]@([a-zA-Z0-9][a-zA-Z0-9\-]*\.)+[a-zA-Z]{2,}$/,emoji:()=>(nm===void 0&&(nm=RegExp("^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$","u")),nm),uuid:/^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/,ipv4:/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/,ipv4Cidr:/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/(3[0-2]|[12]?[0-9])$/,ipv6:/^(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))$/,ipv6Cidr:/^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/,base64:/^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/,base64url:/^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z-_]{3}(=)?))?$/,nanoid:/^[a-zA-Z0-9_-]{21}$/,jwt:/^[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_]*$/};function mc(r,e){let t={type:"string"};if(r.checks)for(let n of r.checks)switch(n.kind){case"min":Se(t,"minLength",typeof t.minLength=="number"?Math.max(t.minLength,n.value):n.value,n.message,e);break;case"max":Se(t,"maxLength",typeof t.maxLength=="number"?Math.min(t.maxLength,n.value):n.value,n.message,e);break;case"email":switch(e.emailStrategy){case"format:email":Vr(t,"email",n.message,e);break;case"format:idn-email":Vr(t,"idn-email",n.message,e);break;case"pattern:zod":Xt(t,jr.email,n.message,e);break}break;case"url":Vr(t,"uri",n.message,e);break;case"uuid":Vr(t,"uuid",n.message,e);break;case"regex":Xt(t,n.regex,n.message,e);break;case"cuid":Xt(t,jr.cuid,n.message,e);break;case"cuid2":Xt(t,jr.cuid2,n.message,e);break;case"startsWith":Xt(t,RegExp(`^${om(n.value,e)}`),n.message,e);break;case"endsWith":Xt(t,RegExp(`${om(n.value,e)}$`),n.message,e);break;case"datetime":Vr(t,"date-time",n.message,e);break;case"date":Vr(t,"date",n.message,e);break;case"time":Vr(t,"time",n.message,e);break;case"duration":Vr(t,"duration",n.message,e);break;case"length":Se(t,"minLength",typeof t.minLength=="number"?Math.max(t.minLength,n.value):n.value,n.message,e),Se(t,"maxLength",typeof t.maxLength=="number"?Math.min(t.maxLength,n.value):n.value,n.message,e);break;case"includes":{Xt(t,RegExp(om(n.value,e)),n.message,e);break}case"ip":{n.version!=="v6"&&Vr(t,"ipv4",n.message,e),n.version!=="v4"&&Vr(t,"ipv6",n.message,e);break}case"base64url":Xt(t,jr.base64url,n.message,e);break;case"jwt":Xt(t,jr.jwt,n.message,e);break;case"cidr":{n.version!=="v6"&&Xt(t,jr.ipv4Cidr,n.message,e),n.version!=="v4"&&Xt(t,jr.ipv6Cidr,n.message,e);break}case"emoji":Xt(t,jr.emoji(),n.message,e);break;case"ulid":{Xt(t,jr.ulid,n.message,e);break}case"base64":{switch(e.base64Strategy){case"format:binary":{Vr(t,"binary",n.message,e);break}case"contentEncoding:base64":{Se(t,"contentEncoding","base64",n.message,e);break}case"pattern:zod":{Xt(t,jr.base64,n.message,e);break}}break}case"nanoid":Xt(t,jr.nanoid,n.message,e);case"toLowerCase":case"toUpperCase":case"trim":break;default:}return t}function om(r,e){return e.patternStrategy==="escape"?EO(r):r}var yO=new Set("ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvxyz0123456789");function EO(r){let e="";for(let t=0;t<r.length;t++)yO.has(r[t])||(e+="\\"),e+=r[t];return e}function Vr(r,e,t,n){r.format||r.anyOf?.some(o=>o.format)?(r.anyOf||(r.anyOf=[]),r.format&&(r.anyOf.push({format:r.format,...r.errorMessage&&n.errorMessages&&{errorMessage:{format:r.errorMessage.format}}}),delete r.format,r.errorMessage&&(delete r.errorMessage.format,Object.keys(r.errorMessage).length===0&&delete r.errorMessage)),r.anyOf.push({format:e,...t&&n.errorMessages&&{errorMessage:{format:t}}})):Se(r,"format",e,t,n)}function Xt(r,e,t,n){r.pattern||r.allOf?.some(o=>o.pattern)?(r.allOf||(r.allOf=[]),r.pattern&&(r.allOf.push({pattern:r.pattern,...r.errorMessage&&n.errorMessages&&{errorMessage:{pattern:r.errorMessage.pattern}}}),delete r.pattern,r.errorMessage&&(delete r.errorMessage.pattern,Object.keys(r.errorMessage).length===0&&delete r.errorMessage)),r.allOf.push({pattern:Iy(e,n),...t&&n.errorMessages&&{errorMessage:{pattern:t}}})):Se(r,"pattern",Iy(e,n),t,n)}function Iy(r,e){if(!e.applyRegexFlags||!r.flags)return r.source;let t={i:r.flags.includes("i"),m:r.flags.includes("m"),s:r.flags.includes("s")},n=t.i?r.source.toLowerCase():r.source,o="",i=!1,a=!1,s=!1;for(let c=0;c<n.length;c++){if(i){o+=n[c],i=!1;continue}if(t.i){if(a){if(n[c].match(/[a-z]/)){s?(o+=n[c],o+=`${n[c-2]}-${n[c]}`.toUpperCase(),s=!1):n[c+1]==="-"&&n[c+2]?.match(/[a-z]/)?(o+=n[c],s=!0):o+=`${n[c]}${n[c].toUpperCase()}`;continue}}else if(n[c].match(/[a-z]/)){o+=`[${n[c]}${n[c].toUpperCase()}]`;continue}}if(t.m){if(n[c]==="^"){o+=`(^|(?<=[\r
|
|
5
5
|
]))`;continue}else if(n[c]==="$"){o+=`($|(?=[\r
|
|
6
6
|
]))`;continue}}if(t.s&&n[c]==="."){o+=a?`${n[c]}\r
|
|
@@ -24,8 +24,8 @@ ${this.decisions.map(e=>e.toString()).join(`
|
|
|
24
24
|
`);process.stderr.write(`${o}
|
|
25
25
|
`),globalThis.console=e}}var gt=" ".repeat(6);function Kb(r,e="",t=!1){let n=process.stdout?.columns||process.stderr?.columns||80,o=Math.max(n-e.length,20),i=r.split(`
|
|
26
26
|
`),a=[];for(let s of i)if(t){let c=s;for(;c.length>o;){let u=c.slice(0,o+1).lastIndexOf(" "),d=u>-1?u:o;a.push(e+c.slice(0,d)),c=c.slice(d).trimStart()}a.push(e+c)}else{let c=s.split(" "),l="";for(let u of c){if(!l.length){l=u;continue}let d=`${l} ${u}`;d.length<=o?l=d:(a.push(e+l),l=u)}a.push(e+l)}return a.join(`
|
|
27
|
-
`)}import qk from"fetch-retry";import Kk from"os";import Yb,{multistream as Yk}from"pino";import Xk from"pino-pretty";import Jk from"pino-std-serializers";var sa=new Map,Qk=!0,Xb="Log throttle exceeded",Zk=100,e0=5e3,t0=qk(global.fetch,{retries:2,retryOn:function(r,e,t){return!!(e!==null||t&&t.status>=500)},retryDelay:function(r){return Math.pow(2,r)*500}}),vh=class r{consoleLogger;hostname;bindingAttributes;disableConsoleLogs;minLevelValue=20;logsInCurrentWindow=0;droppedLogsInWindow=!1;lastWindowStart=Date.now();site="https://ingest.us.signoz.cloud:443/logs/json";flushIntervalMs;maxBatchSize;buffer=[];flushTimer;constructor({bindings:e,hostname:t,disableConsoleLogs:n,flushIntervalMs:o,maxBatchSize:i}){this.hostname=t??Kk.hostname(),this.disableConsoleLogs=n,this.bindingAttributes={...e,env:"production"},this.flushIntervalMs=o??5e3,this.maxBatchSize=i??10;let a={base:this.bindingAttributes,errorKey:"err",level:"debug"};this.consoleLogger=Qk?Yb(a):Yb(a,Yk([{stream:Xk({colorize:!0})}]))}getLevel(){return Jc[this.minLevelValue]}child(e){return new r({bindings:{...this.bindingAttributes,...e},hostname:this.hostname,disableConsoleLogs:this.disableConsoleLogs,flushIntervalMs:this.flushIntervalMs,maxBatchSize:this.maxBatchSize})}async flush(){await this.flushBuffer(),this.disableConsoleLogs||this.consoleLogger.flush()}scheduleFlush(){this.flushTimer||(this.flushTimer=setTimeout(()=>{this.flushTimer=void 0,this.flushBuffer()},this.flushIntervalMs))}async flushBuffer(){if(this.buffer.length===0)return;let e=this.buffer;this.buffer=[];try{let t=await t0(this.site,{method:"POST",headers:{"Content-Type":"application/json","signoz-access-token":"CumAaTMUcwjt05OddAmefKgshbhfRmWxzxih"},body:si(e),signal:AbortSignal.timeout(5e3)});if(!t.ok)throw new Error(`Got error status (${t.statusText}) from SigNoz`)}catch(t){this.consoleLogger.warn({err:t},"Failed to log to Momentic's observability provider, continuing...")}}shouldAllowLog(e){if(e===Xb)return!0;let t=Date.now();return t-this.lastWindowStart>e0&&(this.logsInCurrentWindow=0,this.droppedLogsInWindow&&this.log("error",void 0,Xb),this.droppedLogsInWindow=!1,this.lastWindowStart=t),this.logsInCurrentWindow<Zk?(this.logsInCurrentWindow++,!0):(this.droppedLogsInWindow=!0,!1)}log(e,t,n,...o){try{this.logHelper(e,t,n,...o)}catch(i){this.consoleLogger.warn(`Failed to log to Signoz: ${i}`)}}logHelper(e,t,n,...o){if(zs[e]<this.minLevelValue||!this.shouldAllowLog(n))return;typeof t=="string"&&!n&&(t={message:t}),typeof t=="object"&&t&&"err"in t&&t.err instanceof Error&&(t.err=Jk.err(t.err));let i={...this.bindingAttributes,...t&&typeof t=="object"?t:{},...o.length>0?{args:o}:{}},a={host:this.hostname,env:this.bindingAttributes.env};this.disableConsoleLogs||this.consoleLogger[e](i,n,...o);let s={timestamp:Math.round(Date.now()*1e6),severity_text:e.toUpperCase(),resources:a,attributes:{},body:HT({message:n||"",...i})};this.buffer.push(s),this.buffer.length>=this.maxBatchSize?(this.flushTimer&&(clearTimeout(this.flushTimer),this.flushTimer=void 0),this.flushBuffer()):this.scheduleFlush()}setApp(e){let t=this.bindingAttributes.app;this.bindingAttributes.app=e,sa.set("app",this),sa.delete(t)}debug(e,t,...n){this.log("debug",e,t,...n)}info(e,t,...n){this.log("info",e,t,...n)}warn(e,t,...n){this.log("warn",e,t,...n)}error(e,t,...n){this.log("error",e,t,...n)}bindings(){return this.bindingAttributes}addBinding(e,t){this.bindingAttributes[e]=t}setMinLevel(e){typeof e=="number"?(this.minLevelValue=e,this.consoleLogger.level=Jc[e]):(this.minLevelValue=zs[e],this.consoleLogger.level=e)}enableConsoleLogs(){this.disableConsoleLogs=!1}},ou=({app:r,hostname:e,disableConsoleLogs:t})=>(sa.has(r)||sa.set(r,new vh({bindings:{app:r},hostname:e,disableConsoleLogs:t})),sa.get(r));async function Qb(){await Promise.all([...sa.values()].map(r=>r.flush()))}import{hostname as r0}from"os";var ne=ou({app:"cli",hostname:r0(),disableConsoleLogs:!0}).child({cliVersion:"2.21.
|
|
28
|
-
`);console.warn(n),r.warn({stack:n,time:e},"NodeJS event loop blocked")},{threshold:1e3,trimFalsePositives:!0})}function h0(){process.on("SIGINT",()=>{if("_getActiveHandles"in process){let r=process._getActiveHandles();console.log("Active handles:",r.map(e=>e.constructor?.name))}p0(),setImmediate(()=>{setTimeout(()=>{process.exit(1)},2e3).unref()})})}import{randomUUID as XW}from"crypto";import eP from"body-parser";import k$ from"cors";import U$ from"dedent";import{Router as iU}from"express";import er from"fs";import{globSync as aU}from"glob";import It from"path";import Mu from"fs";import{z as v0}from"zod";var B="v1",wh="cli",ui="2.21.
|
|
27
|
+
`)}import qk from"fetch-retry";import Kk from"os";import Yb,{multistream as Yk}from"pino";import Xk from"pino-pretty";import Jk from"pino-std-serializers";var sa=new Map,Qk=!0,Xb="Log throttle exceeded",Zk=100,e0=5e3,t0=qk(global.fetch,{retries:2,retryOn:function(r,e,t){return!!(e!==null||t&&t.status>=500)},retryDelay:function(r){return Math.pow(2,r)*500}}),vh=class r{consoleLogger;hostname;bindingAttributes;disableConsoleLogs;minLevelValue=20;logsInCurrentWindow=0;droppedLogsInWindow=!1;lastWindowStart=Date.now();site="https://ingest.us.signoz.cloud:443/logs/json";flushIntervalMs;maxBatchSize;buffer=[];flushTimer;constructor({bindings:e,hostname:t,disableConsoleLogs:n,flushIntervalMs:o,maxBatchSize:i}){this.hostname=t??Kk.hostname(),this.disableConsoleLogs=n,this.bindingAttributes={...e,env:"production"},this.flushIntervalMs=o??5e3,this.maxBatchSize=i??10;let a={base:this.bindingAttributes,errorKey:"err",level:"debug"};this.consoleLogger=Qk?Yb(a):Yb(a,Yk([{stream:Xk({colorize:!0})}]))}getLevel(){return Jc[this.minLevelValue]}child(e){return new r({bindings:{...this.bindingAttributes,...e},hostname:this.hostname,disableConsoleLogs:this.disableConsoleLogs,flushIntervalMs:this.flushIntervalMs,maxBatchSize:this.maxBatchSize})}async flush(){await this.flushBuffer(),this.disableConsoleLogs||this.consoleLogger.flush()}scheduleFlush(){this.flushTimer||(this.flushTimer=setTimeout(()=>{this.flushTimer=void 0,this.flushBuffer()},this.flushIntervalMs))}async flushBuffer(){if(this.buffer.length===0)return;let e=this.buffer;this.buffer=[];try{let t=await t0(this.site,{method:"POST",headers:{"Content-Type":"application/json","signoz-access-token":"CumAaTMUcwjt05OddAmefKgshbhfRmWxzxih"},body:si(e),signal:AbortSignal.timeout(5e3)});if(!t.ok)throw new Error(`Got error status (${t.statusText}) from SigNoz`)}catch(t){this.consoleLogger.warn({err:t},"Failed to log to Momentic's observability provider, continuing...")}}shouldAllowLog(e){if(e===Xb)return!0;let t=Date.now();return t-this.lastWindowStart>e0&&(this.logsInCurrentWindow=0,this.droppedLogsInWindow&&this.log("error",void 0,Xb),this.droppedLogsInWindow=!1,this.lastWindowStart=t),this.logsInCurrentWindow<Zk?(this.logsInCurrentWindow++,!0):(this.droppedLogsInWindow=!0,!1)}log(e,t,n,...o){try{this.logHelper(e,t,n,...o)}catch(i){this.consoleLogger.warn(`Failed to log to Signoz: ${i}`)}}logHelper(e,t,n,...o){if(zs[e]<this.minLevelValue||!this.shouldAllowLog(n))return;typeof t=="string"&&!n&&(t={message:t}),typeof t=="object"&&t&&"err"in t&&t.err instanceof Error&&(t.err=Jk.err(t.err));let i={...this.bindingAttributes,...t&&typeof t=="object"?t:{},...o.length>0?{args:o}:{}},a={host:this.hostname,env:this.bindingAttributes.env};this.disableConsoleLogs||this.consoleLogger[e](i,n,...o);let s={timestamp:Math.round(Date.now()*1e6),severity_text:e.toUpperCase(),resources:a,attributes:{},body:HT({message:n||"",...i})};this.buffer.push(s),this.buffer.length>=this.maxBatchSize?(this.flushTimer&&(clearTimeout(this.flushTimer),this.flushTimer=void 0),this.flushBuffer()):this.scheduleFlush()}setApp(e){let t=this.bindingAttributes.app;this.bindingAttributes.app=e,sa.set("app",this),sa.delete(t)}debug(e,t,...n){this.log("debug",e,t,...n)}info(e,t,...n){this.log("info",e,t,...n)}warn(e,t,...n){this.log("warn",e,t,...n)}error(e,t,...n){this.log("error",e,t,...n)}bindings(){return this.bindingAttributes}addBinding(e,t){this.bindingAttributes[e]=t}setMinLevel(e){typeof e=="number"?(this.minLevelValue=e,this.consoleLogger.level=Jc[e]):(this.minLevelValue=zs[e],this.consoleLogger.level=e)}enableConsoleLogs(){this.disableConsoleLogs=!1}},ou=({app:r,hostname:e,disableConsoleLogs:t})=>(sa.has(r)||sa.set(r,new vh({bindings:{app:r},hostname:e,disableConsoleLogs:t})),sa.get(r));async function Qb(){await Promise.all([...sa.values()].map(r=>r.flush()))}import{hostname as r0}from"os";var ne=ou({app:"cli",hostname:r0(),disableConsoleLogs:!0}).child({cliVersion:"2.21.3"});var o0=5;async function au({getResults:r,checkDone:e,name:t,timeoutMs:n=18e5}){let o=Date.now(),i=0;for(;Date.now()-o<n;){let a;i>o0&&(T.error(`Failed to fetch ${t} status too many times.`),process.exit(1));try{a=await r(),i=0}catch(l){i++,ne.warn({err:l},"Failed to fetch run status, retrying..."),T.warn({err:l},"Failed to fetch run status, retrying..."),await new Promise(u=>setTimeout(u,1500*i));continue}if(e(a))return a;let c=Math.max(1e4,Math.floor(n/100));await new Promise(l=>setTimeout(l,c))}T.error(`Timeout elapsed waiting for ${t} to complete (${Math.floor(n/1e3)}s).`),process.exit(1)}function la({results:r,startTime:e,entity:t,getDisplayLine:n,onFailed:o}){let i=r.filter(u=>u.status==="PASSED"&&u.quarantined),a=r.filter(u=>u.status==="PASSED"&&!u.quarantined),s=r.filter(u=>u.status==="FAILED"&&u.quarantined),c=r.filter(u=>u.status==="FAILED"&&!u.quarantined),l=r.filter(u=>u.status==="CANCELLED");return qb(()=>{if(c.forEach(u=>{T.log(""),o(u)}),c.length){T.log("");let u=c.length===1?"":"s";T.error(`${c.length} ${t}${u} failed:`),c.forEach(d=>{T.dimmed(n(d))})}if(l.length){T.log("");let u=l.length===1?"":"s";T.warn(`${l.length} ${t}${u} cancelled:`),l.forEach(d=>{T.dimmed(n(d))})}if(a.length){T.log("");let u=a.length===1?"":"s";T.success(`${a.length} ${t}${u} passed:`),a.forEach(d=>{T.dimmed(n(d))})}if(s.length){T.log("");let u=s.length===1?"":"s";T.warn(`${s.length} quarantined ${t}${u} failed:`),s.forEach(d=>{T.dimmed(n(d))})}if(i.length){T.log("");let u=i.length===1?"":"s";T.warn(`${i.length} quarantined ${t}${u} passed:`),i.forEach(d=>{T.dimmed(n(d))})}T.log(""),T.dimmed(`Total time: ${Math.round((Date.now()-e)/1e3)}s`)}),{quarantinedPassed:i.length,passed:a.length,quarantinedFailed:s.length,failed:c.length,cancelled:l.length}}var su=(r,e)=>{if(!r.failureDetails||!r.failureReason)return;let t=gc[r.failureDetails?.classification?.reason||r.failureReason],n=r.failureDetails?.classification?.summary||qi[r.failureReason],o=r.failureDetails.classification?.rootCause;if(T.error(e),o){T.log(`${gt}- Error type: ${hn.dim(t)}`);let i="- Root cause analysis:",a=Kb(`${i} ${o}`,`${gt} `,!1),s=a.indexOf(":");T.log(`${gt}${i} ${hn.dim(a.slice(s+1))}`)}else T.log(`${gt}Reason: ${hn.red(t)}`),T.log(`${gt}Description: ${hn.red(n)}`)},$s=({status:r,testLogRef:e,getRunningTestsCount:t,getTotalTestsCount:n,additionalText:o})=>{r=r.toUpperCase();let i=r,a;r.includes("FAIL")?(i=hn.bgRed.white("FAIL"),a=3):r.includes("PASS")?(i=hn.bgGreen.white("PASS"),a=3):r.includes("START")?(i=hn.bgBlue.white("START"),a=2):r.includes("CANCEL")?(i=hn.bgRgb(191,68,11).white("CANCEL"),a=1):r.includes("RETRY")?(i=hn.bgRgb(191,68,11).white("RETRY"),a=2):r.includes("RUN")||r.includes("PROG")?(i=hn.bgMagenta.white("RUNNING"),a=0):(T.warn(`Unknown status tried to be logged in run test locally: ${r}`),a=0),n0||(i=`${i}`),T.log(`${i}${" ".repeat(a)} ${e} ${o?`${o} `:""}(${t()}/${n()})`)};import i0 from"fs";import{tmpdir as a0}from"os";import s0 from"path";import{registry as Ws}from"playwright-core/lib/server";import Zb from"proper-lockfile";var ev=s0.join(a0(),"momenticBrowserInstallation");var Rh=["chrome","chromium","chrome-for-testing","ffmpeg"],l0={Chromium:"chromium","Google Chrome":"chrome","Chrome for Testing":"chrome-for-testing"},tv={chrome:"chrome",chromium:"chromium","chrome-for-testing":"chromium-headless-shell",ffmpeg:"ffmpeg"};function rv(r){let e=tv[l0[r]??""]??"",t=Ws.findExecutable(e);return!t||t.installType==="none"?!1:Ah(t)}function Ah(r){let e=r.executablePath();return i0.existsSync(e)}function c0(r,e){let t=tv[r];if(!t)throw new Error(`Requested install of unknown browser type ${r}`);let n=Ws.findExecutable(t);if(!n||n.installType==="none")throw new Error(`Requested install of unknown browser type ${r}`);if(!(!e&&Ah(n)))return n}async function u0({browser:r,force:e}){let t=c0(r,e);if(!t){T.info(`Browser '${r}' is already installed, skipping...`);return}T.info(`Installing browser '${r}'...`);try{await Ws.installDeps([t],!1),await Ws.install([t],!1)}catch(n){if(n.message.includes("Lock file is already being held")){T.warn("Another process is installing Playwright browsers. Waiting for completion before proceeding..");let o=Ws.findExecutable(r),i=5*60*1e3,a=Date.now();for(;Date.now()-a<i&&!Ah(o);)T.info("Waiting for browser to finish installing..."),await new Promise(s=>setTimeout(s,5e3))}else throw n}}async function nv({rawBrowsers:r,force:e=!1,all:t=!1}){let n=t?Rh:Array.from(new Set(r));try{await Zb.lock(ev,{stale:1e3*60*5,update:1e3*60,realpath:!1,retries:{retries:30,factor:2,maxTimeout:15e3,minTimeout:500}})}catch(i){T.warn(`Failed to acquire lock to install browsers. Please ensure that any other process installing browsers completes within 5 minutes: ${i}. Continuing without installation...`);return}let o;try{for(let i of n)try{await u0({browser:i,force:e})}catch(a){o=a,T.error(`Failed to install the ${i} browser: ${a}`)}}finally{await Zb.unlock(ev,{realpath:!1})}if(o)throw o}import d0 from"blocked-at";import p0 from"why-is-node-running";function ov(r){m0(r),h0()}function m0(r){d0((e,t)=>{console.warn(`Detected the NodeJS event loop was blocked for ${e.toFixed(0)}ms. This can cause the CLI to hang.`);let n=t.join(`
|
|
28
|
+
`);console.warn(n),r.warn({stack:n,time:e},"NodeJS event loop blocked")},{threshold:1e3,trimFalsePositives:!0})}function h0(){process.on("SIGINT",()=>{if("_getActiveHandles"in process){let r=process._getActiveHandles();console.log("Active handles:",r.map(e=>e.constructor?.name))}p0(),setImmediate(()=>{setTimeout(()=>{process.exit(1)},2e3).unref()})})}import{randomUUID as XW}from"crypto";import eP from"body-parser";import k$ from"cors";import U$ from"dedent";import{Router as iU}from"express";import er from"fs";import{globSync as aU}from"glob";import It from"path";import Mu from"fs";import{z as v0}from"zod";var B="v1",wh="cli",ui="2.21.3";var mo=3.1783027;function g0(r){let e=0;for(let t=0;t<r.length;t++){let n=r.charCodeAt(t);!(n>=48&&n<=57)&&!(n>=65&&n<=90)&&!(n>=97&&n<=122)&&e++}return e}function Tt(r){return Math.ceil(Ch(r)/mo)}function Ch(r){let e=0;if(typeof r=="string"){let t=r;t=t.replaceAll(`
|
|
29
29
|
`,""),t=t.replaceAll(" ","");let n=g0(t);return t.length-n+mo*n}if(typeof r>"u"||r===null)return 0;if(typeof r=="number")return String(r).length;if(Array.isArray(r))return r.forEach(t=>{e+=Ch(t)}),e;if(typeof r=="object"){let t=r;return Object.keys(t).forEach(n=>{e+=String(n).length,n==="image_url"?(t[n]??{}).detail==="high"?e+=1105*mo:e+=85*mo:n==="source"&&typeof t[n]=="object"&&t[n]?.type==="base64"?e+=1600*mo:e+=Ch(t[n])}),e}if(typeof r=="boolean")return r?4:5;throw new Error(`Unsupported type passed to token length calculator '${typeof r}': ${r}`)}var ho=class extends Error{constructor(e){super(e),this.name="TimeoutError"}};var iv=r=>{let e=r.reason===void 0?new DOMException("This operation was aborted.","AbortError"):r.reason;return e instanceof Error?e:new DOMException(e,"AbortError")};function j(r,e){let{milliseconds:t,fallback:n,message:o,customTimers:i={setTimeout,clearTimeout}}=e,a;if(typeof t!="number"||Math.sign(t)!==1)throw new TypeError(`Expected \`milliseconds\` to be a positive number, got \`${t}\``);return new Promise((s,c)=>{let l;if(e.signal){let{signal:p}=e;if(p.aborted)return c(iv(p));l=()=>c(iv(p)),p.addEventListener("abort",l,{once:!0})}let u=()=>{if(e.signal&&e.signal.removeEventListener("abort",l),n)try{s(n())}catch(p){c(p)}else{typeof r.cancel=="function"&&Promise.resolve().then(()=>r.cancel()).catch(()=>{});let p=o instanceof Error?o:new ho(o??`Promise timed out after ${t}ms`);c(p)}};t<1/0&&(a=i.setTimeout(u,t));let d=()=>{i.clearTimeout(a),e.signal&&e.signal.removeEventListener("abort",l)};Promise.resolve(r).then(p=>{d(),s(p)}).catch(p=>{d(),c(p)})})}var lu=class{limit;windowMs;userActions;constructor(e,t){this.limit=e,this.windowMs=t,this.userActions=new Map}_cleanup(e,t="DEFAULT_USER"){let n=Date.now(),o=`${t}:${e}`;if(this.userActions.has(o)){let a=this.userActions.get(o)?.filter(s=>n-s<=this.windowMs)??[];a.length>0?this.userActions.set(o,a):this.userActions.delete(o)}}increment(e,t="DEFAULT_USER"){let n=Date.now(),o=`${t}:${e}`;this._cleanup(t,e),this.userActions.has(o)||this.userActions.set(o,[]);let i=this.userActions.get(o);return i.length>=this.limit?!0:(i.push(n),!1)}};var f0=9e4,S0=3,y0=1500,E0=15e3,qr=class extends Error{status;rawError;constructor(e,t,n,o={}){super(n,o),this.status=e,this.rawError=t}};async function T0(r){return r.text().then(e=>{try{return JSON.parse(e).error}catch{return e}})}var xh=class{baseUrl;logger;constructor(e){this.baseUrl=e.baseUrl,this.logger=e.logger}getHeaders(){let e={"Content-Type":"application/json"};return ui&&(e[eu]=ui),wh&&(e[$T]=wh),e}async sendRequest(e,t){let{retries:n=S0,requestTimeoutMs:o=f0,initialRetryDelayMs:i=y0,maxRetryDelayMs:a=E0}=t,s=n,c=n,l,u={path:e,baseUrl:this.baseUrl,method:t.method};for(;s>0;)try{return s--,await this.sendSingleRequestHelper(e,t,o)}catch(d){if(l=d,d instanceof qr&&d.status>=400&&d.status<500)throw d;if(d instanceof Error&&d.name==="AbortError"&&(l=new ho),s===0)throw l;let p=c-s,m=Math.min(i*Math.pow(2,p-1),a);await new Promise(h=>setTimeout(h,m))}throw this.logger.warn({...u,err:l},"Got fatal error response from Momentic server"),l}async sendSingleRequestHelper(e,t,n){let o={path:e,baseUrl:this.baseUrl,method:t.method},i=new AbortController,a=setTimeout(()=>i.abort(),n),s=()=>i.abort();t.signal&&t.signal.addEventListener("abort",s,{once:!0});let c=Date.now(),l={...this.getHeaders(),...t.extraHeaders};try{let u=await fetch(`${this.baseUrl}${e}`,{method:t.method,body:t.body?JSON.stringify(t.body):void 0,headers:l,signal:i.signal});if(!u.ok){let p=await T0(u);throw new qr(u.status,p,`Request to ${t.method} ${e} failed with status ${u.status}: ${p}`)}let d;if(u.status===204)d={};else{let p=await u.text();try{d=JSON.parse(p)}catch{d=p}}return this.logger&&t.logResponse===!0&&d&&this.logger.debug({result:d,status:u.status,durationMs:Date.now()-c,...o},"Got response from Momentic server"),d}finally{clearTimeout(a),t.signal&&t.signal.removeEventListener("abort",s)}}},Nt=class extends xh{apiKey;constructor(e){super(e),this.apiKey=e.apiKey}getHeaders(){return{...super.getHeaders(),Authorization:`Bearer ${this.apiKey}`}}};import{createAnthropic as b0}from"@ai-sdk/anthropic";var qs=({baseUrl:r,apiKey:e,sessionId:t,extraHeaders:n,loggerTags:o})=>i=>{let a={Authorization:`Bearer ${e}`,[eu]:ui??"",...t&&{[qT]:t},...n||{}};return o&&(a[WT]=JSON.stringify(o)),b0({baseURL:`${r}/v1/llm/anthropic/${i}`,headers:a,apiKey:e})(i)};var Fn=class extends Nt{agentConfig;constructor(e,t){let n={...Fc,...e};super(t),this.agentConfig=n}getAgentConfig(){return this.agentConfig}async rankChunksWithAi(e,t){let n={...e,loggerTags:t.loggerTags},o=await this.sendRequest(`/${B}/web-agent/recommend-chunks-ai`,{method:"POST",body:n,signal:t.abortSignal});return NE.parse(o)}async rankChunksWithRag(e,t){let n=await this.sendRequest(`/${B}/web-agent/recommend-chunks`,{method:"POST",body:{cliVersion:ui,...e},signal:t.abortSignal});return LE.parse(n)}async getScreenshotFromS3(e){let t=await this.sendRequest(`/${B}/s3/visual-diff-screenshot`,{method:"POST",body:{url:e}});return v0.string().parse(t)}async getElementLocation(e,t){let n={...e,disableCache:t.disableCache,loggerTags:t.loggerTags,useMemory:t.useMemory,agentConfigVersion:this.agentConfig?.locator},o=await this.sendRequest(`/${B}/web-agent/locate-element`,{method:"POST",body:n,signal:t.abortSignal});return JT.parse(o)}async getAssertionResult(e,t){let n={...e,disableCache:!!t.disableCache,useConsensus:!!t.useConsensus,attemptNumber:t.attemptNumber,loggerTags:t.loggerTags,useMemory:t.useMemory,agentConfigVersion:this.agentConfig?.assertion},o=await this.sendRequest(`/${B}/web-agent/assertion`,{method:"POST",body:n,signal:t.abortSignal});return uh.parse(o)}async getLintStepResult(e,t){let n={...e,disableCache:!!t.disableCache,loggerTags:t.loggerTags},o=await this.sendRequest(`/${B}/web-agent/lint/step`,{method:"POST",body:n,signal:t.abortSignal});return XT.parse(o)}async getLintMcpCopilotMessageResult(e,t){let n={message:e.message,disableCache:!!t.disableCache,loggerTags:t.loggerTags},o=await this.sendRequest(`/${B}/web-agent/lint/mcp-copilot`,{method:"POST",body:n,signal:t.abortSignal});return YT.parse(o)}async getVisualAssertionResult(e,t){let n={...e,disableCache:!!t.disableCache,useConsensus:!!t.useConsensus,attemptNumber:t.attemptNumber,loggerTags:t.loggerTags,useMemory:t.useMemory,agentConfigVersion:this.agentConfig?.["visual-assertion"]},o=await this.sendRequest(`/${B}/web-agent/visual-assertion`,{method:"POST",body:n,signal:t.abortSignal});return uh.parse(o)}async getAiActionCommand(e,t){let n=await this.sendRequest(`/${B}/web-agent/next-command-dynamic`,{method:"POST",body:{...e,disableCache:t.disableCache,loggerTags:t.loggerTags},signal:t.abortSignal});return KT.parse(n)}async getMultiturnAiActionCommand(e,t){return await this.sendRequest(`/${B}/web-agent/ai-action/next-command`,{method:"POST",body:{...e,disableCache:t.disableCache,loggerTags:t.loggerTags},signal:t.abortSignal})}async getMultiturnAiActionEvaluation(e,t){let n=await this.sendRequest(`/${B}/web-agent/ai-action/evaluate`,{method:"POST",body:{...e,disableCache:t.disableCache,loggerTags:t.loggerTags},signal:t.abortSignal});return Am.parse(n)}async getReverseMappedDescription(e,t){let n=await this.sendRequest(`/${B}/web-agent/reverse-mapped-description`,{method:"POST",body:{...e,disableCache:t.disableCache,loggerTags:t.loggerTags},signal:t.abortSignal});return QT.parse(n)}async getTextExtraction(e,t){let n={...e,disableCache:t.disableCache,loggerTags:t.loggerTags,agentConfigVersion:this.agentConfig?.["text-extraction"]},o=await this.sendRequest(`/${B}/web-agent/text-extraction`,{method:"POST",body:n,signal:t.abortSignal});return bm.parse(o)}async getPageSummary(e,t){let n={...e,disableCache:t.disableCache,loggerTags:t.loggerTags},o=await this.sendRequest(`/${B}/web-agent/page-summary`,{method:"POST",body:n,signal:t.abortSignal});return dE.parse(o)}async getTestResultClassification(e,t){let n=await this.sendRequest(`/${B}/web-agent/result-classification`,{method:"POST",body:{...e,loggerTags:t.loggerTags},signal:t.abortSignal});return im.parse(n)}async getExtractedKeywords(e,t){let n=await this.sendRequest(`/${B}/web-agent/extract-keywords`,{method:"POST",body:e,signal:t.abortSignal});return $E.parse(n)}async getAutohealingProposal(e,t){let n=await this.sendRequest(`/${B}/web-agent/autoheal-section`,{method:"POST",body:{...e,loggerTags:t.loggerTags},signal:t.abortSignal});return lE.parse(n)}async getFailureRecoveryProposal(e,t){let n=await this.sendRequest(`/${B}/web-agent/failure-recovery`,{method:"POST",body:{...e,loggerTags:t.loggerTags},signal:t.abortSignal});return uE.parse(n)}async getFailureRecoveryPlan(e,t){let n=await this.sendRequest(`/${B}/web-agent/failure-recovery-plan`,{method:"POST",body:{...e,loggerTags:t.loggerTags},signal:t.abortSignal});return cE.parse(n)}async getIframeRegex(e,t){let n=await this.sendRequest(`/${B}/web-agent/iframe-regex`,{method:"POST",body:e,signal:t.abortSignal});return jS.parse(n)}getVercelAnthropicModelFactory({loggerTags:e}){return qs({baseUrl:this.baseUrl,apiKey:this.apiKey,loggerTags:e})}};import{z as _h}from"zod";var rt=class extends Nt{constructor(e){super(e)}getAppUrl(){return this.baseUrl==="http://localhost:8000"?"http://localhost:3000":this.baseUrl.replace(/\/\/api/,"//app")}async getAuthInfo(){let e=await this.sendRequest(`/${B}/auth/check`,{method:"GET",retries:10,requestTimeoutMs:5e3});return db.parse(e)}async bulkGetRunStatus(e){let t=await this.sendRequest(`/${B}/runs/status`,{method:"POST",body:e,retries:3,requestTimeoutMs:1e4});return sb.parse(t)}async getTestYAMLExport(e){let t=await this.sendRequest(`/${B}/tests/export`,{method:"POST",body:e,retries:3,requestTimeoutMs:3e4});return eb.parse(t)}async updateStepCaches(e,t){await this.sendRequest(`/${B}/cache`,{method:"PATCH",body:e,extraHeaders:t,retries:3,requestTimeoutMs:1e4,initialRetryDelayMs:3e3})}async getStepCacheForTest(e,t){let n=await this.sendRequest(`/${B}/cache`,{method:"POST",body:e,extraHeaders:t,retries:10,requestTimeoutMs:3e4,initialRetryDelayMs:3e3});return rb.parse(n)}async updateMobileStepCaches(e,t){await this.sendRequest(`/${B}/mobile-cache`,{method:"PATCH",body:e,extraHeaders:t,retries:3,requestTimeoutMs:1e4,initialRetryDelayMs:3e3})}async getMobileStepCacheForTest(e,t){let n=await this.sendRequest(`/${B}/mobile-cache`,{method:"POST",body:e,extraHeaders:t,retries:10,requestTimeoutMs:3e4,initialRetryDelayMs:3e3});return nb.parse(n)}async queueTests(e){let t=await this.sendRequest(`/${B}/tests/queue`,{method:"POST",body:e,retries:3,requestTimeoutMs:1e4});return ZT.parse(t)}async uploadScreenshot(e){let t=await this.sendRequest(`/${B}/screenshots`,{method:"POST",body:e,retries:3,requestTimeoutMs:5e3});return ub.parse(t)}async getAllEnvironments(){let e=await this.sendRequest(`/${B}/environments`,{method:"GET",retries:3,requestTimeoutMs:5e3});return pb.parse(e)}async acquireCacheLock(e,t){let n=await this.sendRequest(`/${B}/result-cache/lock`,{method:"POST",body:e,signal:t,retries:3,requestTimeoutMs:3e4});return xb.parse(n)}async releaseCacheLock(e){await this.sendRequest(`/${B}/result-cache/lock`,{method:"DELETE",body:{key:e},retries:3,requestTimeoutMs:5e3})}async deleteCacheResult(e){await this.sendRequest(`/${B}/result-cache/entry`,{method:"DELETE",body:e,retries:3,requestTimeoutMs:5e3})}async setCacheResult(e){await this.sendRequest(`/${B}/result-cache/entry`,{method:"PATCH",body:e,retries:3,requestTimeoutMs:5e3})}async getCacheResult(e){try{return await this.sendRequest(`/${B}/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(`/${B}/suites/queue`,{method:"POST",body:e,retries:3,requestTimeoutMs:5e3});return mb.parse(t)}async bulkGetRunGroupStatus(e){let t={runGroupIds:e},n=await this.sendRequest(`/${B}/run-groups/status`,{method:"POST",body:t,retries:3,requestTimeoutMs:5e3});return _E.array().parse(n)}async uploadProposedSteps(e,t){try{await this.sendRequest(`/${B}/test-fragments/`,{method:"POST",body:e,retries:3,requestTimeoutMs:1e4})}catch(n){t.error({err:n},"Failed to upload proposed steps")}}async reportBillableEvents(e,t){try{await this.sendRequest(`/${B}/billing/events`,{method:"POST",body:t,retries:10,requestTimeoutMs:1e4})}catch(n){e.error({err:n},"Failed to report billable event")}}async fetchTestFragment(e){let t=await this.sendRequest(`/${B}/test-fragments/${e}`,{method:"GET",retries:3,requestTimeoutMs:1e4});return hb.parse(t)}async patchTestFragment(e,t){await this.sendRequest(`/${B}/test-fragments/${e}`,{method:"PATCH",body:t,retries:3,requestTimeoutMs:1e4})}async getPastTestResults(e,t){let n=await this.sendRequest(`/${B}/results/tests/${e}`,{method:"POST",body:t,retries:3,requestTimeoutMs:1e4});return gb.parse(n)}async generateTestResultsUploadUrl(){let e=await this.sendRequest(`/${B}/results/uploads`,{method:"POST",retries:3,requestTimeoutMs:1e4});return fb.parse(e)}async startProcessingResultsUpload(e,t){let n=await this.sendRequest(`/${B}/results/uploads/${e}/process`,{method:"POST",body:t,retries:3,requestTimeoutMs:1e4});return Sb.parse(n)}async fetchIconKnowledgeBase(e){try{let t=await this.sendRequest(`/${B}/knowledge-base/icons`,{method:"GET",retries:3,requestTimeoutMs:5e3});return Ob.parse(t)}catch(t){return e.error({err:t},"Failed to fetch icon knowledge base"),null}}async saveNewIcons(e,t){try{await this.sendRequest(`/${B}/knowledge-base/icons`,{method:"POST",body:e,retries:3,requestTimeoutMs:5e3})}catch(n){t.error({err:n},"Failed to save new icons to icon knowledge base")}}async getMergeBaseCommitFromGithub(e,t,n,o){let i=new URLSearchParams;i.set("base",n),i.set("head",o);let a=await this.sendRequest(`/${B}/git/github/${e}/${t}/merge-base-commit?${i.toString()}`,{method:"GET",retries:3,requestTimeoutMs:1e4});return Gs.parse(a)}async getCommitFromGithub(e,t,n){let o=await this.sendRequest(`/${B}/git/github/${e}/${t}/commits/${n}`,{method:"GET",retries:3,requestTimeoutMs:1e4});return Gs.parse(o)}async getMergedBranchFromGithub(e,t,n,o){let i=encodeURIComponent(n),a=await this.sendRequest(`/${B}/git/github/${e}/${t}/${i}/${o}/merged-branch`,{method:"GET",retries:3,requestTimeoutMs:1e4});return hh.parse(a)}async getMergeBaseCommitFromGitlab(e,t,n){let o=new URLSearchParams;o.set("base",t),o.set("head",n);let i=encodeURIComponent(e),a=await this.sendRequest(`/${B}/git/gitlab/${i}/merge-base-commit?${o.toString()}`,{method:"GET",retries:3,requestTimeoutMs:5e3});return Gs.parse(a)}async getCommitFromGitlab(e,t){let n=encodeURIComponent(e),o=await this.sendRequest(`/${B}/git/gitlab/${n}/commits/${t}`,{method:"GET",retries:3,requestTimeoutMs:1e4});return Gs.parse(o)}async getMergedBranchFromGitlab(e,t,n){let o=encodeURIComponent(t),i=encodeURIComponent(e),a=await this.sendRequest(`/${B}/git/gitlab/${i}/${o}/${n}/merged-branch`,{method:"GET",retries:3,requestTimeoutMs:1e4});return hh.parse(a)}async getAgentConfig(){let e=await this.sendRequest(`/${B}/web-agent/agent-config`,{method:"GET",retries:3,requestTimeoutMs:5e3});return _h.record(_h.string(),_h.string()).parse(e)}async getQuarantinedTests(){let e=await this.sendRequest(`/${B}/quarantine`,{method:"GET"});return yb.parse(e)}async quarantineTest(e,t,n){await this.sendRequest(`/${B}/quarantine`,{method:"POST",body:{testId:e.id,testName:e.name,reason:t,...n??{}},retries:3,requestTimeoutMs:1e4})}async unquarantineTest(e,t,n){await this.sendRequest(`/${B}/quarantine/${e.id}`,{method:"DELETE",body:{testName:e.name,reason:t,...n??{}},retries:3,requestTimeoutMs:1e4})}async createAndroidEmulator(e){let t=await this.sendRequest(`/${B}/limbar/android`,{method:"POST",retries:3,body:e,requestTimeoutMs:9e4,initialRetryDelayMs:5e3,maxRetryDelayMs:15e3});return Eb.parse(t)}async extendAndroidEmulatorTtl(e){try{await this.sendRequest(`/${B}/limbar/android/${e}/keepalive`,{method:"POST",retries:3,requestTimeoutMs:15e3})}catch{}}async generateAndroidAssetUrls({channel:e,tag:t,md5:n}){let o={channel:e,tag:t,md5:n},i=await this.sendRequest(`/${B}/limbar/android/upload-url`,{method:"POST",retries:3,body:o,requestTimeoutMs:15e3,logResponse:!0});return Tb.parse(i)}async deleteAndroidEmulator(e){await this.sendRequest(`/${B}/limbar/android/${e}`,{method:"DELETE",retries:3,requestTimeoutMs:3e4})}async getAndroidAssets(){let e=await this.sendRequest(`/${B}/limbar/assets`,{method:"GET",retries:3,requestTimeoutMs:1e4});return bb.parse(e)}async deleteAndroidAsset(e,t){await this.sendRequest(`/${B}/limbar/assets/${e}/${t}`,{method:"DELETE",retries:3,requestTimeoutMs:1e4})}};async function Ih(r){let e=process.versions.node,t=parseInt(e.split(".")[0]);(isNaN(t)||t<18)&&(T.error(`Node.js version 20 or higher is required to run the CLI. Detected: ${process.versions.node}.`),process.exit(1)),T.debug(`Identified node version ${e}`);let n=await r.client.getAuthInfo();return T.debug("Got auth info from API"),n}var cu=class{apiClient;constructor(e){this.apiClient=e}async reportBillableEvents(e,t){await this.apiClient.reportBillableEvents(e,t)}};var go=class extends Nt{generator;constructor(e,t){super(e),this.generator=t}async runTemplateMatching(e,t={}){let n=await this.sendRequest(`/${B}/web-agent/template-matching`,{method:"POST",body:e,signal:t?.signal});return VS.parse(n)}async constructIframeRegex(e,t={}){return this.generator.getIframeRegex(e,{abortSignal:t.signal})}};var ca=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 R0,en as A0}from"@faker-js/faker";var ua="v1",gn=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 R0({locale:A0}),this.fakerInstance.seed(e.fakerSeed))}async sendAiGenerate(e){let t=typeof e=="string"?{input:e}:e;return this.httpClient.sendRequest(`/${ua}/tools/ai/generate`,{method:"POST",body:t}).catch(n=>{throw n instanceof qr?new Error(n.rawError):new Error(`Failed to send AI generation: ${n.message}`)})}async sendSms(e){return this.httpClient.sendRequest(`/${ua}/tools/sms/send`,{method:"POST",body:e}).then(()=>{}).catch(t=>{throw t instanceof qr?new Error(t.rawError):new Error(`Failed to send sms: ${t.message}`)})}async fetchLatestSms(e){return this.httpClient.sendRequest(`/${ua}/tools/sms/fetchLatest`,{method:"POST",body:e}).catch(t=>{throw t instanceof qr?new Error(t.rawError):t})}async sendEmail(e){return this.httpClient.sendRequest(`/${ua}/tools/email/send`,{method:"POST",body:e}).then(()=>{}).catch(t=>{throw t instanceof qr?new Error(t.rawError):new Error(`Failed to send email: ${t.message}`)})}async fetchAllEmails(e){return this.httpClient.sendRequest(`/${ua}/tools/email/fetchAll`,{method:"POST",body:e}).catch(t=>{throw t instanceof qr?new Error(t.rawError):new Error(`Failed to fetch all emails: ${t.message}`)})}async fetchLatestEmail(e){return this.httpClient.sendRequest(`/${ua}/tools/email/fetchLatest`,{method:"POST",body:e}).catch(t=>{throw t instanceof qr?new Error(t.rawError):new Error(`Failed to fetch latest emails: ${t.message}`)})}};function av(r,e,t){return fetch(r,{method:"PUT",body:t,headers:{"Content-Type":e}})}var uu=class{constructor(e){this.client=e}async uploadResultsArchive(e,t){let{uploadUrl:n,id:o}=await this.client.generateTestResultsUploadUrl(),i=await av(n,"application/zip",t);if(!i.ok)throw new Error(`Failed to upload test results: ${await i.text()}`);let{runGroupId:a}=await this.client.startProcessingResultsUpload(o,{runGroupId:e});return a}};import{diff as C0}from"deep-object-diff";import{cloneDeep as x0}from"lodash-es";function Ks(r){let e={parentChain:[]};return du(r,e),e}function du(r,e){let{onPresetAction:t,onSimpleStepContainer:n,onConditional:o,earlyStop:i}=r;for(let a of r.steps)switch(a.type){case"PRESET_ACTION":if(t(a,e)&&i)return!0;break;case"CONDITIONAL":if(o?.(a,e)&&i)return!0;e.parentChain.push(a);for(let c of a.blocks)if(t(c.assertion,e)&&i||du({...r,steps:c.steps},e)&&i)return!0;if(du({...r,steps:a.elseSteps??[]},e)&&i)return!0;e.parentChain.pop();break;case"RESOLVED_MODULE":case"SECTION":case"AI_ACTION":if(n?.(a,e)&&i)return!0;if(a.steps){if(e.parentChain.push(a),du({...r,steps:a.steps},e)&&i)return!0;e.parentChain.pop()}break;case"AI_ACTION_DYNAMIC":{if(n?.(a,e)&&i)return!0;break}default:return(c=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(a)}}function sv(r,e,t,n){let o=Array.from(e),i=Array.from(n);for(let s=0;s<o.length;s++){if(o[s]!==i[s])return!1;i.shift()}return!!w0([r],t,i).result}function w0(r,e,t=[]){let n,o=[],i=(a,s)=>{let c=JSON.stringify(s.parentChain.map(u=>u.id)),l=t.length===0?!0:JSON.stringify(t)===c;return a.id===e&&l?(n=a,o=s.parentChain,!0):!1};return Ks({steps:r,earlyStop:!0,onPresetAction:i,onConditional:i,onSimpleStepContainer:i}),{result:n,parentChain:o}}function lv(r,e){e(r);for(let t in r){let n=r[t];n&&(Array.isArray(n)?mu(n,e):typeof n=="object"&&lv(n,e))}}function mu(r,e){for(let t of r)t&&(Array.isArray(t)?mu(t,e):typeof t=="object"&&lv(t,e))}function Ph(r,e){if(r.length>e.length)return Ph(e,r);for(let t=0;t<r.length;t++)if(r[t]!==e[t])return!1;return!0}function pu(r){for(let e of r.results)switch(e.type){case"PRESET_ACTION":r.onPresetAction(e);break;case"AI_ACTION":case"AI_ACTION_DYNAMIC":case"MODULE":r.onSimpleStepContainer?.(e),pu({...r,results:e.results});break;case"CONDITIONAL":r.onConditional?.(e),e.assertionResult&&r.onPresetAction(e.assertionResult),pu({...r,results:e.results});break;default:throw new Error(`Unsupported result type: ${e.type}`)}}function Ys(r,e){return!r&&!e?!1:!r||!e?!0:Object.keys(C0(r,e)).length>0}function da({steps:r,topLevel:e=!0,...t}){let{stepCacheEntries:n,logger:o,keyPrefix:i}=t,a=[],s=[],c=[],l=0,u=(p,m)=>{try{let h=Dn.parse(m.value);if(h.type!==p.type){o.warn({parsedCacheEntry:h,command:p},"Not using step cache due to type mismatch"),s.push(m.key);return}p.cache=h.cache,a.push(m.key),c.push(m.uniqueKey)}catch(h){s.push(m.key),o.error({err:h,cacheEntry:m},"Not using step cache due to parsing error")}},d=(p,m)=>{let h=_0(p.id,m),g=h.find(f=>!!n[f]);if(g)u(p,n[g]);else{if(p.type==="AI_ASSERTION")return;s.push(h[0])}};for(let p of r)switch(p.type){case"RESOLVED_MODULE":{l+=p.steps.length;let{cacheKeysHit:m,cacheKeysMissed:h,uniqueKeysHit:g}=da({...t,steps:p.steps,keyPrefix:i?`${i}:${p.id}`:p.id,topLevel:!1});a.push(...m),s.push(...h),c.push(...g);break}case"SECTION":case"AI_ACTION":{if(l+=p.steps?.length??0,!p.steps?.length)break;let{cacheKeysHit:m,cacheKeysMissed:h,uniqueKeysHit:g}=da({...t,steps:p.steps,topLevel:!1});a.push(...m),s.push(...h),c.push(...g);break}case"AI_ACTION_DYNAMIC":continue;case"PRESET_ACTION":{if(!uc.includes(p.command.type)||(p.command.type==="TYPE"||p.command.type==="MOUSE_DRAG"||p.command.type==="VISUAL_DIFF"||p.command.type==="SCROLL_DOWN"||p.command.type==="SCROLL_UP"||p.command.type==="SCROLL_LEFT"||p.command.type==="SCROLL_RIGHT")&&!p.command.target||"cache"in p.command&&p.command.cache)continue;l++,d(p.command,i);break}case"CONDITIONAL":{for(let m of p.blocks){l++,d(m.assertion.command,i),l+=m.steps.length;let{cacheKeysHit:h,cacheKeysMissed:g,uniqueKeysHit:f}=da({...t,steps:m.steps,topLevel:!1});a.push(...h),s.push(...g),c.push(...f)}if(p.elseSteps){l+=p.elseSteps.length;let{cacheKeysHit:m,cacheKeysMissed:h,uniqueKeysHit:g}=da({...t,steps:p.elseSteps,topLevel:!1});a.push(...m),s.push(...h),c.push(...g)}break}default:return(h=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(p)}return e&&l&&s.length>0&&o.warn({totalSteps:l,cacheKeysMissed:s,cacheKeysHit:a,uniqueKeysHit:c,cacheEntries:n.length},"Step cache did not fully resolve"),{cacheKeysHit:a,cacheKeysMissed:s,uniqueKeysHit:c}}function cv(r,e){return e?`${e}:${r}`:r}function _0(r,e){let t=[],n=e?.split(":")??[];for(let o=n.length;o>=0;o--){let i=[...n.slice(o),r];t.push(i.join(":"))}return t.reverse(),t}function Mh(r){let{moduleStepParents:e=[],moduleIdParents:t=[]}=r;if(e.length!==t.length)throw new Error(`Invalid cache entry parent length: ${JSON.stringify(e)}
|
|
30
30
|
${JSON.stringify(t)}`);let n=[];return n.push({key:cv(r.id,e.join(":")),organizationId:r.orgId,value:r.value,testId:r.testId}),n}function uv(r){let e=new Set;return mu(r,t=>{if("type"in t&&t.type==="RESOLVED_MODULE"&&"moduleId"in t){let n=t.moduleId;typeof n=="string"&&!e.has(n)&&e.add(n)}}),e}function hu({cmd:r,newTarget:e,key:t,logger:n,updatedWithAI:o}){if(r.type==="DRAG")if(t!=="fromTarget"&&t!=="toTarget")n.error({cmd:r,newTarget:e,key:t},"Attempted to apply invalid cache to DRAG command");else{let i=r.cache?.updatedAt;r.cache={...r.cache,[t]:e,updatedAt:i&&!o?i:new Date}}else if(t==="target"&&my(r)){let i=r.cache?.updatedAt;r.cache={...r.cache,target:e,updatedAt:i&&!o?i:new Date}}else n.error({cmd:r,newTarget:e,key:t},"Invalid target cache application")}function gu(r,e,t){let n=r.cache&&"memory"in r.cache?r.cache.memory?.traces:void 0;return Ys(n,e)?(t.info({updatedTraces:e,oldCmd:r},"Wrote new memory to assertion command"),r.cache={...r.cache,memory:{type:"GCS_TRACES",traces:e},updatedAt:new Date},{changed:!0}):{changed:!1}}function dv({steps:r}){let e={};return Ks({steps:r,onPresetAction:(t,n)=>{let o=t.command;if(!("cache"in o)||!o.cache)return;let i=n.parentChain.filter(c=>c.type==="RESOLVED_MODULE").map(c=>c.id).join(":"),a=cv(t.id,i),s=Dn.parse(o);e[a]=s},onSimpleStepContainer:(t,n)=>{},onConditional:(t,n)=>{}}),e}function Xs(r){return{...r,serializedHtml:void 0,nodeOnlySerializedHtml:void 0,screenshotUrl:void 0,boundingBox:void 0,selector:void 0,hybridSelector:void 0,generatedSelectors:void 0,id:-1}}function I0(r,e){return Ys(r.memory,e.memory)?{...r,memory:e.memory,updatedAt:e.updatedAt}:r}function Oh(r,e){return r?Ys(r.target.memory,e.target.memory)?{target:{...r.target,memory:e.target.memory},updatedAt:e.updatedAt}:r:{target:Xs(e.target),updatedAt:e.updatedAt}}function P0(r,e){let t=x0(r);return t.fromTarget?Ys(r.fromTarget?.memory,e.fromTarget?.memory)&&(t.fromTarget={...t.fromTarget,memory:e.fromTarget?.memory},t.updatedAt=e.updatedAt):(t.fromTarget=e.fromTarget,t.fromTarget&&(t.fromTarget=Xs(t.fromTarget),t.updatedAt=e.updatedAt)),t.toTarget?Ys(r.toTarget?.memory,e.toTarget?.memory)&&(t.toTarget={...t.toTarget,memory:e.toTarget?.memory},t.updatedAt=e.updatedAt):(t.toTarget=e.toTarget,t.toTarget&&(t.toTarget=Xs(t.toTarget),t.updatedAt=e.updatedAt)),t}function pv({newEntries:r,originalCachesMap:e,logger:t}){let n=[];for(let o of r){let i=e[o.key];if(!i||!i.cache||o.value.type!==i.type)continue;let a=o.value.cache;if(o.value={...i},!a){n.push(o);continue}if("memory"in a&&a.memory)t.debug({cacheKey:o.key,newCacheMemory:a.memory,originalCache:i},"Overwriting assertion cache memory"),o.value.cache=I0(i.cache,a);else if("target"in a&&a.target.memory){t.debug({cacheKey:o.key,newCacheMemory:a.target.memory,originalCache:i},"Overwriting target cache memory");let s=dr.safeParse(o.value.cache);o.value.cache=Oh(s.data,a)}else if("fromTarget"in a||"toTarget"in a){let s=Yp.optional().parse(o.value.cache);if(!s)continue;t.debug({cacheKey:o.key,fromTargetMemory:a.fromTarget?.memory,toTargetMemory:a.toTarget?.memory,originalCache:i},"Overwriting drag cache memory"),o.value.cache=P0(s,a)}n.push(o)}return n}function at(r,e,t=!1){return r.length<e?r:r.slice(0,e-3)+(t?"...TRUNCATED...":"[...]")}var Ir={EQUALS:"equals",CONTAINS:"contains",STARTS_WITH:"starts with",EXISTS:"exists"},Pr={EQUALS:"does not equal",CONTAINS:"does not contain",STARTS_WITH:"does not start with",EXISTS:"does not exist"},Lh={EXISTS:"exists",VISIBLE:"is visible",ENABLED:"is enabled",EDITABLE:"is editable",FOCUSED:"is focused"},Nh={EXISTS:"does not exist",VISIBLE:"is not visible",ENABLED:"is disabled",EDITABLE:"is not editable",FOCUSED:"is not focused"};function M0(r){switch(r.type){case"ELEMENT_CONTENT":return`content ${r.negated?Pr[r.operation]:Ir[r.operation]} '${r.value}'`;case"ELEMENT_ATTRIBUTE":{let t=r.negated?Pr[r.operation]:Ir[r.operation];return r.operation==="EXISTS"?`attribute '${r.attr}' ${t}`:`attribute '${r.attr}' ${t} '${r.value}'`}case"ELEMENT_NAME":{let t=r.negated?Pr[r.operation]:Ir[r.operation];return r.operation==="EXISTS"?`tag name ${t}`:`tag name ${t} '${r.value}'`}case"ELEMENT_STYLE":{let t=r.negated?Pr[r.operation]:Ir[r.operation];return r.operation==="EXISTS"?`style property '${r.property}' ${t}`:`style property '${r.property}' ${t} '${r.value}'`}case"ELEMENT_EXISTENCE":return r.negated?Nh[r.condition]:Lh[r.condition];default:return(t=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(r)}}var Mse={CONTENT:"The page"};function O0(r){switch(r.type){case"VALUE":return`the option with value ${r.value}`;case"LABEL":return`the option with label ${r.label}`;case"INDEX":return`the option at index ${r.index}`;default:return(t=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(r)}}function Su(r){switch(r.type){case"SUBSTRING":return`match substring '${r.url}'`;case"REGEX":return`match regex '${r.regex}'`;case"GLOB":return`match glob '${r.glob}'`;case"DOMAIN":return`match domain '${r.domain}'`;default:return(t=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(r)}}function fu(r){let e="";return r.method&&(e=` with method ${r.method}`),`${Su(r.urlMatcher)}${e}`}function L0(r){switch(r.type){case"CONTENT":return`${r.negated?Pr.CONTAINS:Ir.CONTAINS} '${r.value}'`;default:return(t=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(r.type)}}function Sn(r,e=!0){switch(r.type){case"SUCCESS":return r.condition?.assertion?`Check success condition: ${r.condition.assertion}`:"All commands completed";case"AI_EXTRACT":return`Extract data from page: ${r.goal}`;case"NAVIGATE":return`Go to URL: ${e?at(r.url,30):r.url}`;case"DIALOG":return`Automatically ${r.action.toLowerCase()} the next dialog`;case"CAPTCHA":return"Solve captchas on the page";case"GO_BACK":return"Go back to the previous page";case"GO_FORWARD":return"Go forward to the next page";case"SCROLL_DOWN":return`Scroll down ${r.deltaY?`${r.deltaY}px`:"1 page height"}${r.target?` in the container of: ${Bt(r.target)}`:""}`;case"SCROLL_UP":return`Scroll up ${r.deltaY?`${r.deltaY}px`:"1 page height"}${r.target?` in the container of: ${Bt(r.target)}`:""}`;case"SCROLL_LEFT":return`Scroll left ${r.deltaX?`${r.deltaX}px`:"1 page width"}${r.target?` in the container of: ${Bt(r.target)}`:""}`;case"SCROLL_RIGHT":return`Scroll right ${r.deltaX?`${r.deltaX}px`:"1 page width"}${r.target?` in the container of: ${Bt(r.target)}`:""}`;case"WAIT":return`Wait for ${r.delay} seconds`;case"REFRESH":return"Refresh the page";case"CLICK":{if(r.target?.type==="coordinates")return`Click at coordinates: ${Bt(r.target)}`;let n="";return r.target?.elementDescriptor.length?n=` on element: '${r.target.elementDescriptor}'`:r.cache?.target.nodeOnlySerializedHtml&&(n=` on element: '${r.cache?.target.nodeOnlySerializedHtml}'`),`Click${n}`}case"FOCUS":return`Focus ${Bt(r.target)}`;case"BLUR":return`Focus ${Bt(r.target)}`;case"DRAG":return`Drag ${Bt(r.fromTarget)} onto ${Bt(r.toTarget)}`;case"MOUSE_DRAG":return r.target?.type==="description"&&r.target.elementDescriptor?`Click and drag ${Bt(r.target)} by ${r.deltaX}px horizontally, ${r.deltaY}px vertically`:`Click and drag mouse by ${r.deltaX}px horizontally, ${r.deltaY}px vertically`;case"TYPE":{let n="";return r.target?.type==="coordinates"?n=` in element at coordinates: ${Bt(r.target)}`:r.target?.elementDescriptor.length?n=` in element: '${r.target.elementDescriptor}'`:r.cache?.target.nodeOnlySerializedHtml&&(n=` in element: '${r.cache?.target.nodeOnlySerializedHtml}'`),`Type '${r.value}'${n||""}`}case"HOVER":{let n="";return r.target.type==="coordinates"?n=` over coordinates: ${Bt(r.target)}`:r.target.elementDescriptor.length>0?n=` over element: '${r.target.elementDescriptor}'`:r.cache?.target.nodeOnlySerializedHtml&&(n=` over element: '${r.cache?.target.nodeOnlySerializedHtml}'`),`Hover${n}`}case"PRESS":return`Press ${r.value}`;case"KEY_DOWN":return`Hold down ${r.value} on the keyboard`;case"KEY_UP":return`Release ${r.value} on the keyboard`;case"SELECT_OPTION":{let n="",o=O0(r.choice);return r.target.type==="coordinates"?n=` from element at coordinates: ${Bt(r.target)}`:r.target.elementDescriptor.length>0?n=` from: '${r.target.elementDescriptor}'`:r.cache?.target.nodeOnlySerializedHtml&&(n=` from: '${r.cache?.target.nodeOnlySerializedHtml}'`),`Select option '${o}'${n}`}case"TAB":switch(r.action.type){case"SUBSTRING":return`Switch to tab with substring: ${r.action.substring}`;case"REGEX":return`Switch to tab matching regex: ${r.action.pattern}`;case"INDEX":return`Switch to tab at index: ${r.action.index}`;default:return(o=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(r.action)}return"Switch to unknown tab";case"NEW_TAB":return`Open new tab to: ${r.url}`;case"REQUEST":return`Send ${r.method} request to ${r.url}`;case"GRAPHQL_REQUEST":return`Send GraphQL request to ${r.url}`;case"COOKIE":return`Set cookie: ${r.value}`;case"LOCAL_STORAGE":return`Set local storage: ${r.key}: ${r.value}`;case"JAVASCRIPT":return`Run JavaScript: ${e?at(r.code,30):r.code}`;case"AI_ASSERTION":return`Assertion: '${r.assertion}'`;case"VISUAL_DIFF":return`Visual diff against baseline ${r.target?`for element: ${Bt(r.target)}`:"for entire page"}`;case"FILE_UPLOAD":return r.fileSource.type==="URL"?`Upload file: ${r.fileSource.url}`:`Upload file: ${r.fileSource.name}`;case"AUTH_LOAD":return"Load auth state";case"AUTH_SAVE":return"Save auth state";case"ELEMENT_CHECK":return`Check the element ${Bt(r.target)} ${M0(r.assertion)}`;case"PAGE_CHECK":return`Check the page ${L0(r.assertion)}`;case"WAIT_FOR_URL":return`Wait for page URL to ${Su(r.matcher)}`;case"COPY":return"Copy to clipboard";case"PASTE":return"Paste clipboard contents";case"REGISTER_REQUEST_LISTENER":return r.requestMatcher?`Register a listener for network requests that ${fu(r.requestMatcher)}`:"Register a listener for network requests";case"AWAIT_LISTENER":return r.key?`Wait for the listener ${r.key} to resolve`:"Wait for a listener to resolve";case"RECORD_REQUESTS":return r.requestMatcher?`Start recording requests that match ${fu(r.requestMatcher)}`:"Start recording network requests";case"GET_RECORDED_REQUESTS":return r.key?`Get the requests that were recorded for ${r.key}`:"Get the requests that were recorded";case"SET_HEADER":return r.name?r.requestMatcher?`Set a ${r.name} header for requests that match ${fu(r.requestMatcher)}`:`Set a ${r.name} header for all requests`:"Set a header";case"MOCK_ROUTE":return r.requestMatcher?`Mock requests that ${fu(r.requestMatcher)}`:"Mock a network route";case"REMOVE_ROUTE_MOCK":return r.key?`Remove the mock with key ${r.key}`:"Remove all route mocks";case"OFFLINE_MODE":return r.enable?"Enable offline mode":"Disable offline mode";default:return(n=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(r)}}function N0(r){return typeof r=="object"&&r!==null}function fn(r){if(Array.isArray(r))return r.map(fn);if(N0(r)){let e={};return Object.entries(r).forEach(([t,n])=>{n!==void 0&&(e[t]=fn(n))}),e}return r}function mv(r){let e=[];for(let t of r){t.sort((a,s)=>a.timestamp-s.timestamp);let n=[],o,i=1;for(let a of t)o&&o.text===a.text&&o.type===a.type&&JSON.stringify(o.args??null)===JSON.stringify(a.args??null)?i++:(o&&(i>1?o.args&&o.args.length?o.args.push(`(repeated ${i} times)`):o.text+=` (repeated ${i} times)`:n.push(o)),o=a,i=1);o&&n.push(o),e.push(n)}return e}import{cloneDeep as zse}from"lodash-es";import{cloneDeep as Qse}from"lodash-es";import{v4 as ale}from"uuid";import{cloneDeep as D0}from"lodash-es";import Ev from"truncate-json";import{v4 as hv}from"uuid";import{cloneDeep as Tle,unset as ble}from"lodash-es";function fo(r){switch(r.type){case"AI_ACTION":return`AI action: ${at(r.text,100)}`;case"AI_ACTION_DYNAMIC":return`AI action: ${at(r.text,100)}`;case"PRESET_ACTION":return Sn(r.command);case"MODULE":return`Module: ${r.id}`;case"RESOLVED_MODULE":return`Module: ${r.name}`;case"CONDITIONAL":return"Conditional step";case"SECTION":return`Section${r.description?`with goal: ${at(r.description,100)}`:""}`;default:return(t=>{throw new Error("You missed a case in the switch above")})(r)}}function di(r,e){return r.split(`
|
|
31
31
|
`).map(t=>" ".repeat(e)+t).join(`
|
|
@@ -4139,7 +4139,7 @@ Available pages:${JSON.stringify(n.map(i=>i.url))}`);if(!gi(o.url,this.logger)){
|
|
|
4139
4139
|
`),tokenLength:d}),u=[],d=0,p=m.length?[m[m.length-1].id]:[],h=!1);let g=c[l],f=Tt(g);d+=f,g.length>a&&(g=g.slice(0,a));let E=Array.from(g.matchAll(B_)).map(U=>U&&U.length>=3?{tagName:U[1],id:U[2]}:void 0).filter(U=>!!U),b=Array.from(g.matchAll(Cj)).map(U=>U&&(U[2]||U[4])).filter(U=>!!U);b.reverse();let C=g.replace(/ id="[0-9]+"/g,"");u.push(C);for(let U of E)p.push(U.id),m.push(U);for(let U of b){let V=m[m.length-1];V&&V.tagName===U&&m.pop()}let x=m.some(U=>_j.includes(U.tagName)),I=c[l+1]??"",M=Tt(I),W=Array.from(I.matchAll(B_)).map(U=>U&&U.length>2?U[1]:void 0).filter(U=>!!U),G=W.some(U=>G_.includes(U)),H=W.some(U=>xj.includes(U));d+M>=i&&(h=!0),d>=n&&(G&&!x||b.some(U=>Ij.includes(U)))&&(h=!0),d>=o&&H&&!x&&(h=!0),l++}return u.length&&s.push({ids:p,content:u.join(`
|
|
4140
4140
|
`),tokenLength:d}),s.forEach((g,f)=>{let y=g.ids[0],S=g.ids[g.ids.length-1];r.debug({tokenLength:g.tokenLength,minId:y,maxId:S},`Chunk for page filtering (index ${f+1}/${s.length})`)}),{chunks:s}}var Oj=75e4,ep=3e5,Lj=5e3;async function Oi(r){let{options:e,fixtures:t,screenshot:n}=r,{aiPageFiltering:o}=e,{logger:i,generator:a,orgId:s,signal:c}=t,l=r.tree,u=r.serializedTree,d=Tt(u);if(d>Oj)try{let p=Zd({serializedTree:u,options:{minChunkTokenCount:1e4,maxChunkTokenCount:1e5,acceptableChunkTokenCount:5e4,maxLineLength:4e3},logger:i});l=await Dj({...r,tokenLimit:ep-1e4,chunks:p.chunks}),u=l.serialize();let m=Tt(u);i.info({oldTokens:d,newTokens:m},"Filtered page using keywords"),d=m}catch(p){i.warn({err:p},"Error filtering page using keyword matching, using naive truncation"),l=l.pruneToSerializedCharLimit(ep*mo),u=l.serialize();let m=Tt(u);i.info({oldTokens:d,newTokens:m},"Filtered page using naive truncation"),d=m}if(d>ep)try{if(o){let p=Zd({serializedTree:u,options:z_,logger:i}),m=Mj();l=await j(Nj({...r,chunks:p.chunks,callId:m}),{milliseconds:12e3,signal:c}),u=l.serialize();let h=Tt(u);i.info({oldTokens:d,newTokens:h,langfuseCallId:m},"Filtered page using AI chunk ranking"),d=h}else{let p=Zd({serializedTree:u,options:H_,logger:i});l=await j(kj({...r,chunkResult:p,tokenLimit:4e4}),{milliseconds:12e3,signal:c}),u=l.serialize();let m=Tt(u);i.info({oldTokens:d,newTokens:m},"Filtered page using RAG"),d=m}}catch(p){i.warn({err:p},"Error filtering page using RAG/AI, using naive truncation"),l=l.pruneToSerializedCharLimit(ep*mo),u=l.serialize(),i.info("Filtered page using naive truncation")}if(o&&d>Lj&&r.type==="locator"&&(s==="org_01HMSCJQBCCG51M2ZF65YC5B8W"||s==="org_01HMJTX4GT1KG94KZRCT8MZ6YB"))try{let p=await a.getPageSummary({browserContext:u,currentStep:r.description,screenshot:n,type:r.type},{logger:i,loggerTags:We(i),abortSignal:c});if(i.info(p,"Got AI summaries"),p.category!=="OTHER"){let m=new Set;for(let g of p.relevantSections){let f=Math.min(g.startId,g.endId),y=Math.max(g.startId,g.endId);for(let S=f;S<=y;S++)m.add(S.toString())}l=l.pruneUsingRelevantIds(m),u=l.serialize();let h=Tt(u);i.info({newTokens:h,oldTokens:d},"Filtered page using AI summary"),d=h}}catch(p){i.warn({err:p},"Error filtering page using AI summary, continuing...")}return u}async function Nj({type:r,callId:e,chunks:t,description:n,fixtures:o,tree:i}){let{generator:a,signal:s,logger:c}=o,l=await a.rankChunksWithAi({chunks:t,description:n,type:r,softTokenLimit:4e4,hardTokenLimit:8e4,callId:e},{abortSignal:s,logger:c,loggerTags:We(c)}),u=[];return t.forEach((p,m)=>{l.indices.includes(m)&&(u=u.concat(p.ids))}),i.pruneUsingRelevantIds(new Set(u))}async function Dj(r){let{description:e,fixtures:t,tree:n}=r,{generator:o,logger:i,signal:a}=t;if(!e.trim())throw new Error("Empty description passed to page filtering");let s=await o.getExtractedKeywords({goal:e},{logger:i,loggerTags:We(i),abortSignal:a});i.info({keywordsResult:s},"Got keywords for page filtering");for(let c of s.keywords){let l=r.chunks.filter(m=>m.content.toLowerCase().includes(c.toLowerCase()));if(!l.length||l.reduce((m,h)=>m+h.tokenLength,0)>r.tokenLimit&&l.length>1)continue;let d=l.flatMap(m=>m.ids);return n.pruneUsingRelevantIds(new Set(d))}throw new Error("No keywords were unique enough for page filtering")}async function kj(r){let{description:e,fixtures:t,chunkResult:n,tokenLimit:o,tree:i}=r,{generator:a,logger:s,signal:c}=t,l=await a.rankChunksWithRag({description:e,chunks:n.chunks,tokenLimit:o},{abortSignal:c,logger:s,loggerTags:We(s)});if(l.ids.length===0)throw new Error("RAG returned no important ids");return i.pruneUsingRelevantIds(new Set(l.ids.map(d=>`${d}`)))}async function Qf(r,e){if(!r.description)throw new _("UserConfigurationError","Cannot locate element with empty description");return wn({action:async()=>Uj(r,e),frameConfig:r.iframeUrl?{type:"url",url:r.iframeUrl}:void 0,browser:e.browser,logger:r.logger})}async function Uj(r,e){let{disableCache:t,testContext:n,filterByViewport:o,skipWait:i,source:a,memory:s,aiPageFiltering:c,logger:l,allowNotActionableNodesOverride:u}=r,{ctx:d,orgId:p,browser:m,localCodeEvalTools:h,generator:g,abortSignal:f}=e,y=r.description,S=r.useMemory&&!t;n&&(y=await gr({orgId:p,s:y,context:n,localTools:h,signal:f,logger:l})),a&&(y=Bj(y,a));let{serializedTree:E,tree:A}=await _o(m,{allowNotActionableNodesOverride:u,filterByViewport:o,abortSignal:f,skipWait:i,logger:l}),b,C=Date.now(),x;for(;!b&&Date.now()-C<3e3;){f.throwIfAborted();try{b=await m.screenshot({clearHighlights:!0,respectActiveFrame:!0,retries:2})}catch(q){x=q}}if(!b)throw new _("ActionFailureError",`Failed to take screenshot of page to locate element. The page may be unresponsive, or your machine might be severely resource constrained. Error: ${x?.message}`);let I=E,M=!1,W=`data:image/jpeg;base64,${b.toString("base64")}`;I=await Oi({type:"locator",description:y,screenshot:W,serializedTree:E,options:{aiPageFiltering:c},tree:A,fixtures:{generator:g,signal:f,logger:l,orgId:p}}),I!==E&&(M=!0);let G=await g.getElementLocation({browserState:I,goal:y,screenshot:W,source:a,memory:S?s:void 0},{disableCache:t,abortSignal:f,loggerTags:We(l),useMemory:S});l.debug({usedRag:M,result:G},"Got locator result");let H=G.id>0;if(d?.details?.push({type:"AI_LOCATION",matched:H,pageState:I,ragUsed:M,thoughts:G.thoughts}),!H)throw new Ki(`Could not find any relevant element: ${G.thoughts}`,G.updatedMemory?{type:"GCS_TRACES",traces:G.updatedMemory}:void 0);let{resolution:U,target:V,frameConfig:me}=await m.createTargetFromA11yId({id:G.id,requirements:G.requirements,additionalElements:G.additionalElements,description:y,targetSource:"AI",logger:l});if(U.a11yNode?.properties?.hidden&&U.a11yNode?.properties?.hidden!=="false")throw new _("ActionFailureError",`Momentic's AI found a relevant element to interact with, but it is explicitly marked with an 'aria-hidden' attribute. Please remove this attribute or adjust the element description to locate a different element. Element chosen: ${U.displayString}`);return S&&(G.updatedMemory?V.memory={type:"GCS_TRACES",traces:G.updatedMemory}:s&&(V.memory=s)),{thoughts:G.thoughts,target:V,resolution:U,frameConfig:me,screenshot:W}}var Fj=["Element exactly matching the description below. Interpret the description narrowly and do not assume there are any typos or errors. Err on the side of returning -1 unless there is a perfect match. Description:","Element closely matching the description below. Interpret the description narrowly and do not return elements that are merely loosely related. Description:","Element matching the description below. This element is being located as part of a negative check step (i.e. we are trying to verify the element does not exist). Therefore, interpret the description narrowly, do not assume there are typos, and err on the side of returning -1 unless there is a perfect match. Description:"],j_="<select> element:",V_="text input or contenteditable element:",$_="Element matching the description below. It is possible the element is hidden or doesn't exist. Interpret the description narrowly and do not assume there are typos. Return -1 unless there is an straightforward match. Description:",W_="Element matching the description below. This element is being located as part of a check step (i.e. we are trying to verify certain properties about the element). Interpret the description narrowly and do not return elements that are merely loosely related. Description:",Jf=[j_,V_,$_,W_,...Fj];function q_(r,e){if(r===e)return!0;for(let t of Jf){if(!r.startsWith(t))continue;let n=r.slice(t.length).trim();if(Jf.some(o=>e.startsWith(o)&&e.slice(o.length).trim()===n)||n===e.trim())return!0}return!!Jf.some(t=>e.startsWith(t)&&e.slice(t.length).trim()===r.trim())}function Bj(r,e){if(!r||!e)return r;switch(e){case"SELECT_OPTION":return`${j_} ${r}`;case"TYPE":return`${V_} ${r}`;case"NEGATED_ELEMENT_VISIBLE_CHECK":return`${$_}
|
|
4141
4141
|
${r}`;case"ELEMENT_CHECK":return`${W_}
|
|
4142
|
-
${r}`;default:return r}}var Hj=15;async function tp({command:r,aiPageFiltering:e,logger:t,fixtures:n,source:o,useMemory:i,maxRetries:a=Hj}){if(!r.assertion.trim())throw new _("ActionFailureError","Assertion command is missing the assertion content");let{browser:s}=n,c=r.timeout?r.timeout*1e3:s.smartWaitingTimeout,l=tR(c),u=0,d=Date.now(),p,m,h;try{await wn({action:()=>s.clearHighlights(),frameConfig:r.iframeUrl?{type:"url",url:r.iframeUrl}:void 0,browser:s,logger:t})}catch(f){t.warn({err:f},"Failed to clear highlights before AI check, continuing...")}let g;for(;u<a&&(!g||g-d<c);){n.abortSignal.throwIfAborted(),u!==0&&await ie(l,n.abortSignal),g=Date.now();try{if(p=await wn({action:async()=>{let y=await K_(s,t,n.abortSignal);return m&&m.serializedTree===y.serializedTree&&m.screenshotBuff.equals(y.screenshotBuff)?p:(m=y,Y_({command:r,state:y,fixtures:n,useMemory:i,useConsensus:!1,highlightElementsOnFailure:!1,attemptNumber:u,aiPageFiltering:e,logger:t,source:o}))},frameConfig:r.iframeUrl?{type:"url",url:r.iframeUrl}:void 0,logger:t,browser:s}),p?.updatedMemory&&gu(r,p.updatedMemory,t),p?.success)break;throw p?.thoughts?new _("AssertionFailureError",p.thoughts):new _("InternalPlatformError","No thoughts were provided for AI assertion failure")}catch(f){n.abortSignal.throwIfAborted(),h=f instanceof Error?f:new Error(`${f}`),t.info({err:f},`AI check assert attempt ${u} failed, retrying...`)}finally{u++}}if(!p?.success)try{p=await wn({action:async()=>Y_({command:r,state:await K_(s,t,n.abortSignal),fixtures:n,useMemory:i,useConsensus:!0,highlightElementsOnFailure:!0,attemptNumber:u,aiPageFiltering:e,logger:t}),frameConfig:r.iframeUrl?{type:"url",url:r.iframeUrl}:void 0,logger:t,browser:s})}catch(f){n.abortSignal.throwIfAborted(),h=f instanceof Error?f:new Error(`${f}`)}finally{u++}if(!p?.success){let f=`AI check still failing after ${u} attempts.`;throw h&&(f+=` Latest result: ${h.message}`),new _("AssertionFailureError",f)}return{...p,succeedImmediately:!1,urlAfterCommand:s.url()}}async function K_(r,e,t){let[n,o]=await Promise.all([_o(r,{abortSignal:t,skipWait:!0,skipWaitForPageLoad:!0,logger:e}),r.screenshot({retries:1,respectActiveFrame:!0})]);return{...n,screenshotBuff:o}}async function Y_({command:r,state:e,fixtures:t,useConsensus:n,useMemory:o,highlightElementsOnFailure:i,aiPageFiltering:a,attemptNumber:s,source:c,logger:l}){let{browser:u,generator:d,abortSignal:p}=t,m={type:"ASSERTION"},{serializedTree:h,tree:g}=e,f=e.screenshotBuff,y=f.toString("base64"),S=u.url(),E=r.contextChoice??"MULTIMODAL",A=h;E!=="VISION_ONLY"&&(A=await Oi({type:"assertion",serializedTree:h,tree:g,description:r.assertion,screenshot:y,options:{aiPageFiltering:a},fixtures:{generator:d,signal:p,logger:l,orgId:t.orgId}}),A!==h&&(m.ragUsed=!0),m.pageState=A);let b={goal:r.assertion,url:S,memory:o?r.cache?.memory:void 0,browserState:A,screenshot:y,contextChoice:E,source:c},x=await(E==="VISION_ONLY"?(I,M)=>d.getVisualAssertionResult(I,M):(I,M)=>d.getAssertionResult(I,M))(b,{useConsensus:n,attemptNumber:s,useMemory:o,disableCache:!!r.disableCache,abortSignal:p,logger:l,loggerTags:We(l)});return(x.result||i)&&x.relevantElements&&(m.relevantElementsSerialized=x.relevantElements.map(I=>u.getSerializedFormFromA11yId(I)).filter(I=>!!I),await zj(x.relevantElements,u,l)),{success:x.result,thoughts:x.thoughts,afterScreenshotOverride:f,updatedMemory:o?x.updatedMemory:void 0}}async function zj(r,e,t){let n=Date.now();for(let o of r){if(Date.now()-n>2e3){t.debug("Highlighting relevant elements took over 2s, aborting...");return}try{let i=new AbortController;await j(e.highlightA11yId(o),{milliseconds:1e3,fallback:()=>{throw i.abort(),new Error("Timed out waiting for highlighting to complete")}})}catch(i){t.debug({err:i},"Failed to highlight relevant element after assertion, continuing...");return}}}var Gj=3e4;async function X_({command:r,logger:e,baseUrl:t,fetchImplementation:n=fetch}){let o=r.timeout??Gj/1e3,i=new AbortController,a=Object.fromEntries(Object.entries(r.headers||{}).filter(([d,p])=>d&&p));a["Content-Type"]="application/json";let s;if(ha(r.url)&&(s=r.url),t&&ga(r.url,t)&&(s=new URL(r.url,t).toString()),!s)throw new _("ActionFailureError",`Invalid URL: ${r.url}`);let l=await j((async()=>{try{return await n(s,{headers:a,method:"POST",body:JSON.stringify({query:r.query,variables:r.variables?JSON.parse(r.variables):void 0}),signal:i.signal})}catch(d){e.error({err:d},"Failed to make HTTP request")}})(),{milliseconds:o*1e3});if(!l)throw new _("ActionFailureError",`GraphQL request timed out after ${o} seconds`);if(!l.ok){let d,p=await l.text();try{d=JSON.parse(p)}catch{throw new _("ActionFailureError",`GraphQL request failed with status ${l.status}: ${p}`)}throw d?.errors?.length&&d?.errors[0]?.message?new _("ActionFailureError",`GraphQL request failed with status ${l.status}: ${d.errors[0].message}`):new _("ActionFailureError",`GraphQL request failed with status ${l.status}: ${p}`)}let u={};return l.headers.forEach((d,p)=>{u[p]=d}),{status:l.status,headers:u,json:await l.json()}}var Lo=class{orgId;options;storage;localCodeEvalTools;uploadedFileStorage;visualDiffScreenshotStorage;browser;generator;executeAbortController=new AbortController;logger;recordAbortController=null;registeredListeners={};recordedRequests={};constructor({browser:e,generator:t,logger:n,storage:o,orgId:i,localCodeEvalTools:a,uploadedFileStorage:s,visualDiffScreenshotStorage:c,options:l}){this.orgId=i,this.options=l,this.browser=e,this.browser.registerAbortSignal(this.executeAbortController.signal),this.storage=o,this.uploadedFileStorage=s,this.visualDiffScreenshotStorage=c,this.localCodeEvalTools=a,this.generator=t,this.logger=n}setOpen(){this.executeAbortController=new AbortController,this.browser.registerAbortSignal(this.executeAbortController.signal)}setClosed(){this.executeAbortController.abort()}throwIfClosed(){this.executeAbortController.signal.throwIfAborted()}get closed(){return this.executeAbortController.signal.aborted}async evaluateAiAction({goal:e,startingScreenshot:t,history:n,disableCache:o,langfuseSessionId:i,lastError:a,logger:s=this.logger}){let[c,l]=await Promise.all([_o(this.browser,{abortSignal:this.executeAbortController.signal,skipWait:!0,skipWaitForPageLoad:!0,logger:s}),this.browser.screenshot({retries:1,clearHighlights:!0})]),u=`data:image/jpeg;base64,${l.toString("base64")}`,d=await Oi({type:"ai-action",description:e,screenshot:u,serializedTree:c.serializedTree,tree:c.tree,options:{aiPageFiltering:!!this.options?.aiPageFiltering},fixtures:{generator:this.generator,signal:this.executeAbortController.signal,logger:s,orgId:this.orgId}}),p={url:this.browser.url(),browserState:d,startingScreenshot:t,history:n,goal:e,screenshot:u,lastError:a};return await this.generator.getMultiturnAiActionEvaluation(p,{disableCache:o,abortSignal:this.executeAbortController.signal,loggerTags:{...We(s)},langfuseSessionId:i})}async promptToCommand({goal:e,startingScreenshot:t,history:n,actionHint:o,disableCache:i,logger:a=this.logger,langfuseSessionId:s}){let c=this.browser.url(),[l,u]=await Promise.all([_o(this.browser,{abortSignal:this.executeAbortController.signal,skipWait:!0,skipWaitForPageLoad:!0,logger:a}),this.browser.screenshot({retries:1,clearHighlights:!0})]),d=`data:image/jpeg;base64,${u.toString("base64")}`,p=await Oi({type:"ai-action",description:e,screenshot:d,serializedTree:l.serializedTree,tree:l.tree,options:{aiPageFiltering:!!this.options?.aiPageFiltering},fixtures:{generator:this.generator,signal:this.executeAbortController.signal,logger:a,orgId:this.orgId}}),m={url:c,browserState:p,startingScreenshot:t,history:n,goal:e,actionHint:o,screenshot:d};try{return await this.generator.getMultiturnAiActionCommand(m,{disableCache:i,abortSignal:this.executeAbortController.signal,loggerTags:{...We(a)},langfuseSessionId:s})}catch(h){throw new _("InternalWebAgentError",`Error generating command: ${h instanceof Error?h.message:h}`,{errOptions:{cause:h}})}}async getBrowserState(e){return _o(this.browser,e)}async locateElement(e){return await Qf({...e,aiPageFiltering:!!this.options?.aiPageFiltering},this.getControllerFixtures())}async locateElementWithSelector(e,t){return wn({action:async()=>{let n=await this.browser.resolveHardcodedCssSelector({ctx:null,selector:e,timeoutMs:2e3,logger:this.logger});return{thoughts:"Located element with selector",target:{id:-1,selector:e,targetSource:"USER_CSS_SELECTOR",targetUpdateTime:new Date().toUTCString()},resolution:n}},frameConfig:t?{type:"url",url:t}:void 0,browser:this.browser,logger:this.logger})}getControllerFixtures(e){return{ctx:e??null,browser:this.browser,generator:this.generator,logger:this.logger,orgId:this.orgId,storage:this.storage,localCodeEvalTools:this.localCodeEvalTools,abortSignal:this.executeAbortController.signal}}shouldUseMemory(){return this.options?.useMemory??(this.orgId==="org_01HMSCJQBCCG51M2ZF65YC5B8W"||this.orgId==="org_01HMJTX4GT1KG94KZRCT8MZ6YB")}async wrapMultiElementTargetingCommand({ctx:e,tracer:t,command:n,targetNames:o,descriptions:i,caches:a,action:s,options:c,retriesWithAI:l=1}){let u=[];for(let d=0;d<i.length;d++){let p=i[d],m=await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:p,cache:a[d],action:async h=>h,options:{...c,targetName:o[d]}});u.push(m)}try{let d=await s(...u.map(h=>h.result)),p=h=>h==="fromTarget"?"From Target":h==="toTarget"?"To Target":"Target",m=u.map((h,g)=>h.thoughts?`${p(o[g])}: ${h.thoughts}`:void 0).filter(h=>!!h).join(" -------------- ")||void 0;return{result:d,elementInteractedDisplayStrings:u.map(h=>h.elementInteractedDisplayString),thoughts:m}}catch(d){if(this.throwIfClosed(),l>0)return this.logger.warn({err:d},"Failed to execute action with multiple cached targets, retrying with AI"),this.wrapMultiElementTargetingCommand({ctx:e,tracer:t,command:n,targetNames:o,descriptions:i,caches:i.map(()=>{}),action:s,options:c,retriesWithAI:l-1});throw new _("ActionFailureError",d.message,{errOptions:{cause:d}})}}async wrapElementTargetingCommand(e){let t=this.logger.child({commandId:e.command.id}),n;for(let o=0;o<2;o++)try{return await wn({action:()=>this.wrapElementTargetingCommandHelper({...e,originalCache:e.originalCache??e.cache}),frameConfig:e.options.iframeUrl?{type:"url",url:e.options.iframeUrl}:void 0,browser:this.browser,logger:t})}catch(i){if(n=i,this.browser.userBrowserSettings.visualActions&&am(i)){t.warn({err:i},"Invalid mpath error, retrying element targeting command");continue}if(!this.browser.userBrowserSettings.visualActions&&(lm(i)||sm(i))){t.warn({err:i},"Invalid momentic id error, retrying element targeting command");continue}if(cm(i)){t.warn({err:i},"Invalid backend node id error, retrying element targeting command");continue}if(i instanceof cn&&i.retryableWithAI){t.warn({err:i},"Element cache disqualification error, retrying element targeting command");continue}throw i}throw n instanceof _?n:new _("ActionFailureError",n?.message??"An unknown error occurred during element targeting")}async wrapHardcodedCssTargetingCommandHelper({ctx:e,target:t,action:n,options:o,command:i}){let a=this.logger.child({commandId:i.id}),{targetName:s}=o;if(t.type!=="description")throw new _("ActionFailureError","Cannot use selector with non-description target");let c,l=Date.now(),u=Date.now();for(;Date.now()-u<this.browser.smartWaitingTimeout;){l=Date.now();try{let d=await this.browser.resolveHardcodedCssSelector({ctx:e,selector:t.elementDescriptor,targetName:s,logger:a});return{result:await n({locator:d.locator}),elementInteractedDisplayString:d.displayString}}catch(d){if(d.name==="AbortError")throw d;c=d,a.warn({err:d},"Failed to action on hardcoded css selector"),Date.now()-l<500&&await ie(500)}}throw c}async wrapElementTargetingCommandHelper(e){let{ctx:t,tracer:n,target:o,originalCache:i,action:a,options:s,command:c}=e,{disableCache:l,useSelector:u,targetName:d,targetHealingInProgress:p,source:m}=s,h=this.logger.child({commandId:c.id}),g=this.shouldUseMemory(),f=s.retriesWithAI??1,y=!1,S=J_(e.cache);if((!S||l)&&!jp(o))throw new _("ActionFailureError","Cannot target element with no cached data or element descriptor");if(u)return this.wrapHardcodedCssTargetingCommandHelper(e);l&&(h.info("Cache explicitly disabled for this step"),y=!0,S=void 0),S&&this.browser.userBrowserSettings.disableSecondaryCacheResolution&&S.targetSource==="HEURISTIC_HEALED"&&(y=!0,S=void 0),S?.inputDescription&&!q_(o.elementDescriptor,S.inputDescription)&&(h.warn({old:S.inputDescription,new:o.elementDescriptor},"Target cache was generated with a different description, clearing it automatically"),y=!0,S=void 0);let E=b=>!!b&&tc(b),A=!0;if(!E(S)){A=!1,h.info({description:o.elementDescriptor,targetHealingInProgress:p,cacheBustedBeforeAction:y,memory:s.memory,useMemory:g},"Prompting AI for an updated element location"),y&&await ie(this.browser.smartWaitingTimeout,this.executeAbortController.signal),f--;let b;try{b=await Qf({description:o.elementDescriptor,disableCache:!!s.disableCache,iframeUrl:s.iframeUrl,source:m,useMemory:g,memory:g?s.memory:void 0,aiPageFiltering:!!this.options?.aiPageFiltering,allowNotActionableNodesOverride:s.allowNotActionableNodesOverride,logger:h},this.getControllerFixtures(t))}catch(I){if(I instanceof Ki&&I.updatedLocatorMemory){let M={id:-1,...i,memory:I.updatedLocatorMemory};hu({cmd:c,key:d,newTarget:M,logger:h,updatedWithAI:!0})}throw new _("ActionFailureError",I.message)}b.frameConfig&&this.browser.setActiveFrameConfig(b.frameConfig);let C=s.disableGlobalLocatorRedirect?{locator:b.resolution.locator}:await this.attemptLocatorRedirect(b.resolution.locator,h),x=await a(C);return hu({cmd:c,key:d,newTarget:b.target,logger:h,updatedWithAI:!0}),p&&(n.recordTargetAutoHeal({healType:"AI"}),b.target.targetSource="AI_HEALED",b.target.targetUpdateTime=new Date().toUTCString(),b.target.targetUpdateLoggerTags=We(h)),{result:x,elementInteractedDisplayString:b.resolution.displayString,thoughts:b.thoughts}}try{let b=await this.browser.resolveTarget(t,S,{allowNotActionableNodesOverride:s.allowNotActionableNodesOverride,targetName:d,logger:h,signal:this.executeAbortController.signal});(this.browser.userBrowserSettings.visualActions||this.browser.userBrowserSettings.globalLocatorRedirect!==!1)&&await this.browser.scrollIntoViewIfNeeded(b.locator);let C=s.disableGlobalLocatorRedirect?{locator:b.locator}:await this.attemptLocatorRedirect(b.locator,h),x=await a(C);if(tr.increment("cache_target_resolution_v2",1,["outcome:hit","platform:web",`hasRequirements:${!!S.requirements}`,`hasAdditionalElements:${!!S.additionalElements}`,`orgId:${this.orgId}`,"cliVersion:2.21.2"]),hu({cmd:c,key:d,newTarget:S,logger:h,updatedWithAI:!1}),A){let I=b.decisions.filter(M=>M.matched);if(I.length!==1)h.warn({decisions:b.decisions},"Expected exactly 1 matching method for element location, got more or less");else{let M=I[0].type;n.recordTargetAutoHeal({healType:M})}}return{result:x,elementInteractedDisplayString:b.displayString}}catch(b){this.throwIfClosed(),tr.increment("cache_target_resolution_v2",1,["outcome:miss","platform:web",`hasRequirements:${!!S.requirements}`,`hasAdditionalElements:${!!S.additionalElements}`,`orgId:${this.orgId}`,"cliVersion:2.21.2"]);let C=!1;if((b instanceof cn||am(b)||lm(b)||cm(b)||Xy(b)||sm(b))&&(C=!0),b instanceof _&&!C)throw h.error({err:b},"Failed to execute action with cached target (fatal)"),b;if(f>0&&o){h.info({err:b},"Failed to execute action with cached target, retrying with AI");let x;return S.memory&&rc(S.memory)&&(x=S.memory),this.wrapElementTargetingCommand({ctx:t,tracer:n,command:c,target:o,cache:void 0,originalCache:i,action:a,options:{...s,memory:x,retriesWithAI:f,targetHealingInProgress:!0}})}throw new _("ActionFailureError",b.message,{errOptions:{cause:b}})}}async attemptLocatorRedirect(e,t){return this.browser.userBrowserSettings.globalLocatorRedirect!==!1?this.browser.performTargetRedirection(e,t):{locator:e}}async screenshotWithDimensions(e){return ul(this.browser,e)}async executePresetCommand(e,t,n,o,i){this.options?.slowMoMs&&await ie(this.options.slowMoMs);let a=await this.browser.getOpenPages(),s=this.browser.url(),c;try{c=await this.resolveCommandTemplateStrings(n,o)}catch(l){throw this.throwIfClosed(),new _("ActionFailureError",`Failed to substitute template strings in command: ${l.message}`,{errOptions:{cause:l}})}try{let l=await this.executePresetCommandHelper(e,t,n,o,i);return this.browser.userBrowserSettings.visualActions&&dy(n)?await this.browser.waitForDOMStability({timeout:Ae}):!this.browser.userBrowserSettings.visualActions&&["PRESS","TYPE"].includes(n.type)&&await this.browser.waitForDOMStability({timeout:ae}),this.options?.autoFollowNewTabs&&await fx({beforeUrl:s,command:n,beforePages:a.map(u=>u.url),browser:this.browser,logger:this.logger}),l}catch(l){throw l.name!=="AbortError"&&this.logger.error({err:l},"Error thrown in action controller"),l}finally{zR(n,c)}}createCallbacksForBrowser(e){return{createIsolatedFolder:()=>Af(e)}}async resolveCommandTemplateStrings(e,t){return Hu({obj:e,context:t,bannedKeys:["type","a11yData","thoughts","cache","code"],orgId:this.orgId,logger:this.logger,signal:this.executeAbortController.signal,localTools:this.localCodeEvalTools})}async executePresetCommandHelper(e,t,n,o,i){i=i||"disableCache"in n&&!!n.disableCache;let a=this.logger.child({commandId:n.id});switch(n.type){case"SUCCESS":let s=n.condition;return s?.assertion.trim()?tp({command:s,fixtures:this.getControllerFixtures(e),useMemory:this.shouldUseMemory(),aiPageFiltering:!!this.options?.aiPageFiltering,logger:a}):{succeedImmediately:!1,urlAfterCommand:this.browser.url()};case"AI_ASSERTION":{if(!n.assertion.trim())throw new _("ActionFailureError","Missing assertion");if(n.timeout&&n.timeout>1800)throw new _("AssertionFailureError",`AI check timeout of ${n.timeout} exceeds the maximum allowed value of 30 minutes.`);return tp({command:n,fixtures:this.getControllerFixtures(e),useMemory:this.shouldUseMemory(),aiPageFiltering:!!this.options?.aiPageFiltering,logger:a})}case"AI_EXTRACT":{if(!n.goal.trim())throw new _("ActionFailureError","Cannot perform AI extraction without goal");if(n.schema){let f=Ub(n.schema);if(f)throw new _("UserConfigurationError",f)}let h=await this.browser.getCondensedHtml(),g=await this.browser.screenshot({retries:2});try{let f=await this.generator.getTextExtraction({goal:n.goal,browserState:h,returnSchema:n.schema,screenshot:`data:image/jpeg;base64,${g.toString("base64")}`},{disableCache:i,abortSignal:this.executeAbortController.signal,loggerTags:We(a)});if(f.result==="NOT_FOUND")throw new _("ActionFailureError","No relevant data found for extraction goal on this page");if(f.thoughts?.includes("MaxGenerationLengthExceededError"))throw new _("UserConfigurationError",f.thoughts);return{thoughts:f.thoughts||void 0,data:f.result,succeedImmediately:!1,urlAfterCommand:this.browser.url()}}catch(f){let y=f.message;throw y.includes("MaxGenerationLengthExceededError")?new _("UserConfigurationError","You tried to extract too much data. Please rephrase your query to limit the results returned or use a JavaScript step in the browser instead."):y.includes("AIProviderError")&&y.includes("time")?new _("AIProviderError","The AI provider responded with an error. This may be because you tried to extract too much data. Please limit extraction results to 2000 characters.",{errOptions:{cause:f}}):f}}case"NAVIGATE":if(!ha(n.url)&&!ga(n.url,this.browser.baseUrl))throw new _("ActionFailureError",`Invalid URL provided to navigate command: ${n.url}`);await this.browser.navigate({url:n.url,loadTimeoutMs:n.loadTimeout?n.loadTimeout*1e3:void 0});break;case"DIALOG":this.browser.registerDialogHandler(n.action);break;case"CAPTCHA":if(!this.browser.canSolveCaptchas())break;let c=await this.browser.solveCaptcha();c&&(await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:{type:"description",elementDescriptor:"the captcha image solution input"},cache:void 0,action:h=>this.browser.click(h,this.createCallbacksForBrowser(this.orgId),{}),options:{...n,targetName:"target",disableCache:i}}),await this.browser.type(c,{clearContent:!0,pressEnter:!0},!0));break;case"GO_BACK":await this.browser.goBack();break;case"GO_FORWARD":await this.browser.goForward();break;case"SCROLL_LEFT":case"SCROLL_RIGHT":case"SCROLL_DOWN":case"SCROLL_UP":{let h,g;if(n.target&&on(n.target))await this.browser.hoverUsingVisualCoordinates(n.target.pixels);else if(n.target&&n.target.elementDescriptor.trim()){let{elementInteractedDisplayString:S,thoughts:E}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:n.target,cache:n.cache?.target,action:A=>this.browser.hover(A),options:{...n,targetName:"target",disableGlobalLocatorRedirect:!0,disableCache:i}});h=S,g=E}let f=this.browser.getViewport()?.height??Gt.height,y=this.browser.getViewport()?.width??Gt.width;switch(n.type){case"SCROLL_UP":await this.browser.scrollVertical(-(n.deltaY??f));break;case"SCROLL_DOWN":await this.browser.scrollVertical(n.deltaY??f);break;case"SCROLL_LEFT":await this.browser.scrollHorizontal(-(n.deltaX??y));break;case"SCROLL_RIGHT":await this.browser.scrollHorizontal(n.deltaX??y);break}return{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:h,thoughts:g}}case"WAIT_FOR_URL":{if(n.timeout&&n.timeout>1800)throw new _("UserConfigurationError",`Wait for URL timeout of ${n.timeout} exceeds the maximum allowed value of 30 minutes.`);let h=n.matcher;await this.browser.waitForUrl({beforeUrl:this.browser.url(),matcher:h},{timeout:n.timeout?n.timeout*1e3:void 0,negated:n.negated,caseInsensitive:n.caseInsensitive});break}case"WAIT":if(n.delay>1800)throw new _("UserConfigurationError",`Wait timeout of ${n.delay} seconds exceeds the maximum allowed value of 30 minutes`);let l=n.delay*1e3;await ie(l,this.executeAbortController.signal);break;case"REFRESH":await this.browser.refresh({loadTimeoutMs:n.loadTimeout?n.loadTimeout*1e3:void 0});break;case"CLICK":{if(on(n.target)){await this.browser.clickUsingVisualCoordinates(n.target.pixels,n);break}let h=this.browser.url(),{elementInteractedDisplayString:g,result:f,thoughts:y}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,target:n.target,command:n,cache:n.cache?.target,action:E=>this.browser.click(E,this.createCallbacksForBrowser(this.orgId),n),options:{disableCache:i,targetName:"target",...n}}),S={urlAfterCommand:this.browser.url(),succeedImmediately:!1,elementInteracted:g,thoughts:y,data:f.downloadedFile?{downloadedFile:f.downloadedFile}:void 0};return Iu(h,S.urlAfterCommand)&&(S.succeedImmediately=!0,S.succeedImmediatelyReason="URL changed"),S}case"COPY":return await this.browser.copy(n.value),{succeedImmediately:!1,data:n.value,urlAfterCommand:this.browser.url()};case"PASTE":{await this.browser.paste();break}case"DRAG":{if(on(n.fromTarget)&&on(n.toTarget)){await this.browser.dragAndDropUsingVisualCoordinates(n.fromTarget.pixels,n.toTarget.pixels,{hoverSeconds:n.hoverSeconds});break}if(on(n.fromTarget)||on(n.toTarget))throw new Error("Drag and drop targets must be both coordinates or both descriptions");let{elementInteractedDisplayStrings:h,thoughts:g}=await this.wrapMultiElementTargetingCommand({ctx:e,tracer:t,command:n,targetNames:["fromTarget","toTarget"],descriptions:[n.fromTarget,n.toTarget],caches:[n.cache?.fromTarget,n.cache?.toTarget],action:(f,y)=>this.browser.dragAndDrop(f.locator,y.locator,{hoverSeconds:n.hoverSeconds,steps:n.steps}),options:{useSelector:!!n.useSelector,disableCache:i}});return{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:h[0],thoughts:g}}case"MOUSE_DRAG":{let h=parseInt(n.deltaX),g=parseInt(n.deltaY),f=n.steps??5;if(isNaN(h)||isNaN(g))throw new _("ActionFailureError",`Invalid pixel values passed to mouse drag command: (${n.deltaX}, ${n.deltaY})`);if(n.target&&on(n.target)){await this.browser.mouseDragUsingVisualCoordinates(h,g,f,n.target.pixels,{force:n.force});break}let y,S,E;if(n.target?.elementDescriptor){let{elementInteractedDisplayString:A,result:b,thoughts:C}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:n.target,cache:n.cache?.target,action:async x=>x.locator,options:{disableCache:i,targetName:"target",...n}});y=b,S=A,E=C}return await this.browser.mouseDrag(h,g,f,y,{force:n.force}),{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:S,thoughts:E}}case"SELECT_OPTION":{if(!Zn(n.target))throw new Error("Select with x/y is not supported yet");let h=n.target.elementDescriptor,g=n.choice,{elementInteractedDisplayString:f,thoughts:y}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:{type:"description",elementDescriptor:h},cache:n.cache?.target,action:S=>this.browser.selectOption(S,g,n.force),options:{...n,targetName:"target",disableCache:i,source:Jo(n)}});return{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:f,thoughts:y}}case"TAB":{let h={loadTimeoutMs:n.loadTimeout?n.loadTimeout*1e3:void 0,retry:!0};await this.browser.switchToPage(n.action,h);break}case"NEW_TAB":await this.browser.createNewTab(n.url,{loadTimeoutMs:n.loadTimeout?n.loadTimeout*1e3:void 0});break;case"COOKIE":if(!n.value)break;let u=await this.browser.setCookie(n.value);a.debug({results:u},"Set cookies");break;case"LOCAL_STORAGE":if(!n.value||!n.key)break;await this.browser.setLocalStorage(n.key,n.value);break;case"JAVASCRIPT":{let h;try{n.environment==="BROWSER"?(h=await this.browser.evaluateCodeInPage({code:n.code,fragment:n.fragment??!1,context:o.toObjectCopy(),timeoutMs:n.timeout?n.timeout*1e3:void 0}),a.info({result:h},"Executed JavaScript in browser")):h=await bo({orgId:this.orgId,code:n.code,fragment:!!n.fragment,context:o,timeoutMs:n.timeout?n.timeout*1e3:void 0,logger:a,localTools:this.localCodeEvalTools,signal:this.executeAbortController.signal,callbacks:{onPersistentVariableUpdates:async g=>{if(!this.options?.scratchPadId){a.warn({updates:g},"Got persistent variable updates but scratch pad is not available");return}await this.storage.savePersistentVariables?.({scratchPadId:this.options?.scratchPadId,orgId:this.orgId,updates:g,logger:a})}}})}catch(g){throw this.throwIfClosed(),new _("ActionFailureError",g instanceof Error?g.message:`${g}`,{errOptions:{cause:g}})}try{JSON.stringify(h)}catch(g){throw new _("ActionFailureError",`Return value is not serializable: ${g instanceof Error?g.message:`${g}`}`,{errOptions:{cause:g}})}return{urlAfterCommand:this.browser.url(),succeedImmediately:!1,data:h}}case"TYPE":{if(n.target&&on(n.target)){await this.browser.clickUsingVisualCoordinates(n.target.pixels,n),await this.browser.type(n.value,{force:n.force,clearContent:n.clearContent,forceClearContent:n.forceClearContent,delay:n.delay,pressEnter:n.pressEnter},!0);break}let h=this.browser.url(),g,f,y=J_(n.target),S=this.browser.userBrowserSettings.globalLocatorRedirect===void 0||this.browser.userBrowserSettings.globalLocatorRedirect==="always";if(y){let{elementInteractedDisplayString:A,thoughts:b}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:y,cache:n.cache?.target,action:C=>this.browser.typeIntoTarget(n.value,C,{force:n.force,clearContent:n.clearContent,forceClearContent:n.forceClearContent,delay:n.delay,pressEnter:n.pressEnter,relativePosition:n.relativePosition}),options:{...n,targetName:"target",disableCache:i,disableGlobalLocatorRedirect:!S,source:Jo(n)}});g=A,f=b}else await this.browser.type(n.value,{force:n.force,clearContent:n.clearContent,forceClearContent:n.forceClearContent,delay:n.delay,pressEnter:n.pressEnter},!0);let E={urlAfterCommand:this.browser.url(),succeedImmediately:!1,elementInteracted:g,thoughts:f};return Iu(h,E.urlAfterCommand)&&(E.succeedImmediately=!0,E.succeedImmediatelyReason="URL changed"),E}case"HOVER":{if(on(n.target)){await this.browser.hoverUsingVisualCoordinates(n.target.pixels);break}let{elementInteractedDisplayString:h,thoughts:g}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:n.target,cache:n.cache?.target,action:f=>this.browser.hover(f),options:{...n,targetName:"target",disableCache:i}});return{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:h,thoughts:g}}case"FOCUS":{if(!Zn(n.target))throw new Error("Focus with x/y is not supported yet");let{elementInteractedDisplayString:h,thoughts:g}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:n.target,cache:n.cache?.target,action:f=>this.browser.focus(f),options:{...n,targetName:"target",disableCache:i}});return{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:h,thoughts:g}}case"BLUR":{if(n.target&&!Zn(n.target))throw new Error("Blur with x/y is not supported yet");if(!n.target||!n.target.elementDescriptor)return await this.browser.blur(null),{succeedImmediately:!1,urlAfterCommand:this.browser.url()};let{elementInteractedDisplayString:h,thoughts:g}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,target:n.target,command:n,cache:n.cache?.target,action:f=>this.browser.blur(f),options:{...n,targetName:"target",disableCache:i}});return{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:h,thoughts:g}}case"PRESS":let d=this.browser.url();await this.browser.press(n.value,{repeat:n.repeat,convertMeta:n.convertMeta??!0,delayMs:n.delayMs});let p={urlAfterCommand:this.browser.url(),succeedImmediately:!1};return Iu(d,p.urlAfterCommand)&&(p.succeedImmediately=!0,p.succeedImmediatelyReason="URL changed"),p;case"KEY_DOWN":return await this.browser.keyDown(n.value,{convertMeta:n.convertMeta??!0}),{urlAfterCommand:this.browser.url(),succeedImmediately:!1};case"KEY_UP":return await this.browser.keyUp(n.value,{convertMeta:n.convertMeta??!0}),{urlAfterCommand:this.browser.url(),succeedImmediately:!1};case"REQUEST":{let h=new Vj,g=jj(fetch,h),f;try{f=new URL(n.url).hostname}catch{}return{data:{...await KR({command:n,baseUrl:this.browser.baseUrl,logger:a,fetchImplementation:g}),cookies:tT(h,f)},succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"GRAPHQL_REQUEST":return{data:await X_({command:n,baseUrl:this.browser.baseUrl,logger:a}),succeedImmediately:!1,urlAfterCommand:this.browser.url()};case"VISUAL_DIFF":return qR({ctx:e,tracer:t,command:n,disableCache:i,browser:this.browser,logger:a,storage:this.storage,screenshotStorage:this.visualDiffScreenshotStorage,targetingWrapper:h=>this.wrapElementTargetingCommand(h)});case"FILE_UPLOAD":{let h,g;if(n.fileSource.type==="URL"?(g=n.fileSource.url,h=await Ox({uri:n.fileSource.url,logger:a,orgId:this.orgId})):n.fileSource.type==="USER_FILE"&&(g=n.fileSource.name,h=await this.uploadedFileStorage?.getFileForUpload(n.fileSource.name,this.orgId)),!h)throw new _("UserConfigurationError",`Attempted to use non-existent file for upload step: ${g}`);await this.browser.setFileChooserHandler({...h,filename:n.filename});break}case"AUTH_SAVE":return{data:await this.browser.saveAuthState(),succeedImmediately:!1,urlAfterCommand:this.browser.url()};case"AUTH_LOAD":{let h;if(!n.storageState.trim())h=void 0;else if(h=await bo({orgId:this.orgId,code:n.storageState,fragment:!1,context:o,logger:a,localTools:this.localCodeEvalTools,signal:this.executeAbortController.signal}),typeof h!="object")throw new _("ActionFailureError",`Credentials must evaluate to an object (received ${typeof h} instead)`);let g;try{g=Hc.optional().parse(h)}catch(f){throw new _("ActionFailureError",`Credentials provided do not follow the required format: ${f}`)}await this.browser.loadAuthState(g);break}case"ELEMENT_CHECK":{let h=(n.timeout??an)*1e3,g=this.generator.getAgentConfig()?.assertion;if($R(n.assertion)&&!n.useSelector&&n.target.type==="description"&&g&&g!=="v1"){let y={id:n.id,type:"AI_ASSERTION",assertion:`There is no element on the page closely matches the following description. If the description has single quotes, remember that requires an exact text substring match. Description: ${n.target.elementDescriptor}`,iframeUrl:n.iframeUrl,timeout:n.timeout,cache:n.cache&&"memory"in n.cache?{memory:n.cache?.memory}:void 0};try{let S=await tp({command:y,logger:a,aiPageFiltering:!!this.options?.aiPageFiltering,fixtures:this.getControllerFixtures(e),useMemory:this.shouldUseMemory(),source:"NEGATED_CHECK"});return{succeedImmediately:!1,thoughts:`The element described does not exist on the page: ${S.thoughts}`,urlAfterCommand:this.browser.url(),afterScreenshotOverride:S.afterScreenshotOverride}}finally{y.cache?.memory&&gu(n,y.cache?.memory.traces,a)}}let f=await VR({command:n,tracer:t,timeoutMs:h,targetingWrapper:y=>this.wrapElementTargetingCommand(y),fixtures:this.getControllerFixtures(e),disableCache:i});return{fail:!f.success,data:f.data,elementInteracted:f.elementInteractedDisplayString,thoughts:f.err?.message??f.thoughts??`Element assertion ${f.success?"succeeded":"failed"}.`,succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"PAGE_CHECK":{let h=await wn({action:async()=>Gu({assertion:n.assertion,browser:this.browser,logger:a,timeout:n.timeout,signal:this.executeAbortController.signal,autoExpandIframes:!!this.browser.userBrowserSettings.autoExpandIframes}),frameConfig:n.iframeUrl?{type:"url",url:n.iframeUrl}:void 0,browser:this.browser,logger:a});return{fail:!h.success,data:h.data,thoughts:h.success?"Page assertion passed.":h.err?.message??`Page assertion still failing after ${n.timeout} seconds.`,urlAfterCommand:this.browser.url(),succeedImmediately:!1}}case"REGISTER_REQUEST_LISTENER":{let h=new Po(n.requestMatcher),g=this.browser.registerRequestListener(h);return this.registeredListeners[n.key]=g.then(async f=>await Pf(f)).catch(f=>{a.error({err:f},"Failed to get request listener response")}),{succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"AWAIT_LISTENER":{let h=this.registeredListeners[n.key];if(!h)throw new _("ActionFailureError",`No listener registered with key: ${n.key}`);let g=n.timeout??10;return{data:await j(h,{milliseconds:g*1e3,message:`Request listener timed out after ${g} seconds`}),succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"RECORD_REQUESTS":{let h=new Po(n.requestMatcher);return this.recordedRequests[n.key]={},this.browser.registerRequestRecorder(n.key,h,{onRequestStart:(g,f)=>{this.recordedRequests[n.key][g]=Vd(f)},onRequestComplete:(g,f)=>{this.recordedRequests[n.key][g]=Vd(f)}}),{succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"GET_RECORDED_REQUESTS":{let h=this.recordedRequests[n.key];if(!h)throw new _("ActionFailureError",`No recorder registered with key: ${n.key}`);return delete this.recordedRequests[n.key],{data:Object.values(h),succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"SET_HEADER":{let h;return n.requestMatcher&&(h=new Po(n.requestMatcher)),this.browser.setHeader(n.name,n.value,h),{succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"MOCK_ROUTE":return{data:{key:this.browser.registerMock(n.key,new Po(n.requestMatcher),async(g,f)=>{let y=await bo({orgId:this.orgId,code:n.responseGenerator,fragment:!1,context:o,timeoutMs:void 0,logger:a,localTools:this.localCodeEvalTools,mock:{request:g,response:f},disallowVariableUpdates:!0,responseSerialization:"RESPONSE"}),S=pT.parse(y);return new Response(S.body,{status:S.status,headers:S.headers})},n.fetchOriginalResponse??!1)},succeedImmediately:!1,urlAfterCommand:this.browser.url()};case"REMOVE_ROUTE_MOCK":return this.browser.removeMock(n.key),{succeedImmediately:!1,urlAfterCommand:this.browser.url()};case"OFFLINE_MODE":return await this.browser.setOfflineMode(n.enable),{succeedImmediately:!1,urlAfterCommand:this.browser.url()};default:return(h=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(n)}return{succeedImmediately:!1,urlAfterCommand:this.browser.url()}}async getReverseMappedDescription({browserState:e,targetId:t,disableCache:n,screenshot:o}){return(await this.generator.getReverseMappedDescription({browserState:e,target:t,screenshot:o},{disableCache:n,abortSignal:this.executeAbortController.signal,loggerTags:We(this.logger)})).phrase}async stopRecordMode(){this.recordAbortController?.abort(),await this.browser.clearAllCdpHighlights()}async startRecordMode({params:e,abortController:t,isClickToRecord:n}){this.recordAbortController=t;let o=new Xd({signal:t.signal,...e});return await this.browser.startRecording(this.recordAbortController.signal,o,n),o}async runSectionAutohealing(e){return this.generator.getAutohealingProposal(e,{disableCache:!0,abortSignal:this.executeAbortController.signal,loggerTags:We(this.logger)})}async getFailureRecoveryPlan(e){return this.generator.getFailureRecoveryPlan(e,{disableCache:!0,abortSignal:this.executeAbortController.signal,loggerTags:We(this.logger)})}};import{cloneDeep as $j}from"lodash-es";var Wj={showOverlay:!1},rp=class{sessions=new Map;sessionCountByIp=new Map;getCurrentConnectionsByIp(e){return this.sessionCountByIp.get(e)??0}getCurrentSessionsByIp(){return Object.fromEntries(this.sessionCountByIp)}reserveCapacityByIp(e){e&&this.sessionCountByIp.set(e,(this.sessionCountByIp.get(e)??0)+1)}releaseCapacityByIp(e){e&&this.sessionCountByIp.set(e,Math.max(this.getCurrentConnectionsByIp(e)-1,0))}registerSession({controller:e,context:t,cleanup:n,clientIp:o,sessionId:i,socket:a}){return this.sessions.set(i,{controller:e,context:t,cleanup:n,clientIp:o,browserBehavior:$j(Wj),socket:a}),i}removeSession(e,t){(async()=>{let o=this.sessions.get(e);if(!o)return;this.releaseCapacityByIp(o.clientIp);let{controller:i}=o;try{i.setClosed(),await i.browser.cleanup()}catch(a){t.error({err:a},"Error cleaning up browser in global state manager")}try{await o.cleanup?.()}catch(a){t.error({err:a},"Error running cleanup function in global state manager")}this.sessions.delete(e)})()}getSession(e){return this.sessions.get(e)}};function Q_(r,e,t,n){let o=Date.now(),i=Date.now(),a,s,c,l,u=!1,d=async(g,f)=>{if(!g.closed&&!g.isInPageLoad)try{let y=c;c=void 0;let S=g.url(),E=f.toEditorDisplayCopy();JSON.stringify(E)===JSON.stringify(a)&&S===l&&o>i||(r.emit("browserState",{logsPerPage:y?.logsPerPage,harPages:y?.harPages,harEntries:y?.harEntries,viewport:g.getViewport(),url:S,iframeSrcUrls:s??[],context:E,isInPageLoad:g.isInPageLoad}),o=Date.now()),l=S,a=E}catch(y){if(!r.connected)return;let S=y instanceof Error?y.message:`${y}`;if(S.includes("Frame was detached")||S.includes("Not attached to an active page")||S.includes("browser has been closed")||S.includes("UserInfrastructureError"))return;t.error({err:y,sessionId:e},"Error grabbing browser state")}},p=setInterval(()=>{let g=n.getSession(e),f=g?.controller?.browser;if(!f||f.closed){t.debug("Clearing browser state socket cron due to the browser being closed"),clearInterval(p);return}d(f,g.context)},1e3),m=(g,f)=>!!(JSON.stringify(g)!==JSON.stringify(s)||f.logsPerPage.some(y=>y.length>0)||f.harPages&&Object.keys(f.harPages).length>0||f.harEntries&&Object.keys(f.harEntries).length>0),h=setInterval(async()=>{let f=n.getSession(e)?.controller?.browser;if(!f||f.closed){clearInterval(h);return}else if(u)return;u=!0;try{let y=await f.getAllFrameUrls(),S=f.retrieveAndClearDebugData();m(y,S)&&(s=y,c=S,i=Date.now())}catch(y){t.warn({err:y},"Failed to fetch extended details")}finally{u=!1}},2500);return{timers:[p,h]}}var qj=4;async function Z_({socket:r,logger:e,storageFactory:t,uploadedFileStorage:n,visualDiffScreenshotStorage:o,devicePixelRatio:i,generatorFactory:a,enricherFactory:s,authorization:c,settingsFactory:l,getOrgId:u,branchGetter:d,globalE2eStateManager:p}){let m=r.id,h=r.handshake.query.testId;if(!h)throw new Error("Socket connection request is missing testId");let g=await u({type:"e2e",testId:h}),f=await d?.();e=e.child({testId:h,orgId:g,sessionId:m,branch:f});let y=await a(g,e),S=await s(g,e),E=await l(g,e),A=await t(g),{testMetadata:b,baseUrl:C,envName:x,browserConfig:I,aiSettings:M,environmentVariables:X,localCodeEvalTools:W}=await Li({testId:h,orgId:g,logger:e,storage:A,authorization:c,settings:E}),G=p.getSession(m);if(G)return e.info("Associating connection with existing session (likely reconnect)"),await G.controller.browser.clearAllCdpHighlights(),{type:"e2e",sessionId:m,orgId:g,testId:h};let H=r.handshake.headers["x-forwarded-for"]?.split(",")[0];if(e.info({clientIp:H,event:"connect",args:r.handshake.query},"Websocket event (connect)"),H&&p.getCurrentConnectionsByIp(H)>=qj)throw e.error({clientIp:H,sessions:p.getCurrentSessionsByIp(),...r.handshake.query},"Socket connection browser creation rate limit triggered"),new Error("You have exceeded the maximum number of connections allowed. Momentic limits the number of simultaneously open tabs to uphold browser reliability. Please close duplicate tabs and try again later.");p.reserveCapacityByIp(H);try{await Kj({socket:r,baseUrl:C,envName:x,testMetadata:b,orgId:g,sessionId:m,logger:e,environmentVariables:X,clientIp:H,devicePixelRatio:i,storage:A,uploadedFileStorage:n,visualDiffScreenshotStorage:o,localCodeEvalTools:W,generator:y,enricher:S,browserConfig:I,aiSettings:M,globalE2eStateManager:p})}catch(U){throw e.warn({err:U},"Error setting up socket session, possibly due to client closing the connection"),p.releaseCapacityByIp(H),U}return{type:"e2e",sessionId:m,testId:h,orgId:g}}async function Kj({socket:r,baseUrl:e,envName:t,devicePixelRatio:n,testMetadata:o,orgId:i,sessionId:a,logger:s,storage:c,uploadedFileStorage:l,visualDiffScreenshotStorage:u,localCodeEvalTools:d,generator:p,environmentVariables:m,browserConfig:h,aiSettings:g,clientIp:f,enricher:y,globalE2eStateManager:S}){let E={viewport:o.advanced?.viewport??Gt,locale:o.advanced?.locale??oo,timezoneId:o.advanced?.timezone??io,geolocation:o.advanced?.geolocation??ao,colorScheme:o.advanced?.colorScheme};n&&(E.deviceScaleFactor=n);let A=o.id,b=await zd({settings:h,orgId:i,baseUrl:e,envName:t,testName:o.name,localTools:d,envVariables:m,logger:s,customHeaders:void 0});s=s.child({orgId:i,sessionId:a,testId:A});let C=await Ur.init({baseUrl:e,userBrowserSettings:b,enricher:y,storage:c,logger:s,contextArgs:E,iconKnowledgeBase:null,callbacks:{onTabsChange:(W,G)=>{r.emit("tabs",{tabs:W,activeTab:G})},onScreencastFrame:(W,G)=>{let H=r;dn&&(H=r.compress(!0)),H.emit("screenshot",{buffer:W},()=>{G()})},onSvgsCollected:W=>{r.emit("newIconDetected",{numIcons:W.newSvgs.length}),c.saveNewIcons(W,s)}}});await C.navigate({url:e,initialNavigation:!0});let x=new Lo({browser:C,generator:p,logger:s,orgId:i,options:{scratchPadId:void 0,slowMoMs:b.slowMoMs,autoFollowNewTabs:b.autoFollowNewTabs,useMemory:g.useMemory,aiPageFiltering:g.aiPageFiltering},storage:c,localCodeEvalTools:d,uploadedFileStorage:l,visualDiffScreenshotStorage:u}),I=Q_(r,a,s,S),M=async()=>{I.timers.forEach(W=>clearInterval(W))},X=new ir({baseUrl:e,testName:o.name,currentUrl:x.browser.url(),variablesFromEnvironment:m,envName:t});if(!r.connected)throw await C.cleanup(),new Error("Socket not connected anymore, not proceeding with session setup");r.emit("session",{url:e,userAgent:Ur.USER_AGENT,viewport:x.browser.getViewport(),sessionId:a}),S.registerSession({controller:x,context:X,sessionId:a,cleanup:M,clientIp:f,socket:r})}async function Li({testId:r,orgId:e,logger:t,storage:n,authorization:o,settings:i}){let a=await n.fetchTestMetadata(r,t);if(!a)throw new Error(`Test metadata could not found for test ${r}`);let s;o?.type==="API_KEY"&&(s=new gn({httpClient:new Nt({...o,logger:t}),fakerSeed:void 0}));let c=a.envs?.find(g=>g.default),l;c&&(l=await n.fetchEnvironment(c.name,t));let u=l&&"browser"in l?l.browser:void 0,d={...i.browser,...u,...a.advanced},p=a.baseUrl||l?.variables?.[Ct];if(!p)throw new Error("Base URL is empty in both test options and the configured environment");let m={...l?.variables};await Promise.all((a.parameters??[]).map(async g=>{let f=await gr({orgId:e,s:g.defaultValue,context:ir.dummyContext(a.name,l?.name,m),logger:t,localTools:s});m[g.name]=f}));let h={...i.ai,...a.advanced};return{localCodeEvalTools:s,baseUrl:p,envName:l?.name,testName:a.name,browserConfig:d,environmentVariables:m,testMetadata:a,aiSettings:h}}var Zf=class{parentTracer=null;socket;step;orgId;constructor({step:e,socket:t,parentTracer:n,orgId:o}){this.socket=t,this.parentTracer=n,this.step=e,this.orgId=o}getParentStepIdChain(){return this.parentTracer?this.parentTracer?.getParentStepIdChain()??[]:[]}recordStepDuration(e){let t=e.step.type!=="PRESET_ACTION"?e.step.type:e.step.command.type;tr.distribution("test_step_duration",e.durationMs,[`type:${t}`,"platform:browser","executor:editor",`orgId:${this.orgId}`])}attachBeforeScreenshot(){}attachAfterScreenshot(){}attachBeforeHtmlSnapshot(){}attachAfterHtmlSnapshot(){}recordTargetAutoHeal(){}async finish(e){switch(e.step.status){case"SUCCESS":this.socket.emit("success",{...e,parentStepIdChain:this.getParentStepIdChain()});return;case"FAILED":this.socket.emit("failure",{...e,parentStepIdChain:this.getParentStepIdChain()});return;case"CANCELLED":this.socket.emit("cancelled",{...e,parentStepIdChain:this.getParentStepIdChain()});return}}async startSubSteps(){return new $n({parentStep:this.step,socket:this.socket,parentTracer:this,orgId:this.orgId})}},$n=class{stepFrequenciesByType={};parentTracer;parentStep;socket;orgId;recordStepStat(e){e.type!=="PRESET_ACTION"?this.stepFrequenciesByType[e.type]=(this.stepFrequenciesByType[e.type]||0)+1:this.stepFrequenciesByType[e.command.type]=(this.stepFrequenciesByType[e.command.type]||0)+1}sendFinalizedStepStats(){for(let[e,t]of Object.entries(this.stepFrequenciesByType))tr.increment("test_step_execution",t,[`type:${e}`,"platform:browser","executor:editor",`orgId:${this.orgId}`])}constructor({parentStep:e,socket:t,parentTracer:n,orgId:o}){this.parentTracer=n,this.parentStep=e,this.socket=t,this.orgId=o}async getScreenshot(){throw new Error("getScreenshot is not supported in the editor")}async getHtmlSnapshot(){throw new Error("getHtmlSnapshot is not supported in the editor")}getParentStepIdChain(){return this.parentStep?[...this.parentTracer?.getParentStepIdChain()??[],this.parentStep.id]:[]}async startStep(e){return this.recordStepStat(e.step),this.socket.emit("started",{stepId:e.step.id,parentStepIdChain:this.getParentStepIdChain(),attempt:e.attempt}),new Zf({step:e.step,parentTracer:this,socket:this.socket,orgId:this.orgId})}async finish(){this.sendFinalizedStepStats()}},np=class{constructor(e,t,n,o,i){this.socket=e;this.storage=t;this.orgId=n;this.testId=o;this.stepsBeforeRun=i}children=[];loggerBindings;setActiveVideo(){}async getScreenshot(){throw new Error("getScreenshot is not supported in the editor")}async getHtmlSnapshot(){throw new Error("getHtmlSnapshot is not supported in the editor")}attachConsoleLogs(){}attachNetworkLogs(){}attachBrowserCrashDump(){}async finish(){this.socket.emit("finished"),await Promise.all(this.children.map(e=>e.finish()))}async startBeforeStepList(){let e=new $n({orgId:this.orgId,parentStep:null,parentTracer:null,socket:this.socket});return this.children.push(e),e}async startMainStepList(){let e=new $n({orgId:this.orgId,parentStep:null,parentTracer:null,socket:this.socket});return this.children.push(e),e}async startAfterStepList(){let e=new $n({orgId:this.orgId,parentStep:null,parentTracer:null,socket:this.socket});return this.children.push(e),e}};var eS={currentlyExecutingRequests:{}},Xj=r=>async(e,t)=>{let{testId:n,orgId:o}=r.metadata,i=await r.settingsFactory(o,r.logger),a=await r.storageFactory(o),s,c=await Li({testId:n,orgId:o,logger:r.logger,storage:a,authorization:r.authorization,settings:i}),l=`${n}|${c.baseUrl}`;try{let u=eS.currentlyExecutingRequests[l]??0;eS.currentlyExecutingRequests[l]=u+1,s=await Jj({...r,...e,...c,done:t})}finally{r.logger.info({result:s,sessionId:r.metadata.sessionId},"Test execution complete"),eS.currentlyExecutingRequests[l]--}},Jj=async({socket:r,steps:e,baseUrl:t,testMetadata:n,reInitialize:o,toStep:i,fromStep:a,storageFactory:s,aiSettings:c,browserConfig:l,metadata:u,logger:d,envName:p,testName:m,environmentVariables:h,localCodeEvalTools:g,done:f,cacheStorageFactory:y,globalE2eStateManager:S})=>{let{testId:E,sessionId:A,orgId:b}=u,C=A,x=S.getSession(A);if(!x)throw new Error("No active session found");let{controller:I,context:M}=x;I.setOpen(),d=d.child({testId:E,orgId:b,sessionId:A,runId:C}),d.info({steps:e.map(te=>`${te.type}${"command"in te?` - ${te.command.type}`:""}`),toStep:i,fromStep:a,reInitialize:o,envName:p,testName:m,baseUrl:t,context:M,browserConfig:l,aiSettings:c},"Socket execution parameters");let X=h??{},W=async()=>{o&&(await I.browser.reset({newUrl:t}),M.reset({baseUrl:t,currentUrl:I.browser.url(),variablesFromEnvironment:X,envName:p,testName:m}))},G=await s(b),H=await y(b),U=async()=>{try{await H.resolveStepCacheEntries({schemaVersion:n.schemaVersion,testId:E,stepLists:{steps:e},logger:d})}catch(te){d.error({err:te},"Failed to fetch step cache entries from Momentic server. This can drastically reduce test reliability and performance.")}};try{await Zs({promiseGenerator:async()=>Promise.all([W(),U()]),signal:I.executeAbortController.signal,codePath:"resolveStepCacheAndInitBrowser"}),I.setOpen()}catch(te){if(r.emit("finished"),te.name!=="AbortError")throw new Error(`Failed to setup browser for execution: ${te}`)}let V=Yj(e),me={collectDebugData:!1,reinitializeBrowser:!1,disableHealing:!0},q={orgId:b,runId:C,testMetadata:n,steps:e,fromStep:a,toStep:i,orgSettings:{ai:c,browser:l}},nt={controller:I,context:M,storage:G,codeEvalTools:g,usageTracker:new na,logger:d},De={test:{},step:{onDynamicAIActionStatusUpdateEvent:te=>{r.emit("dynamicCommandStatusUpdate",te)},onDynamicAIActionEvaluatingEvent:te=>{r.emit("dynamicCommandEvaluating",te)},onDynamicCommandGenerated:te=>{r.emit("dynamicCommandGenerated",te)},onDynamicCommandExecuted:te=>{r.emit("dynamicCommandExecuted",te)}}},dt=new np(r,G,b,E,V),Mt=await Hd({fixtures:nt,options:me,callbacks:De,inputs:q,testParams:{tracer:dt}});return Mt?.status==="PASSED"?await Au({logger:d,cacheStorage:H,orgId:b,testId:E,originalSteps:{steps:V},updatedSteps:{steps:e}}):Mt?.status==="FAILED"&&await wu({logger:d,cacheStorage:H,orgId:b,testId:E,originalSteps:{steps:V},updatedSteps:{steps:e}}),await dt.finish(),f?.(Mt),Mt.status};var eI={event:"execute",createHandler:Xj};import{cloneDeep as Qj}from"lodash-es";var Zj=r=>async({command:e},t)=>{let{logger:n,generatorFactory:o,metadata:i}=r,a=Qj(e),s=bv(a);if(s.category!=="NO_DESCRIPTION_PROVIDED"){if(s.category!=="NONE"){t?.({result:s});return}"cache"in a&&(a.cache=void 0);try{let l=await(await o(i.orgId,n)).getLintStepResult({command:a},{logger:n});t?.({result:l})}catch(c){n.error({event:"lint",err:c},"Failed to lint step"),t?.({result:void 0})}}},tI={event:"lintStep",createHandler:Zj};var eV=({metadata:r,logger:e,storageFactory:t,globalE2eStateManager:n})=>{let{sessionId:o,orgId:i}=r;return async(a,s)=>{let{description:c,command:l,testMetadata:u,returnScreenshot:d}=a;e.info({params:a},`Locate handler called - ${c}`);let p=n.getSession(o);if(!p)throw new Error("No active session found");let{controller:m,context:h}=p;m.setOpen();let g=await t(i),f=ri.parse(u.advanced??{}),y={},S;if(c){if("useSelector"in l&&l.useSelector)try{let E=await m.locateElementWithSelector(c,"iframeUrl"in l?l.iframeUrl:void 0);S=E.resolution.locator,y={target:E.target,thoughts:E.thoughts}}catch(E){e.warn({err:E},"Failed resolving target with selector"),s({err:`Failed locating element: ${E.message}`,decisions:E instanceof ln?E.decisions:void 0});return}else try{let E=await m.locateElement({description:c,disableCache:f.disableAICaching??!1,skipWait:!0,testContext:h,source:Jo(l),iframeUrl:"iframeUrl"in l?l.iframeUrl:void 0,memory:"cache"in l&&l.cache&&"target"in l.cache&&rc(l.cache.target.memory)?l.cache.target.memory:void 0,logger:e});y={target:E.target,thoughts:E.thoughts},S=E.resolution.locator}catch(E){(async()=>{try{let A=await m.browser.getCondensedHtml({skipWait:!0});e.warn({err:E,html:A.slice(0,1e5)},"Failed locating element with AI")}catch(A){e.warn({err:A},"Failed grabbing HTML after trying to locate element with AI")}})(),s({err:`${E.message}`});return}if(l.type==="SELECT_OPTION"&&S)try{y.options=await m.browser.getSelectOptions(S)}catch(E){e.warn({err:E},"Failed getting select options"),s({err:`Failed getting select options: ${E.message}`});return}e.info({result:y},"Locate handler result")}if(d)try{let{buffer:E,width:A,height:b}=await m.screenshotWithDimensions({clearHighlights:!0,locator:S}),C=await g.uploadScreenshot(E);y.screenshot={data:C,width:A,height:b},e.info({width:A,height:b},"Captured screenshot during locate")}catch(E){e.error({err:E},"Error capturing screenshot during locate"),s({err:`Error taking screenshot: ${E.message}`});return}if(s({result:y}),S)try{await Promise.all([m.browser.scrollIntoViewIfNeeded(S),m.browser.highlight(S)])}catch(E){e.warn({err:E},"Error highlighting element, continuing...")}}},rI={event:"locate",createHandler:eV};var tV=({metadata:r,logger:e,globalE2eStateManager:t})=>{let{sessionId:n}=r;return async({event:o,percentX:i,percentY:a})=>{let s=t.getSession(n);if(!s)throw new Error("No active session found");let c=s.controller.browser;if(c.closed||c.getActivePage().isClosed()){e.warn("Ignoring mouse move because the browser is closed");return}try{await c.clickMouseFromPositionPercentages(o,i,a)}catch(l){e.error({err:l},"Error performing click during cloud recording in control mode")}}},nI={event:"mouseClickEvent",createHandler:tV};var rV=({metadata:r,generatorFactory:e,logger:t,socket:n,globalE2eStateManager:o})=>{let{sessionId:i,orgId:a,testId:s}=r;return async({stepId:c,parentStepIdChain:l,attribute:u})=>{let d=o.getSession(i);if(!d)throw new Error("No active session found");let{controller:p}=d,m=await e(a,t);p.setOpen(),d.browserBehavior.showOverlay=!0;let h=new AbortController;h.signal.addEventListener("abort",async()=>{try{d.browserBehavior.showOverlay=!1,await p.stopRecordMode()}catch(y){t.warn({err:y},"Failed to stop record mode in target click socket handler")}},{once:!0});let g=!1,f=(y,S)=>{S.type!=="PRESET_ACTION"||S.command.type!=="CLICK"||(n.emit("targetRecordingUpdate",{type:y,stepId:c,parentStepIdChain:l,command:S.command,attribute:u}),h.abort(),g=!0)};setTimeout(()=>{g||(h.abort(),n.emit("targetRecordingUpdate",{type:"error",err:"Timed out waiting for click event",stepId:c,parentStepIdChain:l,attribute:u}))},1e4),await p.startRecordMode({params:{generator:m,logger:t,testId:s,orgId:a,callbacks:{onActionReceived:y=>f("clickReceived",y),onStepRecorded:y=>f("descriptionGenerated",y)}},abortController:h,isClickToRecord:!0}),n.emit("targetRecordingUpdate",{type:"listenersInitialized",stepId:c,parentStepIdChain:l,attribute:u})}},oI={event:"recordTargetClick",createHandler:rV};var nV=({metadata:r,logger:e,globalE2eStateManager:t})=>{let{sessionId:n}=r;return async({key:o})=>{let i=t.getSession(n);if(!i)throw new Error("No active session found");if(o==="Dead")return;let{controller:a}=i;if(a.browser.closed||a.browser.getActivePage().isClosed()){e.debug({sessionId:n},"Browser is closed, ignoring keyboard press socket event");return}try{a.setOpen(),await a.browser.keyDown(o,{})}catch(s){if(s.message.includes("has been closed")){e.debug({sessionId:n,err:s},"Browser is closed, ignoring key down socket event error");return}throw s}}},iI={event:"keyDownEvent",createHandler:nV};var oV=({metadata:r,logger:e,globalE2eStateManager:t})=>{let{sessionId:n}=r;return async({key:o})=>{let i=t.getSession(n);if(!i)throw new Error("No active session found");if(o==="Dead")return;let{controller:a}=i;if(a.browser.closed||a.browser.getActivePage().isClosed()){e.debug({sessionId:n},"Browser is closed, ignoring keyboard press socket event");return}try{a.setOpen(),await a.browser.keyUp(o,{})}catch(s){if(s.message.includes("has been closed")){e.debug({sessionId:n,err:s},"Browser is closed, ignoring key up socket event error");return}throw s}}},aI={event:"keyUpEvent",createHandler:oV};var iV=({metadata:r,logger:e,globalE2eStateManager:t})=>{let{sessionId:n}=r,o,i=0,a=(l,u)=>{let d=async()=>{o=void 0};clearTimeout(o),o=setTimeout(d,Math.min(1e3,250*(i+1)))},s,c=0;return async l=>{let u=t.getSession(n);if(!u)throw new Error("No active session found");let{controller:d,browserBehavior:p}=u,m=d.browser;if(m.closed||m.getActivePage().isClosed()){e.warn("Ignoring mouse move because the page is closed");return}if(l.event==="scroll"){let h=await m.scrollFromPositionPercentages(l.percentX,l.percentY,s?.x??0,s?.y??0),g=u.browserBehavior.recordingState?.transformer;g&&h&&g.recordScroll(h);return}p.showOverlay&&a(m,l);try{let h=await m.moveMouseFromPositionPercentages(l.percentX,l.percentY);c=0,s=h}catch(h){c++,c%5===0&&e.warn({err:h,mouseErrors:c},"Error in socket mouse move handler")}}},sI={event:"mouseMoveEvent",createHandler:iV};var aV=({metadata:r,generatorFactory:e,socket:t,logger:n,globalE2eStateManager:o})=>{let{sessionId:i,orgId:a,testId:s}=r;return async({stepId:c})=>{let l=o.getSession(i);if(!l)throw new Error("No active session found");let{controller:u,browserBehavior:d}=l,p=await e(a,n);n.info("Starting cloud recording");let m=new AbortController,h=await u.startRecordMode({params:{generator:p,logger:n,testId:s,orgId:a,callbacks:{onActionReceived:(g,f)=>{t.emit("stepRecorded",{stepId:c,step:g,offset:f})},onStepRecorded:(g,f)=>{t.emit("stepRecorded",{stepId:c,step:g,offset:f})}}},abortController:m,isClickToRecord:!1});d.recordingState={transformer:h}}},lI={event:"recordingStart",createHandler:aV};var sV=({metadata:r,logger:e,globalE2eStateManager:t})=>{let{sessionId:n}=r;return async()=>{let o=t.getSession(n);if(!o)throw new Error("No active session found");e.info("Stopping cloud recording"),await o.controller.stopRecordMode(),o.browserBehavior.recordingState=void 0,o.browserBehavior.showOverlay=!1}},cI={event:"recordingStop",createHandler:sV};var lV=({socket:r,metadata:e,logger:t,storageFactory:n,authorization:o,settingsFactory:i,globalE2eStateManager:a})=>async(s,c)=>{let{testId:l,sessionId:u,orgId:d}=e;t.info({testId:l,sessionId:u},"Refresh event received");let p=await i(d,t),m=await n(d),{baseUrl:h}=await Li({testId:l,orgId:d,logger:t,storage:m,authorization:o,settings:p}),g=a.getSession(u);if(!g){r.emit("error",{message:"No session to refresh"});return}let{controller:f}=g;f.setOpen(),await f.browser.refresh();let y=f.browser.getViewport();t.info({baseUrl:h,viewport:y},`Session refreshed for test ${l} at ${h}`),c()},uI={event:"refresh",createHandler:lV};var cV=({socket:r,metadata:e,logger:t,storageFactory:n,authorization:o,settingsFactory:i,globalE2eStateManager:a})=>async()=>{let{testId:s,sessionId:c,orgId:l}=e;t.info({testId:s,sessionId:c},"Reset event received");let u=await i(l,t),d=await n(l),{baseUrl:p,envName:m,testName:h,environmentVariables:g}=await Li({testId:s,orgId:l,logger:t,storage:d,authorization:o,settings:u}),f=a.getSession(c);if(!f){r.emit("error",{message:"No session to reset"});return}let{controller:y,context:S}=f;await y.browser.reset({newUrl:p});let E=y.browser.baseUrl;S.reset({baseUrl:E,currentUrl:y.browser.url(),variablesFromEnvironment:g,envName:m,testName:h});let A=y.browser.getViewport(),b=Ur.USER_AGENT;t.info({baseUrl:p,viewport:A},`Session reset for test ${s} at ${E}`),r.emit("session",{url:E,userAgent:b,viewport:A,sessionId:c})},dI={event:"reset",createHandler:cV};var uV=({metadata:r,globalE2eStateManager:e})=>{let{sessionId:t}=r;return async({url:n})=>{let o=e.getSession(t);if(!o)throw new Error("No active session found");await o.controller.browser.switchToPage({type:"SUBSTRING",substring:n})}},pI={event:"switchTab",createHandler:uV};async function mI(r){return Z_(r)}var hI=[LR,eI,rI,dI,uI,PR,pI,tI,oI,lI,cI,sI,nI,iI,aI,OR,MR];var gI=r=>{let{logger:e}=r,t=new dV(r.baseServer,{cors:{origin:"*",methods:["GET","POST"]},pingTimeout:15*60*1e3,pingInterval:15*60*1e3,maxHttpBufferSize:1e7,perMessageDeflate:!0});return t.on("connection",async n=>{let o;try{e.info({event:"connection",transport:n.conn.transport.name},"Websocket connection established"),o=await mI({...r,socket:n,logger:e}),e=e.child(o)}catch(i){e.error({event:"connection",type:"websocket",err:i},"Failed to setup connection"),n.emit("error",{message:i instanceof Error?i.message:`${i}`}),n.disconnect(!0);return}hI.forEach(i=>pV(i,{...r,socket:n,metadata:o,logger:e}))}),t},pV=(r,e)=>{let t=r.createHandler(e),n=(...o)=>{["mouseMoveEvent","keyDownEvent","keyUpEvent","mouseClickEvent","lintStep"].includes(r.event)||e.logger.debug({...e.metadata,event:r.event},`Websocket event (${r.event})`);let i=a=>{e.logger.error({event:r.event,type:"websocket",err:a instanceof Error?a:new Error(`${a}`)},"Unhandled exception in socket handler"),e.socket.emit("error",{message:a instanceof Error?a.message:`${a}`})};try{let a=t.apply(void 0,o);a&&typeof a.catch=="function"&&a.catch(i)}catch(a){i(a)}};e.socket.on(r.event,n)};import{Router as SV}from"express";import{Router as hV}from"express";import Hl from"fs";import Bl from"path";import{v4 as gV}from"uuid";import fV from"yaml";import{hostname as mV}from"os";var tS="2.21.2",Xe=ou({app:"desktop-server",hostname:mV(),disableConsoleLogs:!0}).child({cliVersion:tS});(async()=>{try{let r=await ll(Xe);r.gitBranchName&&Xe.addBinding("branch",r.gitBranchName)}catch{}})();var Va=hV();async function rS(r){return(await Du(r,Xe)).map(n=>{let o=r.modules[n.moduleId];if(!o){T.warn(`Found a dangling module with ID ${n.moduleId} that could not be found on disk.`);return}return{...o,content:n}}).filter(n=>n!==void 0)}Va.get("/",Re(async(r,e)=>{let t=ce(),n=await Q(t),o=await rS(n);e.status(200).json(o)}));Va.post("/",Re(async(r,e)=>{let t;try{t=PT.parse(r.body)}catch(s){e.status(400).json({error:`Invalid request body: ${s}`});return}try{ro(t.name)}catch(s){e.status(400).json({error:`Invalid module name: ${s}`});return}let n=ce(),o=(await Q(n)).modules;if(Object.values(o).find(s=>s.name===t.name)){e.status(400).send(`A module with the name "${t.name}" already exists. Please choose a different name.`);return}let i=Bl.join(n.rootDir,t.folderPath??"");if(!Hl.existsSync(i)||!Hl.statSync(i).isDirectory()){e.status(400).json({error:`The folder configured for module creation '${i}' does not exist.`});return}let a=await Nu({...t,folder:i,project:n});e.status(201).json(a)}));Va.get("/:moduleId",Re(async(r,e)=>{if(!r.params.moduleId){e.status(400).json({error:"Missing moduleId in url path."});return}let t=await Q(ce()),n=t.modules[r.params.moduleId];if(!n){e.status(404).json({error:"Module not found."});return}try{let o=await Xr(n,t,T);e.json(o)}catch(o){e.status(400).json({err:o})}}));Va.post("/:moduleId/duplicate",Re(async(r,e)=>{if(!r.params.moduleId){e.status(400).json({error:"Missing moduleId in url path."});return}let t;try{t=IT.parse(r.body)}catch(g){e.status(400).json({error:`Invalid request body: ${g}`});return}try{ro(t.name)}catch(g){e.status(400).json({error:g.message});return}let n=ce(),o=await Q(n),i=o.modules[r.params.moduleId];if(!i){e.status(404).json({error:"Module not found."});return}if(Object.values(o.modules).find(g=>g.name===t.name)){e.status(400).send(`A module with the name "${t.name}" already exists. Please choose a different name.`);return}let a=await Xr(i,o,T),s=Bl.join(n.rootDir,Bl.dirname(i.relativePath));if(!Hl.existsSync(s)||!Hl.statSync(s).isDirectory()){e.status(400).json({error:`The folder configured for module creation '${s}' does not exist.`});return}let c=Oe(t.name),l=Bl.join(s,`${c}.module.yaml`),u=gV(),{stepsToSave:d}=await ct({stepLists:{steps:a.steps},createNewCacheIds:!0,cacheCreationParams:{orgId:_t()}}),p={fileType:de.MODULE,schemaVersion:Te,moduleId:u,name:t.name,description:"",enabled:!0,steps:d.steps,parameters:a.parameters,defaultParameters:a.defaultParameters,parameterEnums:a.parameterEnums,defaultCacheKey:a.defaultCacheKey,defaultCacheTtl:a.defaultCacheTtl,defaultCacheAllInvocations:a.defaultCacheAllInvocations,autoAuth:a.autoAuth,advanced:a.advanced},m=fV.stringify(p);Hl.writeFileSync(l,m,"utf-8");let h={relativeFilePath:Bl.relative(n.rootDir,l)};e.status(201).json(h)}));Va.patch("/:moduleId/metadata",Re(async(r,e)=>{if(!r.params.moduleId){e.status(400).json({error:"Missing moduleId in url path."});return}let t;try{t=MT.parse(r.body)}catch(i){e.status(400).json({error:`Invalid request body: ${i}`});return}let n=ce(),o=await Q(n);uR({moduleId:r.params.moduleId,content:t,momenticFiles:o,logger:T,project:n}),e.status(201).json({message:"ok"})}));var fI=Va;var SI=SV();SI.get("/",Re(async(r,e)=>{let t=ce(),n=await Q(t),o=new Set;n?.tests&&Object.values(n.tests).forEach(l=>{l.labels?.forEach(u=>o.add(u))});let i=Array.from(o).sort(),a=Object.values(n.tests),s=await rS(n),c={labels:i,tests:a,modules:s};e.status(200).json(c)}));var yI=SI;import{Router as yV}from"express";var nS=yV();nS.get("/",Re((r,e)=>{let t=ku(ce(),Xe);e.status(200).json(t)}));nS.get("/names",Re((r,e)=>{let n=ce().config.environments?.map(o=>o.name)??[];e.status(200).json(n)}));var EI=nS;import{Router as EV}from"express";var TI=EV();TI.get("/",Re((r,e)=>{let t={userId:So(),orgId:_t()};e.status(200).json(t)}));var bI=TI;import{StreamableHTTPServerTransport as A$}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{isInitializeRequest as w$}from"@modelcontextprotocol/sdk/types.js";import{randomUUID as C$}from"crypto";import{Router as x$}from"express";import{McpServer as v$}from"@modelcontextprotocol/sdk/server/mcp.js";import{SSEServerTransport as R$}from"@modelcontextprotocol/sdk/server/sse.js";import{streamObject as AV}from"ai";import sp from"dedent";import{z as No}from"zod";import{tool as TV}from"ai";import{z as bV}from"zod";var op=(r,e)=>({builder:n=>TV({description:r.schema.description,inputSchema:bV.object(r.schema.inputSchema),execute:async o=>{let i=e(n);n.logger.info({input:o},`Executing tool ${r.schema.name}`);try{await r.handle(n,o,i,void 0)}catch(s){i.addError(String(s))}let a=await i.serialize();return a.isError?n.logger.error({toolName:r.schema.name,input:o,err:a.content.map(s=>s.text).join(`
|
|
4142
|
+
${r}`;default:return r}}var Hj=15;async function tp({command:r,aiPageFiltering:e,logger:t,fixtures:n,source:o,useMemory:i,maxRetries:a=Hj}){if(!r.assertion.trim())throw new _("ActionFailureError","Assertion command is missing the assertion content");let{browser:s}=n,c=r.timeout?r.timeout*1e3:s.smartWaitingTimeout,l=tR(c),u=0,d=Date.now(),p,m,h;try{await wn({action:()=>s.clearHighlights(),frameConfig:r.iframeUrl?{type:"url",url:r.iframeUrl}:void 0,browser:s,logger:t})}catch(f){t.warn({err:f},"Failed to clear highlights before AI check, continuing...")}let g;for(;u<a&&(!g||g-d<c);){n.abortSignal.throwIfAborted(),u!==0&&await ie(l,n.abortSignal),g=Date.now();try{if(p=await wn({action:async()=>{let y=await K_(s,t,n.abortSignal);return m&&m.serializedTree===y.serializedTree&&m.screenshotBuff.equals(y.screenshotBuff)?p:(m=y,Y_({command:r,state:y,fixtures:n,useMemory:i,useConsensus:!1,highlightElementsOnFailure:!1,attemptNumber:u,aiPageFiltering:e,logger:t,source:o}))},frameConfig:r.iframeUrl?{type:"url",url:r.iframeUrl}:void 0,logger:t,browser:s}),p?.updatedMemory&&gu(r,p.updatedMemory,t),p?.success)break;throw p?.thoughts?new _("AssertionFailureError",p.thoughts):new _("InternalPlatformError","No thoughts were provided for AI assertion failure")}catch(f){n.abortSignal.throwIfAborted(),h=f instanceof Error?f:new Error(`${f}`),t.info({err:f},`AI check assert attempt ${u} failed, retrying...`)}finally{u++}}if(!p?.success)try{p=await wn({action:async()=>Y_({command:r,state:await K_(s,t,n.abortSignal),fixtures:n,useMemory:i,useConsensus:!0,highlightElementsOnFailure:!0,attemptNumber:u,aiPageFiltering:e,logger:t}),frameConfig:r.iframeUrl?{type:"url",url:r.iframeUrl}:void 0,logger:t,browser:s})}catch(f){n.abortSignal.throwIfAborted(),h=f instanceof Error?f:new Error(`${f}`)}finally{u++}if(!p?.success){let f=`AI check still failing after ${u} attempts.`;throw h&&(f+=` Latest result: ${h.message}`),new _("AssertionFailureError",f)}return{...p,succeedImmediately:!1,urlAfterCommand:s.url()}}async function K_(r,e,t){let[n,o]=await Promise.all([_o(r,{abortSignal:t,skipWait:!0,skipWaitForPageLoad:!0,logger:e}),r.screenshot({retries:1,respectActiveFrame:!0})]);return{...n,screenshotBuff:o}}async function Y_({command:r,state:e,fixtures:t,useConsensus:n,useMemory:o,highlightElementsOnFailure:i,aiPageFiltering:a,attemptNumber:s,source:c,logger:l}){let{browser:u,generator:d,abortSignal:p}=t,m={type:"ASSERTION"},{serializedTree:h,tree:g}=e,f=e.screenshotBuff,y=f.toString("base64"),S=u.url(),E=r.contextChoice??"MULTIMODAL",A=h;E!=="VISION_ONLY"&&(A=await Oi({type:"assertion",serializedTree:h,tree:g,description:r.assertion,screenshot:y,options:{aiPageFiltering:a},fixtures:{generator:d,signal:p,logger:l,orgId:t.orgId}}),A!==h&&(m.ragUsed=!0),m.pageState=A);let b={goal:r.assertion,url:S,memory:o?r.cache?.memory:void 0,browserState:A,screenshot:y,contextChoice:E,source:c},x=await(E==="VISION_ONLY"?(I,M)=>d.getVisualAssertionResult(I,M):(I,M)=>d.getAssertionResult(I,M))(b,{useConsensus:n,attemptNumber:s,useMemory:o,disableCache:!!r.disableCache,abortSignal:p,logger:l,loggerTags:We(l)});return(x.result||i)&&x.relevantElements&&(m.relevantElementsSerialized=x.relevantElements.map(I=>u.getSerializedFormFromA11yId(I)).filter(I=>!!I),await zj(x.relevantElements,u,l)),{success:x.result,thoughts:x.thoughts,afterScreenshotOverride:f,updatedMemory:o?x.updatedMemory:void 0}}async function zj(r,e,t){let n=Date.now();for(let o of r){if(Date.now()-n>2e3){t.debug("Highlighting relevant elements took over 2s, aborting...");return}try{let i=new AbortController;await j(e.highlightA11yId(o),{milliseconds:1e3,fallback:()=>{throw i.abort(),new Error("Timed out waiting for highlighting to complete")}})}catch(i){t.debug({err:i},"Failed to highlight relevant element after assertion, continuing...");return}}}var Gj=3e4;async function X_({command:r,logger:e,baseUrl:t,fetchImplementation:n=fetch}){let o=r.timeout??Gj/1e3,i=new AbortController,a=Object.fromEntries(Object.entries(r.headers||{}).filter(([d,p])=>d&&p));a["Content-Type"]="application/json";let s;if(ha(r.url)&&(s=r.url),t&&ga(r.url,t)&&(s=new URL(r.url,t).toString()),!s)throw new _("ActionFailureError",`Invalid URL: ${r.url}`);let l=await j((async()=>{try{return await n(s,{headers:a,method:"POST",body:JSON.stringify({query:r.query,variables:r.variables?JSON.parse(r.variables):void 0}),signal:i.signal})}catch(d){e.error({err:d},"Failed to make HTTP request")}})(),{milliseconds:o*1e3});if(!l)throw new _("ActionFailureError",`GraphQL request timed out after ${o} seconds`);if(!l.ok){let d,p=await l.text();try{d=JSON.parse(p)}catch{throw new _("ActionFailureError",`GraphQL request failed with status ${l.status}: ${p}`)}throw d?.errors?.length&&d?.errors[0]?.message?new _("ActionFailureError",`GraphQL request failed with status ${l.status}: ${d.errors[0].message}`):new _("ActionFailureError",`GraphQL request failed with status ${l.status}: ${p}`)}let u={};return l.headers.forEach((d,p)=>{u[p]=d}),{status:l.status,headers:u,json:await l.json()}}var Lo=class{orgId;options;storage;localCodeEvalTools;uploadedFileStorage;visualDiffScreenshotStorage;browser;generator;executeAbortController=new AbortController;logger;recordAbortController=null;registeredListeners={};recordedRequests={};constructor({browser:e,generator:t,logger:n,storage:o,orgId:i,localCodeEvalTools:a,uploadedFileStorage:s,visualDiffScreenshotStorage:c,options:l}){this.orgId=i,this.options=l,this.browser=e,this.browser.registerAbortSignal(this.executeAbortController.signal),this.storage=o,this.uploadedFileStorage=s,this.visualDiffScreenshotStorage=c,this.localCodeEvalTools=a,this.generator=t,this.logger=n}setOpen(){this.executeAbortController=new AbortController,this.browser.registerAbortSignal(this.executeAbortController.signal)}setClosed(){this.executeAbortController.abort()}throwIfClosed(){this.executeAbortController.signal.throwIfAborted()}get closed(){return this.executeAbortController.signal.aborted}async evaluateAiAction({goal:e,startingScreenshot:t,history:n,disableCache:o,langfuseSessionId:i,lastError:a,logger:s=this.logger}){let[c,l]=await Promise.all([_o(this.browser,{abortSignal:this.executeAbortController.signal,skipWait:!0,skipWaitForPageLoad:!0,logger:s}),this.browser.screenshot({retries:1,clearHighlights:!0})]),u=`data:image/jpeg;base64,${l.toString("base64")}`,d=await Oi({type:"ai-action",description:e,screenshot:u,serializedTree:c.serializedTree,tree:c.tree,options:{aiPageFiltering:!!this.options?.aiPageFiltering},fixtures:{generator:this.generator,signal:this.executeAbortController.signal,logger:s,orgId:this.orgId}}),p={url:this.browser.url(),browserState:d,startingScreenshot:t,history:n,goal:e,screenshot:u,lastError:a};return await this.generator.getMultiturnAiActionEvaluation(p,{disableCache:o,abortSignal:this.executeAbortController.signal,loggerTags:{...We(s)},langfuseSessionId:i})}async promptToCommand({goal:e,startingScreenshot:t,history:n,actionHint:o,disableCache:i,logger:a=this.logger,langfuseSessionId:s}){let c=this.browser.url(),[l,u]=await Promise.all([_o(this.browser,{abortSignal:this.executeAbortController.signal,skipWait:!0,skipWaitForPageLoad:!0,logger:a}),this.browser.screenshot({retries:1,clearHighlights:!0})]),d=`data:image/jpeg;base64,${u.toString("base64")}`,p=await Oi({type:"ai-action",description:e,screenshot:d,serializedTree:l.serializedTree,tree:l.tree,options:{aiPageFiltering:!!this.options?.aiPageFiltering},fixtures:{generator:this.generator,signal:this.executeAbortController.signal,logger:a,orgId:this.orgId}}),m={url:c,browserState:p,startingScreenshot:t,history:n,goal:e,actionHint:o,screenshot:d};try{return await this.generator.getMultiturnAiActionCommand(m,{disableCache:i,abortSignal:this.executeAbortController.signal,loggerTags:{...We(a)},langfuseSessionId:s})}catch(h){throw new _("InternalWebAgentError",`Error generating command: ${h instanceof Error?h.message:h}`,{errOptions:{cause:h}})}}async getBrowserState(e){return _o(this.browser,e)}async locateElement(e){return await Qf({...e,aiPageFiltering:!!this.options?.aiPageFiltering},this.getControllerFixtures())}async locateElementWithSelector(e,t){return wn({action:async()=>{let n=await this.browser.resolveHardcodedCssSelector({ctx:null,selector:e,timeoutMs:2e3,logger:this.logger});return{thoughts:"Located element with selector",target:{id:-1,selector:e,targetSource:"USER_CSS_SELECTOR",targetUpdateTime:new Date().toUTCString()},resolution:n}},frameConfig:t?{type:"url",url:t}:void 0,browser:this.browser,logger:this.logger})}getControllerFixtures(e){return{ctx:e??null,browser:this.browser,generator:this.generator,logger:this.logger,orgId:this.orgId,storage:this.storage,localCodeEvalTools:this.localCodeEvalTools,abortSignal:this.executeAbortController.signal}}shouldUseMemory(){return this.options?.useMemory??(this.orgId==="org_01HMSCJQBCCG51M2ZF65YC5B8W"||this.orgId==="org_01HMJTX4GT1KG94KZRCT8MZ6YB")}async wrapMultiElementTargetingCommand({ctx:e,tracer:t,command:n,targetNames:o,descriptions:i,caches:a,action:s,options:c,retriesWithAI:l=1}){let u=[];for(let d=0;d<i.length;d++){let p=i[d],m=await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:p,cache:a[d],action:async h=>h,options:{...c,targetName:o[d]}});u.push(m)}try{let d=await s(...u.map(h=>h.result)),p=h=>h==="fromTarget"?"From Target":h==="toTarget"?"To Target":"Target",m=u.map((h,g)=>h.thoughts?`${p(o[g])}: ${h.thoughts}`:void 0).filter(h=>!!h).join(" -------------- ")||void 0;return{result:d,elementInteractedDisplayStrings:u.map(h=>h.elementInteractedDisplayString),thoughts:m}}catch(d){if(this.throwIfClosed(),l>0)return this.logger.warn({err:d},"Failed to execute action with multiple cached targets, retrying with AI"),this.wrapMultiElementTargetingCommand({ctx:e,tracer:t,command:n,targetNames:o,descriptions:i,caches:i.map(()=>{}),action:s,options:c,retriesWithAI:l-1});throw new _("ActionFailureError",d.message,{errOptions:{cause:d}})}}async wrapElementTargetingCommand(e){let t=this.logger.child({commandId:e.command.id}),n;for(let o=0;o<2;o++)try{return await wn({action:()=>this.wrapElementTargetingCommandHelper({...e,originalCache:e.originalCache??e.cache}),frameConfig:e.options.iframeUrl?{type:"url",url:e.options.iframeUrl}:void 0,browser:this.browser,logger:t})}catch(i){if(n=i,this.browser.userBrowserSettings.visualActions&&am(i)){t.warn({err:i},"Invalid mpath error, retrying element targeting command");continue}if(!this.browser.userBrowserSettings.visualActions&&(lm(i)||sm(i))){t.warn({err:i},"Invalid momentic id error, retrying element targeting command");continue}if(cm(i)){t.warn({err:i},"Invalid backend node id error, retrying element targeting command");continue}if(i instanceof cn&&i.retryableWithAI){t.warn({err:i},"Element cache disqualification error, retrying element targeting command");continue}throw i}throw n instanceof _?n:new _("ActionFailureError",n?.message??"An unknown error occurred during element targeting")}async wrapHardcodedCssTargetingCommandHelper({ctx:e,target:t,action:n,options:o,command:i}){let a=this.logger.child({commandId:i.id}),{targetName:s}=o;if(t.type!=="description")throw new _("ActionFailureError","Cannot use selector with non-description target");let c,l=Date.now(),u=Date.now();for(;Date.now()-u<this.browser.smartWaitingTimeout;){l=Date.now();try{let d=await this.browser.resolveHardcodedCssSelector({ctx:e,selector:t.elementDescriptor,targetName:s,logger:a});return{result:await n({locator:d.locator}),elementInteractedDisplayString:d.displayString}}catch(d){if(d.name==="AbortError")throw d;c=d,a.warn({err:d},"Failed to action on hardcoded css selector"),Date.now()-l<500&&await ie(500)}}throw c}async wrapElementTargetingCommandHelper(e){let{ctx:t,tracer:n,target:o,originalCache:i,action:a,options:s,command:c}=e,{disableCache:l,useSelector:u,targetName:d,targetHealingInProgress:p,source:m}=s,h=this.logger.child({commandId:c.id}),g=this.shouldUseMemory(),f=s.retriesWithAI??1,y=!1,S=J_(e.cache);if((!S||l)&&!jp(o))throw new _("ActionFailureError","Cannot target element with no cached data or element descriptor");if(u)return this.wrapHardcodedCssTargetingCommandHelper(e);l&&(h.info("Cache explicitly disabled for this step"),y=!0,S=void 0),S&&this.browser.userBrowserSettings.disableSecondaryCacheResolution&&S.targetSource==="HEURISTIC_HEALED"&&(y=!0,S=void 0),S?.inputDescription&&!q_(o.elementDescriptor,S.inputDescription)&&(h.warn({old:S.inputDescription,new:o.elementDescriptor},"Target cache was generated with a different description, clearing it automatically"),y=!0,S=void 0);let E=b=>!!b&&tc(b),A=!0;if(!E(S)){A=!1,h.info({description:o.elementDescriptor,targetHealingInProgress:p,cacheBustedBeforeAction:y,memory:s.memory,useMemory:g},"Prompting AI for an updated element location"),y&&await ie(this.browser.smartWaitingTimeout,this.executeAbortController.signal),f--;let b;try{b=await Qf({description:o.elementDescriptor,disableCache:!!s.disableCache,iframeUrl:s.iframeUrl,source:m,useMemory:g,memory:g?s.memory:void 0,aiPageFiltering:!!this.options?.aiPageFiltering,allowNotActionableNodesOverride:s.allowNotActionableNodesOverride,logger:h},this.getControllerFixtures(t))}catch(I){if(I instanceof Ki&&I.updatedLocatorMemory){let M={id:-1,...i,memory:I.updatedLocatorMemory};hu({cmd:c,key:d,newTarget:M,logger:h,updatedWithAI:!0})}throw new _("ActionFailureError",I.message)}b.frameConfig&&this.browser.setActiveFrameConfig(b.frameConfig);let C=s.disableGlobalLocatorRedirect?{locator:b.resolution.locator}:await this.attemptLocatorRedirect(b.resolution.locator,h),x=await a(C);return hu({cmd:c,key:d,newTarget:b.target,logger:h,updatedWithAI:!0}),p&&(n.recordTargetAutoHeal({healType:"AI"}),b.target.targetSource="AI_HEALED",b.target.targetUpdateTime=new Date().toUTCString(),b.target.targetUpdateLoggerTags=We(h)),{result:x,elementInteractedDisplayString:b.resolution.displayString,thoughts:b.thoughts}}try{let b=await this.browser.resolveTarget(t,S,{allowNotActionableNodesOverride:s.allowNotActionableNodesOverride,targetName:d,logger:h,signal:this.executeAbortController.signal});(this.browser.userBrowserSettings.visualActions||this.browser.userBrowserSettings.globalLocatorRedirect!==!1)&&await this.browser.scrollIntoViewIfNeeded(b.locator);let C=s.disableGlobalLocatorRedirect?{locator:b.locator}:await this.attemptLocatorRedirect(b.locator,h),x=await a(C);if(tr.increment("cache_target_resolution_v2",1,["outcome:hit","platform:web",`hasRequirements:${!!S.requirements}`,`hasAdditionalElements:${!!S.additionalElements}`,`orgId:${this.orgId}`,"cliVersion:2.21.3"]),hu({cmd:c,key:d,newTarget:S,logger:h,updatedWithAI:!1}),A){let I=b.decisions.filter(M=>M.matched);if(I.length!==1)h.warn({decisions:b.decisions},"Expected exactly 1 matching method for element location, got more or less");else{let M=I[0].type;n.recordTargetAutoHeal({healType:M})}}return{result:x,elementInteractedDisplayString:b.displayString}}catch(b){this.throwIfClosed(),tr.increment("cache_target_resolution_v2",1,["outcome:miss","platform:web",`hasRequirements:${!!S.requirements}`,`hasAdditionalElements:${!!S.additionalElements}`,`orgId:${this.orgId}`,"cliVersion:2.21.3"]);let C=!1;if((b instanceof cn||am(b)||lm(b)||cm(b)||Xy(b)||sm(b))&&(C=!0),b instanceof _&&!C)throw h.error({err:b},"Failed to execute action with cached target (fatal)"),b;if(f>0&&o){h.info({err:b},"Failed to execute action with cached target, retrying with AI");let x;return S.memory&&rc(S.memory)&&(x=S.memory),this.wrapElementTargetingCommand({ctx:t,tracer:n,command:c,target:o,cache:void 0,originalCache:i,action:a,options:{...s,memory:x,retriesWithAI:f,targetHealingInProgress:!0}})}throw new _("ActionFailureError",b.message,{errOptions:{cause:b}})}}async attemptLocatorRedirect(e,t){return this.browser.userBrowserSettings.globalLocatorRedirect!==!1?this.browser.performTargetRedirection(e,t):{locator:e}}async screenshotWithDimensions(e){return ul(this.browser,e)}async executePresetCommand(e,t,n,o,i){this.options?.slowMoMs&&await ie(this.options.slowMoMs);let a=await this.browser.getOpenPages(),s=this.browser.url(),c;try{c=await this.resolveCommandTemplateStrings(n,o)}catch(l){throw this.throwIfClosed(),new _("ActionFailureError",`Failed to substitute template strings in command: ${l.message}`,{errOptions:{cause:l}})}try{let l=await this.executePresetCommandHelper(e,t,n,o,i);return this.browser.userBrowserSettings.visualActions&&dy(n)?await this.browser.waitForDOMStability({timeout:Ae}):!this.browser.userBrowserSettings.visualActions&&["PRESS","TYPE"].includes(n.type)&&await this.browser.waitForDOMStability({timeout:ae}),this.options?.autoFollowNewTabs&&await fx({beforeUrl:s,command:n,beforePages:a.map(u=>u.url),browser:this.browser,logger:this.logger}),l}catch(l){throw l.name!=="AbortError"&&this.logger.error({err:l},"Error thrown in action controller"),l}finally{zR(n,c)}}createCallbacksForBrowser(e){return{createIsolatedFolder:()=>Af(e)}}async resolveCommandTemplateStrings(e,t){return Hu({obj:e,context:t,bannedKeys:["type","a11yData","thoughts","cache","code"],orgId:this.orgId,logger:this.logger,signal:this.executeAbortController.signal,localTools:this.localCodeEvalTools})}async executePresetCommandHelper(e,t,n,o,i){i=i||"disableCache"in n&&!!n.disableCache;let a=this.logger.child({commandId:n.id});switch(n.type){case"SUCCESS":let s=n.condition;return s?.assertion.trim()?tp({command:s,fixtures:this.getControllerFixtures(e),useMemory:this.shouldUseMemory(),aiPageFiltering:!!this.options?.aiPageFiltering,logger:a}):{succeedImmediately:!1,urlAfterCommand:this.browser.url()};case"AI_ASSERTION":{if(!n.assertion.trim())throw new _("ActionFailureError","Missing assertion");if(n.timeout&&n.timeout>1800)throw new _("AssertionFailureError",`AI check timeout of ${n.timeout} exceeds the maximum allowed value of 30 minutes.`);return tp({command:n,fixtures:this.getControllerFixtures(e),useMemory:this.shouldUseMemory(),aiPageFiltering:!!this.options?.aiPageFiltering,logger:a})}case"AI_EXTRACT":{if(!n.goal.trim())throw new _("ActionFailureError","Cannot perform AI extraction without goal");if(n.schema){let f=Ub(n.schema);if(f)throw new _("UserConfigurationError",f)}let h=await this.browser.getCondensedHtml(),g=await this.browser.screenshot({retries:2});try{let f=await this.generator.getTextExtraction({goal:n.goal,browserState:h,returnSchema:n.schema,screenshot:`data:image/jpeg;base64,${g.toString("base64")}`},{disableCache:i,abortSignal:this.executeAbortController.signal,loggerTags:We(a)});if(f.result==="NOT_FOUND")throw new _("ActionFailureError","No relevant data found for extraction goal on this page");if(f.thoughts?.includes("MaxGenerationLengthExceededError"))throw new _("UserConfigurationError",f.thoughts);return{thoughts:f.thoughts||void 0,data:f.result,succeedImmediately:!1,urlAfterCommand:this.browser.url()}}catch(f){let y=f.message;throw y.includes("MaxGenerationLengthExceededError")?new _("UserConfigurationError","You tried to extract too much data. Please rephrase your query to limit the results returned or use a JavaScript step in the browser instead."):y.includes("AIProviderError")&&y.includes("time")?new _("AIProviderError","The AI provider responded with an error. This may be because you tried to extract too much data. Please limit extraction results to 2000 characters.",{errOptions:{cause:f}}):f}}case"NAVIGATE":if(!ha(n.url)&&!ga(n.url,this.browser.baseUrl))throw new _("ActionFailureError",`Invalid URL provided to navigate command: ${n.url}`);await this.browser.navigate({url:n.url,loadTimeoutMs:n.loadTimeout?n.loadTimeout*1e3:void 0});break;case"DIALOG":this.browser.registerDialogHandler(n.action);break;case"CAPTCHA":if(!this.browser.canSolveCaptchas())break;let c=await this.browser.solveCaptcha();c&&(await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:{type:"description",elementDescriptor:"the captcha image solution input"},cache:void 0,action:h=>this.browser.click(h,this.createCallbacksForBrowser(this.orgId),{}),options:{...n,targetName:"target",disableCache:i}}),await this.browser.type(c,{clearContent:!0,pressEnter:!0},!0));break;case"GO_BACK":await this.browser.goBack();break;case"GO_FORWARD":await this.browser.goForward();break;case"SCROLL_LEFT":case"SCROLL_RIGHT":case"SCROLL_DOWN":case"SCROLL_UP":{let h,g;if(n.target&&on(n.target))await this.browser.hoverUsingVisualCoordinates(n.target.pixels);else if(n.target&&n.target.elementDescriptor.trim()){let{elementInteractedDisplayString:S,thoughts:E}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:n.target,cache:n.cache?.target,action:A=>this.browser.hover(A),options:{...n,targetName:"target",disableGlobalLocatorRedirect:!0,disableCache:i}});h=S,g=E}let f=this.browser.getViewport()?.height??Gt.height,y=this.browser.getViewport()?.width??Gt.width;switch(n.type){case"SCROLL_UP":await this.browser.scrollVertical(-(n.deltaY??f));break;case"SCROLL_DOWN":await this.browser.scrollVertical(n.deltaY??f);break;case"SCROLL_LEFT":await this.browser.scrollHorizontal(-(n.deltaX??y));break;case"SCROLL_RIGHT":await this.browser.scrollHorizontal(n.deltaX??y);break}return{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:h,thoughts:g}}case"WAIT_FOR_URL":{if(n.timeout&&n.timeout>1800)throw new _("UserConfigurationError",`Wait for URL timeout of ${n.timeout} exceeds the maximum allowed value of 30 minutes.`);let h=n.matcher;await this.browser.waitForUrl({beforeUrl:this.browser.url(),matcher:h},{timeout:n.timeout?n.timeout*1e3:void 0,negated:n.negated,caseInsensitive:n.caseInsensitive});break}case"WAIT":if(n.delay>1800)throw new _("UserConfigurationError",`Wait timeout of ${n.delay} seconds exceeds the maximum allowed value of 30 minutes`);let l=n.delay*1e3;await ie(l,this.executeAbortController.signal);break;case"REFRESH":await this.browser.refresh({loadTimeoutMs:n.loadTimeout?n.loadTimeout*1e3:void 0});break;case"CLICK":{if(on(n.target)){await this.browser.clickUsingVisualCoordinates(n.target.pixels,n);break}let h=this.browser.url(),{elementInteractedDisplayString:g,result:f,thoughts:y}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,target:n.target,command:n,cache:n.cache?.target,action:E=>this.browser.click(E,this.createCallbacksForBrowser(this.orgId),n),options:{disableCache:i,targetName:"target",...n}}),S={urlAfterCommand:this.browser.url(),succeedImmediately:!1,elementInteracted:g,thoughts:y,data:f.downloadedFile?{downloadedFile:f.downloadedFile}:void 0};return Iu(h,S.urlAfterCommand)&&(S.succeedImmediately=!0,S.succeedImmediatelyReason="URL changed"),S}case"COPY":return await this.browser.copy(n.value),{succeedImmediately:!1,data:n.value,urlAfterCommand:this.browser.url()};case"PASTE":{await this.browser.paste();break}case"DRAG":{if(on(n.fromTarget)&&on(n.toTarget)){await this.browser.dragAndDropUsingVisualCoordinates(n.fromTarget.pixels,n.toTarget.pixels,{hoverSeconds:n.hoverSeconds});break}if(on(n.fromTarget)||on(n.toTarget))throw new Error("Drag and drop targets must be both coordinates or both descriptions");let{elementInteractedDisplayStrings:h,thoughts:g}=await this.wrapMultiElementTargetingCommand({ctx:e,tracer:t,command:n,targetNames:["fromTarget","toTarget"],descriptions:[n.fromTarget,n.toTarget],caches:[n.cache?.fromTarget,n.cache?.toTarget],action:(f,y)=>this.browser.dragAndDrop(f.locator,y.locator,{hoverSeconds:n.hoverSeconds,steps:n.steps}),options:{useSelector:!!n.useSelector,disableCache:i}});return{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:h[0],thoughts:g}}case"MOUSE_DRAG":{let h=parseInt(n.deltaX),g=parseInt(n.deltaY),f=n.steps??5;if(isNaN(h)||isNaN(g))throw new _("ActionFailureError",`Invalid pixel values passed to mouse drag command: (${n.deltaX}, ${n.deltaY})`);if(n.target&&on(n.target)){await this.browser.mouseDragUsingVisualCoordinates(h,g,f,n.target.pixels,{force:n.force});break}let y,S,E;if(n.target?.elementDescriptor){let{elementInteractedDisplayString:A,result:b,thoughts:C}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:n.target,cache:n.cache?.target,action:async x=>x.locator,options:{disableCache:i,targetName:"target",...n}});y=b,S=A,E=C}return await this.browser.mouseDrag(h,g,f,y,{force:n.force}),{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:S,thoughts:E}}case"SELECT_OPTION":{if(!Zn(n.target))throw new Error("Select with x/y is not supported yet");let h=n.target.elementDescriptor,g=n.choice,{elementInteractedDisplayString:f,thoughts:y}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:{type:"description",elementDescriptor:h},cache:n.cache?.target,action:S=>this.browser.selectOption(S,g,n.force),options:{...n,targetName:"target",disableCache:i,source:Jo(n)}});return{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:f,thoughts:y}}case"TAB":{let h={loadTimeoutMs:n.loadTimeout?n.loadTimeout*1e3:void 0,retry:!0};await this.browser.switchToPage(n.action,h);break}case"NEW_TAB":await this.browser.createNewTab(n.url,{loadTimeoutMs:n.loadTimeout?n.loadTimeout*1e3:void 0});break;case"COOKIE":if(!n.value)break;let u=await this.browser.setCookie(n.value);a.debug({results:u},"Set cookies");break;case"LOCAL_STORAGE":if(!n.value||!n.key)break;await this.browser.setLocalStorage(n.key,n.value);break;case"JAVASCRIPT":{let h;try{n.environment==="BROWSER"?(h=await this.browser.evaluateCodeInPage({code:n.code,fragment:n.fragment??!1,context:o.toObjectCopy(),timeoutMs:n.timeout?n.timeout*1e3:void 0}),a.info({result:h},"Executed JavaScript in browser")):h=await bo({orgId:this.orgId,code:n.code,fragment:!!n.fragment,context:o,timeoutMs:n.timeout?n.timeout*1e3:void 0,logger:a,localTools:this.localCodeEvalTools,signal:this.executeAbortController.signal,callbacks:{onPersistentVariableUpdates:async g=>{if(!this.options?.scratchPadId){a.warn({updates:g},"Got persistent variable updates but scratch pad is not available");return}await this.storage.savePersistentVariables?.({scratchPadId:this.options?.scratchPadId,orgId:this.orgId,updates:g,logger:a})}}})}catch(g){throw this.throwIfClosed(),new _("ActionFailureError",g instanceof Error?g.message:`${g}`,{errOptions:{cause:g}})}try{JSON.stringify(h)}catch(g){throw new _("ActionFailureError",`Return value is not serializable: ${g instanceof Error?g.message:`${g}`}`,{errOptions:{cause:g}})}return{urlAfterCommand:this.browser.url(),succeedImmediately:!1,data:h}}case"TYPE":{if(n.target&&on(n.target)){await this.browser.clickUsingVisualCoordinates(n.target.pixels,n),await this.browser.type(n.value,{force:n.force,clearContent:n.clearContent,forceClearContent:n.forceClearContent,delay:n.delay,pressEnter:n.pressEnter},!0);break}let h=this.browser.url(),g,f,y=J_(n.target),S=this.browser.userBrowserSettings.globalLocatorRedirect===void 0||this.browser.userBrowserSettings.globalLocatorRedirect==="always";if(y){let{elementInteractedDisplayString:A,thoughts:b}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:y,cache:n.cache?.target,action:C=>this.browser.typeIntoTarget(n.value,C,{force:n.force,clearContent:n.clearContent,forceClearContent:n.forceClearContent,delay:n.delay,pressEnter:n.pressEnter,relativePosition:n.relativePosition}),options:{...n,targetName:"target",disableCache:i,disableGlobalLocatorRedirect:!S,source:Jo(n)}});g=A,f=b}else await this.browser.type(n.value,{force:n.force,clearContent:n.clearContent,forceClearContent:n.forceClearContent,delay:n.delay,pressEnter:n.pressEnter},!0);let E={urlAfterCommand:this.browser.url(),succeedImmediately:!1,elementInteracted:g,thoughts:f};return Iu(h,E.urlAfterCommand)&&(E.succeedImmediately=!0,E.succeedImmediatelyReason="URL changed"),E}case"HOVER":{if(on(n.target)){await this.browser.hoverUsingVisualCoordinates(n.target.pixels);break}let{elementInteractedDisplayString:h,thoughts:g}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:n.target,cache:n.cache?.target,action:f=>this.browser.hover(f),options:{...n,targetName:"target",disableCache:i}});return{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:h,thoughts:g}}case"FOCUS":{if(!Zn(n.target))throw new Error("Focus with x/y is not supported yet");let{elementInteractedDisplayString:h,thoughts:g}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,command:n,target:n.target,cache:n.cache?.target,action:f=>this.browser.focus(f),options:{...n,targetName:"target",disableCache:i}});return{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:h,thoughts:g}}case"BLUR":{if(n.target&&!Zn(n.target))throw new Error("Blur with x/y is not supported yet");if(!n.target||!n.target.elementDescriptor)return await this.browser.blur(null),{succeedImmediately:!1,urlAfterCommand:this.browser.url()};let{elementInteractedDisplayString:h,thoughts:g}=await this.wrapElementTargetingCommand({ctx:e,tracer:t,target:n.target,command:n,cache:n.cache?.target,action:f=>this.browser.blur(f),options:{...n,targetName:"target",disableCache:i}});return{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:h,thoughts:g}}case"PRESS":let d=this.browser.url();await this.browser.press(n.value,{repeat:n.repeat,convertMeta:n.convertMeta??!0,delayMs:n.delayMs});let p={urlAfterCommand:this.browser.url(),succeedImmediately:!1};return Iu(d,p.urlAfterCommand)&&(p.succeedImmediately=!0,p.succeedImmediatelyReason="URL changed"),p;case"KEY_DOWN":return await this.browser.keyDown(n.value,{convertMeta:n.convertMeta??!0}),{urlAfterCommand:this.browser.url(),succeedImmediately:!1};case"KEY_UP":return await this.browser.keyUp(n.value,{convertMeta:n.convertMeta??!0}),{urlAfterCommand:this.browser.url(),succeedImmediately:!1};case"REQUEST":{let h=new Vj,g=jj(fetch,h),f;try{f=new URL(n.url).hostname}catch{}return{data:{...await KR({command:n,baseUrl:this.browser.baseUrl,logger:a,fetchImplementation:g}),cookies:tT(h,f)},succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"GRAPHQL_REQUEST":return{data:await X_({command:n,baseUrl:this.browser.baseUrl,logger:a}),succeedImmediately:!1,urlAfterCommand:this.browser.url()};case"VISUAL_DIFF":return qR({ctx:e,tracer:t,command:n,disableCache:i,browser:this.browser,logger:a,storage:this.storage,screenshotStorage:this.visualDiffScreenshotStorage,targetingWrapper:h=>this.wrapElementTargetingCommand(h)});case"FILE_UPLOAD":{let h,g;if(n.fileSource.type==="URL"?(g=n.fileSource.url,h=await Ox({uri:n.fileSource.url,logger:a,orgId:this.orgId})):n.fileSource.type==="USER_FILE"&&(g=n.fileSource.name,h=await this.uploadedFileStorage?.getFileForUpload(n.fileSource.name,this.orgId)),!h)throw new _("UserConfigurationError",`Attempted to use non-existent file for upload step: ${g}`);await this.browser.setFileChooserHandler({...h,filename:n.filename});break}case"AUTH_SAVE":return{data:await this.browser.saveAuthState(),succeedImmediately:!1,urlAfterCommand:this.browser.url()};case"AUTH_LOAD":{let h;if(!n.storageState.trim())h=void 0;else if(h=await bo({orgId:this.orgId,code:n.storageState,fragment:!1,context:o,logger:a,localTools:this.localCodeEvalTools,signal:this.executeAbortController.signal}),typeof h!="object")throw new _("ActionFailureError",`Credentials must evaluate to an object (received ${typeof h} instead)`);let g;try{g=Hc.optional().parse(h)}catch(f){throw new _("ActionFailureError",`Credentials provided do not follow the required format: ${f}`)}await this.browser.loadAuthState(g);break}case"ELEMENT_CHECK":{let h=(n.timeout??an)*1e3,g=this.generator.getAgentConfig()?.assertion;if($R(n.assertion)&&!n.useSelector&&n.target.type==="description"&&g&&g!=="v1"){let y={id:n.id,type:"AI_ASSERTION",assertion:`There is no element on the page closely matches the following description. If the description has single quotes, remember that requires an exact text substring match. Description: ${n.target.elementDescriptor}`,iframeUrl:n.iframeUrl,timeout:n.timeout,cache:n.cache&&"memory"in n.cache?{memory:n.cache?.memory}:void 0};try{let S=await tp({command:y,logger:a,aiPageFiltering:!!this.options?.aiPageFiltering,fixtures:this.getControllerFixtures(e),useMemory:this.shouldUseMemory(),source:"NEGATED_CHECK"});return{succeedImmediately:!1,thoughts:`The element described does not exist on the page: ${S.thoughts}`,urlAfterCommand:this.browser.url(),afterScreenshotOverride:S.afterScreenshotOverride}}finally{y.cache?.memory&&gu(n,y.cache?.memory.traces,a)}}let f=await VR({command:n,tracer:t,timeoutMs:h,targetingWrapper:y=>this.wrapElementTargetingCommand(y),fixtures:this.getControllerFixtures(e),disableCache:i});return{fail:!f.success,data:f.data,elementInteracted:f.elementInteractedDisplayString,thoughts:f.err?.message??f.thoughts??`Element assertion ${f.success?"succeeded":"failed"}.`,succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"PAGE_CHECK":{let h=await wn({action:async()=>Gu({assertion:n.assertion,browser:this.browser,logger:a,timeout:n.timeout,signal:this.executeAbortController.signal,autoExpandIframes:!!this.browser.userBrowserSettings.autoExpandIframes}),frameConfig:n.iframeUrl?{type:"url",url:n.iframeUrl}:void 0,browser:this.browser,logger:a});return{fail:!h.success,data:h.data,thoughts:h.success?"Page assertion passed.":h.err?.message??`Page assertion still failing after ${n.timeout} seconds.`,urlAfterCommand:this.browser.url(),succeedImmediately:!1}}case"REGISTER_REQUEST_LISTENER":{let h=new Po(n.requestMatcher),g=this.browser.registerRequestListener(h);return this.registeredListeners[n.key]=g.then(async f=>await Pf(f)).catch(f=>{a.error({err:f},"Failed to get request listener response")}),{succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"AWAIT_LISTENER":{let h=this.registeredListeners[n.key];if(!h)throw new _("ActionFailureError",`No listener registered with key: ${n.key}`);let g=n.timeout??10;return{data:await j(h,{milliseconds:g*1e3,message:`Request listener timed out after ${g} seconds`}),succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"RECORD_REQUESTS":{let h=new Po(n.requestMatcher);return this.recordedRequests[n.key]={},this.browser.registerRequestRecorder(n.key,h,{onRequestStart:(g,f)=>{this.recordedRequests[n.key][g]=Vd(f)},onRequestComplete:(g,f)=>{this.recordedRequests[n.key][g]=Vd(f)}}),{succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"GET_RECORDED_REQUESTS":{let h=this.recordedRequests[n.key];if(!h)throw new _("ActionFailureError",`No recorder registered with key: ${n.key}`);return delete this.recordedRequests[n.key],{data:Object.values(h),succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"SET_HEADER":{let h;return n.requestMatcher&&(h=new Po(n.requestMatcher)),this.browser.setHeader(n.name,n.value,h),{succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"MOCK_ROUTE":return{data:{key:this.browser.registerMock(n.key,new Po(n.requestMatcher),async(g,f)=>{let y=await bo({orgId:this.orgId,code:n.responseGenerator,fragment:!1,context:o,timeoutMs:void 0,logger:a,localTools:this.localCodeEvalTools,mock:{request:g,response:f},disallowVariableUpdates:!0,responseSerialization:"RESPONSE"}),S=pT.parse(y);return new Response(S.body,{status:S.status,headers:S.headers})},n.fetchOriginalResponse??!1)},succeedImmediately:!1,urlAfterCommand:this.browser.url()};case"REMOVE_ROUTE_MOCK":return this.browser.removeMock(n.key),{succeedImmediately:!1,urlAfterCommand:this.browser.url()};case"OFFLINE_MODE":return await this.browser.setOfflineMode(n.enable),{succeedImmediately:!1,urlAfterCommand:this.browser.url()};default:return(h=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(n)}return{succeedImmediately:!1,urlAfterCommand:this.browser.url()}}async getReverseMappedDescription({browserState:e,targetId:t,disableCache:n,screenshot:o}){return(await this.generator.getReverseMappedDescription({browserState:e,target:t,screenshot:o},{disableCache:n,abortSignal:this.executeAbortController.signal,loggerTags:We(this.logger)})).phrase}async stopRecordMode(){this.recordAbortController?.abort(),await this.browser.clearAllCdpHighlights()}async startRecordMode({params:e,abortController:t,isClickToRecord:n}){this.recordAbortController=t;let o=new Xd({signal:t.signal,...e});return await this.browser.startRecording(this.recordAbortController.signal,o,n),o}async runSectionAutohealing(e){return this.generator.getAutohealingProposal(e,{disableCache:!0,abortSignal:this.executeAbortController.signal,loggerTags:We(this.logger)})}async getFailureRecoveryPlan(e){return this.generator.getFailureRecoveryPlan(e,{disableCache:!0,abortSignal:this.executeAbortController.signal,loggerTags:We(this.logger)})}};import{cloneDeep as $j}from"lodash-es";var Wj={showOverlay:!1},rp=class{sessions=new Map;sessionCountByIp=new Map;getCurrentConnectionsByIp(e){return this.sessionCountByIp.get(e)??0}getCurrentSessionsByIp(){return Object.fromEntries(this.sessionCountByIp)}reserveCapacityByIp(e){e&&this.sessionCountByIp.set(e,(this.sessionCountByIp.get(e)??0)+1)}releaseCapacityByIp(e){e&&this.sessionCountByIp.set(e,Math.max(this.getCurrentConnectionsByIp(e)-1,0))}registerSession({controller:e,context:t,cleanup:n,clientIp:o,sessionId:i,socket:a}){return this.sessions.set(i,{controller:e,context:t,cleanup:n,clientIp:o,browserBehavior:$j(Wj),socket:a}),i}removeSession(e,t){(async()=>{let o=this.sessions.get(e);if(!o)return;this.releaseCapacityByIp(o.clientIp);let{controller:i}=o;try{i.setClosed(),await i.browser.cleanup()}catch(a){t.error({err:a},"Error cleaning up browser in global state manager")}try{await o.cleanup?.()}catch(a){t.error({err:a},"Error running cleanup function in global state manager")}this.sessions.delete(e)})()}getSession(e){return this.sessions.get(e)}};function Q_(r,e,t,n){let o=Date.now(),i=Date.now(),a,s,c,l,u=!1,d=async(g,f)=>{if(!g.closed&&!g.isInPageLoad)try{let y=c;c=void 0;let S=g.url(),E=f.toEditorDisplayCopy();JSON.stringify(E)===JSON.stringify(a)&&S===l&&o>i||(r.emit("browserState",{logsPerPage:y?.logsPerPage,harPages:y?.harPages,harEntries:y?.harEntries,viewport:g.getViewport(),url:S,iframeSrcUrls:s??[],context:E,isInPageLoad:g.isInPageLoad}),o=Date.now()),l=S,a=E}catch(y){if(!r.connected)return;let S=y instanceof Error?y.message:`${y}`;if(S.includes("Frame was detached")||S.includes("Not attached to an active page")||S.includes("browser has been closed")||S.includes("UserInfrastructureError"))return;t.error({err:y,sessionId:e},"Error grabbing browser state")}},p=setInterval(()=>{let g=n.getSession(e),f=g?.controller?.browser;if(!f||f.closed){t.debug("Clearing browser state socket cron due to the browser being closed"),clearInterval(p);return}d(f,g.context)},1e3),m=(g,f)=>!!(JSON.stringify(g)!==JSON.stringify(s)||f.logsPerPage.some(y=>y.length>0)||f.harPages&&Object.keys(f.harPages).length>0||f.harEntries&&Object.keys(f.harEntries).length>0),h=setInterval(async()=>{let f=n.getSession(e)?.controller?.browser;if(!f||f.closed){clearInterval(h);return}else if(u)return;u=!0;try{let y=await f.getAllFrameUrls(),S=f.retrieveAndClearDebugData();m(y,S)&&(s=y,c=S,i=Date.now())}catch(y){t.warn({err:y},"Failed to fetch extended details")}finally{u=!1}},2500);return{timers:[p,h]}}var qj=4;async function Z_({socket:r,logger:e,storageFactory:t,uploadedFileStorage:n,visualDiffScreenshotStorage:o,devicePixelRatio:i,generatorFactory:a,enricherFactory:s,authorization:c,settingsFactory:l,getOrgId:u,branchGetter:d,globalE2eStateManager:p}){let m=r.id,h=r.handshake.query.testId;if(!h)throw new Error("Socket connection request is missing testId");let g=await u({type:"e2e",testId:h}),f=await d?.();e=e.child({testId:h,orgId:g,sessionId:m,branch:f});let y=await a(g,e),S=await s(g,e),E=await l(g,e),A=await t(g),{testMetadata:b,baseUrl:C,envName:x,browserConfig:I,aiSettings:M,environmentVariables:X,localCodeEvalTools:W}=await Li({testId:h,orgId:g,logger:e,storage:A,authorization:c,settings:E}),G=p.getSession(m);if(G)return e.info("Associating connection with existing session (likely reconnect)"),await G.controller.browser.clearAllCdpHighlights(),{type:"e2e",sessionId:m,orgId:g,testId:h};let H=r.handshake.headers["x-forwarded-for"]?.split(",")[0];if(e.info({clientIp:H,event:"connect",args:r.handshake.query},"Websocket event (connect)"),H&&p.getCurrentConnectionsByIp(H)>=qj)throw e.error({clientIp:H,sessions:p.getCurrentSessionsByIp(),...r.handshake.query},"Socket connection browser creation rate limit triggered"),new Error("You have exceeded the maximum number of connections allowed. Momentic limits the number of simultaneously open tabs to uphold browser reliability. Please close duplicate tabs and try again later.");p.reserveCapacityByIp(H);try{await Kj({socket:r,baseUrl:C,envName:x,testMetadata:b,orgId:g,sessionId:m,logger:e,environmentVariables:X,clientIp:H,devicePixelRatio:i,storage:A,uploadedFileStorage:n,visualDiffScreenshotStorage:o,localCodeEvalTools:W,generator:y,enricher:S,browserConfig:I,aiSettings:M,globalE2eStateManager:p})}catch(U){throw e.warn({err:U},"Error setting up socket session, possibly due to client closing the connection"),p.releaseCapacityByIp(H),U}return{type:"e2e",sessionId:m,testId:h,orgId:g}}async function Kj({socket:r,baseUrl:e,envName:t,devicePixelRatio:n,testMetadata:o,orgId:i,sessionId:a,logger:s,storage:c,uploadedFileStorage:l,visualDiffScreenshotStorage:u,localCodeEvalTools:d,generator:p,environmentVariables:m,browserConfig:h,aiSettings:g,clientIp:f,enricher:y,globalE2eStateManager:S}){let E={viewport:o.advanced?.viewport??Gt,locale:o.advanced?.locale??oo,timezoneId:o.advanced?.timezone??io,geolocation:o.advanced?.geolocation??ao,colorScheme:o.advanced?.colorScheme};n&&(E.deviceScaleFactor=n);let A=o.id,b=await zd({settings:h,orgId:i,baseUrl:e,envName:t,testName:o.name,localTools:d,envVariables:m,logger:s,customHeaders:void 0});s=s.child({orgId:i,sessionId:a,testId:A});let C=await Ur.init({baseUrl:e,userBrowserSettings:b,enricher:y,storage:c,logger:s,contextArgs:E,iconKnowledgeBase:null,callbacks:{onTabsChange:(W,G)=>{r.emit("tabs",{tabs:W,activeTab:G})},onScreencastFrame:(W,G)=>{let H=r;dn&&(H=r.compress(!0)),H.emit("screenshot",{buffer:W},()=>{G()})},onSvgsCollected:W=>{r.emit("newIconDetected",{numIcons:W.newSvgs.length}),c.saveNewIcons(W,s)}}});await C.navigate({url:e,initialNavigation:!0});let x=new Lo({browser:C,generator:p,logger:s,orgId:i,options:{scratchPadId:void 0,slowMoMs:b.slowMoMs,autoFollowNewTabs:b.autoFollowNewTabs,useMemory:g.useMemory,aiPageFiltering:g.aiPageFiltering},storage:c,localCodeEvalTools:d,uploadedFileStorage:l,visualDiffScreenshotStorage:u}),I=Q_(r,a,s,S),M=async()=>{I.timers.forEach(W=>clearInterval(W))},X=new ir({baseUrl:e,testName:o.name,currentUrl:x.browser.url(),variablesFromEnvironment:m,envName:t});if(!r.connected)throw await C.cleanup(),new Error("Socket not connected anymore, not proceeding with session setup");r.emit("session",{url:e,userAgent:Ur.USER_AGENT,viewport:x.browser.getViewport(),sessionId:a}),S.registerSession({controller:x,context:X,sessionId:a,cleanup:M,clientIp:f,socket:r})}async function Li({testId:r,orgId:e,logger:t,storage:n,authorization:o,settings:i}){let a=await n.fetchTestMetadata(r,t);if(!a)throw new Error(`Test metadata could not found for test ${r}`);let s;o?.type==="API_KEY"&&(s=new gn({httpClient:new Nt({...o,logger:t}),fakerSeed:void 0}));let c=a.envs?.find(g=>g.default),l;c&&(l=await n.fetchEnvironment(c.name,t));let u=l&&"browser"in l?l.browser:void 0,d={...i.browser,...u,...a.advanced},p=a.baseUrl||l?.variables?.[Ct];if(!p)throw new Error("Base URL is empty in both test options and the configured environment");let m={...l?.variables};await Promise.all((a.parameters??[]).map(async g=>{let f=await gr({orgId:e,s:g.defaultValue,context:ir.dummyContext(a.name,l?.name,m),logger:t,localTools:s});m[g.name]=f}));let h={...i.ai,...a.advanced};return{localCodeEvalTools:s,baseUrl:p,envName:l?.name,testName:a.name,browserConfig:d,environmentVariables:m,testMetadata:a,aiSettings:h}}var Zf=class{parentTracer=null;socket;step;orgId;constructor({step:e,socket:t,parentTracer:n,orgId:o}){this.socket=t,this.parentTracer=n,this.step=e,this.orgId=o}getParentStepIdChain(){return this.parentTracer?this.parentTracer?.getParentStepIdChain()??[]:[]}recordStepDuration(e){let t=e.step.type!=="PRESET_ACTION"?e.step.type:e.step.command.type;tr.distribution("test_step_duration",e.durationMs,[`type:${t}`,"platform:browser","executor:editor",`orgId:${this.orgId}`])}attachBeforeScreenshot(){}attachAfterScreenshot(){}attachBeforeHtmlSnapshot(){}attachAfterHtmlSnapshot(){}recordTargetAutoHeal(){}async finish(e){switch(e.step.status){case"SUCCESS":this.socket.emit("success",{...e,parentStepIdChain:this.getParentStepIdChain()});return;case"FAILED":this.socket.emit("failure",{...e,parentStepIdChain:this.getParentStepIdChain()});return;case"CANCELLED":this.socket.emit("cancelled",{...e,parentStepIdChain:this.getParentStepIdChain()});return}}async startSubSteps(){return new $n({parentStep:this.step,socket:this.socket,parentTracer:this,orgId:this.orgId})}},$n=class{stepFrequenciesByType={};parentTracer;parentStep;socket;orgId;recordStepStat(e){e.type!=="PRESET_ACTION"?this.stepFrequenciesByType[e.type]=(this.stepFrequenciesByType[e.type]||0)+1:this.stepFrequenciesByType[e.command.type]=(this.stepFrequenciesByType[e.command.type]||0)+1}sendFinalizedStepStats(){for(let[e,t]of Object.entries(this.stepFrequenciesByType))tr.increment("test_step_execution",t,[`type:${e}`,"platform:browser","executor:editor",`orgId:${this.orgId}`])}constructor({parentStep:e,socket:t,parentTracer:n,orgId:o}){this.parentTracer=n,this.parentStep=e,this.socket=t,this.orgId=o}async getScreenshot(){throw new Error("getScreenshot is not supported in the editor")}async getHtmlSnapshot(){throw new Error("getHtmlSnapshot is not supported in the editor")}getParentStepIdChain(){return this.parentStep?[...this.parentTracer?.getParentStepIdChain()??[],this.parentStep.id]:[]}async startStep(e){return this.recordStepStat(e.step),this.socket.emit("started",{stepId:e.step.id,parentStepIdChain:this.getParentStepIdChain(),attempt:e.attempt}),new Zf({step:e.step,parentTracer:this,socket:this.socket,orgId:this.orgId})}async finish(){this.sendFinalizedStepStats()}},np=class{constructor(e,t,n,o,i){this.socket=e;this.storage=t;this.orgId=n;this.testId=o;this.stepsBeforeRun=i}children=[];loggerBindings;setActiveVideo(){}async getScreenshot(){throw new Error("getScreenshot is not supported in the editor")}async getHtmlSnapshot(){throw new Error("getHtmlSnapshot is not supported in the editor")}attachConsoleLogs(){}attachNetworkLogs(){}attachBrowserCrashDump(){}async finish(){this.socket.emit("finished"),await Promise.all(this.children.map(e=>e.finish()))}async startBeforeStepList(){let e=new $n({orgId:this.orgId,parentStep:null,parentTracer:null,socket:this.socket});return this.children.push(e),e}async startMainStepList(){let e=new $n({orgId:this.orgId,parentStep:null,parentTracer:null,socket:this.socket});return this.children.push(e),e}async startAfterStepList(){let e=new $n({orgId:this.orgId,parentStep:null,parentTracer:null,socket:this.socket});return this.children.push(e),e}};var eS={currentlyExecutingRequests:{}},Xj=r=>async(e,t)=>{let{testId:n,orgId:o}=r.metadata,i=await r.settingsFactory(o,r.logger),a=await r.storageFactory(o),s,c=await Li({testId:n,orgId:o,logger:r.logger,storage:a,authorization:r.authorization,settings:i}),l=`${n}|${c.baseUrl}`;try{let u=eS.currentlyExecutingRequests[l]??0;eS.currentlyExecutingRequests[l]=u+1,s=await Jj({...r,...e,...c,done:t})}finally{r.logger.info({result:s,sessionId:r.metadata.sessionId},"Test execution complete"),eS.currentlyExecutingRequests[l]--}},Jj=async({socket:r,steps:e,baseUrl:t,testMetadata:n,reInitialize:o,toStep:i,fromStep:a,storageFactory:s,aiSettings:c,browserConfig:l,metadata:u,logger:d,envName:p,testName:m,environmentVariables:h,localCodeEvalTools:g,done:f,cacheStorageFactory:y,globalE2eStateManager:S})=>{let{testId:E,sessionId:A,orgId:b}=u,C=A,x=S.getSession(A);if(!x)throw new Error("No active session found");let{controller:I,context:M}=x;I.setOpen(),d=d.child({testId:E,orgId:b,sessionId:A,runId:C}),d.info({steps:e.map(te=>`${te.type}${"command"in te?` - ${te.command.type}`:""}`),toStep:i,fromStep:a,reInitialize:o,envName:p,testName:m,baseUrl:t,context:M,browserConfig:l,aiSettings:c},"Socket execution parameters");let X=h??{},W=async()=>{o&&(await I.browser.reset({newUrl:t}),M.reset({baseUrl:t,currentUrl:I.browser.url(),variablesFromEnvironment:X,envName:p,testName:m}))},G=await s(b),H=await y(b),U=async()=>{try{await H.resolveStepCacheEntries({schemaVersion:n.schemaVersion,testId:E,stepLists:{steps:e},logger:d})}catch(te){d.error({err:te},"Failed to fetch step cache entries from Momentic server. This can drastically reduce test reliability and performance.")}};try{await Zs({promiseGenerator:async()=>Promise.all([W(),U()]),signal:I.executeAbortController.signal,codePath:"resolveStepCacheAndInitBrowser"}),I.setOpen()}catch(te){if(r.emit("finished"),te.name!=="AbortError")throw new Error(`Failed to setup browser for execution: ${te}`)}let V=Yj(e),me={collectDebugData:!1,reinitializeBrowser:!1,disableHealing:!0},q={orgId:b,runId:C,testMetadata:n,steps:e,fromStep:a,toStep:i,orgSettings:{ai:c,browser:l}},nt={controller:I,context:M,storage:G,codeEvalTools:g,usageTracker:new na,logger:d},De={test:{},step:{onDynamicAIActionStatusUpdateEvent:te=>{r.emit("dynamicCommandStatusUpdate",te)},onDynamicAIActionEvaluatingEvent:te=>{r.emit("dynamicCommandEvaluating",te)},onDynamicCommandGenerated:te=>{r.emit("dynamicCommandGenerated",te)},onDynamicCommandExecuted:te=>{r.emit("dynamicCommandExecuted",te)}}},dt=new np(r,G,b,E,V),Mt=await Hd({fixtures:nt,options:me,callbacks:De,inputs:q,testParams:{tracer:dt}});return Mt?.status==="PASSED"?await Au({logger:d,cacheStorage:H,orgId:b,testId:E,originalSteps:{steps:V},updatedSteps:{steps:e}}):Mt?.status==="FAILED"&&await wu({logger:d,cacheStorage:H,orgId:b,testId:E,originalSteps:{steps:V},updatedSteps:{steps:e}}),await dt.finish(),f?.(Mt),Mt.status};var eI={event:"execute",createHandler:Xj};import{cloneDeep as Qj}from"lodash-es";var Zj=r=>async({command:e},t)=>{let{logger:n,generatorFactory:o,metadata:i}=r,a=Qj(e),s=bv(a);if(s.category!=="NO_DESCRIPTION_PROVIDED"){if(s.category!=="NONE"){t?.({result:s});return}"cache"in a&&(a.cache=void 0);try{let l=await(await o(i.orgId,n)).getLintStepResult({command:a},{logger:n});t?.({result:l})}catch(c){n.error({event:"lint",err:c},"Failed to lint step"),t?.({result:void 0})}}},tI={event:"lintStep",createHandler:Zj};var eV=({metadata:r,logger:e,storageFactory:t,globalE2eStateManager:n})=>{let{sessionId:o,orgId:i}=r;return async(a,s)=>{let{description:c,command:l,testMetadata:u,returnScreenshot:d}=a;e.info({params:a},`Locate handler called - ${c}`);let p=n.getSession(o);if(!p)throw new Error("No active session found");let{controller:m,context:h}=p;m.setOpen();let g=await t(i),f=ri.parse(u.advanced??{}),y={},S;if(c){if("useSelector"in l&&l.useSelector)try{let E=await m.locateElementWithSelector(c,"iframeUrl"in l?l.iframeUrl:void 0);S=E.resolution.locator,y={target:E.target,thoughts:E.thoughts}}catch(E){e.warn({err:E},"Failed resolving target with selector"),s({err:`Failed locating element: ${E.message}`,decisions:E instanceof ln?E.decisions:void 0});return}else try{let E=await m.locateElement({description:c,disableCache:f.disableAICaching??!1,skipWait:!0,testContext:h,source:Jo(l),iframeUrl:"iframeUrl"in l?l.iframeUrl:void 0,memory:"cache"in l&&l.cache&&"target"in l.cache&&rc(l.cache.target.memory)?l.cache.target.memory:void 0,logger:e});y={target:E.target,thoughts:E.thoughts},S=E.resolution.locator}catch(E){(async()=>{try{let A=await m.browser.getCondensedHtml({skipWait:!0});e.warn({err:E,html:A.slice(0,1e5)},"Failed locating element with AI")}catch(A){e.warn({err:A},"Failed grabbing HTML after trying to locate element with AI")}})(),s({err:`${E.message}`});return}if(l.type==="SELECT_OPTION"&&S)try{y.options=await m.browser.getSelectOptions(S)}catch(E){e.warn({err:E},"Failed getting select options"),s({err:`Failed getting select options: ${E.message}`});return}e.info({result:y},"Locate handler result")}if(d)try{let{buffer:E,width:A,height:b}=await m.screenshotWithDimensions({clearHighlights:!0,locator:S}),C=await g.uploadScreenshot(E);y.screenshot={data:C,width:A,height:b},e.info({width:A,height:b},"Captured screenshot during locate")}catch(E){e.error({err:E},"Error capturing screenshot during locate"),s({err:`Error taking screenshot: ${E.message}`});return}if(s({result:y}),S)try{await Promise.all([m.browser.scrollIntoViewIfNeeded(S),m.browser.highlight(S)])}catch(E){e.warn({err:E},"Error highlighting element, continuing...")}}},rI={event:"locate",createHandler:eV};var tV=({metadata:r,logger:e,globalE2eStateManager:t})=>{let{sessionId:n}=r;return async({event:o,percentX:i,percentY:a})=>{let s=t.getSession(n);if(!s)throw new Error("No active session found");let c=s.controller.browser;if(c.closed||c.getActivePage().isClosed()){e.warn("Ignoring mouse move because the browser is closed");return}try{await c.clickMouseFromPositionPercentages(o,i,a)}catch(l){e.error({err:l},"Error performing click during cloud recording in control mode")}}},nI={event:"mouseClickEvent",createHandler:tV};var rV=({metadata:r,generatorFactory:e,logger:t,socket:n,globalE2eStateManager:o})=>{let{sessionId:i,orgId:a,testId:s}=r;return async({stepId:c,parentStepIdChain:l,attribute:u})=>{let d=o.getSession(i);if(!d)throw new Error("No active session found");let{controller:p}=d,m=await e(a,t);p.setOpen(),d.browserBehavior.showOverlay=!0;let h=new AbortController;h.signal.addEventListener("abort",async()=>{try{d.browserBehavior.showOverlay=!1,await p.stopRecordMode()}catch(y){t.warn({err:y},"Failed to stop record mode in target click socket handler")}},{once:!0});let g=!1,f=(y,S)=>{S.type!=="PRESET_ACTION"||S.command.type!=="CLICK"||(n.emit("targetRecordingUpdate",{type:y,stepId:c,parentStepIdChain:l,command:S.command,attribute:u}),h.abort(),g=!0)};setTimeout(()=>{g||(h.abort(),n.emit("targetRecordingUpdate",{type:"error",err:"Timed out waiting for click event",stepId:c,parentStepIdChain:l,attribute:u}))},1e4),await p.startRecordMode({params:{generator:m,logger:t,testId:s,orgId:a,callbacks:{onActionReceived:y=>f("clickReceived",y),onStepRecorded:y=>f("descriptionGenerated",y)}},abortController:h,isClickToRecord:!0}),n.emit("targetRecordingUpdate",{type:"listenersInitialized",stepId:c,parentStepIdChain:l,attribute:u})}},oI={event:"recordTargetClick",createHandler:rV};var nV=({metadata:r,logger:e,globalE2eStateManager:t})=>{let{sessionId:n}=r;return async({key:o})=>{let i=t.getSession(n);if(!i)throw new Error("No active session found");if(o==="Dead")return;let{controller:a}=i;if(a.browser.closed||a.browser.getActivePage().isClosed()){e.debug({sessionId:n},"Browser is closed, ignoring keyboard press socket event");return}try{a.setOpen(),await a.browser.keyDown(o,{})}catch(s){if(s.message.includes("has been closed")){e.debug({sessionId:n,err:s},"Browser is closed, ignoring key down socket event error");return}throw s}}},iI={event:"keyDownEvent",createHandler:nV};var oV=({metadata:r,logger:e,globalE2eStateManager:t})=>{let{sessionId:n}=r;return async({key:o})=>{let i=t.getSession(n);if(!i)throw new Error("No active session found");if(o==="Dead")return;let{controller:a}=i;if(a.browser.closed||a.browser.getActivePage().isClosed()){e.debug({sessionId:n},"Browser is closed, ignoring keyboard press socket event");return}try{a.setOpen(),await a.browser.keyUp(o,{})}catch(s){if(s.message.includes("has been closed")){e.debug({sessionId:n,err:s},"Browser is closed, ignoring key up socket event error");return}throw s}}},aI={event:"keyUpEvent",createHandler:oV};var iV=({metadata:r,logger:e,globalE2eStateManager:t})=>{let{sessionId:n}=r,o,i=0,a=(l,u)=>{let d=async()=>{o=void 0};clearTimeout(o),o=setTimeout(d,Math.min(1e3,250*(i+1)))},s,c=0;return async l=>{let u=t.getSession(n);if(!u)throw new Error("No active session found");let{controller:d,browserBehavior:p}=u,m=d.browser;if(m.closed||m.getActivePage().isClosed()){e.warn("Ignoring mouse move because the page is closed");return}if(l.event==="scroll"){let h=await m.scrollFromPositionPercentages(l.percentX,l.percentY,s?.x??0,s?.y??0),g=u.browserBehavior.recordingState?.transformer;g&&h&&g.recordScroll(h);return}p.showOverlay&&a(m,l);try{let h=await m.moveMouseFromPositionPercentages(l.percentX,l.percentY);c=0,s=h}catch(h){c++,c%5===0&&e.warn({err:h,mouseErrors:c},"Error in socket mouse move handler")}}},sI={event:"mouseMoveEvent",createHandler:iV};var aV=({metadata:r,generatorFactory:e,socket:t,logger:n,globalE2eStateManager:o})=>{let{sessionId:i,orgId:a,testId:s}=r;return async({stepId:c})=>{let l=o.getSession(i);if(!l)throw new Error("No active session found");let{controller:u,browserBehavior:d}=l,p=await e(a,n);n.info("Starting cloud recording");let m=new AbortController,h=await u.startRecordMode({params:{generator:p,logger:n,testId:s,orgId:a,callbacks:{onActionReceived:(g,f)=>{t.emit("stepRecorded",{stepId:c,step:g,offset:f})},onStepRecorded:(g,f)=>{t.emit("stepRecorded",{stepId:c,step:g,offset:f})}}},abortController:m,isClickToRecord:!1});d.recordingState={transformer:h}}},lI={event:"recordingStart",createHandler:aV};var sV=({metadata:r,logger:e,globalE2eStateManager:t})=>{let{sessionId:n}=r;return async()=>{let o=t.getSession(n);if(!o)throw new Error("No active session found");e.info("Stopping cloud recording"),await o.controller.stopRecordMode(),o.browserBehavior.recordingState=void 0,o.browserBehavior.showOverlay=!1}},cI={event:"recordingStop",createHandler:sV};var lV=({socket:r,metadata:e,logger:t,storageFactory:n,authorization:o,settingsFactory:i,globalE2eStateManager:a})=>async(s,c)=>{let{testId:l,sessionId:u,orgId:d}=e;t.info({testId:l,sessionId:u},"Refresh event received");let p=await i(d,t),m=await n(d),{baseUrl:h}=await Li({testId:l,orgId:d,logger:t,storage:m,authorization:o,settings:p}),g=a.getSession(u);if(!g){r.emit("error",{message:"No session to refresh"});return}let{controller:f}=g;f.setOpen(),await f.browser.refresh();let y=f.browser.getViewport();t.info({baseUrl:h,viewport:y},`Session refreshed for test ${l} at ${h}`),c()},uI={event:"refresh",createHandler:lV};var cV=({socket:r,metadata:e,logger:t,storageFactory:n,authorization:o,settingsFactory:i,globalE2eStateManager:a})=>async()=>{let{testId:s,sessionId:c,orgId:l}=e;t.info({testId:s,sessionId:c},"Reset event received");let u=await i(l,t),d=await n(l),{baseUrl:p,envName:m,testName:h,environmentVariables:g}=await Li({testId:s,orgId:l,logger:t,storage:d,authorization:o,settings:u}),f=a.getSession(c);if(!f){r.emit("error",{message:"No session to reset"});return}let{controller:y,context:S}=f;await y.browser.reset({newUrl:p});let E=y.browser.baseUrl;S.reset({baseUrl:E,currentUrl:y.browser.url(),variablesFromEnvironment:g,envName:m,testName:h});let A=y.browser.getViewport(),b=Ur.USER_AGENT;t.info({baseUrl:p,viewport:A},`Session reset for test ${s} at ${E}`),r.emit("session",{url:E,userAgent:b,viewport:A,sessionId:c})},dI={event:"reset",createHandler:cV};var uV=({metadata:r,globalE2eStateManager:e})=>{let{sessionId:t}=r;return async({url:n})=>{let o=e.getSession(t);if(!o)throw new Error("No active session found");await o.controller.browser.switchToPage({type:"SUBSTRING",substring:n})}},pI={event:"switchTab",createHandler:uV};async function mI(r){return Z_(r)}var hI=[LR,eI,rI,dI,uI,PR,pI,tI,oI,lI,cI,sI,nI,iI,aI,OR,MR];var gI=r=>{let{logger:e}=r,t=new dV(r.baseServer,{cors:{origin:"*",methods:["GET","POST"]},pingTimeout:15*60*1e3,pingInterval:15*60*1e3,maxHttpBufferSize:1e7,perMessageDeflate:!0});return t.on("connection",async n=>{let o;try{e.info({event:"connection",transport:n.conn.transport.name},"Websocket connection established"),o=await mI({...r,socket:n,logger:e}),e=e.child(o)}catch(i){e.error({event:"connection",type:"websocket",err:i},"Failed to setup connection"),n.emit("error",{message:i instanceof Error?i.message:`${i}`}),n.disconnect(!0);return}hI.forEach(i=>pV(i,{...r,socket:n,metadata:o,logger:e}))}),t},pV=(r,e)=>{let t=r.createHandler(e),n=(...o)=>{["mouseMoveEvent","keyDownEvent","keyUpEvent","mouseClickEvent","lintStep"].includes(r.event)||e.logger.debug({...e.metadata,event:r.event},`Websocket event (${r.event})`);let i=a=>{e.logger.error({event:r.event,type:"websocket",err:a instanceof Error?a:new Error(`${a}`)},"Unhandled exception in socket handler"),e.socket.emit("error",{message:a instanceof Error?a.message:`${a}`})};try{let a=t.apply(void 0,o);a&&typeof a.catch=="function"&&a.catch(i)}catch(a){i(a)}};e.socket.on(r.event,n)};import{Router as SV}from"express";import{Router as hV}from"express";import Hl from"fs";import Bl from"path";import{v4 as gV}from"uuid";import fV from"yaml";import{hostname as mV}from"os";var tS="2.21.3",Xe=ou({app:"desktop-server",hostname:mV(),disableConsoleLogs:!0}).child({cliVersion:tS});(async()=>{try{let r=await ll(Xe);r.gitBranchName&&Xe.addBinding("branch",r.gitBranchName)}catch{}})();var Va=hV();async function rS(r){return(await Du(r,Xe)).map(n=>{let o=r.modules[n.moduleId];if(!o){T.warn(`Found a dangling module with ID ${n.moduleId} that could not be found on disk.`);return}return{...o,content:n}}).filter(n=>n!==void 0)}Va.get("/",Re(async(r,e)=>{let t=ce(),n=await Q(t),o=await rS(n);e.status(200).json(o)}));Va.post("/",Re(async(r,e)=>{let t;try{t=PT.parse(r.body)}catch(s){e.status(400).json({error:`Invalid request body: ${s}`});return}try{ro(t.name)}catch(s){e.status(400).json({error:`Invalid module name: ${s}`});return}let n=ce(),o=(await Q(n)).modules;if(Object.values(o).find(s=>s.name===t.name)){e.status(400).send(`A module with the name "${t.name}" already exists. Please choose a different name.`);return}let i=Bl.join(n.rootDir,t.folderPath??"");if(!Hl.existsSync(i)||!Hl.statSync(i).isDirectory()){e.status(400).json({error:`The folder configured for module creation '${i}' does not exist.`});return}let a=await Nu({...t,folder:i,project:n});e.status(201).json(a)}));Va.get("/:moduleId",Re(async(r,e)=>{if(!r.params.moduleId){e.status(400).json({error:"Missing moduleId in url path."});return}let t=await Q(ce()),n=t.modules[r.params.moduleId];if(!n){e.status(404).json({error:"Module not found."});return}try{let o=await Xr(n,t,T);e.json(o)}catch(o){e.status(400).json({err:o})}}));Va.post("/:moduleId/duplicate",Re(async(r,e)=>{if(!r.params.moduleId){e.status(400).json({error:"Missing moduleId in url path."});return}let t;try{t=IT.parse(r.body)}catch(g){e.status(400).json({error:`Invalid request body: ${g}`});return}try{ro(t.name)}catch(g){e.status(400).json({error:g.message});return}let n=ce(),o=await Q(n),i=o.modules[r.params.moduleId];if(!i){e.status(404).json({error:"Module not found."});return}if(Object.values(o.modules).find(g=>g.name===t.name)){e.status(400).send(`A module with the name "${t.name}" already exists. Please choose a different name.`);return}let a=await Xr(i,o,T),s=Bl.join(n.rootDir,Bl.dirname(i.relativePath));if(!Hl.existsSync(s)||!Hl.statSync(s).isDirectory()){e.status(400).json({error:`The folder configured for module creation '${s}' does not exist.`});return}let c=Oe(t.name),l=Bl.join(s,`${c}.module.yaml`),u=gV(),{stepsToSave:d}=await ct({stepLists:{steps:a.steps},createNewCacheIds:!0,cacheCreationParams:{orgId:_t()}}),p={fileType:de.MODULE,schemaVersion:Te,moduleId:u,name:t.name,description:"",enabled:!0,steps:d.steps,parameters:a.parameters,defaultParameters:a.defaultParameters,parameterEnums:a.parameterEnums,defaultCacheKey:a.defaultCacheKey,defaultCacheTtl:a.defaultCacheTtl,defaultCacheAllInvocations:a.defaultCacheAllInvocations,autoAuth:a.autoAuth,advanced:a.advanced},m=fV.stringify(p);Hl.writeFileSync(l,m,"utf-8");let h={relativeFilePath:Bl.relative(n.rootDir,l)};e.status(201).json(h)}));Va.patch("/:moduleId/metadata",Re(async(r,e)=>{if(!r.params.moduleId){e.status(400).json({error:"Missing moduleId in url path."});return}let t;try{t=MT.parse(r.body)}catch(i){e.status(400).json({error:`Invalid request body: ${i}`});return}let n=ce(),o=await Q(n);uR({moduleId:r.params.moduleId,content:t,momenticFiles:o,logger:T,project:n}),e.status(201).json({message:"ok"})}));var fI=Va;var SI=SV();SI.get("/",Re(async(r,e)=>{let t=ce(),n=await Q(t),o=new Set;n?.tests&&Object.values(n.tests).forEach(l=>{l.labels?.forEach(u=>o.add(u))});let i=Array.from(o).sort(),a=Object.values(n.tests),s=await rS(n),c={labels:i,tests:a,modules:s};e.status(200).json(c)}));var yI=SI;import{Router as yV}from"express";var nS=yV();nS.get("/",Re((r,e)=>{let t=ku(ce(),Xe);e.status(200).json(t)}));nS.get("/names",Re((r,e)=>{let n=ce().config.environments?.map(o=>o.name)??[];e.status(200).json(n)}));var EI=nS;import{Router as EV}from"express";var TI=EV();TI.get("/",Re((r,e)=>{let t={userId:So(),orgId:_t()};e.status(200).json(t)}));var bI=TI;import{StreamableHTTPServerTransport as A$}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{isInitializeRequest as w$}from"@modelcontextprotocol/sdk/types.js";import{randomUUID as C$}from"crypto";import{Router as x$}from"express";import{McpServer as v$}from"@modelcontextprotocol/sdk/server/mcp.js";import{SSEServerTransport as R$}from"@modelcontextprotocol/sdk/server/sse.js";import{streamObject as AV}from"ai";import sp from"dedent";import{z as No}from"zod";import{tool as TV}from"ai";import{z as bV}from"zod";var op=(r,e)=>({builder:n=>TV({description:r.schema.description,inputSchema:bV.object(r.schema.inputSchema),execute:async o=>{let i=e(n);n.logger.info({input:o},`Executing tool ${r.schema.name}`);try{await r.handle(n,o,i,void 0)}catch(s){i.addError(String(s))}let a=await i.serialize();return a.isError?n.logger.error({toolName:r.schema.name,input:o,err:a.content.map(s=>s.text).join(`
|
|
4143
4143
|
`)},"Tool execution resulted in error"):n.logger.info({toolName:r.schema.name,input:o},"Tool execution completed"),a}}),tool:r});var zl=class{results=[];isError;addResult(e){this.results.push(e)}addError(e){this.results.push(`Error: ${e}`),this.isError=!0}getResult(){return this.results.join(`
|
|
4144
4144
|
`)}async serialize(){let e=[];return this.results.length&&(e.push("### Result"),e.push(this.results.join(`
|
|
4145
4145
|
`)),e.push("")),{content:[{type:"text",text:e.join(`
|
|
@@ -4536,8 +4536,8 @@ ${r.map(p=>`${gt}- ${p}`).join(`
|
|
|
4536
4536
|
`)}`),Object.values(e.tests).forEach(p=>{r.some(m=>p.relativePath.includes(m))&&c.add(p.fullFilePath)}))}else{!n&&!await Lt("No test paths or substrings were provided. Do you want to run all tests?")&&(s.error("Cancelled by user."),process.exit(1));let u=Object.values(e.tests);s.info(`Reading all ${u.length} tests in the project from local disk.`),u.forEach(d=>{c.add(d.fullFilePath)})}for(let u of c){let d=xS.relative(t.rootDir,u);o&&!o.some(p=>new RegExp(p).test(d))&&c.delete(u),i&&i.some(p=>new RegExp(p).test(d))&&c.delete(u)}let l=Array.from(c).map(async u=>{try{let d=await ut(u,ne,e);if(tW.gt(d.schemaVersion,Te)&&s.warn(`Test ${u} has schema version ${d.schemaVersion}, which is greater than what is currently supported by this SDK. Please update your momentic package version to avoid unexpected behavior.`),a&&a.length>0){let p=d.labels||[];if(!a.some(h=>p.includes(h)))return null}return{...d,fullFilePath:u,relativeFilePath:xS.relative(t.rootDir,u)}}catch(d){s.error(`Failed to read and resolve test at '${u}': ${d}`),process.exit(1)}});return Promise.all(l).then(Z$)}function NP({testDefinitions:r,quarantinedTestReasons:e,onlyQuarantined:t=!1,skipQuarantined:n=!1}){if(t){let[u,d]=Pp(r,h=>h.id in e),[p,m]=Pp(u,h=>h.disabled||n);return{testsToSkip:p,quarantinedTestsToSkip:[],testsToRun:m,quarantinedTestsToRun:[]}}let[o,i]=Pp(r,u=>u.disabled),[a,s]=Pp(i,u=>u.id in e);return{testsToSkip:o,testsToRun:s,quarantinedTestsToRun:n?[]:a,quarantinedTestsToSkip:n?a:[]}}function DP({testsToRun:r,quarantinedTestsToRun:e,quarantinedTestReasons:t,testInputMatrix:n}){let o=[],i=(a,s,c)=>{n?n.forEach((l,u)=>{o.push({inputs:l,inputIndex:u,testDefinition:a,quarantined:s,quarantinedReason:c})}):o.push({inputs:void 0,testDefinition:a,quarantined:s,quarantinedReason:c})};return r.forEach(a=>i(a,!1)),e.forEach(a=>i(a,!0,t[a.id])),o}async function kP({project:r,apiClient:e}){let t=await Q(r),n=await Ya({tests:[],momenticFiles:t,yes:!0,project:r,logger:new li(40,{})}),o=(await e.getQuarantinedTests()).quarantined,i=new Set(o.map(s=>s.testId)),a=n.filter(s=>i.has(s.id));T.info(a.map(s=>s.relativeFilePath).join(`
|
|
4537
4537
|
`))}async function UP({test:r,reason:e,apiClient:t,project:n,identity:o}){let i=(await Q(n)).tests,a=Object.values(i),s=(await t.getQuarantinedTests()).quarantined,c=new Set(s.map(p=>p.testId)),l=a.filter(p=>c.has(p.id)),u=await _p({prompt:"Select a test to unquarantine.",inputtedTest:r,testOptions:l}),d=await Ip({prompt:"Enter a reason for unquarantining the test.",inputtedReason:e});await t.unquarantineTest(u,d,o),T.success(`Test ${u.name} has been successfully removed from quarantine.`)}function FP(r){return r?Oe(r):"Unknown suite"}async function BP({client:r,orgId:e,suitePaths:t,wait:n,waitTimeout:o,...i}){let{suiteRunIds:a,runGroupIds:s}=await r.queueSuiteRuns({paths:t,...i});ne.info({orgId:e,suiteRunIds:a,runGroupIds:s,suitePaths:t},"Queued suites remotely"),T.dimmed(`Queued ${t.length} suites.`),n||process.exit(0);let c=Date.now();T.dimmed(`Waiting for ${t.length} suites to finish. You can view results upon completion at:`);for(let f of s)T.dimmed(`${gt}- ${r.getAppUrl()}/run-groups/${f}`);let l=new Set,u=[],d=f=>(f.status==="FAILED"||f.status==="PASSED"||f.status==="CANCELLED")&&f.runs.every(S=>S.status==="FAILED"&&(S.failureReason||S.finishedAt&&Date.now()-S.finishedAt.getTime()>30*1e3)||S.status==="PASSED"||S.status==="CANCELLED"),p=await au({name:"suites",getResults:async()=>{let f=s.filter(E=>!u.some(A=>A.id===E)),y=await r.bulkGetRunGroupStatus(f),S=[];for(let E of y)d(E)?u.push(E):S.push(E);return[...u,...S]},timeoutMs:o?o*1e3:void 0,checkDone:f=>(f.forEach(y=>{y.status==="RUNNING"&&(l.has(y.id)||(l.add(y.id),T.log(`${l.size}/${s.length} ${FP(y.suite?.name)}`)))}),f.every(d))}),m=r.getAppUrl(),g=la({results:p,startTime:c,onFailed:f=>{let y=FP(f.suite?.name),S=f.runs.filter(A=>A.status==="FAILED").length,E=f.runs.length;T.error(`${y} (${S}/${E} tests failed):`);for(let A of f.runs)if(A.status==="FAILED"){let b=A.testName||A.test?.name;T.error(` ${b?Oe(b):"Unknown test"} (${m}/runs/${A.id})`)}},entity:"suite",getDisplayLine:f=>` ${f.suite?.name?Oe(f.suite.name):"Unknown suite name"} (${m}/run-groups/${f.id})`});process.exit(g.failed>0?1:0)}async function HP({tests:r,client:e,orgId:t,...n}){!n.yes&&!await Lt(`This command will queue ${r.length} tests to run remotely on Momentic's infrastructure. Results will be available on ${e.getAppUrl()}. Continue?`)&&process.exit(1);let{queuedTests:o,runIds:i}=await e.queueTests({testPaths:r,...n});if(ne.info({queuedTests:o,runIds:i,orgId:t},"Queued tests remotely"),T.dimmed(`Queued ${o.length} tests. Processing time may depend on a variety of factors, including how many tests have already been queued from your organization.`),n.wait||process.exit(0),!i.length)return;T.dimmed(`Waiting for ${o.length} tests to complete.`);let a=new Set,s=[],c=m=>m.status==="FAILED"&&m.failureReason||m.status==="PASSED"||m.status==="CANCELLED",l=e.getAppUrl(),u=Date.now(),d=await au({name:"runs",getResults:async()=>{let m=i.filter(f=>!s.some(y=>y.id===f)),h=await e.bulkGetRunStatus(m),g=[];for(let f of h)c(f)?s.push(f):g.push(f);return[...s,...g]},timeoutMs:n.waitTimeout?n.waitTimeout*1e3:void 0,checkDone:m=>(m.forEach(h=>{if(h.status==="RUNNING"&&!a.has(h.id)){a.add(h.id);let g=h.testName||h.test?.name;g&&T.log(`${a.size}/${o.length} ${Oe(g)}`)}}),m.every(c))}),p=la({results:d,startTime:u,onFailed:m=>{let h=m.testName||m.test?.name;su(m,h?Oe(h):"Unknown test")},getDisplayLine:m=>{let h=m.testName||m.test?.name,g=` ${h?Oe(h):"Unknown test"}`;return m.id&&(g+=` (${l}/runs/${m.id})`),g},entity:"test"});process.exit(p.failed>0?1:0)}import{randomUUID as HW}from"crypto";import zW from"fs";import{existsSync as gW,mkdirSync as fW,statSync as SW}from"fs";import{randomUUID as zP}from"crypto";import _S from"fs";import{hostname as rW}from"os";import IS from"path";async function Mp(r,e,t,n){if(n){let o=await e.getScreenshot(r,n);if(o){let i=`${n}-screenshot.jpeg`,a=IS.join(t,i);return _S.writeFileSync(a,o),i}}}async function nW(r,e,t,n){let o=n.runId??zP(),i={uuid:o,historyId:o,testCaseId:n.test.id,fullName:n.test.name,name:Oe(n.test.name),status:n.status==="PASSED"?"passed":n.status==="CANCELLED"?"skipped":"failed",start:n.lastAttemptStartedAt.getTime(),stop:n.finishedAt.getTime(),parameters:[],labels:[{name:"suite",value:t.suiteName},{name:"host",value:rW()},{name:"platform",value:"momentic"},{name:"attempts",value:n.attempts.toString()}],steps:[]};n.runId&&i.labels?.push({name:"runUrl",value:`https://app.momentic.ai/runs/${n.runId}`});for(let[s,c]of Object.entries(n.parameters))c!=null&&i.parameters.push({name:s,value:JSON.stringify(c)});n.results&&await oW(r,e,t.folder,i.steps,n.results);let a=`${o}-result.json`;_S.writeFileSync(IS.join(t.folder,a),JSON.stringify(i,void 0,2))}async function Xa(r,e,t,n){let o={name:fo(n),start:n.startedAt.getTime(),stop:n.finishedAt.getTime(),status:n.status==="SUCCESS"?"passed":n.status==="CANCELLED"?"skipped":"failed",labels:[],steps:[],attachments:[]};n.beforeUrl&&o.labels?.push({name:"URL before step",value:n.beforeUrl}),n.afterUrl&&o.labels?.push({name:"URL after step",value:n.afterUrl});let i=await Mp(r,e,t,n.beforeSnapshot);i&&o.attachments.push({name:"Screenshot before step",source:i,type:"image/jpeg"});let a=await Mp(r,e,t,n.afterSnapshot);if(a&&o.attachments.push({name:"Screenshot after step",source:a,type:"image/jpeg"}),n.message&&(o.statusDetails={message:n.message}),n.data){let s=`${zP()}-attachment.json`,c=IS.join(t,s);_S.writeFileSync(c,JSON.stringify(n.data,null,2)),o.attachments.push({name:"Step output data",source:s,type:"text/plain"})}return o}async function oW(r,e,t,n,o){for(let i of o)switch(i.type){case"PRESET_ACTION":{n.push(await Xa(r,e,t,i));break}case"CONDITIONAL":{let a=await Xa(r,e,t,i);a.steps=[],i.assertionResult&&a.steps.push(await Xa(r,e,t,i.assertionResult)),a.steps.push(...await Promise.all(i.results.map(s=>Xa(r,e,t,s)))),n.push(a);break}case"AI_ACTION":case"SECTION":case"MODULE":{let a=await Xa(r,e,t,i);if(a.steps=await Promise.all(i.results.map(s=>Xa(r,e,t,s))),i.type==="MODULE"&&i.inputs){a.parameters=[];for(let[s,c]of Object.entries(i.inputs))a.parameters.push({name:s,value:c})}n.push(a)}}}async function GP(r,e,t,n){for(let o of n.runs)await nW(r,e,{folder:t,suiteName:n.suiteName},o)}import iW from"junit-report-builder";import Op from"path";function aW(r,e){if(e.name(r.test.name).className(r.test.name).file(Op.relative(".",r.filePath)).property("id",r.test.id).property("dd_tags[id]",r.test.id),r.test.labels&&(e.property("labels",r.test.labels.join(",")),r.test.labels.forEach(t=>{e.property("dd_tags[label]",t)})),r.baseUrl&&(e.property("base_url",r.baseUrl),e.property("dd_tags[base_url]",r.baseUrl)),r.runId&&(e.property("run_url",`https://app.momentic.ai/runs/${r.runId}`),e.property("dd_tags[run_url]",`https://app.momentic.ai/runs/${r.runId}`)),r.quarantined&&(e.property("quarantined","true"),e.property("dd_tags[quarantined]","true"),r.quarantinedReason&&(e.property("quarantined_reason",r.quarantinedReason),e.property("dd_tags[quarantined_reason]",r.quarantinedReason))),r.beforeResults?.some(t=>t.status==="FAILED")&&(e.property("setup_failed","true"),e.property("dd_tags[setup_failed]","true")),r.results?.some(t=>t.status==="FAILED")&&(e.property("main_failed","true"),e.property("dd_tags[main_failed]","true")),r.afterResults?.some(t=>t.status==="FAILED")&&(e.property("teardown_failed","true"),e.property("dd_tags[teardown_failed]","true")),r.status==="FAILED"){if(r.failureReason){let t=gc[r.failureDetails?.classification?.reason||r.failureReason],n=r.failureDetails?.classification?.summary||qi[r.failureReason];r.runId&&(n+=` Visit https://app.momentic.ai/runs/${r.runId} for more details.`),e.failure(n,t)}r.failureDetails?.errorStack&&e.stacktrace(r.failureDetails.errorStack)}else r.status==="CANCELLED"&&e.skipped();return e.time((r.finishedAt.getTime()-r.lastAttemptStartedAt.getTime())/1e3).property("started_at",r.lastAttemptStartedAt.toISOString()).property("dd_tags[started_at]",r.lastAttemptStartedAt.toISOString()).property("finished_at",r.finishedAt.toISOString()).property("dd_tags[finished_at]",r.finishedAt.toISOString()),e.property("attempts",r.attempts.toString()).property("dd_tags[attempts]",r.attempts.toString()),r.parameters.envName&&(e.property("environment",r.parameters.envName),e.property("dd_tags[environment]",r.parameters.envName)),r.parameters.urlOverride&&e.property("url_override",r.parameters.urlOverride),e}function sW(r,{suiteId:e,suiteName:t,startedAt:n,finishedAt:o,runs:i,testsToSkip:a,quarantinedTestsToSkip:s,quarantinedTestReasons:c}){let l=r.testSuite().name(t);e&&l.property("id",e),l.timestamp(n).property("startedAt",n.toISOString()).property("finishedAt",o.toISOString()).time((o.getTime()-n.getTime())/1e3);for(let u of i){let d=l.testCase();aW(u,d)}for(let u of a){let d=l.testCase();d.name(u.name).className(u.name).file(Op.relative(".",u.relativeFilePath)).property("id",u.id),u.baseUrl&&d.property("baseUrl",u.baseUrl),u.labels&&(d.property("labels",u.labels.join(",")),u.labels.forEach(p=>{d.property("dd_tags[label]",p)})),d.skipped()}for(let u of s){let d=l.testCase();d.name(u.name).className(u.name).file(Op.relative(".",u.relativeFilePath)).property("id",u.id).property("quarantined","true");let p=c[u.id];p&&d.property("quarantinedReason",p),u.baseUrl&&d.property("baseUrl",u.baseUrl),u.labels&&(d.property("labels",u.labels.join(",")),u.labels.forEach(m=>{d.property("dd_tags[label]",m)})),d.skipped()}return l}function jP(r,e){let t=iW.newBuilder();sW(t,e),t.writeTo(Op.join(r,`${e.suiteName}.xml`))}import lW from"fs";import cW from"path";function VP(r){return{title:fo(r),duration:r.finishedAt.getTime()-r.startedAt.getTime(),error:r.status==="FAILED"?{value:r.failureReason}:void 0,steps:r.results&&r.type!=="PRESET_ACTION"?r.results.map(VP):[]}}async function uW(r,e,t,n){if(n.results?.length){let o=await Mp(r,e,t,n.results[n.results.length-1].afterSnapshot);return o?[{name:"Final state screenshot",path:o,contentType:"image/jpeg"}]:[]}return[]}async function dW(r,e,t,n){return{status:n.status==="PASSED"?"passed":n.status==="CANCELLED"?"interrupted":"failed",duration:n.finishedAt.getTime()-n.lastAttemptStartedAt.getTime(),error:n.status==="FAILED"&&n.failureReason?{value:n.failureDetails?.classification?.reason||n.failureReason,message:n.failureDetails?.classification?.summary||qi[n.failureReason]}:void 0,retry:n.attempts-1,steps:n.results?.map(VP)||[],startTime:n.lastAttemptStartedAt.toISOString(),attachments:await uW(r,e,t,n)}}async function pW(r,e,t,n){return{expectedStatus:"passed",status:n.status==="PASSED"?"expected":"unexpected",results:[await dW(r,e,t,n)]}}async function mW(r,e,t,n){return{tags:[],title:n.test.name,ok:n.status==="PASSED",tests:[await pW(r,e,t,n)],id:n.runId,file:n.filePath}}function PS(r,e){return r.reduce((t,n)=>e(n)?t+1:t,0)}async function hW(r,e,t,n){return{suites:[{title:n.suiteName,file:n.projectConfigPath,specs:await Promise.all(n.runs.map(o=>mW(r,e,t,o)))}],errors:[],stats:{startTime:n.startedAt.toISOString(),duration:n.finishedAt.getTime()-n.startedAt.getTime(),expected:PS(n.runs,o=>o.status==="PASSED"),unexpected:PS(n.runs,o=>o.status!=="PASSED"),flaky:PS(n.runs,o=>!!o.isFlake),skipped:0}}}async function $P(r,e,t,n){let o=await hW(r,e,t,n);lW.writeFileSync(cW.join(t,`${n.suiteName}.json`),JSON.stringify(o,null,2))}async function WP(r,e,t,n,o){switch(gW(o)?SW(o).isDirectory()||(T.error(`The specified reporter output directory '${o}' exists on disk but is not a folder. Please move or delete the existing object or specify a different reporter path.`),process.exit(1)):(T.info(`Reporter output directory '${o}' does not exist on disk, creating it now...`),fW(o,{recursive:!0})),t){case"junit":jP(o,n);return;case"allure":case"allure-json":await GP(r,e,o,n);return;case"playwright-json":await $P(r,e,o,n);return;default:throw new Error(`Unknown reporter format requested: '${t}'`)}}import GW from"wait-on";import{execSync as yW}from"child_process";import{platform as EW}from"os";function MS(){return qP()?(T.dimmed("Setting device pixel ratio to 2 automatically since a Mac OS Retina screen was detected."),T.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.
|
|
4538
4538
|
`),2):(T.dimmed("Setting device pixel ratio to 1."),T.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.
|
|
4539
|
-
`),1)}function qP(){return EW()==="darwin"&&yW("system_profiler SPDisplaysDataType").toString().includes("Retina")}function OS(r){qP()&&r===1&&(T.warn("If you are using Momentic on a Retina screen, relaunch with the --pixel-ratio option to avoid incorrect viewport calculations."),T.warn("Confirm your device's pixel-ratio at https://www.mydevice.io."))}import TW from"@actions/exec";import bW from"@actions/io";import vW from"quote";import RW from"string-argv";async function KP(r,e=!0){let t=RW(r),n=await bW.which(t[0],!0),o=t.slice(1),i=TW.exec(vW(n),o,{delay:100});if(e)return i}import AW from"csv-parser";import{createReadStream as wW}from"fs";function LS(r){return new Promise((e,t)=>{let n=[];wW(r).pipe(AW()).on("data",o=>n.push(o)).on("end",()=>e(n)).on("error",o=>t(o))})}import Ja from"semver";import{z as Lp}from"zod";var yr="2.21.2",CW="https://registry.npmjs.org/momentic",xW=Lp.object({versions:Lp.record(Lp.string(),Lp.unknown()).optional()});async function YP(r){try{await _W(r)}catch(e){T.warn({err:e},"Failed to check CLI version against NPM servers")}}async function NS(){let r=await j(fetch(CW),{milliseconds:5e3});if(!r.ok)throw new Error(`Got error status code ${r.statusText}`);let e=await r.json(),t=xW.parse(e).versions;if(!t)throw new Error("Failed to fetch npm registry data. Skipping version check.");let n=yr;for(let o of Object.keys(t))Ja.valid(o)&&Ja.major(o)===Ja.major(yr)&&Ja.gt(o,n)&&Ja.prerelease(o)===null&&(n=o);return n}async function _W(r){let e;for(let t=0;t<2;t++)try{e=await NS()}catch(n){r.warn({err:n},"Failed to fetch latest version from npm registry")}if(!e){r.warn("Failed to fetch npm registry data. Skipping version check.");return}Ja.eq(yr,e)||(T.warn(`Update available: v${yr} -> v${e}`),T.warn("This version may be missing critical fixes, features, and security updates."),T.warn(`Run "npx momentic@${e} -V" to update`))}async function qn(){try{await j(Promise.all([Qb(),tr.flush()]),{milliseconds:5e3})}catch{}}import{partition as IW}from"lodash-es";function Np(r){return r.length===1?"test":"tests"}function XP(r){return r===1?"1 worker":`${r} workers`}function JP(r){r.length!==0&&(T.info(`Skipping ${r.length} disabled ${Np(r)}:`),r.forEach(e=>{T.info(`${gt}- ${[e.relativeFilePath]}`)}),T.log(""))}function QP(r,e){r.length!==0&&(T.info(`Skipping ${r.length} quarantined ${Np(r)}:`),r.forEach(t=>{T.info(`${gt}- ${[t.relativeFilePath]}: ${e[t.id]}`)}),T.log(""))}function PW(r,e){r.length!==0&&(T.info(`Running ${r.length} quarantined ${Np(r)} with ${XP(e)}:`),r.forEach(t=>{T.info(`${gt}- ${[t.testDefinition.relativeFilePath]}${typeof t.inputIndex=="number"?` with input set ${t.inputIndex}`:""}`)}),T.log(""))}function MW(r,e,t){e.length===0&&r.length>0||(T.info(`Running ${e.length} ${Np(e)} with ${XP(t)}:`),e.forEach(n=>{T.info(`${gt}- ${[n.testDefinition.relativeFilePath]}${typeof n.inputIndex=="number"?` with input set ${n.inputIndex}`:""}`)}),T.log(""))}function ZP({logger:r,localTestsToRunWithInputs:e,parallel:t,shardCount:n,shardIndex:o}){r.info({tests:e.length,shardCount:n,shardIndex:o,parallel:t},"Running local tests");let[i,a]=IW(e,s=>s.quarantined);PW(i,t),MW(i,a,t)}import{cloneDeep as Qa}from"lodash-es";async function eM({orgId:r,codeEvalTools:e,logger:t,outputDefinitions:n,testContext:o}){let i={};for(let a of n){let{name:s,value:c}=a;i[s]=await gr({orgId:r,s:c,localTools:e,logger:t,context:o})}return i}async function tM({baseUrl:r,envName:e,testName:t,devicePixelRatio:n,apiClient:o,test:i,storageClient:a,codeEvalTools:s,generator:c,orgId:l,variables:u,logger:d,customHeaders:p,testInputs:m,localBrowserConfig:h,aiSettings:g,visualDiffScreenshotStorage:f,tracer:y}){let S=await zd({settings:h,customHeaders:p,envVariables:u,envName:e,testName:t,baseUrl:r,logger:d,localTools:s,orgId:l}),E={baseUrl:o.baseUrl,apiKey:o.apiKey,logger:ne},A=S.browserType??"Chromium";if(!rv(A)){let I=`Browser ${A} is required by the test named ${i.name} but does not appear to be installed on this machine. Please install it using 'momentic install-browsers' before running tests. Attempting to continue...`;T.warn(I),ne.warn(I)}let b=await Ur.init({baseUrl:r,logger:d,userBrowserSettings:S,storage:a,enricher:new go(E,c),contextArgs:{viewport:i.advanced.viewport??Gt,locale:i.advanced.locale??oo,geolocation:i.advanced.geolocation??ao,timezoneId:i.advanced.timezone??io,colorScheme:i.advanced.colorScheme,deviceScaleFactor:n},iconKnowledgeBase:null,videoOptions:y.videoOutputPath?{videoOutputPath:y.videoOutputPath,onVideoPageChange:({videoName:I})=>{y.setActiveVideo(I)}}:void 0}),C=new Lo({browser:b,generator:c,logger:d,orgId:l,options:{scratchPadId:void 0,slowMoMs:S.slowMoMs,autoFollowNewTabs:S.autoFollowNewTabs,useMemory:g.useMemory,aiPageFiltering:g.aiPageFiltering},storage:a,localCodeEvalTools:s,visualDiffScreenshotStorage:f}),x=new ir({baseUrl:r,currentUrl:C.browser.url(),variablesFromEnvironment:u,envName:e,testName:t});return i.parameters&&await Promise.all(i.parameters.map(async I=>{let{name:M,defaultValue:X,required:W}=I,G=m?.[M];W&&G===void 0&&(T.error(`Required parameter '${M}' is required by test '${i.name}' but not provided`),process.exit(1));let H=await gr({orgId:l,s:G??X,localTools:s,logger:d,context:ir.dummyContext(x.getEnvName())});x.setMomenticSystemVariable(M,H)})),{controller:C,context:x}}async function rM({testAdvancedSettings:r,orgSettings:e,logger:t}){if(r.failureRecovery===!1||r.failureRecovery===void 0&&!e?.failureRecovery)return!1;if(!ci){let n="This test is ineligible for failure recovery since this does not appear to be a CI environment";return t.warn(n),T.warn(n),!1}return!0}async function nM({attemptInputs:r,attemptFixtures:e,attemptMetadata:t}){let{orgId:n,runId:o}=t,{controller:i,context:a,codeEvalTools:s,storageClient:c,logger:l,usageTracker:u,tracer:d}=e,{test:p,orgSettings:m}=r;l.info(`Running test '${p.name}' locally (run link: https://app.momentic.ai/runs/${o})`);let h={controller:i,storage:c,usageTracker:u,context:a,logger:l,codeEvalTools:s},g={orgId:n,runId:o,testMetadata:p,steps:p.steps,beforeSteps:p.beforeSteps,afterSteps:p.afterSteps,orgSettings:m},f={collectDebugData:!0,reinitializeBrowser:!0,disableHealing:!await rM({testAdvancedSettings:p.advanced,orgSettings:m.ai,logger:l})};return await Hd({fixtures:h,inputs:g,options:f,callbacks:{step:{},test:{onTestComplete:async()=>{await i.browser.cleanup()}}},testParams:{tracer:d}})}async function oM(r){let{testDefinition:e,logger:t}=r,n=new Date;try{return await OW(r)}catch(o){let i="Fatal error running test";return T.error(`${i}: ${o.message}`),t.error({err:o},i),{results:[],parameters:r,failureReason:"UnknownError",failureDetails:{errorMessage:o.message,errorStack:o.stack},status:"FAILED",attempts:0,test:e,filePath:e.relativeFilePath,startedAt:n,lastAttemptStartedAt:n,finishedAt:new Date,outputs:{}}}}async function OW(r){let{testDefinition:e,project:t,apiClient:n,orgId:o,urlOverride:i,runSigIntHandlers:a,runGroupTracer:s,logger:c,gitMetadata:l,regenerateCache:u,alwaysSaveCache:d,noCache:p,runId:m,testInputs:h,quarantined:g,quarantinedReason:f,usageTracker:y}=r,S=new ca(n,o),E=fa({orgId:o,client:n,gitMetadata:l,regenerateCache:u??!1,alwaysSaveCache:d??!1,noCache:p??!1}),A=Qa(e.steps),b=Qa(e.beforeSteps)??void 0,C=Qa(e.afterSteps)??void 0;try{await E.resolveStepCacheEntries({testId:e.id,stepLists:{steps:A,beforeSteps:b,afterSteps:C},schemaVersion:e.schemaVersion,logger:c})}catch(H){throw c.error({err:H},"Failed to resolve step cache entries"),new Error(`Failed to resolve step cache entries. Please ensure you are running using a supported version of Momentic. If you believe this is a Momentic issue, please contact Support with the following error: ${H}`)}let x=r.envName??NW(e),I,M={};if(x){try{I=al(x,t,c)}catch(H){let U=`Failed to resolve environment ${x} for test ${e.name}: ${H}`;throw new Error(U)}M=I.variables}let X=e.baseUrl;if(i)X=i;else if(!X){let H=M[Ct];typeof H=="string"&&(X=H)}if(!X){let H=`Cannot run test with no base URL and no ${Ct} variable defined in its environment`;throw new Error(H)}let W=await s.startRun({logger:c,runId:m,originalSteps:{beforeSteps:e.beforeSteps,steps:e.steps,afterSteps:e.afterSteps},testId:e.id,testName:e.name,testDescription:e.description??void 0,testLabels:e.labels,baseUrl:X,environmentName:x,schemaVersion:e.schemaVersion,resolvedInputs:h,quarantined:g,quarantinedReason:f}),G=c.child(W.loggerBindings||{});Object.entries(W.envVarBindings||{}).forEach(([H,U])=>{M[H]=U});try{let H=await LW({...r,variables:M,envName:x,resolvedEnv:I,baseUrl:X,storageClient:S,tracer:W,logger:G,cacheStorage:E,stepsWithCaches:A,beforeStepsWithCaches:b,afterStepsWithCaches:C,usageTracker:y});return await W.finish({logger:c,status:H.status,finishedAt:H.finishedAt,failureDetails:H.failureDetails,failureReason:H.failureReason,isFlake:H.isFlake,failureRecoveryDetails:H.failureRecoveryDetails}),{runId:W.runId,...H}}finally{a?.pop()}}async function LW(r){let{testDefinition:e,stepsWithCaches:t,beforeStepsWithCaches:n,afterStepsWithCaches:o,project:i,regenerateGoldenFiles:a,apiClient:s,generator:c,baseUrl:l,storageClient:u,orgId:d,envName:p,urlOverride:m,customHeaders:h,testInputs:g,variables:f,resolvedEnv:y,retriesOverride:S,devicePixelRatio:E,logUpdate:A,tracer:b,logger:C,cacheStorage:x,gitMetadata:I,quarantined:M,quarantinedReason:X,usageTracker:W}=r,G=i.config.ai?.aiFailureAnalysis??!1,H=new Date,U=new ba(i,a),V={...i.config},me={envName:p,urlOverride:m,customHeaders:h,testInputs:g},q,nt=Math.abs(S??i.config.retries??e.retries??0),De=[];C.info({...I,labels:e.labels,name:e.name,cwd:process.cwd()},"Starting test run using CLI");for(let dt=0;dt<=nt;dt++){let Mt=await b.startAttempt(),te=C.child(Mt.loggerBindings||{}),we={...e,steps:Qa(t),beforeSteps:Qa(n),afterSteps:Qa(o)};dt!==0&&A("RETRY",`attempt ${dt+1}/${nt+1}`);let Hr=new Date,zr=V.advanced?.fakerConstantSeed,Pn=new gn({httpClient:new Nt({baseUrl:s.baseUrl,apiKey:s.apiKey,logger:te}),fakerSeed:zr?ia:void 0}),Xl=Mt;try{let{controller:Mn,context:Ho}=await tM({tracer:Mt,baseUrl:l,envName:p,testName:we.name,apiClient:s,devicePixelRatio:E,logger:te,storageClient:u,codeEvalTools:Pn,test:we,generator:c,orgId:d,variables:f,customHeaders:h,testInputs:g,localBrowserConfig:{...i.config.browser||{},...y?.browser||{},...we.advanced},aiSettings:{...i.config.ai||{},...we.advanced||{}},visualDiffScreenshotStorage:U});q=await nM({attemptMetadata:{attemptNumber:dt+1,orgId:d,runId:b.runId},attemptFixtures:{logger:te,storageClient:u,usageTracker:W,codeEvalTools:Pn,apiClient:s,context:Ho,controller:Mn,tracer:Mt},attemptInputs:{test:we,orgSettings:V}});let ki=new Date,Er={logger:C,cacheStorage:x,orgId:d,testId:e.id,originalSteps:{steps:e.steps,beforeSteps:e.beforeSteps,afterSteps:e.afterSteps},updatedSteps:{steps:we.steps,beforeSteps:we.beforeSteps,afterSteps:we.afterSteps}};q?.status==="PASSED"?await Au(Er):q?.status==="FAILED"&&await wu(Er),await Mt.finish({logger:te,result:q}),De.unshift(q.status);let rn=await eM({orgId:d,codeEvalTools:Pn,logger:te,outputDefinitions:e.outputs??[],testContext:Ho}),K=xE(De),zo=dt+1;if(q.status!=="FAILED")return{...q,parameters:me,test:we,filePath:we.relativeFilePath,startedAt:H,lastAttemptStartedAt:Hr,finishedAt:ki,attempts:zo,baseUrl:l,outputs:rn,isFlake:K,quarantined:M,quarantinedReason:X};let Ui=q.failedStepResult,Gr=Ui?.message||"Unknown failure",nn=Ui?.failureReason??Yy(Gr)??"UnknownError",es=te.child({errResult:Ui,failureReason:nn,errorMessage:Gr,numAttempts:nt+1,name:we.name});if(dt<nt){es.warn(`Retrying failed execution attempt for run: ${Gr}`);continue}es.error(`Test failed after all exhausting attempts: ${Gr}`);let ts=new Error(Gr),Yn={errorMessage:Gr,errorStack:ts.stack},Fp;if(G){let rs;try{if(q.results&&q.results.length>0){let{classification:Ue,aiFailureReason:On}=await nR({logger:te,browserStateStorage:Xl,generator:c,fullResults:q,failureReason:nn,error:ts,maxItemsFromEnd:void 0,numStepsWithScreenshots:void 0,disableCache:!1});rs=Ue,Fp=On}}catch(Ue){te.warn({err:Ue},"Failed to classify test results")}rs&&(Yn.classification=rs,nn=Fp??nn)}return{...q,parameters:me,failureDetails:Yn,failureReason:nn,test:we,filePath:we.relativeFilePath,startedAt:H,lastAttemptStartedAt:Hr,finishedAt:ki,attempts:dt+1,baseUrl:l,outputs:rn,quarantined:M,quarantinedReason:X}}catch(Mn){os(Mn);let Ho=`Encountered fatal platform error while running test '${we.name}': ${Mn}`,ki=new Date,Er=dt+1;te.error({err:Mn},Ho),T.error(Ho);let rn={errorMessage:Mn.message,errStack:Mn.stack},K={status:"FAILED",failureDetails:rn,failureReason:"InternalPlatformError",finishedAt:ki};return await Mt.finish({logger:te,result:{status:"FAILED",results:[]}}),{...K,results:[],parameters:me,test:we,filePath:we.relativeFilePath,startedAt:H,lastAttemptStartedAt:Hr,finishedAt:new Date,attempts:Er,baseUrl:l,outputs:{},quarantined:M,quarantinedReason:X}}}throw new Error("This code should not be reachable")}function NW(r){for(let e of r.envs??[])if(e.default)return e.name}import DW from"adm-zip";import{randomUUID as kW}from"crypto";import UW from"path";var Kn="assets";function FW(r){switch(r){case"PASSED":return"SUCCESS";case"FAILED":return"FAILED";case"CANCELLED":return"CANCELLED";case"RUNNING":case"PENDING":case"RETRYING":case"WAITING_FOR_USER":return"RUNNING"}}function BW(r){switch(r){case"SUCCESS":return"PASSED";case"FAILED":return"FAILED";case"CANCELLED":return"CANCELLED";case"RUNNING":return"RUNNING";case"IDLE":return"PENDING"}}var DS=class{constructor(e,t,n,o,i){this.orgId=e;this.testId=t;this.testName=n;this.metadata=o;this.diskStorage=i}children=[];finished=!1;getParentStepIdChain(){return[]}attachBeforeScreenshot(e){let{snapshotId:t,screenshot:n}=e;this.metadata.beforeSnapshotId=t,this.diskStorage.storeFile({name:`${Kn}/${t}.jpeg`,contents:n})}attachAfterScreenshot(e){let{snapshotId:t,screenshot:n}=e;this.metadata.afterSnapshotId=t,this.diskStorage.storeFile({name:`${Kn}/${t}.jpeg`,contents:n})}attachBeforeHtmlSnapshot(e){let{snapshotId:t,html:n}=e;this.metadata.beforeSnapshotId=t,this.diskStorage.storeFile({name:`${Kn}/${t}.html`,contents:n})}attachAfterHtmlSnapshot(e){let{snapshotId:t,html:n}=e;this.metadata.afterSnapshotId=t,this.diskStorage.storeFile({name:`${Kn}/${t}.html`,contents:n})}recordTargetAutoHeal(e){let{healType:t}=e,n=t==="AI"?"ai-target-heal":"cache-heal";tr.increment("test_event",1,[`name:${n}`,`orgId:${this.orgId}`]),this.metadata.healMetadata={healType:t,healedAt:new Date}}recordStepDuration(e){let t=e.step.type!=="PRESET_ACTION"?e.step.type:e.step.command.type;tr.distribution("test_step_duration",e.durationMs,[`type:${t}`,"platform:browser","executor:cli",`orgId:${this.orgId}`])}async finishInternal(e){this.finished||(this.finished=!0,await Promise.all(this.children.map(t=>t.finish({status:BW(e.status),finishedAt:e.finishedAt}))))}async finish(e){await this.finishInternal(e.step)}async startSubSteps(){let e=new Za(this.orgId,this.testId,this.testName,this.diskStorage);return this.children.push(e),e}},Za=class{constructor(e,t,n,o){this.orgId=e;this.testId=t;this.testName=n;this.diskStorage=o}children=[];finished=!1;stepFrequenciesByType={};async getScreenshot(e,t){return this.diskStorage.readFile(`${Kn}/${t}.jpeg`)}async getHtmlSnapshot(e,t){return this.diskStorage.readFile(`${Kn}/${t}.html`)?.toString()}getParentStepIdChain(){return[]}recordStepStat(e){e.type!=="PRESET_ACTION"?this.stepFrequenciesByType[e.type]=(this.stepFrequenciesByType[e.type]||0)+1:this.stepFrequenciesByType[e.command.type]=(this.stepFrequenciesByType[e.command.type]||0)+1}sendFinalizedStepStats(){for(let[e,t]of Object.entries(this.stepFrequenciesByType))tr.increment("test_step_execution",t,[`type:${e}`,"platform:browser","executor:cli",`orgId:${this.orgId}`])}async startStep(e){let{step:t}=e;this.recordStepStat(t);let n={step:t,status:"RUNNING",startedAt:new Date},o=new DS(this.orgId,this.testId,this.testName,n,this.diskStorage);return this.children.push(o),o}async finish(e){this.finished||(this.finished=!0,await Promise.all(this.children.map(t=>t.finishInternal({status:FW(e.status),finishedAt:e.finishedAt}))),this.sendFinalizedStepStats())}},kS=class{constructor(e,t,n,o,i,a,s){this.orgId=e;this.testId=t;this.testName=n;this.runAttemptId=o;this.metadata=i;this.diskStorage=a;this.recordVideo=s;this.diskStorage.mkdir("assets")}finished=!1;children=[];get loggerBindings(){return{runAttemptId:this.runAttemptId}}get videoOutputPath(){if(this.recordVideo)return UW.resolve(this.diskStorage.cwd(),"assets")}setActiveVideo(e){this.recordVideo&&(this.metadata.activeVideos=this.metadata.activeVideos||[],this.metadata.activeVideos.push({videoName:e,timestamp:new Date}))}attachNetworkLogs(e){let{logs:t}=e;this.diskStorage.storeFile({name:"network.har",contents:JSON.stringify(t,null,2)})}attachConsoleLogs(e){let{logs:t}=e;this.diskStorage.storeFile({name:"console.json",contents:JSON.stringify(t,null,2)})}attachBrowserCrashDump(e){let{crashReportDirFetcher:t,logger:n}=e,o=t();if(!o)return;let i=new DW;i.addLocalFolder(o,void 0,a=>a!==".DS_Store"),this.diskStorage.storeFile({name:`${Kn}/${Sh}`,contents:i.toBuffer()}),n.info({browserCrashZipName:Sh},"Attached browser crash ZIP")}async finish(e){if(this.finished)return;this.finished=!0;let{logger:t,result:n}=e,o={...this.metadata,status:n.status,finishedAt:new Date,results:Tu(n.results,t),beforeResults:n.beforeResults?Tu(n.beforeResults,t):void 0,afterResults:n.afterResults?Tu(n.afterResults,t):void 0};await Promise.all(this.children.map(i=>i.finish({status:o.status,finishedAt:o.finishedAt}))),this.diskStorage.storeFile({name:"metadata.json",contents:JSON.stringify(o,null,2)})}async startBeforeStepList(){let e=new Za(this.orgId,this.testId,this.testName,this.diskStorage);return this.children.push(e),e}async startMainStepList(){let e=new Za(this.orgId,this.testId,this.testName,this.diskStorage);return this.children.push(e),e}async startAfterStepList(){let e=new Za(this.orgId,this.testId,this.testName,this.diskStorage);return this.children.push(e),e}async getScreenshot(e,t){return this.diskStorage.readFile(`${Kn}/${t}.jpeg`)}async getHtmlSnapshot(e,t){return this.diskStorage.readFile(`${Kn}/${t}.html`)?.toString()}},US=class{constructor(e,t,n,o,i,a,s){this.orgId=e;this.testId=t;this.testName=n;this.runId=o;this.metadata=i;this.diskStorage=a;this.recordVideo=s}children=[];finished=!1;get loggerBindings(){return{runId:this.runId}}get envVarBindings(){return{[Sx]:this.runId}}async finish(e){if(this.finished)return;this.finished=!0;let t={...this.metadata,finishedAt:e.finishedAt||new Date,status:e.status,failureDetails:e.failureDetails,failureReason:e.failureReason,flake:e.isFlake||!1,failureRecoveryDetails:e.failureRecoveryDetails};await Promise.all(this.children.map(n=>n.finish({logger:e.logger,result:{status:t.status,results:[],beforeResults:[],afterResults:[]}}))),this.diskStorage.storeFile({name:"metadata.json",contents:JSON.stringify(t,null,2)}),this.diskStorage.close()}async startAttempt(){this.metadata.attempts=this.metadata.attempts+1,this.metadata.status="RUNNING",this.diskStorage.storeFile({name:"metadata.json",contents:JSON.stringify(this.metadata,null,2)});let e=this.diskStorage.cd(`attempts/${this.metadata.attempts}`),t=kW(),n={id:t,schemaVersion:Te,runAttemptSchemaVersion:Bb,startedAt:new Date,status:"RUNNING"};e.storeFile({name:"metadata.json",contents:JSON.stringify(n,null,2)});let o=new kS(this.orgId,this.testId,this.testName,t,n,e,this.recordVideo);return this.children.push(o),o}},Dp=class r{constructor(e,t,n,o,i){this.orgId=e;this.runGroupId=t;this.metadata=n;this.diskStorage=o;this.recordVideo=i}children=[];finished=!1;get loggerBindings(){return{orgId:this.orgId,runGroupId:this.runGroupId,branch:this.metadata.gitBranchName}}static async start({orgId:e,runGroupId:t,outputDir:n,gitMetadata:o,labels:i,recordVideo:a}){let s={...o,id:t,trigger:Ar.CLI,startedAt:new Date,status:"RUNNING",cliVersion:yr,labels:i??[]},c=new cl(n);return c.storeFile({name:"metadata.json",contents:JSON.stringify(s,null,2)}),new r(e,t,s,c,a??!1)}async finish(e){if(this.finished)return;this.finished=!0;let{status:t}=e,n={...this.metadata,status:t,updatedAt:new Date,finishedAt:new Date};await Promise.all(this.children.map(o=>o.finish({logger:e.logger,status:n.status,finishedAt:n.finishedAt}))),this.diskStorage.storeFile({name:"metadata.json",contents:JSON.stringify(n,null,2)})}async startRun(e){let t=this.diskStorage.createRunArchive(e.runId),n={stepsSnapshot:e.originalSteps.steps,runGroupId:this.runGroupId,testId:e.testId,testName:e.testName,testDescription:e.testDescription,labels:e.testLabels,trigger:"CLI",status:"RUNNING",resolvedBaseUrl:e.baseUrl,environmentName:e.environmentName,resolvedInputs:e.resolvedInputs,cliVersion:yr,schemaVersion:e.schemaVersion,startedAt:new Date,attempts:0,quarantined:e.quarantined??!1,quarantinedReason:e.quarantinedReason,executionType:"WEB"};t.storeFile({name:"metadata.json",contents:JSON.stringify(n,null,2)});let o=new US(this.orgId,e.testId,e.testName,e.runId,n,t,this.recordVideo);return this.children.push(o),o}};async function iM(r,e,t){if(t)return{};try{return(await e.getQuarantinedTests()).quarantined.reduce((o,i)=>(o[i.testId]=i.quarantinedReason,o),{})}catch(n){return r.warn({err:n},"Failed to fetch quarantined tests, proceeding without them."),{}}}async function aM(r){let{logger:e,tests:t,yes:n,start:o,waitOn:i,waitOnProxy:a,client:s,debugDataStorage:c,project:l,retriesOverride:u,urlOverride:d,envName:p,orgId:m,devicePixelRatio:h,customHeaders:g,testInputMatrix:f,reporter:y,include:S,exclude:E,labels:A,reporterDir:b=bR,outputDir:C=vR,uploadResults:x=!1,waitOnTimeout:I=60,parallel:M,shardIndex:X=1,shardCount:W=1,regenerateGoldenFiles:G,gitMetadata:H,regenerateCache:U,alwaysSaveCache:V,noCache:me,ignoreQuarantine:q,skipQuarantined:nt,onlyQuarantined:De,runGroupId:dt,recordVideo:Mt}=r;if(o&&(e.info({orgId:m},`Executing start command: ${o}`),await KP(o,!1)),i){e.info({orgId:m},`Waiting for url: ${i} with timeout: ${I} seconds.`);let Ue=a?new URL(a):void 0,On;Ue&&(On={host:Ue.hostname,port:Ue.port?parseInt(Ue.port):Ue.protocol.startsWith("https")?443:80,auth:Ue.username||Ue.password?{username:Ue.username,password:Ue.password}:void 0}),await GW({resources:[i],interval:2500,timeout:I*1e3,headers:{Accept:"*/*"},followRedirect:!0,verbose:!1,log:!0,strictSSL:!1,proxy:On})}let te=new Fn(l.config.ai?.agentConfig,{baseUrl:s.baseUrl,apiKey:s.apiKey,logger:e}),we=await Q(l),Hr=await Ya({tests:t,momenticFiles:we,yes:n,project:l,include:S,exclude:E,labels:A,logger:T}),zr=await iM(e,s,q),{testsToSkip:Pn,quarantinedTestsToSkip:Xl,testsToRun:Mn,quarantinedTestsToRun:Ho}=NP({testDefinitions:Hr,quarantinedTestReasons:zr,onlyQuarantined:De,skipQuarantined:nt});JP(Pn),QP(Xl,zr);let ki=DP({testsToRun:Mn,quarantinedTestsToRun:Ho,quarantinedTestReasons:zr,testInputMatrix:f}),Er=VW({globalTestsToRunWithInputs:ki,shardIndex:X,shardCount:W});ZP({logger:e,localTestsToRunWithInputs:Er,parallel:M,shardCount:W,shardIndex:X});let rn=[],K=new Date,zo=new Set,Ui=async()=>{let Ue=s.getAppUrl(),On=la({results:rn,startTime:K.getTime(),onFailed:ur=>{su(ur,ur.filePath)},getDisplayLine:ur=>{let Go=`${gt}- ${ur.filePath}${ur.failureRecoveryDetails?" [recovered] ":""}`;return ur.runId&&(Go+=` ( link when uploaded: ${Ue}/runs/${ur.runId} )`),Go},entity:"test"}),Jl=rn.filter(ur=>!!ur.failureRecoveryDetails?.attempts);return Jl.length>0&&T.warn(`Our AI agent automatically prevented ${Jl.length} tests from failing due to transient issues. Use the run links above to review the additional steps that were executed.`),T.log(""),x?(T.success(`Test results have been saved to the folder ${C}. Uploading to Momentic Cloud...`),await Bu({client:s,consoleLogger:T,resultsPath:C})):T.success(`Test results have been saved to the folder ${C}. Upload them to Momentic Cloud by running 'npx momentic results upload ${C}'.`),On};zW.existsSync(C)&&T.warn(`Output directory ${C} already exists, removing before test execution...`);let Gr=await Dp.start({orgId:m,runGroupId:dt,outputDir:C,gitMetadata:H,labels:A,recordVideo:Mt}),nn=e.child(Gr.loggerBindings||{}),es=[],ts=async()=>{T.warn("SIGINT received. Stopping tests and printing latest results..."),await Gr.finish({logger:nn,status:"CANCELLED"}),await Ui(),await Promise.allSettled(es.map(Ue=>Ue())),await qn(),process.exit(1)};process.once("SIGINT",ts);let Yn={};for(let Ue=0;Ue<Er.length;Ue++){let On=Object.values(Yn);On.length===M&&await Promise.race(On.map(Go=>Go.promise));let Jl=Er[Ue],ur=`test-${Ue}`;Yn[ur]={done:!1,promise:(async({inputs:Go,quarantined:hM,quarantinedReason:gM,testDefinition:jo})=>{zo.add({inputs:Go});let Ql=jo.relativeFilePath.includes("..")?jo.fullFilePath:jo.relativeFilePath;$s({status:"START",testLogRef:Ql,getRunningTestsCount:()=>zo.size,getTotalTestsCount:()=>Er.length});let fM=setInterval(()=>$s({status:"RUN",testLogRef:Ql,getRunningTestsCount:()=>zo.size,getTotalTestsCount:()=>Er.length}),5*60*1e3),Bp=HW(),Hp=nn.child({testId:jo.id,runId:Bp}),zS=new Pu({logger:Hp,reporter:new cu(s),runType:"test-run",runId:Bp,testMetadata:jo,suiteMetadata:void 0});try{let ns=await oM({testDefinition:jo,project:l,testInputs:Go,quarantined:hM,quarantinedReason:gM,orgId:m,runId:Bp,devicePixelRatio:h,apiClient:s,runGroupTracer:Gr,generator:te,retriesOverride:u,urlOverride:d,envName:p,customHeaders:g,regenerateGoldenFiles:G,logUpdate:(Zl,SM)=>$s({status:Zl,testLogRef:Ql,getRunningTestsCount:()=>zo.size,getTotalTestsCount:()=>Er.length,additionalText:SM}),runSigIntHandlers:es,logger:Hp,gitMetadata:H,regenerateCache:U,alwaysSaveCache:V,noCache:me,usageTracker:zS});$s({status:ns.status,testLogRef:Ql,getRunningTestsCount:()=>zo.size,getTotalTestsCount:()=>Er.length}),rn.push(ns)}catch(ns){let Zl=`Encountered unexpected fatal error when running test '${jo.name}': ${ns.message}`;T.error(Zl),Hp.error({err:ns},Zl)}finally{clearInterval(fM),Yn[ur].done=!0,delete Yn[ur]}await zS.flush(e)})(Jl)}}await Promise.allSettled(Object.values(Yn).map(Ue=>Ue.promise));let rs=rn.some(Ue=>!Ue.quarantined&&Ue.status==="FAILED")?"FAILED":"PASSED";return await Gr.finish({logger:nn,status:rs}),process.off("SIGINT",ts),y&&await WP(nn,c,y,{projectConfigPath:l.configFilePath,suiteName:l.config.name,startedAt:K,finishedAt:new Date,runs:rn,testsToSkip:Pn,quarantinedTestsToSkip:Xl,quarantinedTestReasons:zr},b),Ui()}function jW(r,e,t){if(t>r.length&&(T.warn(`Shard count ${t} is greater than the number of tests ${r.length}! Some workers won't have any tests to run.`),t=Math.max(t,r.length),e>t))return[];let n=Math.floor((e-1)*(r.length/t)),o=Math.floor(e*(r.length/t));return r.sort().filter((a,s)=>s>=n&&s<o)}function VW({globalTestsToRunWithInputs:r,shardIndex:e,shardCount:t}){return t&&t>1?jW(r,e,t):r}import{installPackage as $W}from"@antfu/install-pkg";import{cloneDeep as WW}from"lodash-es";import qW from"semver";async function sM(){let r=await NS();qW.lt(yr,r)&&T.warn(`The current CLI version (${yr}) is not the latest. It's recommended to run the upgrade command using momentic@latest.`),await $W(`momentic@${r}`,{silent:!0,dev:!0})}function lM(r){let e=WW(r.config),t={...e.ai?.agentConfig,...Fc},n={...e.ai,agentConfig:t};e.ai=n,yo(e,r.configFilePath)}zp||ne.warn("Sentry is not enabled in this environment due to unsupported node version");ux({serviceName:"cli"});var uM=process.argv.some(r=>r.includes("--log-level"))&&process.argv.some(r=>r.includes("debug")),FS=r=>{uM&&T.dimmed(r)};uM&&ov(ne);var Ut=new KW;Ut.name("momentic").description("Momentic CLI").version(yr);Ut.command("install-browsers").description("Install browser executables onto the local machine.").option("-f, --force","Force reinstallation even if the browser executables already exist on disk.").option("-a, --all","Install all browsers types.").argument("[browsers...]",`Browsers to install. Available choices: ${Rh.join(", ")}.`).action(async(r,e)=>{!e.all&&r.length===0&&(T.error("No browsers specified"),process.exit(1)),await nv({rawBrowsers:r,force:e.force,all:e.all})});Ut.addOption(new nr("--log-level <level>").choices(["debug","info","warn","error"]).default("info")).on("option:log-level",r=>{r==="debug"&&T.info("Enabling debug logging"),T.setMinLevel(r.toLowerCase())});Ut.addOption(new nr("--verbose","enable verbose logging")).on("option:verbose",()=>{ne.enableConsoleLogs(),T.setMinLevel(20)});var BS=Ut.command("checks").alias("check").description("Perform various project checks");BS.command("config").addOption(rr).action(async r=>{await bt({configFilePath:r.config})});BS.command("duplicate-ids").description("Checks if any steps in your entire Momentic test repository share the same ID.").addOption(rr).addOption(bP).action(async r=>{let e=await bt({configFilePath:r.config});await sP({project:e,fix:r.fix})});BS.command("duplicate-names").description("Checks if tests or modules with duplicate names or ids exist").addOption(rr).action(async r=>{let e=await bt({configFilePath:r.config});await lP({project:e})});var dM=Ut.command("migrate").description("Migrate and upgrade tooling");dM.command("steps").description("Migrate steps in all tests and modules to the latest schema version. Note that this is always done when a test is loaded through the interactive editor, so is generally not needed.").addOption(rr).action(async r=>{let e=await bt({configFilePath:r.config});await MP(e)});dM.command("v1-v2").description("Migrate from v1 of the Momentic CLI to v2").addOption(Br).addOption(rr).addOption(Fr).addOption(Fo).action(async r=>{!r.yes&&!await Lt("This command will modify your existing Momentic configuration. Please backup your local directory using Git or another version control system before proceeding. Continue?")&&process.exit(1);let e=await bt({configFilePath:r.config}),t=new rt({baseUrl:r.server,apiKey:r.apiKey,logger:ne}),{orgId:n}=await t.getAuthInfo();await OP({project:e,orgId:n,apiClient:t}),process.exit(0)});Ut.command("import").addOption(Fr).addOption(Br).addOption(rr).addOption(Fo).addArgument(xP).action(async(r,e)=>{let{apiKey:t,server:n,config:o,yes:i}=e,a=await bt({configFilePath:o}),s=new rt({baseUrl:n,apiKey:t,logger:ne});!r||r.length===0?await mP({client:s,project:a,skipPrompts:i}):await hP({client:s,project:a,paths:r,skipPrompts:i}),process.exit(0)});Ut.command("init").description("Initialize an empty Momentic project in the current working directory").addOption(new nr("--name <name>","Name of the project")).action(async r=>{T.info(`Welcome to the Momentic project setup wizard! \u{1F680}
|
|
4539
|
+
`),1)}function qP(){return EW()==="darwin"&&yW("system_profiler SPDisplaysDataType").toString().includes("Retina")}function OS(r){qP()&&r===1&&(T.warn("If you are using Momentic on a Retina screen, relaunch with the --pixel-ratio option to avoid incorrect viewport calculations."),T.warn("Confirm your device's pixel-ratio at https://www.mydevice.io."))}import TW from"@actions/exec";import bW from"@actions/io";import vW from"quote";import RW from"string-argv";async function KP(r,e=!0){let t=RW(r),n=await bW.which(t[0],!0),o=t.slice(1),i=TW.exec(vW(n),o,{delay:100});if(e)return i}import AW from"csv-parser";import{createReadStream as wW}from"fs";function LS(r){return new Promise((e,t)=>{let n=[];wW(r).pipe(AW()).on("data",o=>n.push(o)).on("end",()=>e(n)).on("error",o=>t(o))})}import Ja from"semver";import{z as Lp}from"zod";var yr="2.21.3",CW="https://registry.npmjs.org/momentic",xW=Lp.object({versions:Lp.record(Lp.string(),Lp.unknown()).optional()});async function YP(r){try{await _W(r)}catch(e){T.warn({err:e},"Failed to check CLI version against NPM servers")}}async function NS(){let r=await j(fetch(CW),{milliseconds:5e3});if(!r.ok)throw new Error(`Got error status code ${r.statusText}`);let e=await r.json(),t=xW.parse(e).versions;if(!t)throw new Error("Failed to fetch npm registry data. Skipping version check.");let n=yr;for(let o of Object.keys(t))Ja.valid(o)&&Ja.major(o)===Ja.major(yr)&&Ja.gt(o,n)&&Ja.prerelease(o)===null&&(n=o);return n}async function _W(r){let e;for(let t=0;t<2;t++)try{e=await NS()}catch(n){r.warn({err:n},"Failed to fetch latest version from npm registry")}if(!e){r.warn("Failed to fetch npm registry data. Skipping version check.");return}Ja.eq(yr,e)||(T.warn(`Update available: v${yr} -> v${e}`),T.warn("This version may be missing critical fixes, features, and security updates."),T.warn(`Run "npx momentic@${e} -V" to update`))}async function qn(){try{await j(Promise.all([Qb(),tr.flush()]),{milliseconds:5e3})}catch{}}import{partition as IW}from"lodash-es";function Np(r){return r.length===1?"test":"tests"}function XP(r){return r===1?"1 worker":`${r} workers`}function JP(r){r.length!==0&&(T.info(`Skipping ${r.length} disabled ${Np(r)}:`),r.forEach(e=>{T.info(`${gt}- ${[e.relativeFilePath]}`)}),T.log(""))}function QP(r,e){r.length!==0&&(T.info(`Skipping ${r.length} quarantined ${Np(r)}:`),r.forEach(t=>{T.info(`${gt}- ${[t.relativeFilePath]}: ${e[t.id]}`)}),T.log(""))}function PW(r,e){r.length!==0&&(T.info(`Running ${r.length} quarantined ${Np(r)} with ${XP(e)}:`),r.forEach(t=>{T.info(`${gt}- ${[t.testDefinition.relativeFilePath]}${typeof t.inputIndex=="number"?` with input set ${t.inputIndex}`:""}`)}),T.log(""))}function MW(r,e,t){e.length===0&&r.length>0||(T.info(`Running ${e.length} ${Np(e)} with ${XP(t)}:`),e.forEach(n=>{T.info(`${gt}- ${[n.testDefinition.relativeFilePath]}${typeof n.inputIndex=="number"?` with input set ${n.inputIndex}`:""}`)}),T.log(""))}function ZP({logger:r,localTestsToRunWithInputs:e,parallel:t,shardCount:n,shardIndex:o}){r.info({tests:e.length,shardCount:n,shardIndex:o,parallel:t},"Running local tests");let[i,a]=IW(e,s=>s.quarantined);PW(i,t),MW(i,a,t)}import{cloneDeep as Qa}from"lodash-es";async function eM({orgId:r,codeEvalTools:e,logger:t,outputDefinitions:n,testContext:o}){let i={};for(let a of n){let{name:s,value:c}=a;i[s]=await gr({orgId:r,s:c,localTools:e,logger:t,context:o})}return i}async function tM({baseUrl:r,envName:e,testName:t,devicePixelRatio:n,apiClient:o,test:i,storageClient:a,codeEvalTools:s,generator:c,orgId:l,variables:u,logger:d,customHeaders:p,testInputs:m,localBrowserConfig:h,aiSettings:g,visualDiffScreenshotStorage:f,tracer:y}){let S=await zd({settings:h,customHeaders:p,envVariables:u,envName:e,testName:t,baseUrl:r,logger:d,localTools:s,orgId:l}),E={baseUrl:o.baseUrl,apiKey:o.apiKey,logger:ne},A=S.browserType??"Chromium";if(!rv(A)){let I=`Browser ${A} is required by the test named ${i.name} but does not appear to be installed on this machine. Please install it using 'momentic install-browsers' before running tests. Attempting to continue...`;T.warn(I),ne.warn(I)}let b=await Ur.init({baseUrl:r,logger:d,userBrowserSettings:S,storage:a,enricher:new go(E,c),contextArgs:{viewport:i.advanced.viewport??Gt,locale:i.advanced.locale??oo,geolocation:i.advanced.geolocation??ao,timezoneId:i.advanced.timezone??io,colorScheme:i.advanced.colorScheme,deviceScaleFactor:n},iconKnowledgeBase:null,videoOptions:y.videoOutputPath?{videoOutputPath:y.videoOutputPath,onVideoPageChange:({videoName:I})=>{y.setActiveVideo(I)}}:void 0}),C=new Lo({browser:b,generator:c,logger:d,orgId:l,options:{scratchPadId:void 0,slowMoMs:S.slowMoMs,autoFollowNewTabs:S.autoFollowNewTabs,useMemory:g.useMemory,aiPageFiltering:g.aiPageFiltering},storage:a,localCodeEvalTools:s,visualDiffScreenshotStorage:f}),x=new ir({baseUrl:r,currentUrl:C.browser.url(),variablesFromEnvironment:u,envName:e,testName:t});return i.parameters&&await Promise.all(i.parameters.map(async I=>{let{name:M,defaultValue:X,required:W}=I,G=m?.[M];W&&G===void 0&&(T.error(`Required parameter '${M}' is required by test '${i.name}' but not provided`),process.exit(1));let H=await gr({orgId:l,s:G??X,localTools:s,logger:d,context:ir.dummyContext(x.getEnvName())});x.setMomenticSystemVariable(M,H)})),{controller:C,context:x}}async function rM({testAdvancedSettings:r,orgSettings:e,logger:t}){if(r.failureRecovery===!1||r.failureRecovery===void 0&&!e?.failureRecovery)return!1;if(!ci){let n="This test is ineligible for failure recovery since this does not appear to be a CI environment";return t.warn(n),T.warn(n),!1}return!0}async function nM({attemptInputs:r,attemptFixtures:e,attemptMetadata:t}){let{orgId:n,runId:o}=t,{controller:i,context:a,codeEvalTools:s,storageClient:c,logger:l,usageTracker:u,tracer:d}=e,{test:p,orgSettings:m}=r;l.info(`Running test '${p.name}' locally (run link: https://app.momentic.ai/runs/${o})`);let h={controller:i,storage:c,usageTracker:u,context:a,logger:l,codeEvalTools:s},g={orgId:n,runId:o,testMetadata:p,steps:p.steps,beforeSteps:p.beforeSteps,afterSteps:p.afterSteps,orgSettings:m},f={collectDebugData:!0,reinitializeBrowser:!0,disableHealing:!await rM({testAdvancedSettings:p.advanced,orgSettings:m.ai,logger:l})};return await Hd({fixtures:h,inputs:g,options:f,callbacks:{step:{},test:{onTestComplete:async()=>{await i.browser.cleanup()}}},testParams:{tracer:d}})}async function oM(r){let{testDefinition:e,logger:t}=r,n=new Date;try{return await OW(r)}catch(o){let i="Fatal error running test";return T.error(`${i}: ${o.message}`),t.error({err:o},i),{results:[],parameters:r,failureReason:"UnknownError",failureDetails:{errorMessage:o.message,errorStack:o.stack},status:"FAILED",attempts:0,test:e,filePath:e.relativeFilePath,startedAt:n,lastAttemptStartedAt:n,finishedAt:new Date,outputs:{}}}}async function OW(r){let{testDefinition:e,project:t,apiClient:n,orgId:o,urlOverride:i,runSigIntHandlers:a,runGroupTracer:s,logger:c,gitMetadata:l,regenerateCache:u,alwaysSaveCache:d,noCache:p,runId:m,testInputs:h,quarantined:g,quarantinedReason:f,usageTracker:y}=r,S=new ca(n,o),E=fa({orgId:o,client:n,gitMetadata:l,regenerateCache:u??!1,alwaysSaveCache:d??!1,noCache:p??!1}),A=Qa(e.steps),b=Qa(e.beforeSteps)??void 0,C=Qa(e.afterSteps)??void 0;try{await E.resolveStepCacheEntries({testId:e.id,stepLists:{steps:A,beforeSteps:b,afterSteps:C},schemaVersion:e.schemaVersion,logger:c})}catch(H){throw c.error({err:H},"Failed to resolve step cache entries"),new Error(`Failed to resolve step cache entries. Please ensure you are running using a supported version of Momentic. If you believe this is a Momentic issue, please contact Support with the following error: ${H}`)}let x=r.envName??NW(e),I,M={};if(x){try{I=al(x,t,c)}catch(H){let U=`Failed to resolve environment ${x} for test ${e.name}: ${H}`;throw new Error(U)}M=I.variables}let X=e.baseUrl;if(i)X=i;else if(!X){let H=M[Ct];typeof H=="string"&&(X=H)}if(!X){let H=`Cannot run test with no base URL and no ${Ct} variable defined in its environment`;throw new Error(H)}let W=await s.startRun({logger:c,runId:m,originalSteps:{beforeSteps:e.beforeSteps,steps:e.steps,afterSteps:e.afterSteps},testId:e.id,testName:e.name,testDescription:e.description??void 0,testLabels:e.labels,baseUrl:X,environmentName:x,schemaVersion:e.schemaVersion,resolvedInputs:h,quarantined:g,quarantinedReason:f}),G=c.child(W.loggerBindings||{});Object.entries(W.envVarBindings||{}).forEach(([H,U])=>{M[H]=U});try{let H=await LW({...r,variables:M,envName:x,resolvedEnv:I,baseUrl:X,storageClient:S,tracer:W,logger:G,cacheStorage:E,stepsWithCaches:A,beforeStepsWithCaches:b,afterStepsWithCaches:C,usageTracker:y});return await W.finish({logger:c,status:H.status,finishedAt:H.finishedAt,failureDetails:H.failureDetails,failureReason:H.failureReason,isFlake:H.isFlake,failureRecoveryDetails:H.failureRecoveryDetails}),{runId:W.runId,...H}}finally{a?.pop()}}async function LW(r){let{testDefinition:e,stepsWithCaches:t,beforeStepsWithCaches:n,afterStepsWithCaches:o,project:i,regenerateGoldenFiles:a,apiClient:s,generator:c,baseUrl:l,storageClient:u,orgId:d,envName:p,urlOverride:m,customHeaders:h,testInputs:g,variables:f,resolvedEnv:y,retriesOverride:S,devicePixelRatio:E,logUpdate:A,tracer:b,logger:C,cacheStorage:x,gitMetadata:I,quarantined:M,quarantinedReason:X,usageTracker:W}=r,G=i.config.ai?.aiFailureAnalysis??!1,H=new Date,U=new ba(i,a),V={...i.config},me={envName:p,urlOverride:m,customHeaders:h,testInputs:g},q,nt=Math.abs(S??i.config.retries??e.retries??0),De=[];C.info({...I,labels:e.labels,name:e.name,cwd:process.cwd()},"Starting test run using CLI");for(let dt=0;dt<=nt;dt++){let Mt=await b.startAttempt(),te=C.child(Mt.loggerBindings||{}),we={...e,steps:Qa(t),beforeSteps:Qa(n),afterSteps:Qa(o)};dt!==0&&A("RETRY",`attempt ${dt+1}/${nt+1}`);let Hr=new Date,zr=V.advanced?.fakerConstantSeed,Pn=new gn({httpClient:new Nt({baseUrl:s.baseUrl,apiKey:s.apiKey,logger:te}),fakerSeed:zr?ia:void 0}),Xl=Mt;try{let{controller:Mn,context:Ho}=await tM({tracer:Mt,baseUrl:l,envName:p,testName:we.name,apiClient:s,devicePixelRatio:E,logger:te,storageClient:u,codeEvalTools:Pn,test:we,generator:c,orgId:d,variables:f,customHeaders:h,testInputs:g,localBrowserConfig:{...i.config.browser||{},...y?.browser||{},...we.advanced},aiSettings:{...i.config.ai||{},...we.advanced||{}},visualDiffScreenshotStorage:U});q=await nM({attemptMetadata:{attemptNumber:dt+1,orgId:d,runId:b.runId},attemptFixtures:{logger:te,storageClient:u,usageTracker:W,codeEvalTools:Pn,apiClient:s,context:Ho,controller:Mn,tracer:Mt},attemptInputs:{test:we,orgSettings:V}});let ki=new Date,Er={logger:C,cacheStorage:x,orgId:d,testId:e.id,originalSteps:{steps:e.steps,beforeSteps:e.beforeSteps,afterSteps:e.afterSteps},updatedSteps:{steps:we.steps,beforeSteps:we.beforeSteps,afterSteps:we.afterSteps}};q?.status==="PASSED"?await Au(Er):q?.status==="FAILED"&&await wu(Er),await Mt.finish({logger:te,result:q}),De.unshift(q.status);let rn=await eM({orgId:d,codeEvalTools:Pn,logger:te,outputDefinitions:e.outputs??[],testContext:Ho}),K=xE(De),zo=dt+1;if(q.status!=="FAILED")return{...q,parameters:me,test:we,filePath:we.relativeFilePath,startedAt:H,lastAttemptStartedAt:Hr,finishedAt:ki,attempts:zo,baseUrl:l,outputs:rn,isFlake:K,quarantined:M,quarantinedReason:X};let Ui=q.failedStepResult,Gr=Ui?.message||"Unknown failure",nn=Ui?.failureReason??Yy(Gr)??"UnknownError",es=te.child({errResult:Ui,failureReason:nn,errorMessage:Gr,numAttempts:nt+1,name:we.name});if(dt<nt){es.warn(`Retrying failed execution attempt for run: ${Gr}`);continue}es.error(`Test failed after all exhausting attempts: ${Gr}`);let ts=new Error(Gr),Yn={errorMessage:Gr,errorStack:ts.stack},Fp;if(G){let rs;try{if(q.results&&q.results.length>0){let{classification:Ue,aiFailureReason:On}=await nR({logger:te,browserStateStorage:Xl,generator:c,fullResults:q,failureReason:nn,error:ts,maxItemsFromEnd:void 0,numStepsWithScreenshots:void 0,disableCache:!1});rs=Ue,Fp=On}}catch(Ue){te.warn({err:Ue},"Failed to classify test results")}rs&&(Yn.classification=rs,nn=Fp??nn)}return{...q,parameters:me,failureDetails:Yn,failureReason:nn,test:we,filePath:we.relativeFilePath,startedAt:H,lastAttemptStartedAt:Hr,finishedAt:ki,attempts:dt+1,baseUrl:l,outputs:rn,quarantined:M,quarantinedReason:X}}catch(Mn){os(Mn);let Ho=`Encountered fatal platform error while running test '${we.name}': ${Mn}`,ki=new Date,Er=dt+1;te.error({err:Mn},Ho),T.error(Ho);let rn={errorMessage:Mn.message,errStack:Mn.stack},K={status:"FAILED",failureDetails:rn,failureReason:"InternalPlatformError",finishedAt:ki};return await Mt.finish({logger:te,result:{status:"FAILED",results:[]}}),{...K,results:[],parameters:me,test:we,filePath:we.relativeFilePath,startedAt:H,lastAttemptStartedAt:Hr,finishedAt:new Date,attempts:Er,baseUrl:l,outputs:{},quarantined:M,quarantinedReason:X}}}throw new Error("This code should not be reachable")}function NW(r){for(let e of r.envs??[])if(e.default)return e.name}import DW from"adm-zip";import{randomUUID as kW}from"crypto";import UW from"path";var Kn="assets";function FW(r){switch(r){case"PASSED":return"SUCCESS";case"FAILED":return"FAILED";case"CANCELLED":return"CANCELLED";case"RUNNING":case"PENDING":case"RETRYING":case"WAITING_FOR_USER":return"RUNNING"}}function BW(r){switch(r){case"SUCCESS":return"PASSED";case"FAILED":return"FAILED";case"CANCELLED":return"CANCELLED";case"RUNNING":return"RUNNING";case"IDLE":return"PENDING"}}var DS=class{constructor(e,t,n,o,i){this.orgId=e;this.testId=t;this.testName=n;this.metadata=o;this.diskStorage=i}children=[];finished=!1;getParentStepIdChain(){return[]}attachBeforeScreenshot(e){let{snapshotId:t,screenshot:n}=e;this.metadata.beforeSnapshotId=t,this.diskStorage.storeFile({name:`${Kn}/${t}.jpeg`,contents:n})}attachAfterScreenshot(e){let{snapshotId:t,screenshot:n}=e;this.metadata.afterSnapshotId=t,this.diskStorage.storeFile({name:`${Kn}/${t}.jpeg`,contents:n})}attachBeforeHtmlSnapshot(e){let{snapshotId:t,html:n}=e;this.metadata.beforeSnapshotId=t,this.diskStorage.storeFile({name:`${Kn}/${t}.html`,contents:n})}attachAfterHtmlSnapshot(e){let{snapshotId:t,html:n}=e;this.metadata.afterSnapshotId=t,this.diskStorage.storeFile({name:`${Kn}/${t}.html`,contents:n})}recordTargetAutoHeal(e){let{healType:t}=e,n=t==="AI"?"ai-target-heal":"cache-heal";tr.increment("test_event",1,[`name:${n}`,`orgId:${this.orgId}`]),this.metadata.healMetadata={healType:t,healedAt:new Date}}recordStepDuration(e){let t=e.step.type!=="PRESET_ACTION"?e.step.type:e.step.command.type;tr.distribution("test_step_duration",e.durationMs,[`type:${t}`,"platform:browser","executor:cli",`orgId:${this.orgId}`])}async finishInternal(e){this.finished||(this.finished=!0,await Promise.all(this.children.map(t=>t.finish({status:BW(e.status),finishedAt:e.finishedAt}))))}async finish(e){await this.finishInternal(e.step)}async startSubSteps(){let e=new Za(this.orgId,this.testId,this.testName,this.diskStorage);return this.children.push(e),e}},Za=class{constructor(e,t,n,o){this.orgId=e;this.testId=t;this.testName=n;this.diskStorage=o}children=[];finished=!1;stepFrequenciesByType={};async getScreenshot(e,t){return this.diskStorage.readFile(`${Kn}/${t}.jpeg`)}async getHtmlSnapshot(e,t){return this.diskStorage.readFile(`${Kn}/${t}.html`)?.toString()}getParentStepIdChain(){return[]}recordStepStat(e){e.type!=="PRESET_ACTION"?this.stepFrequenciesByType[e.type]=(this.stepFrequenciesByType[e.type]||0)+1:this.stepFrequenciesByType[e.command.type]=(this.stepFrequenciesByType[e.command.type]||0)+1}sendFinalizedStepStats(){for(let[e,t]of Object.entries(this.stepFrequenciesByType))tr.increment("test_step_execution",t,[`type:${e}`,"platform:browser","executor:cli",`orgId:${this.orgId}`])}async startStep(e){let{step:t}=e;this.recordStepStat(t);let n={step:t,status:"RUNNING",startedAt:new Date},o=new DS(this.orgId,this.testId,this.testName,n,this.diskStorage);return this.children.push(o),o}async finish(e){this.finished||(this.finished=!0,await Promise.all(this.children.map(t=>t.finishInternal({status:FW(e.status),finishedAt:e.finishedAt}))),this.sendFinalizedStepStats())}},kS=class{constructor(e,t,n,o,i,a,s){this.orgId=e;this.testId=t;this.testName=n;this.runAttemptId=o;this.metadata=i;this.diskStorage=a;this.recordVideo=s;this.diskStorage.mkdir("assets")}finished=!1;children=[];get loggerBindings(){return{runAttemptId:this.runAttemptId}}get videoOutputPath(){if(this.recordVideo)return UW.resolve(this.diskStorage.cwd(),"assets")}setActiveVideo(e){this.recordVideo&&(this.metadata.activeVideos=this.metadata.activeVideos||[],this.metadata.activeVideos.push({videoName:e,timestamp:new Date}))}attachNetworkLogs(e){let{logs:t}=e;this.diskStorage.storeFile({name:"network.har",contents:JSON.stringify(t,null,2)})}attachConsoleLogs(e){let{logs:t}=e;this.diskStorage.storeFile({name:"console.json",contents:JSON.stringify(t,null,2)})}attachBrowserCrashDump(e){let{crashReportDirFetcher:t,logger:n}=e,o=t();if(!o)return;let i=new DW;i.addLocalFolder(o,void 0,a=>a!==".DS_Store"),this.diskStorage.storeFile({name:`${Kn}/${Sh}`,contents:i.toBuffer()}),n.info({browserCrashZipName:Sh},"Attached browser crash ZIP")}async finish(e){if(this.finished)return;this.finished=!0;let{logger:t,result:n}=e,o={...this.metadata,status:n.status,finishedAt:new Date,results:Tu(n.results,t),beforeResults:n.beforeResults?Tu(n.beforeResults,t):void 0,afterResults:n.afterResults?Tu(n.afterResults,t):void 0};await Promise.all(this.children.map(i=>i.finish({status:o.status,finishedAt:o.finishedAt}))),this.diskStorage.storeFile({name:"metadata.json",contents:JSON.stringify(o,null,2)})}async startBeforeStepList(){let e=new Za(this.orgId,this.testId,this.testName,this.diskStorage);return this.children.push(e),e}async startMainStepList(){let e=new Za(this.orgId,this.testId,this.testName,this.diskStorage);return this.children.push(e),e}async startAfterStepList(){let e=new Za(this.orgId,this.testId,this.testName,this.diskStorage);return this.children.push(e),e}async getScreenshot(e,t){return this.diskStorage.readFile(`${Kn}/${t}.jpeg`)}async getHtmlSnapshot(e,t){return this.diskStorage.readFile(`${Kn}/${t}.html`)?.toString()}},US=class{constructor(e,t,n,o,i,a,s){this.orgId=e;this.testId=t;this.testName=n;this.runId=o;this.metadata=i;this.diskStorage=a;this.recordVideo=s}children=[];finished=!1;get loggerBindings(){return{runId:this.runId}}get envVarBindings(){return{[Sx]:this.runId}}async finish(e){if(this.finished)return;this.finished=!0;let t={...this.metadata,finishedAt:e.finishedAt||new Date,status:e.status,failureDetails:e.failureDetails,failureReason:e.failureReason,flake:e.isFlake||!1,failureRecoveryDetails:e.failureRecoveryDetails};await Promise.all(this.children.map(n=>n.finish({logger:e.logger,result:{status:t.status,results:[],beforeResults:[],afterResults:[]}}))),this.diskStorage.storeFile({name:"metadata.json",contents:JSON.stringify(t,null,2)}),this.diskStorage.close()}async startAttempt(){this.metadata.attempts=this.metadata.attempts+1,this.metadata.status="RUNNING",this.diskStorage.storeFile({name:"metadata.json",contents:JSON.stringify(this.metadata,null,2)});let e=this.diskStorage.cd(`attempts/${this.metadata.attempts}`),t=kW(),n={id:t,schemaVersion:Te,runAttemptSchemaVersion:Bb,startedAt:new Date,status:"RUNNING"};e.storeFile({name:"metadata.json",contents:JSON.stringify(n,null,2)});let o=new kS(this.orgId,this.testId,this.testName,t,n,e,this.recordVideo);return this.children.push(o),o}},Dp=class r{constructor(e,t,n,o,i){this.orgId=e;this.runGroupId=t;this.metadata=n;this.diskStorage=o;this.recordVideo=i}children=[];finished=!1;get loggerBindings(){return{orgId:this.orgId,runGroupId:this.runGroupId,branch:this.metadata.gitBranchName}}static async start({orgId:e,runGroupId:t,outputDir:n,gitMetadata:o,labels:i,recordVideo:a}){let s={...o,id:t,trigger:Ar.CLI,startedAt:new Date,status:"RUNNING",cliVersion:yr,labels:i??[]},c=new cl(n);return c.storeFile({name:"metadata.json",contents:JSON.stringify(s,null,2)}),new r(e,t,s,c,a??!1)}async finish(e){if(this.finished)return;this.finished=!0;let{status:t}=e,n={...this.metadata,status:t,updatedAt:new Date,finishedAt:new Date};await Promise.all(this.children.map(o=>o.finish({logger:e.logger,status:n.status,finishedAt:n.finishedAt}))),this.diskStorage.storeFile({name:"metadata.json",contents:JSON.stringify(n,null,2)})}async startRun(e){let t=this.diskStorage.createRunArchive(e.runId),n={stepsSnapshot:e.originalSteps.steps,runGroupId:this.runGroupId,testId:e.testId,testName:e.testName,testDescription:e.testDescription,labels:e.testLabels,trigger:"CLI",status:"RUNNING",resolvedBaseUrl:e.baseUrl,environmentName:e.environmentName,resolvedInputs:e.resolvedInputs,cliVersion:yr,schemaVersion:e.schemaVersion,startedAt:new Date,attempts:0,quarantined:e.quarantined??!1,quarantinedReason:e.quarantinedReason,executionType:"WEB"};t.storeFile({name:"metadata.json",contents:JSON.stringify(n,null,2)});let o=new US(this.orgId,e.testId,e.testName,e.runId,n,t,this.recordVideo);return this.children.push(o),o}};async function iM(r,e,t){if(t)return{};try{return(await e.getQuarantinedTests()).quarantined.reduce((o,i)=>(o[i.testId]=i.quarantinedReason,o),{})}catch(n){return r.warn({err:n},"Failed to fetch quarantined tests, proceeding without them."),{}}}async function aM(r){let{logger:e,tests:t,yes:n,start:o,waitOn:i,waitOnProxy:a,client:s,debugDataStorage:c,project:l,retriesOverride:u,urlOverride:d,envName:p,orgId:m,devicePixelRatio:h,customHeaders:g,testInputMatrix:f,reporter:y,include:S,exclude:E,labels:A,reporterDir:b=bR,outputDir:C=vR,uploadResults:x=!1,waitOnTimeout:I=60,parallel:M,shardIndex:X=1,shardCount:W=1,regenerateGoldenFiles:G,gitMetadata:H,regenerateCache:U,alwaysSaveCache:V,noCache:me,ignoreQuarantine:q,skipQuarantined:nt,onlyQuarantined:De,runGroupId:dt,recordVideo:Mt}=r;if(o&&(e.info({orgId:m},`Executing start command: ${o}`),await KP(o,!1)),i){e.info({orgId:m},`Waiting for url: ${i} with timeout: ${I} seconds.`);let Ue=a?new URL(a):void 0,On;Ue&&(On={host:Ue.hostname,port:Ue.port?parseInt(Ue.port):Ue.protocol.startsWith("https")?443:80,auth:Ue.username||Ue.password?{username:Ue.username,password:Ue.password}:void 0}),await GW({resources:[i],interval:2500,timeout:I*1e3,headers:{Accept:"*/*"},followRedirect:!0,verbose:!1,log:!0,strictSSL:!1,proxy:On})}let te=new Fn(l.config.ai?.agentConfig,{baseUrl:s.baseUrl,apiKey:s.apiKey,logger:e}),we=await Q(l),Hr=await Ya({tests:t,momenticFiles:we,yes:n,project:l,include:S,exclude:E,labels:A,logger:T}),zr=await iM(e,s,q),{testsToSkip:Pn,quarantinedTestsToSkip:Xl,testsToRun:Mn,quarantinedTestsToRun:Ho}=NP({testDefinitions:Hr,quarantinedTestReasons:zr,onlyQuarantined:De,skipQuarantined:nt});JP(Pn),QP(Xl,zr);let ki=DP({testsToRun:Mn,quarantinedTestsToRun:Ho,quarantinedTestReasons:zr,testInputMatrix:f}),Er=VW({globalTestsToRunWithInputs:ki,shardIndex:X,shardCount:W});ZP({logger:e,localTestsToRunWithInputs:Er,parallel:M,shardCount:W,shardIndex:X});let rn=[],K=new Date,zo=new Set,Ui=async()=>{let Ue=s.getAppUrl(),On=la({results:rn,startTime:K.getTime(),onFailed:ur=>{su(ur,ur.filePath)},getDisplayLine:ur=>{let Go=`${gt}- ${ur.filePath}${ur.failureRecoveryDetails?" [recovered] ":""}`;return ur.runId&&(Go+=` ( link when uploaded: ${Ue}/runs/${ur.runId} )`),Go},entity:"test"}),Jl=rn.filter(ur=>!!ur.failureRecoveryDetails?.attempts);return Jl.length>0&&T.warn(`Our AI agent automatically prevented ${Jl.length} tests from failing due to transient issues. Use the run links above to review the additional steps that were executed.`),T.log(""),x?(T.success(`Test results have been saved to the folder ${C}. Uploading to Momentic Cloud...`),await Bu({client:s,consoleLogger:T,resultsPath:C})):T.success(`Test results have been saved to the folder ${C}. Upload them to Momentic Cloud by running 'npx momentic results upload ${C}'.`),On};zW.existsSync(C)&&T.warn(`Output directory ${C} already exists, removing before test execution...`);let Gr=await Dp.start({orgId:m,runGroupId:dt,outputDir:C,gitMetadata:H,labels:A,recordVideo:Mt}),nn=e.child(Gr.loggerBindings||{}),es=[],ts=async()=>{T.warn("SIGINT received. Stopping tests and printing latest results..."),await Gr.finish({logger:nn,status:"CANCELLED"}),await Ui(),await Promise.allSettled(es.map(Ue=>Ue())),await qn(),process.exit(1)};process.once("SIGINT",ts);let Yn={};for(let Ue=0;Ue<Er.length;Ue++){let On=Object.values(Yn);On.length===M&&await Promise.race(On.map(Go=>Go.promise));let Jl=Er[Ue],ur=`test-${Ue}`;Yn[ur]={done:!1,promise:(async({inputs:Go,quarantined:hM,quarantinedReason:gM,testDefinition:jo})=>{zo.add({inputs:Go});let Ql=jo.relativeFilePath.includes("..")?jo.fullFilePath:jo.relativeFilePath;$s({status:"START",testLogRef:Ql,getRunningTestsCount:()=>zo.size,getTotalTestsCount:()=>Er.length});let fM=setInterval(()=>$s({status:"RUN",testLogRef:Ql,getRunningTestsCount:()=>zo.size,getTotalTestsCount:()=>Er.length}),5*60*1e3),Bp=HW(),Hp=nn.child({testId:jo.id,runId:Bp}),zS=new Pu({logger:Hp,reporter:new cu(s),runType:"test-run",runId:Bp,testMetadata:jo,suiteMetadata:void 0});try{let ns=await oM({testDefinition:jo,project:l,testInputs:Go,quarantined:hM,quarantinedReason:gM,orgId:m,runId:Bp,devicePixelRatio:h,apiClient:s,runGroupTracer:Gr,generator:te,retriesOverride:u,urlOverride:d,envName:p,customHeaders:g,regenerateGoldenFiles:G,logUpdate:(Zl,SM)=>$s({status:Zl,testLogRef:Ql,getRunningTestsCount:()=>zo.size,getTotalTestsCount:()=>Er.length,additionalText:SM}),runSigIntHandlers:es,logger:Hp,gitMetadata:H,regenerateCache:U,alwaysSaveCache:V,noCache:me,usageTracker:zS});$s({status:ns.status,testLogRef:Ql,getRunningTestsCount:()=>zo.size,getTotalTestsCount:()=>Er.length}),rn.push(ns)}catch(ns){let Zl=`Encountered unexpected fatal error when running test '${jo.name}': ${ns.message}`;T.error(Zl),Hp.error({err:ns},Zl)}finally{clearInterval(fM),Yn[ur].done=!0,delete Yn[ur]}await zS.flush(e)})(Jl)}}await Promise.allSettled(Object.values(Yn).map(Ue=>Ue.promise));let rs=rn.some(Ue=>!Ue.quarantined&&Ue.status==="FAILED")?"FAILED":"PASSED";return await Gr.finish({logger:nn,status:rs}),process.off("SIGINT",ts),y&&await WP(nn,c,y,{projectConfigPath:l.configFilePath,suiteName:l.config.name,startedAt:K,finishedAt:new Date,runs:rn,testsToSkip:Pn,quarantinedTestsToSkip:Xl,quarantinedTestReasons:zr},b),Ui()}function jW(r,e,t){if(t>r.length&&(T.warn(`Shard count ${t} is greater than the number of tests ${r.length}! Some workers won't have any tests to run.`),t=Math.max(t,r.length),e>t))return[];let n=Math.floor((e-1)*(r.length/t)),o=Math.floor(e*(r.length/t));return r.sort().filter((a,s)=>s>=n&&s<o)}function VW({globalTestsToRunWithInputs:r,shardIndex:e,shardCount:t}){return t&&t>1?jW(r,e,t):r}import{installPackage as $W}from"@antfu/install-pkg";import{cloneDeep as WW}from"lodash-es";import qW from"semver";async function sM(){let r=await NS();qW.lt(yr,r)&&T.warn(`The current CLI version (${yr}) is not the latest. It's recommended to run the upgrade command using momentic@latest.`),await $W(`momentic@${r}`,{silent:!1,dev:!0})}function lM(r){let e=WW(r.config),t={...e.ai?.agentConfig,...Fc},n={...e.ai,agentConfig:t};e.ai=n,yo(e,r.configFilePath)}zp||ne.warn("Sentry is not enabled in this environment due to unsupported node version");ux({serviceName:"cli"});var uM=process.argv.some(r=>r.includes("--log-level"))&&process.argv.some(r=>r.includes("debug")),FS=r=>{uM&&T.dimmed(r)};uM&&ov(ne);var Ut=new KW;Ut.name("momentic").description("Momentic CLI").version(yr);Ut.command("install-browsers").description("Install browser executables onto the local machine.").option("-f, --force","Force reinstallation even if the browser executables already exist on disk.").option("-a, --all","Install all browsers types.").argument("[browsers...]",`Browsers to install. Available choices: ${Rh.join(", ")}.`).action(async(r,e)=>{!e.all&&r.length===0&&(T.error("No browsers specified"),process.exit(1)),await nv({rawBrowsers:r,force:e.force,all:e.all})});Ut.addOption(new nr("--log-level <level>").choices(["debug","info","warn","error"]).default("info")).on("option:log-level",r=>{r==="debug"&&T.info("Enabling debug logging"),T.setMinLevel(r.toLowerCase())});Ut.addOption(new nr("--verbose","enable verbose logging")).on("option:verbose",()=>{ne.enableConsoleLogs(),T.setMinLevel(20)});var BS=Ut.command("checks").alias("check").description("Perform various project checks");BS.command("config").addOption(rr).action(async r=>{await bt({configFilePath:r.config})});BS.command("duplicate-ids").description("Checks if any steps in your entire Momentic test repository share the same ID.").addOption(rr).addOption(bP).action(async r=>{let e=await bt({configFilePath:r.config});await sP({project:e,fix:r.fix})});BS.command("duplicate-names").description("Checks if tests or modules with duplicate names or ids exist").addOption(rr).action(async r=>{let e=await bt({configFilePath:r.config});await lP({project:e})});var dM=Ut.command("migrate").description("Migrate and upgrade tooling");dM.command("steps").description("Migrate steps in all tests and modules to the latest schema version. Note that this is always done when a test is loaded through the interactive editor, so is generally not needed.").addOption(rr).action(async r=>{let e=await bt({configFilePath:r.config});await MP(e)});dM.command("v1-v2").description("Migrate from v1 of the Momentic CLI to v2").addOption(Br).addOption(rr).addOption(Fr).addOption(Fo).action(async r=>{!r.yes&&!await Lt("This command will modify your existing Momentic configuration. Please backup your local directory using Git or another version control system before proceeding. Continue?")&&process.exit(1);let e=await bt({configFilePath:r.config}),t=new rt({baseUrl:r.server,apiKey:r.apiKey,logger:ne}),{orgId:n}=await t.getAuthInfo();await OP({project:e,orgId:n,apiClient:t}),process.exit(0)});Ut.command("import").addOption(Fr).addOption(Br).addOption(rr).addOption(Fo).addArgument(xP).action(async(r,e)=>{let{apiKey:t,server:n,config:o,yes:i}=e,a=await bt({configFilePath:o}),s=new rt({baseUrl:n,apiKey:t,logger:ne});!r||r.length===0?await mP({client:s,project:a,skipPrompts:i}):await hP({client:s,project:a,paths:r,skipPrompts:i}),process.exit(0)});Ut.command("init").description("Initialize an empty Momentic project in the current working directory").addOption(new nr("--name <name>","Name of the project")).action(async r=>{T.info(`Welcome to the Momentic project setup wizard! \u{1F680}
|
|
4540
4540
|
`),T.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."),Up.existsSync(Ea)&&(T.error("A momentic.config.yaml file already exists in this directory. Please rename or remove it to initialize a new project."),process.exit(1));let e=r.name??await $b("Choose an identifier for your project, such as a service, product, or team name (default: 'app'):","app");await AR()||await Lt("A Git repository was not detected in the current directory. Momentic highly recommends initializing your project within a Git repository for seamless version control. Continue?")||process.exit(1),yo({name:e,include:qh},Ea),T.success(`Initialized Momentic project file at ${kp.resolve(Ea)}`)});Ut.command("app").addOption(Fr).addOption(Br).addOption(Fo).addOption(yS).addOption(rr).addOption(TS).addOption(bS).addOption(vS).action(async r=>{let{apiKey:e,yes:t,server:n,pixelRatio:o,disableCache:i,saveCache:a,regenerateCache:s}=r,c=await bt({configFilePath:r.config,nameFilter:void 0}),{errors:l}=await vp({project:c,fix:!1});l>0&&(T.error(`Found ${l} errors`),T.warn("To fix these errors automatically, run the duplicate-ids check with the --fix flag and then commit the resulting changes"),process.exit(1)),sA(ne);let u=new rt({baseUrl:n,apiKey:e,logger:ne});await Ih({client:u,skipPrompts:t});let d=ZW(import.meta.url),p=kp.dirname(d),m=kp.resolve(p,"..","static"),h=kp.resolve(p,"..","assets"),g=o??MS();OS(g),await nP({momenticServerUrl:n,apiKey:e,serverPort:Rp,appPort:Rp,staticDir:m,assetsDir:h,devicePixelRatio:g,regenerateCache:s,noCache:i,alwaysSaveCache:a,initialProject:c});let f=`http://localhost:${Rp}`;await QW(f)});var pM=Ut.command("queue").description("Queue tests or suites to run on Momentic Cloud");pM.command("suites").description("Run one or more suites on Momentic Cloud").addOption(Fr).addOption(Br).addOption(mS).addOption(hS).addOption(Fo).addArgument(_P).addOption(xp).addOption(Cp).addOption(wp).action(async(r,e)=>{let{apiKey:t,server:n,wait:o,waitTimeout:i,env:a,urlOverride:s}=e,c=Ap(e.customHeaders),l=new rt({baseUrl:n,apiKey:t,logger:ne});(!r||!Array.isArray(r)||!r.length)&&(T.error("Must pass at least one suite to run."),process.exit(1));let{orgId:u}=await l.getAuthInfo();await BP({client:l,orgId:u,wait:o,suitePaths:r,waitTimeout:i,env:a,urlOverride:s,customHeaders:c}),await qn()});pM.command("tests").description("Run one or more tests on Momentic Cloud").addOption(Fr).addOption(Br).addOption(Fo).addOption(wp).addOption(ES).addOption(xp).addOption(Cp).addOption(new nr("--all","Run all tests.").default(!1)).addOption(mS).addOption(hS).addArgument(CP).action(async(r,e)=>{let{all:t,apiKey:n,env:o,server:i,inputCsv:a,urlOverride:s,wait:c,waitTimeout:l,yes:u}=e,d=Ap(e.customHeaders);for(let g of r)(g.endsWith(".yaml")||Up.existsSync(g))&&T.warn("Are you trying to run a test on your local machine? If so, please use the 'run' command instead of the 'queue' command");let p=new rt({baseUrl:i,apiKey:n,logger:ne}),{orgId:m}=await p.getAuthInfo(),h;a&&(h=await LS(a)),await HP({client:p,orgId:m,tests:r,all:t,customHeaders:d,env:o,urlOverride:s,wait:c,waitTimeout:l,testInputMatrix:h,yes:u}),await qn(),process.exit(0)});var eq=Ut.command("list").description("List test paths");eq.addOption(rr).addOption(Bo).addOption(fS).addOption(SS).addOption(new nr("--labels <labels...>","Only run tests with the specified label(s).")).addArgument(RS).action(async(r,e)=>{let t=await bt({configFilePath:e.config,nameFilter:e.filter}),n=await Q(t),o=await Ya({tests:r,momenticFiles:n,yes:!0,project:t,include:e.include,exclude:e.exclude,labels:e.labels,logger:new li(40,{})});T.info(o.map(i=>i.relativeFilePath).join(`
|
|
4541
4541
|
`)),process.exit(0)});var tq=Ut.command("run").alias("test").description("Run tests on the local machine");tq.addOption(Fr).addOption(Br).addOption(rr).addOption(Bo).addOption(Fo).addOption(wp).addOption(ES).addOption(TS).addOption(bS).addOption(vS).addOption(wP).addOption(vP).addOption(RP).addOption(AP).addOption(Cp).addOption(xp).addOption(yS).addOption(new nr("--start <start>","Arbitrary setup command that will run before Momentic steps begin.")).addOption(new nr("--wait-on <waitOn>","URL to wait to become accessible before Momentic tests begin.")).addOption(new nr("--wait-on-proxy <waitOnProxy>","HTTP proxy to use with the --wait-on command. Specify as https://username:pass@domain.com:2345")).addOption(new nr("--wait-on-timeout <waitOnTimeout>","Max time in seconds to wait for the --wait-on URL to become accessible.").default(60).argParser(Uo)).addOption(new nr("--retries <retries>","Number of retries to attempt when running tests locally. Defaults to each test's own retry configuration.").argParser(Uo)).addOption(new nr("-p, --parallel <parallel>","The number of tests to run in parallel. Defaults to 1.").argParser(Uo)).addOption(new nr("--labels <labels...>","Only run tests with the specified label(s).")).addOption(new nr("--update-golden-files","Update locally stored golden files for steps that this is enabled for.").default(!1)).addOption(fP).addOption(SP).addOption(gS).addOption(yP).addOption(TP).addOption(EP).addOption(fS).addOption(SS).addArgument(RS).action(async(r,e)=>{if(e.shardIndex>e.shardCount)throw new Error("Shard index cannot be greater than shard count");let t=Ap(e.customHeaders),n=await bt({configFilePath:e.config,nameFilter:e.filter}),o=e.parallel??n.config.parallel??1;cM().length<o*2&&T.warn(`You requested to run tests in parallel ${o} at a time on a machine with ${cM().length} cores. This may cause performance issues and test failures as Chrome requires at least 2 cores per browser instance.`),T.debug({projectName:n.config.name},"Identified project config");let{errors:i}=await vp({project:n,fix:!1});i>0&&(T.error(`Found ${i} errors`),T.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 rt({baseUrl:e.server,apiKey:e.apiKey,logger:ne});T.debug("Checking API key and dependencies");let{orgId:s,userId:c}=await Ih({client:a,skipPrompts:e.yes});T.debug("API key check and browser installation complete");let l=new Bs,u=e.outputDir??n.config.outputDir,d=e.reporterDir??n.config.reporterDir,p=XW(),m=ne.child({cliVersion:yr,orgId:s,userId:c,runGroupId:p}),h=await Eo(ne,a,n);m.info({gitMetadata:h,config:n.config},"Got local metadata");let g;e.inputCsv&&(g=await LS(e.inputCsv));let f=e.pixelRatio??MS();OS(f);try{let y=await aM({...e,parallel:o,retriesOverride:e.retries,devicePixelRatio:f,tests:r,project:n,client:a,debugDataStorage:l,outputDir:u,uploadResults:e.uploadResults,reporterDir:d,customHeaders:t,envName:e.env,orgId:s,testInputMatrix:g,logger:m,regenerateGoldenFiles:e.updateGoldenFiles,gitMetadata:h,regenerateCache:e.regenerateCache,alwaysSaveCache:e.saveCache,noCache:e.disableCache,recordVideo:e.recordVideo??n.config.recordVideo,runGroupId:p});await qn(),y.failed>0?process.exit(1):process.exit(0)}catch(y){T.error("Failed to run tests locally. Please check the error message below or run with the --verbose flag."),T.error(y),await qn(),process.exit(1)}});var rq=Ut.command("apply").description("Apply an operation to local resources");rq.command("patch").addOption(Fr).addOption(Br).addOption(rr).addOption(Bo).addOption(Fo).addOption(new nr("--from <from>","Name or ID of the patch to apply").makeOptionMandatory()).addOption(new nr("--to <to>","Name or ID of the test to apply the patch to").makeOptionMandatory()).action(async r=>{let{apiKey:e,server:t,config:n,yes:o}=r,i=await bt({configFilePath:n}),a=ne,s=new rt({baseUrl:t,apiKey:e,logger:a}),c=await Q(i),l=c.tests[r.to]??Object.values(c.tests).find(d=>Oe(d.name)===r.to.trim());l||(T.error(`No test matching '${r.to}' could be found in the current project.`),process.exit(1));let u=await s.fetchTestFragment(r.from);await iP({client:s,test:l,fragment:u,yes:o,entities:c,logger:ne}),process.exit(0)});var mM=Ut.command("results").description("Merge and upload test results.");mM.command("merge").description("Merge test results files.").addOption(gS).addArgument(IP).action(async(r,e)=>{let{outputDir:t}=e;t||(T.error("Output directory is required."),process.exit(1)),Up.existsSync(r)||(T.warn("Results path does not exist, skipping merge."),process.exit(0)),Up.existsSync(t)&&T.warn(`Output directory ${t} already exists, removing before merging...`),_R(ne,t,r)});mM.command("upload").description("Upload test results to Momentic cloud.").addOption(Fr).addOption(Br).addArgument(PP).action(async(r,e)=>{let{apiKey:t,server:n}=e,o=ne,i=new rt({baseUrl:n,apiKey:t,logger:o});await Bu({consoleLogger:T,resultsPath:r,client:i}),process.exit(0)});var HS=Ut.command("quarantine").description("Manage test quarantines");HS.command("add").description("Add a test to the quarantine. This will prevent it from running.").addOption(Fr).addOption(Br).addOption(rr).addOption(Bo).addOption(AS).addArgument(wS).action(async(r,e)=>{let{apiKey:t,server:n,config:o,reason:i}=e,a=ne,s=await bt({configFilePath:o}),c=new rt({baseUrl:n,apiKey:t,logger:a}),l=await Eo(ne,c,s);await LP({test:r,reason:i,apiClient:c,project:s,logger:a,identity:l})});HS.command("list").description("List quarantined tests.").addOption(Fr).addOption(Br).addOption(rr).addOption(Bo).action(async r=>{let{apiKey:e,server:t,config:n}=r,o=ne,i=await bt({configFilePath:n}),a=new rt({baseUrl:t,apiKey:e,logger:o});await kP({apiClient:a,project:i})});HS.command("remove").description("Remove a test from the quarantine. This will allow it to run again.").addOption(Fr).addOption(Br).addOption(rr).addOption(Bo).addOption(AS).addArgument(wS).action(async(r,e)=>{let{apiKey:t,server:n,config:o,reason:i}=e,a=ne,s=await bt({configFilePath:o}),c=new rt({baseUrl:n,apiKey:t,logger:a}),l=await Eo(ne,c,s);await UP({test:r,reason:i,apiClient:c,project:s,identity:l})});Ut.command("upgrade").description("Upgrade your configuration to the latest recommended settings").addOption(rr).addOption(Bo).action(async r=>{let e=await bt({configFilePath:r.config,nameFilter:r.filter});T.info("Updating Momentic version in package.json..."),await sM(),T.info("Updating project configuration..."),lM(e),T.success("Your project configuration was successfully updated to the latest recommended settings."),T.info("You can optionally run tests with the `--regenerate-cache` flag to entirely rebuild caches with the newer configuration. Warning: using this option will cause all steps to run without any cached data, resulting in significantly longer execution times.")});async function nq(){FS("Main program started"),await YP(ne),FS("CLI version check complete");try{await Ut.parseAsync(process.argv),await qn()}catch(r){let e={};try{e.playwrightVersion=YW("npx playwright --version").toString()}catch(t){ne.error({err:t},"Error fetching debug information")}ne.error({err:r,debugInfo:e},"Uncaught error in CLI"),os(r,e),T.error(r),await qn(),process.exit(1)}}JW.setMaxListeners(25);process.on("warning",r=>{ne.warn({err:r},`Node warning received on CLI: ${r.message}`)});FS("CLI parsing setup complete");nq();
|
|
4542
4542
|
//# sourceMappingURL=cli.js.map
|
|
4543
|
-
//# debugId=
|
|
4543
|
+
//# debugId=e0dde94b-a515-52fa-8ab8-de6b1c9ef5ea
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "momentic",
|
|
3
|
-
"version": "2.21.
|
|
3
|
+
"version": "2.21.3",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "momentic",
|
|
9
|
-
"version": "2.21.
|
|
9
|
+
"version": "2.21.3",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@actions/exec": "^1.1.1",
|
|
12
12
|
"@actions/io": "^1.1.3",
|
|
@@ -3238,9 +3238,9 @@
|
|
|
3238
3238
|
}
|
|
3239
3239
|
},
|
|
3240
3240
|
"node_modules/default-browser-id": {
|
|
3241
|
-
"version": "5.0.
|
|
3242
|
-
"resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.
|
|
3243
|
-
"integrity": "sha512-
|
|
3241
|
+
"version": "5.0.1",
|
|
3242
|
+
"resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.1.tgz",
|
|
3243
|
+
"integrity": "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==",
|
|
3244
3244
|
"license": "MIT",
|
|
3245
3245
|
"engines": {
|
|
3246
3246
|
"node": ">=18"
|