momentic 0.0.154 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cli.js +41 -41
- package/dist/commonjs/lib/config.d.ts +2 -2
- package/dist/commonjs/lib/config.js +2 -2
- package/dist/commonjs/lib/config.js.map +1 -1
- package/dist/esm/lib/config.d.ts +2 -2
- package/dist/esm/lib/config.js +2 -2
- package/dist/esm/lib/config.js.map +1 -1
- package/package.json +3 -1
- package/src/lib/config.ts +2 -2
- package/static/assets/{index-PpcTHV0x.js → index-wglMxLb8.js} +184 -184
- package/static/index.html +1 -1
- package/momentic/fixtures/inputs.html +0 -44
- package/momentic/fixtures/test.html +0 -11
package/bin/cli.js
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{Command as Yf,Option as At}from"@commander-js/extra-typings";import{execSync as Xf}from"child_process";import{z as Nn}from"zod";import{z as Vo}from"zod";function re(r){if(typeof r.ZodType.prototype.openapi<"u")return;r.ZodType.prototype.openapi=function(o){return new this.constructor({...this._def,openapi:o})};let e=r.ZodObject.prototype.extend;r.ZodObject.prototype.extend=function(...o){let s=e.apply(this,o);return s._def.extendMetadata={extends:this},delete s._def.openapi,s};let t=r.ZodObject.prototype.omit;r.ZodObject.prototype.omit=function(...o){let s=t.apply(this,o);return delete s._def.extendMetadata,delete s._def.openapi,s};let n=r.ZodObject.prototype.pick;r.ZodObject.prototype.pick=function(...o){let s=n.apply(this,o);return delete s._def.extendMetadata,delete s._def.openapi,s}}import{z as Go}from"zod";import{v4 as oe}from"uuid";import*as S from"zod";import{z as K}from"zod";re(K);var Si=K.object({thoughts:K.string(),result:K.boolean(),relevantElements:K.array(K.number()).optional()}),Nr=(n=>(n.CONTAINS="CONTAINS",n.STARTS_WITH="STARTS_WITH",n.EQUALS="EQUALS",n))(Nr||{});var Kd=K.object({type:K.literal("ELEMENT_CONTENT"),negated:K.boolean().optional(),operation:K.nativeEnum(Nr),value:K.string()}).openapi({ref:"ElementContentAssertion"}),Yd=K.object({type:K.literal("ELEMENT_ATTRIBUTE"),negated:K.boolean().optional(),operation:K.nativeEnum(Nr),attr:K.string(),value:K.string()}).openapi({ref:"ElementAttributeValueAssertion"}),_r=(o=>(o.EXISTS="EXISTS",o.VISIBLE="VISIBLE",o.ENABLED="ENABLED",o.EDITABLE="EDITABLE",o))(_r||{}),Xd=K.object({type:K.literal("ELEMENT_EXISTENCE"),negated:K.boolean().optional(),condition:K.nativeEnum(_r)}).openapi({ref:"ElementExistenceAssertion"}),wi=K.discriminatedUnion("type",[Kd,Yd,Xd]).openapi({ref:"ManualElementAssertion"});var Jd=K.object({type:K.literal("CONTENT"),negated:K.boolean().optional(),value:K.string()}).openapi({ref:"PageContentAssertion"}),bi=K.discriminatedUnion("type",[Jd]).openapi({ref:"ManualPageAssertion"});import*as k from"zod";re(k);var Ft=(i=>(i.AI="AI",i.AI_HEALED="AI_HEALED",i.CLICK_TO_FIND="CLICK_TO_FIND",i.XY_PERCENT="XY_PERCENT",i.RECORDING="RECORDING",i.USER_CSS_SELECTOR="USER_CSS_SELECTOR",i))(Ft||{}),Ut=k.object({id:k.number().int(),dataMomenticId:k.number().int().optional(),selector:k.string().optional(),generatedSelectors:k.string().array().optional(),role:k.string().optional(),name:k.string().optional(),numChildren:k.number().optional(),content:k.string().optional(),pathFromRoot:k.string().optional(),serializedForm:k.string().optional(),nodeOnlySerializedForm:k.string().optional(),serializedHtml:k.string().optional().describe("pruned html including 1 neighbor and 1 layer of children. value for text inputs pruned."),nodeOnlySerializedHtml:k.string().optional().describe("outerHtml of the element without any children. value for text inputs pruned."),screenshotUrl:k.string().url().optional(),boundingBox:k.object({x:k.number().optional(),y:k.number().optional(),width:k.number(),height:k.number()}).describe("css pixel bounding box").optional(),inputDescription:k.string().optional().describe("the description that generated this cache"),targetSource:k.nativeEnum(Ft).optional(),targetUpdateTime:k.string().optional()}).openapi({ref:"A11yTargetWithCache"});function In(r){return!!(r.name||r.role||r.content||r.serializedForm||r.serializedHtml||r.screenshotUrl)}var Zd=k.object({percentX:k.number().describe("between 0 and 1"),percentY:k.number()}),Qd=k.object({type:k.literal("description"),elementDescriptor:k.string(),a11yData:Ut.optional().describe("DEPRECATED: new a11y cache is stored in DB and resolved into the 'cache' field")}).openapi({ref:"DescriptionTarget"});function at(r){return r.type==="description"}function $t(r){return r.type==="coordinates"}var Se=k.discriminatedUnion("type",[Qd,k.object({type:k.literal("coordinates"),percentXYLocation:Zd}).openapi({ref:"CoordinatesTarget"})]).openapi({ref:"ElementTarget"});function $o(r){if(!r)return!1;switch(r.type){case"description":return!!r.elementDescriptor;case"coordinates":return r.percentXYLocation.percentX>=0||r.percentXYLocation.percentY>=0}return!0}function we(r){if(!r)return"";switch(r.type){case"description":return r.elementDescriptor;case"coordinates":return`x: ${r.percentXYLocation.percentX}, y: ${r.percentXYLocation.percentY}`}}var se=(N=>(N.AI_EXTRACT="AI_EXTRACT",N.AI_ASSERTION="AI_ASSERTION",N.AI_WAIT="AI_WAIT",N.AUTH_LOAD="AUTH_LOAD",N.AUTH_SAVE="AUTH_SAVE",N.BLUR="BLUR",N.CAPTCHA="CAPTCHA",N.CLICK="CLICK",N.COOKIE="COOKIE",N.DIALOG="DIALOG",N.DRAG="DRAG",N.ELEMENT_CHECK="ELEMENT_CHECK",N.FILE_UPLOAD="FILE_UPLOAD",N.FOCUS="FOCUS",N.GO_BACK="GO_BACK",N.GO_FORWARD="GO_FORWARD",N.HOVER="HOVER",N.JAVASCRIPT="JAVASCRIPT",N.LOCAL_STORAGE="LOCAL_STORAGE",N.MOUSE_DRAG="MOUSE_DRAG",N.NAVIGATE="NAVIGATE",N.NEW_TAB="NEW_TAB",N.PAGE_CHECK="PAGE_CHECK",N.PRESS="PRESS",N.REFRESH="REFRESH",N.REQUEST="REQUEST",N.SCROLL_DOWN="SCROLL_DOWN",N.SCROLL_UP="SCROLL_UP",N.SCROLL_LEFT="SCROLL_LEFT",N.SCROLL_RIGHT="SCROLL_RIGHT",N.SELECT_OPTION="SELECT_OPTION",N.TAB="TAB",N.TYPE="TYPE",N.VISUAL_DIFF="VISUAL_DIFF",N.WAIT="WAIT",N.WAIT_FOR_URL="WAIT_FOR_URL",N.SUCCESS="SUCCESS",N))(se||{});re(S);var $=S.object({thoughts:S.string().optional(),id:S.string().uuid().describe("unique identifier to this step, used for step cache")}),Fe=S.object({useSelector:S.boolean().optional(),useXY:S.boolean().optional(),force:S.boolean().optional(),disableCache:S.boolean().optional().describe("disable element caching for this step"),iframeUrl:S.string().optional().describe("url or url regex for the iframe")}).openapi({ref:"CommonTargetingOptions"}),Je=S.object({target:Ut}).optional().openapi({ref:"SingleTargetCache"}),Pn=S.object({loadTimeout:S.number().int().max(60).optional().describe("Max seconds for the page to load")}),eu=$.merge(Pn).merge(S.object({type:S.literal("NAVIGATE"),url:S.string()})).openapi({ref:"NavigateCommand"}),On=Fe.merge(S.object({cache:Je})),nr=$.merge(On.merge(S.object({target:Se.optional(),type:S.literal("SCROLL_UP"),deltaY:S.number().optional()}))).openapi({ref:"ScrollUpCommand"}),or=$.merge(On.merge(S.object({target:Se.optional(),type:S.literal("SCROLL_DOWN"),deltaY:S.number().optional()}))).openapi({ref:"ScrollDownCommand"}),sr=$.merge(On.merge(S.object({target:Se.optional(),type:S.literal("SCROLL_LEFT"),deltaX:S.number().optional()}))).openapi({ref:"ScrollLeftCommand"}),ir=$.merge(On.merge(S.object({target:Se.optional(),type:S.literal("SCROLL_RIGHT"),deltaX:S.number().optional()}))).openapi({ref:"ScrollRightCommand"}),yy=S.discriminatedUnion("type",[nr,or,sr,ir]).openapi({ref:"AllScrollCommands"}),tu=$.merge(S.object({type:S.literal("DIALOG"),action:S.union([S.literal("ACCEPT"),S.literal("DISMISS")])})).openapi({ref:"DialogCommand"}),ru=$.merge(S.object({type:S.literal("WAIT"),delay:S.number()})).openapi({ref:"WaitCommand"}),nu=$.merge(S.object({type:S.literal("WAIT_FOR_URL"),url:S.string(),timeout:S.number().int().optional().describe("Max seconds to wait for the URL to match")})).openapi({ref:"WaitUrlCommand"}),ou=$.merge(Pn).merge(S.object({type:S.literal("REFRESH")})).openapi({ref:"RefreshCommand"}),su=$.merge(S.object({type:S.literal("GO_BACK")})).openapi({ref:"GoBackCommand"}),iu=$.merge(S.object({type:S.literal("GO_FORWARD")})).openapi({ref:"GoForwardCommand"}),au=$.extend({type:S.literal("AUTH_SAVE")}).openapi({ref:"AuthSaveCommand"}),lu=$.extend({type:S.literal("AUTH_LOAD"),storageState:S.string().describe("JSON string auth state")}).openapi({ref:"AuthLoadCommand"}),zo=$.merge(Fe).extend({type:S.literal("CAPTCHA")}).openapi({ref:"CaptchaCommand"}),cu=$.merge(S.object({type:S.literal("JAVASCRIPT"),code:S.string(),fragment:S.boolean().optional(),envKey:S.string().optional(),environment:S.union([S.literal("NODE"),S.literal("BROWSER")]).optional().describe("default NODE"),timeout:S.number().int().max(60).optional().describe("Max seconds for the code to complete")})).openapi({ref:"JavaScriptCommand"}),Dr=$.merge(Fe).merge(S.object({type:S.literal("CLICK"),target:Se,doubleClick:S.boolean().optional(),rightClick:S.boolean().optional(),waitForUrl:S.string().optional().describe("Wait for the click to trigger a page load or new tab that matches the provided URL or URL glob (e.g. https://google.com/**/*)."),waitForDownload:S.boolean().optional().describe("Wait for the click to trigger a file download and for the file download to complete."),cache:Je})).openapi({ref:"ClickCommand"}),kr=$.merge(Fe).merge(S.object({type:S.literal("DRAG"),fromTarget:Se,toTarget:Se,hoverSeconds:S.number().optional().describe("Seconds to hover the object before dropping"),cache:S.object({fromTarget:Ut.optional(),toTarget:Ut.optional()}).optional()})).openapi({ref:"DragCommand"}),Fr=$.merge(Fe).merge(S.object({type:S.literal("MOUSE_DRAG"),target:Se.optional(),deltaX:S.string().describe("pixels to move horizontally, can be template"),deltaY:S.string().describe("pixels to move vertically, can be template"),steps:S.number().optional(),cache:Je})).openapi({ref:"MouseDragCommand"}),Ur=$.merge(Fe).merge(S.object({type:S.literal("HOVER"),target:Se,cache:Je})).openapi({ref:"HoverCommand"}),$r=$.merge(Fe).merge(S.object({type:S.literal("FOCUS"),target:Se,cache:Je})).openapi({ref:"FocusCommand"}),Br=$.merge(Fe).merge(S.object({type:S.literal("BLUR"),target:Se,cache:Je})).openapi({ref:"BlurCommand"}),du=S.object({type:S.literal("URL"),url:S.string()}).describe("Accessible link to the file, either public http or local file://").openapi({ref:"UrlSource"}),uu=$.extend({type:S.literal("FILE_UPLOAD"),fileSource:S.discriminatedUnion("type",[du])}).openapi({ref:"FileUploadCommand"}),zr=$.merge(Fe).merge(S.object({type:S.literal("SELECT_OPTION"),target:Se,option:S.string(),cache:Je})).openapi({ref:"SelectOptionCommand"}),Ho=$.merge(S.object({type:S.literal("AI_ASSERTION"),assertion:S.string(),disableCache:S.boolean().optional(),iframeUrl:S.string().optional(),timeout:S.number().int().optional().describe("Max seconds to wait for assertion to be true")})).openapi({ref:"AIAssertionCommand"}),mu=Ho.extend({type:S.literal("AI_WAIT")}).openapi({ref:"AIWaitCommand"}),Bt=5,Wo=60,Hr=$.merge(Fe).extend({type:S.literal("ELEMENT_CHECK"),target:Se,assertion:wi,cache:Je,timeout:S.number().int().min(0).max(Wo).optional().describe("max seconds to wait for the assertion to be true")}).openapi({ref:"ElementAssertionCommand"}),pu=$.extend({type:S.literal("PAGE_CHECK"),assertion:bi,iframeUrl:S.string().optional().describe("url or url regex for the iframe"),timeout:S.number().int().min(0).max(Wo).optional().describe("max seconds to wait for the assertion to be true")}).openapi({ref:"PageAssertionCommand"}),gu=$.merge(S.object({type:S.literal("AI_EXTRACT"),goal:S.string(),schema:S.string().optional(),envKey:S.string().optional(),disableCache:S.boolean().optional(),iframeUrl:S.string().optional()})).openapi({ref:"AIExtractCommand"}),hu=S.object({clearContent:S.boolean().optional(),pressKeysSequentially:S.boolean().optional(),force:S.boolean().optional(),pressEnter:S.boolean().optional()}),Wr=$.merge(Fe).merge(hu).extend({type:S.literal("TYPE"),target:Se.optional(),value:S.string(),cache:Je}).openapi({ref:"TypeCommand"}),fu=$.merge(S.object({type:S.literal("PRESS"),value:S.string()})).openapi({ref:"PressCommand"}),yu=$.merge(Pn).merge(S.object({type:S.literal("TAB"),url:S.string()})).openapi({ref:"TabCommand"}),Su=$.merge(Pn).merge(S.object({type:S.literal("NEW_TAB"),url:S.string()})).openapi({ref:"NewTabCommand"}),wu=$.merge(S.object({type:S.literal("COOKIE"),value:S.string()})).openapi({ref:"CookieCommand"}),bu=$.merge(S.object({type:S.literal("LOCAL_STORAGE"),key:S.string(),value:S.string()})).openapi({ref:"LocalStorageCommand"}),Cu=$.merge(S.object({type:S.literal("REQUEST"),url:S.string(),method:S.union([S.literal("GET"),S.literal("POST"),S.literal("PUT"),S.literal("DELETE"),S.literal("PATCH")]),headers:S.record(S.string(),S.string()).optional(),params:S.record(S.string(),S.string()).optional(),body:S.string().optional(),timeout:S.number().int().optional().describe("Max seconds to wait for the request to complete")})).openapi({ref:"RequestCommand"}),Tu=$.merge(S.object({type:S.literal("SUCCESS"),condition:Ho.optional()})).openapi({ref:"SuccessCommand"}),Eu=$.merge(S.object({type:S.literal("FAILURE")})).openapi({ref:"FailureCommand"}),vu=S.object({data:S.string().describe("s3 url to a jpg"),width:S.number(),height:S.number()}),jr=$.merge(Fe).merge(S.object({type:S.literal("VISUAL_DIFF"),threshold:S.number().optional().describe("default 0.1"),target:Se.optional(),screenshot:vu.optional(),cache:Je})).openapi({ref:"VisualDiffCommand"}),Ln=S.discriminatedUnion("type",[Dr,Wr,fu,zr,eu,or,nr,Ho,Tu]),xu=S.discriminatedUnion("type",[mu,gu,lu,au,zo,wu,tu,kr,Hr,uu,su,iu,Ur,cu,bu,Fr,Su,pu,ou,Cu,sr,ir,yu,jr,ru,$r,Br,nu]),Mn=S.discriminatedUnion("type",[...Ln.options,...xu.options]).openapi({ref:"Command"}),jo=S.discriminatedUnion("type",[...Ln.options,Eu]);function It(r){let e;switch(r){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:oe(),type:r};break;case"AUTH_LOAD":{e={id:oe(),type:r,storageState:""};break}case"AI_EXTRACT":e={id:oe(),type:r,goal:""};break;case"DIALOG":e={id:oe(),type:r,action:"DISMISS"};break;case"DRAG":e={id:oe(),type:r,fromTarget:{type:"description",elementDescriptor:""},toTarget:{type:"description",elementDescriptor:""}};break;case"MOUSE_DRAG":e={id:oe(),type:r,deltaX:"0",deltaY:"0",steps:1};break;case"WAIT_FOR_URL":e={id:oe(),type:r,url:""};break;case"WAIT":e={id:oe(),type:r,delay:1};break;case"HOVER":case"BLUR":case"FOCUS":case"CLICK":e={id:oe(),type:r,target:{type:"description",elementDescriptor:""}};break;case"COOKIE":case"PRESS":case"TYPE":e={id:oe(),type:r,value:"",clearContent:!0};break;case"SELECT_OPTION":e={id:oe(),type:r,target:{type:"description",elementDescriptor:""},option:""};break;case"NAVIGATE":case"NEW_TAB":case"TAB":e={id:oe(),type:r,url:""};break;case"REQUEST":e={id:oe(),type:r,url:"",method:"GET"};break;case"LOCAL_STORAGE":e={id:oe(),type:r,key:"",value:""};break;case"JAVASCRIPT":e={id:oe(),type:r,code:""};break;case"AI_WAIT":case"AI_ASSERTION":e={id:oe(),type:r,assertion:""};break;case"FILE_UPLOAD":{e={id:oe(),type:r,fileSource:{type:"URL",url:""}};break}case"ELEMENT_CHECK":{e={id:oe(),type:r,target:{type:"description",elementDescriptor:""},assertion:{type:"ELEMENT_EXISTENCE",condition:"EXISTS"}};break}case"PAGE_CHECK":{e={id:oe(),type:r,assertion:{type:"CONTENT",value:""}};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}import{z as Gr}from"zod";var Ue=Gr.object({index:Gr.number().optional().describe("global index within a test (in-order traversal)"),id:Gr.string().optional(),skipped:Gr.boolean().optional(),envKey:Gr.string().optional().describe("key in the environment to save the result of this step to")});var Y=(i=>(i.PRESET_ACTION="PRESET_ACTION",i.MODULE="MODULE",i.AI_ACTION="AI_ACTION",i.CONDITIONAL="CONDITIONAL",i.IFRAME="IFRAME",i.SECTION="SECTION",i))(Y||{});re(Go);var $e=Ue.extend({type:Go.literal("PRESET_ACTION"),command:Mn,skipped:Go.boolean().optional()}).openapi({ref:"PresetAction"});re(Vo);var ar=Ue.extend({type:Vo.literal("AI_ACTION"),text:Vo.string(),steps:$e.array().optional()}).openapi({ref:"AIAction"});import{z as ee}from"zod";var Au=ee.object({cacheKey:ee.string(),cacheExpiryMs:ee.number()}),qo=Ue.extend({id:ee.string().uuid().describe("ID of the module step itself. Used to 'namespace' step cache entries."),inputs:ee.record(ee.string()).optional(),cacheConfig:Au.optional()}),lr=qo.extend({type:ee.literal("MODULE"),moduleId:ee.string().uuid()}),Ru=ee.union([lr.pick({type:!0,moduleId:!0}),ee.record(ee.unknown())]),qe=ee.object({moduleId:ee.string().uuid(),name:ee.string(),description:ee.string().nullish(),enabled:ee.boolean().nullish(),parameters:ee.string().array().nullish(),defaultParameters:ee.record(ee.string(),ee.string()).nullish(),defaultCacheKey:ee.string().nullish(),defaultCacheTtl:ee.number().nullish()});import{z as he}from"zod";import{z as Ti}from"zod";var Vr=Ue.extend({type:Ti.literal("CONDITIONAL"),skipped:Ti.boolean().optional()});import{z as Be}from"zod";var Iu=Be.object({type:Be.literal("attr"),name:Be.string(),value:Be.string()}),Pu=Be.object({type:Be.literal("css"),selector:Be.string()}),Ou=Be.object({type:Be.literal("url"),url:Be.string()}),Lu=Be.union([Iu,Ou,Pu]),qr=Ue.extend({type:Be.literal("IFRAME"),identifier:Lu});import{z as ze}from"zod";var Ko=(n=>(n.ALWAYS="ALWAYS",n.ON_FAILURE="ON_FAILURE",n.ON_ACTION_FAILURE="ON_ACTION_FAILURE",n))(Ko||{});var Mu=ze.discriminatedUnion("type",[ze.object({type:ze.literal("NAVIGATE_URL"),url:ze.string().url()}),ze.object({type:ze.literal("GO_TO_SECTION_START")})]),Nu=ze.object({trigger:ze.nativeEnum(Ko).optional(),attempts:ze.number().int().optional(),restartBehavior:Mu}),Kr=Ue.extend({type:ze.literal("SECTION"),description:ze.string().describe("user provided goal of what the section should accomplish"),plan:ze.string().array().optional(),autohealingConfig:Nu.optional()});var Ei=qe.merge(qo).extend({type:he.literal("RESOLVED_MODULE"),steps:he.lazy(()=>de.array())}),Yo=qe.extend({steps:he.lazy(()=>de.array())}),_u=qr.extend({steps:he.lazy(()=>He.array())}),Du=qr.extend({steps:he.lazy(()=>de.array())}),ku=Kr.extend({steps:he.lazy(()=>He.array())}),Fu=Kr.extend({steps:he.lazy(()=>de.array())}),Uu=Vr.extend({blocks:he.object({assertion:he.lazy(()=>$e),steps:he.lazy(()=>He.array())}).array(),elseSteps:he.lazy(()=>He.array().optional())}),$u=Vr.extend({blocks:he.object({assertion:he.lazy(()=>$e),steps:he.lazy(()=>de.array())}).array(),elseSteps:he.lazy(()=>de.array().optional())}),He=he.discriminatedUnion("type",[$e,ar,lr,Uu,_u,ku]),de=he.discriminatedUnion("type",[$e,ar,Ei,$u,Du,Fu]);var Oe="1.0.13";import{z as Ht}from"zod";import{z as Bu}from"zod";var bS=Bu.discriminatedUnion("type",[Br,zo,Dr,kr,$r,Ur,Fr,nr,or,sr,ir,zr,Wr,jr,Hr]);function vi(r){return["AI_ASSERTION","ELEMENT_CHECK","PAGE_CHECK"].includes(r)}import{z as zu}from"zod";var Le={type:!0,cache:!0},zt=zu.discriminatedUnion("type",[Br.pick(Le),Dr.pick(Le),kr.pick(Le),Hr.pick(Le),$r.pick(Le),Ur.pick(Le),Fr.pick(Le),nr.pick(Le),or.pick(Le),sr.pick(Le),ir.pick(Le),zr.pick(Le),Wr.pick(Le),jr.pick(Le)]),Xo=Object.values(se).filter(r=>zt.options.some(e=>e.shape.type.safeParse(r).success));Mn.options.forEach(r=>{if("target"in r.shape&&!Xo.includes(r.shape.type.value))throw new Error(`Command ${r.shape.type.value} has a target but no cache`)});var Jo=Ht.object({key:Ht.string(),testId:Ht.string().optional(),moduleId:Ht.string().optional(),organizationId:Ht.string(),value:zt}),xi=Ht.record(Ht.string(),Jo);var ow=Nn.object({testId:Nn.string(),orgId:Nn.string(),runId:Nn.string(),steps:de.array()});import{z as lt}from"zod";var _n=lt.object({x:lt.number(),y:lt.number(),correlation:lt.number()}),aw=lt.object({searchImageBase64String:lt.string(),pageImageBase64String:lt.string(),id:lt.string().uuid(),timeoutMs:lt.number().max(1e4).min(0).optional()});import Tb from"string-argv";import{v4 as vb}from"uuid";import{z as L}from"zod";import*as fe from"zod";re(fe);var Hu=fe.object({url:fe.string(),lineNumber:fe.number(),columnNumber:fe.number()}).openapi({ref:"CodeLocation"}),Wu=fe.object({timestamp:fe.number(),text:fe.string(),type:fe.string(),tabIndex:fe.number(),args:fe.unknown().array().optional(),url:fe.string().optional(),location:Hu.optional()}).openapi({ref:"ConsoleLog"}),Ai=fe.object({logsPerPage:Wu.array().array()}).openapi({ref:"DebugData"});import{z as F}from"zod";import{isValidCron as ju}from"cron-validator";import{z as te}from"zod";import{z as Zo}from"zod";var Dn=Zo.object({width:Zo.number().min(200).max(1e4),height:Zo.number().min(200).max(1e4)}),Ri={"Desktop Large":{width:1920,height:1080},"Desktop Small":{width:1280,height:800},iPad:{width:768,height:1024},"Pixel 8":{width:448,height:998},"iPhone 15":{width:393,height:852}},pw=Object.keys(Ri);var ct=Ri["Desktop Large"];var Ii=1e4,Pi=6e4,Yr=te.object({pageLoadTimeoutMs:te.number().optional().refine(r=>r===void 0||r<=Pi&&r>=-1,{message:`Page load timeout must be between 0 and ${Pi/1e3} seconds`}),smartWaitingTimeoutMs:te.number().optional().refine(r=>r===void 0||r<=Ii&&r>=-1,{message:`Smart waiting timeout must be between 0 and ${Ii/1e3} seconds`}),extraHeaders:te.record(te.string(),te.string()).optional().describe("HTTP headers to be sent on every request"),userAgent:te.string().optional()}),Gu=te.object({disableAICaching:te.boolean().default(!1),viewport:Dn.optional()}),cr=Gu.merge(Yr),Oi=te.object({cron:te.string().refine(r=>ju(r),{message:"Invalid cron expression."}).default("0 0 */1 * *"),enabled:te.boolean().default(!1),env:te.string().optional(),timeZone:te.string().default("America/Los_Angeles"),jobKey:te.string().optional()}),Li=te.object({onSuccess:te.boolean().default(!1),onFailure:te.boolean().default(!0)}),Vu=te.object({name:te.string(),required:te.boolean().optional(),defaultValue:te.string().describe("this is not optional because we need a value when the editor is first loaded")}),Mi=Vu.array();import*as U from"zod";import{cloneDeep as mr}from"lodash-es";import*as We from"zod";import{z as dr}from"zod";var dt="BASE_URL",kn="CURRENT_URL",ur="ENV_NAME",bw={[dt]:"https://www.google.com"},Ni=dr.string().describe("Name of the fixture (must be available locally in the fixtures directory)."),ke=dr.object({name:dr.string(),variables:dr.record(dr.string().describe("variable name"),dr.string().describe("variable value"))});re(We);var es=We.object({env:We.record(We.unknown()),results:We.array(We.unknown()),inputs:We.record(We.unknown()).optional()}).openapi({ref:"TestContextSnapshot"}),qu="\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022",_i=500,Ku=[dt,ur],Di=[kn,dt,ur],ie=class r{env={};inputs=void 0;results=[];varsFromMomenticEnvironment={};constructor(e){this.reset(e)}static dummyContext(e=void 0,t={}){return new r({baseUrl:"about:blank",currentUrl:"about:blank",envName:e,variablesFromEnvironment:t})}static fromSnapshot({snapshot:e,environmentVariables:t}){let n=e.env[dt]??"about:blank",o=e.env[kn]??"about:blank",s=e.env[ur],i={};for(let[l,c]of Object.entries(e.env))Di.includes(l)||(t??{})[l]===void 0&&(i[l]=c);let a=new r({baseUrl:n,currentUrl:o,dynamicVariables:i,envName:s,variablesFromEnvironment:t??{}});return a.setInputs(e.inputs),a.setResults(e.results),a}setEnvVariables(e){let t=mr(e);this.env=Object.assign(this.env,t)}setInputs(e){this.inputs=e}setResult(e,t){this.results[e]=t||null;for(let n=0;n<e;n++)this.results[n]===void 0&&(this.results[n]=null)}getResult(e){return this.results[e]}getResultsCopy(){return mr(this.results)}setMomenticSystemVariable(e,t){this.varsFromMomenticEnvironment[e]=t}setResults(e){this.results=e}clearResults(){this.results=[]}getVariable(e){return this.env[e]}setVariable(e,t){Ku.includes(e)||(this.env[e]=t)}getEnvName(){return this.env[ur]}toObjectCopy(){let e={results:this.results,env:Object.assign({},this.env,this.varsFromMomenticEnvironment)};return this.inputs&&(e.inputs=this.inputs),mr(e)}toRedactedDisplayCopy(){let e=this.toObjectCopy();return e.env=Object.fromEntries(Object.entries(e.env).map(([t,n])=>Di.includes(t)||this.varsFromMomenticEnvironment[t]===void 0?[t,n]:[t,qu])),ts(e),e}setCurrentUrl(e){this.env[kn]=e}reset(e){this.results=[],this.env={},this.varsFromMomenticEnvironment={},this.setEnvVariables(e.dynamicVariables??{}),this.setCurrentUrl(e.currentUrl),this.varsFromMomenticEnvironment=mr(e.variablesFromEnvironment),this.setMomenticSystemVariable(dt,e.baseUrl),e.envName&&this.setMomenticSystemVariable(ur,e.envName)}getDynamicVariablesCopy(){return mr(this.env)}getVariablesFromEnvironmentCopy(){return mr(this.varsFromMomenticEnvironment)}},xw=Object.getPrototypeOf(async function(){}).constructor;function Qo(r){if(r==null)return r;let e=typeof r=="string"?r:JSON.stringify(r);return e.length>_i?`${e.slice(0,_i)}...(TRUNCATED, original type: ${typeof r})`:r}function ts(r){r.env=Object.fromEntries(Object.entries(r.env).map(([e,t])=>[e,Qo(t)])),r.results=r.results.map(e=>Qo(e)),r.inputs=Object.fromEntries(Object.entries(r.inputs??{}).map(([e,t])=>[e,Qo(t)]))}import{z as Wt}from"zod";re(Wt);var ue=(a=>(a.AI_PROVIDER="AIProviderError",a.ACTION_FAILURE="ActionFailureError",a.ASSERTION_FAILURE="AssertionFailureError",a.CONFIG_ERROR="UserConfigurationError",a.JOB_TIMEOUT="JobTimeoutError",a.WEB_AGENT_PLATFORM="InternalWebAgentError",a.UNKNOWN_PLATFORM="InternalPlatformError",a))(ue||{});var ki={ActionFailureError:"Action failure",AssertionFailureError:"Assertion failure",UserConfigurationError:"Configuration error",AIProviderError:"AI provider error",InternalWebAgentError:"Momentic AI agent error",InternalPlatformError:"Infrastructure error",JobTimeoutError:"Job timeout"},Fi={ActionFailureError:"A browser action such as a click or type failed to execute because of the underlying page state is incorrect, suggesting a bug in the application itself.",AssertionFailureError:"An AI assertion or check failed for a legitimate reason, such as a missing element, a change in the page structure, or an unexpected state (e.g. loading state).",UserConfigurationError:"The error message suggests a misconfiguration in the test, such as a variable being undefined, an environment variable missing, or a typo in a step. Do not use this reason if the error is caused by a bug in the application being tested, or Momentic's AI software.",AIProviderError:"The AI provider failed to return a response or returned a malformed response.",InternalWebAgentError:"The AI testing framework failed to find the correct element or evaluate the assertion correctly, even though the test steps and application state look valid. In other words, the AI agent failed to understand the page.",InternalPlatformError:"A platform error occurred, such as the Chromium browser failing, the network being down, or an action timing out. The error is likely caused by a transient infrastructure issue such as lack of resources or network flakiness.",JobTimeoutError:"The test took too long to complete, suggesting a problem with the test itself."},rs=Wt.object({reason:Wt.nativeEnum(ue),summary:Wt.string()}).openapi({ref:"TestResultClassification"}),Ui=Wt.object({errorMessage:Wt.string(),errorStack:Wt.string().optional(),classification:rs.optional()}).openapi({ref:"TestFailureDetails"});re(U);var Qe=(s=>(s.SUCCESS="SUCCESS",s.FAILED="FAILED",s.RUNNING="RUNNING",s.IDLE="IDLE",s.CANCELLED="CANCELLED",s))(Qe||{}),Fn=(n=>(n.SUCCESS="SUCCESS",n.FAILED="FAILED",n.CANCELLED="CANCELLED",n))(Fn||{}),$i=U.object({beforeUrl:U.string().optional(),afterUrl:U.string().optional(),beforeScreenshot:U.string().optional(),afterScreenshot:U.string().optional(),startedAt:U.coerce.date(),finishedAt:U.coerce.date()}),Yu=$i.extend({viewport:U.object({height:U.number(),width:U.number()}),status:U.nativeEnum(Fn),message:U.string().optional(),elementInteracted:U.string().optional()}),jt=$i.extend({status:U.nativeEnum(Qe),message:U.string().optional(),data:U.unknown().optional(),beforeTestContext:es.optional(),afterTestContext:es.optional(),failureReason:U.nativeEnum(ue).optional(),details:U.unknown().describe("Parse using StepExecutionLogSchema.array() to get type safety. We don't explicitly type it because it's non-critical information.")}).openapi({ref:"StepResultMetadata"}),ns=jt.merge($e).extend({results:Yu.array()}),Xu=jt.merge(ar).extend({results:U.lazy(()=>ns.array())}),Ju=jt.merge(lr).extend({moduleName:U.string().optional(),results:U.lazy(()=>Ze.array())}),Zu=jt.merge(Vr).extend({assertion:ns.optional(),results:U.lazy(()=>Ze.array()).describe("results for the block actually executed")}),Qu=jt.merge(qr).extend({results:U.lazy(()=>Ze.array())}),em=jt.merge(Kr).extend({results:U.lazy(()=>Ze.array()),healingAttempts:U.lazy(()=>Ze.array().array()).optional()}),Ze=U.discriminatedUnion("type",[Xu,ns,Ju,Zu,Qu,em]),Un=jt.pick({startedAt:!0,finishedAt:!0,status:!0,message:!0,data:!0}),Bw=U.object({results:Ze.array(),errorMessage:U.string(),errorStack:U.string().optional()});re(F);var Xr={WEBHOOK:"WEBHOOK",CRON:"CRON",MANUAL:"MANUAL",CLI:"CLI"},Gt=(a=>(a.PENDING="PENDING",a.RUNNING="RUNNING",a.PASSED="PASSED",a.FAILED="FAILED",a.CANCELLED="CANCELLED",a.RETRYING="RETRYING",a.WAITING_FOR_USER="WAITING_FOR_USER",a))(Gt||{}),ut=F.string().pipe(F.coerce.date()).or(F.date()),Jr=F.object({id:F.string(),runKey:F.string(),organizationId:F.string(),createdAt:ut,createdBy:F.string(),flake:F.boolean().nullish(),scheduledAt:ut.or(F.null()),startedAt:ut.or(F.null()),updatedAt:ut.nullish(),finishedAt:ut.or(F.null()),resolvedBaseUrl:F.string().nullish(),status:F.nativeEnum(Gt),trigger:F.nativeEnum(Xr),attempts:F.number(),failureReason:F.nativeEnum(ue).nullish(),failureDetails:Ui.nullish(),testId:F.string().or(F.null()),testName:F.string().or(F.null()).optional(),test:F.object({name:F.string(),id:F.string()}).or(F.null()),suiteId:F.string().or(F.null()).optional()}).openapi({ref:"RunMetadata"}),tm={id:!0,status:!0,testName:!0,testId:!0,test:{select:{name:!0,id:!0}},failureReason:!0,failureDetails:!0},Bi=Jr.pick({...tm,test:!0}),Kw=Jr.omit({failureReason:!0,failureDetails:!0}),os=Jr.merge(F.object({results:Ze.array(),debugData:Ai.nullish().catch(void 0),resolvedInputs:F.record(F.string(),F.string()).nullish(),test:F.object({name:F.string(),id:F.string(),baseUrl:F.string().nullish(),advanced:cr.nullish()}).nullish()})),Yw=F.object({id:F.string(),name:F.string()}),zi=r=>{let e=r.filter(t=>t==="PASSED"||t==="FAILED");return new Set(e).size>1};import{z as me}from"zod";import*as z from"zod";var eb=z.object({thoughts:z.string().optional().describe("only provided if a description was provided"),target:Ut.optional().describe("only provided if a description was provided"),pageState:z.string().optional().describe("serialized a11y tree, only provided if a description was provided"),options:z.array(z.string()).optional().describe("provided for <select> elements only"),screenshot:z.object({data:z.string(),height:z.number().int(),width:z.number().int()}).optional().describe("only provided if returnScreenshot is true")});function Zr(r,e){if(!e||"useSelector"in r&&r.useSelector)return e;switch(r.type){case"SELECT_OPTION":return`<select> element: ${e}`;case"TYPE":return`text input element: ${e}`;default:return e}return e}var pr=z.object({matched:z.boolean(),reason:z.string().optional().describe("Human understandable description")}),rm=pr.extend({type:z.literal("A11Y_ID")}),nm=pr.extend({type:z.literal("USER_SELECTOR")}),om=pr.extend({type:z.literal("CSS_SELECTOR"),selectors:z.string().array()}),sm=pr.extend({type:z.literal("A11Y_DISTANCE"),distance:z.number().optional(),closestElement:z.string().optional(),savedElement:z.string().optional()}),im=pr.extend({type:z.literal("HTML_DISTANCE"),distance:z.number().optional(),closestElement:z.string().optional(),savedElement:z.string().optional()}),am=pr.extend({type:z.literal("TEMPLATE_MATCHING"),elementImageUrl:z.string().url()}),Hi=z.discriminatedUnion("type",[rm,nm,om,sm,im,am]);var lm=me.object({type:me.literal("TARGETING"),name:me.string().optional().describe("Target name for steps with multiple targets"),elementLocationDecisions:Hi.array(),pageState:me.string().optional(),targetSource:me.nativeEnum(Ft).optional(),targetUpdateTime:me.string().optional()}),cm=me.object({type:me.literal("AI_LOCATION"),matched:me.boolean(),pageState:me.string().optional(),ragUsed:me.boolean().optional(),thoughts:me.string().optional()}),dm=me.object({type:me.literal("ASSERTION"),relevantElementsSerialized:me.string().array().optional(),pageState:me.string().optional(),ragUsed:me.boolean().optional()}),um=me.discriminatedUnion("type",[lm,cm,dm]);function $n(){return{details:[]}}import{z as et}from"zod";var Wi=et.object({id:et.string().uuid(),orgId:et.string(),createdAt:ut,startedAt:ut.or(et.null()),finishedAt:ut.or(et.null()),status:et.nativeEnum(Gt),trigger:et.nativeEnum(Xr),suite:et.object({id:et.string(),name:et.string()}).nullish(),runs:Jr.array()}),lb=Wi.pick({id:!0,createdAt:!0,startedAt:!0,finishedAt:!0,status:!0,trigger:!0,suite:!0}),ji=Wi.extend({runs:Bi.array()});var Ke=class extends Error{constructor(e,t={}){super(e,t),this.name="CancellationError"}};var Bn=class extends Error{constructor(e,t,n,o={}){super(`The ${n} with id ${t} is invalid: ${e}`,o),this.name="InvalidEntityError"}};var zn=class extends Error{constructor(e,t={}){super(e,t),this.name="TemplateMatcherThresholdError"}},R=class extends Error{reason;emitToUser;constructor(e,t,n={},o=!1){let s=!1;for(let i of Object.values(ue))if(t.startsWith(i)){s=!0,e=i;break}s?super(t,n):super(`${e}${t?`: ${t}`:""}`,n),this.name="TestFailureError",this.stack=this.stack?.slice(this.name.length+2),this.reason=e,this.emitToUser=o}toString(){return this.message}toJSON(){return{message:this.message}}},mt=class extends Error{decisions;constructor(e,t,n={}){super(e,n),this.decisions=t,this.name="NoElementsFoundError"}toString(){return`${this.message}
|
|
2
|
+
var np=Object.create;var Ua=Object.defineProperty;var rp=Object.getOwnPropertyDescriptor;var op=Object.getOwnPropertyNames;var sp=Object.getPrototypeOf,ip=Object.prototype.hasOwnProperty;var $a=(r,e)=>()=>(e||r((e={exports:{}}).exports,e),e.exports);var ap=(r,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of op(e))!ip.call(r,o)&&o!==t&&Ua(r,o,{get:()=>e[o],enumerable:!(n=rp(e,o))||n.enumerable});return r};var lp=(r,e,t)=>(t=r!=null?np(sp(r)):{},ap(e||!r||!r.__esModule?Ua(t,"default",{value:r,enumerable:!0}):t,r));var au=$a(($U,iu)=>{"use strict";iu.exports=ou;function ou(r,e,t){r instanceof RegExp&&(r=ru(r,t)),e instanceof RegExp&&(e=ru(e,t));var n=su(r,e,t);return n&&{start:n[0],end:n[1],pre:t.slice(0,n[0]),body:t.slice(n[0]+r.length,n[1]),post:t.slice(n[1]+e.length)}}function ru(r,e){var t=e.match(r);return t?t[0]:null}ou.range=su;function su(r,e,t){var n,o,s,i,a,l=t.indexOf(r),c=t.indexOf(e,l+1),u=l;if(l>=0&&c>0){if(r===e)return[l,c];for(n=[],s=t.length;u>=0&&!a;)u==l?(n.push(u),l=t.indexOf(r,u+1)):n.length==1?a=[n.pop(),c]:(o=n.pop(),o<s&&(s=o,i=c),c=t.indexOf(e,u+1)),u=l<c&&l>=0?l:c;n.length&&(a=[s,i])}return a}});var fu=$a((BU,hu)=>{"use strict";var lu=au();hu.exports=Ly;var cu="\0SLASH"+Math.random()+"\0",du="\0OPEN"+Math.random()+"\0",Zi="\0CLOSE"+Math.random()+"\0",uu="\0COMMA"+Math.random()+"\0",mu="\0PERIOD"+Math.random()+"\0";function Ji(r){return parseInt(r,10)==r?parseInt(r,10):r.charCodeAt(0)}function Py(r){return r.split("\\\\").join(cu).split("\\{").join(du).split("\\}").join(Zi).split("\\,").join(uu).split("\\.").join(mu)}function Oy(r){return r.split(cu).join("\\").split(du).join("{").split(Zi).join("}").split(uu).join(",").split(mu).join(".")}function pu(r){if(!r)return[""];var e=[],t=lu("{","}",r);if(!t)return r.split(",");var n=t.pre,o=t.body,s=t.post,i=n.split(",");i[i.length-1]+="{"+o+"}";var a=pu(s);return s.length&&(i[i.length-1]+=a.shift(),i.push.apply(i,a)),e.push.apply(e,i),e}function Ly(r){return r?(r.substr(0,2)==="{}"&&(r="\\{\\}"+r.substr(2)),Vr(Py(r),!0).map(Oy)):[]}function My(r){return"{"+r+"}"}function Ny(r){return/^-?0\d/.test(r)}function _y(r,e){return r<=e}function ky(r,e){return r>=e}function Vr(r,e){var t=[],n=lu("{","}",r);if(!n)return[r];var o=n.pre,s=n.post.length?Vr(n.post,!1):[""];if(/\$$/.test(n.pre))for(var i=0;i<s.length;i++){var a=o+"{"+n.body+"}"+s[i];t.push(a)}else{var l=/^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(n.body),c=/^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(n.body),u=l||c,d=n.body.indexOf(",")>=0;if(!u&&!d)return n.post.match(/,.*\}/)?(r=n.pre+"{"+n.body+Zi+n.post,Vr(r)):[r];var m;if(u)m=n.body.split(/\.\./);else if(m=pu(n.body),m.length===1&&(m=Vr(m[0],!1).map(My),m.length===1))return s.map(function(M){return n.pre+m[0]+M});var p;if(u){var f=Ji(m[0]),h=Ji(m[1]),g=Math.max(m[0].length,m[1].length),y=m.length==3?Math.abs(Ji(m[2])):1,S=_y,b=h<f;b&&(y*=-1,S=ky);var C=m.some(Ny);p=[];for(var v=f;S(v,h);v+=y){var E;if(c)E=String.fromCharCode(v),E==="\\"&&(E="");else if(E=String(v),C){var P=g-E.length;if(P>0){var A=new Array(P+1).join("0");v<0?E="-"+A+E.slice(1):E=A+E}}p.push(E)}}else{p=[];for(var O=0;O<m.length;O++)p.push.apply(p,Vr(m[O],!1))}for(var O=0;O<p.length;O++)for(var i=0;i<s.length;i++){var a=o+p[O]+s[i];(!e||u||a)&&t.push(a)}}return t}});import{Command as yb,Option as qt}from"@commander-js/extra-typings";import{execSync as Sb}from"child_process";import{z as To}from"zod";import{z as ri}from"zod";function ne(r){if(typeof r.ZodType.prototype.openapi<"u")return;r.ZodType.prototype.openapi=function(o){return new this.constructor({...this._def,openapi:o})};let e=r.ZodObject.prototype.extend;r.ZodObject.prototype.extend=function(...o){let s=e.apply(this,o);return s._def.extendMetadata={extends:this},delete s._def.openapi,s};let t=r.ZodObject.prototype.omit;r.ZodObject.prototype.omit=function(...o){let s=t.apply(this,o);return delete s._def.extendMetadata,delete s._def.openapi,s};let n=r.ZodObject.prototype.pick;r.ZodObject.prototype.pick=function(...o){let s=n.apply(this,o);return delete s._def.extendMetadata,delete s._def.openapi,s}}import{z as ni}from"zod";import{v4 as ie}from"uuid";import*as w from"zod";import{z as V}from"zod";ne(V);var Ba=V.object({thoughts:V.string(),result:V.boolean(),relevantElements:V.array(V.number()).optional()}),ur=(n=>(n.CONTAINS="CONTAINS",n.STARTS_WITH="STARTS_WITH",n.EQUALS="EQUALS",n))(ur||{});var cp=V.object({type:V.literal("ELEMENT_CONTENT"),negated:V.boolean().optional(),operation:V.nativeEnum(ur),value:V.string()}).openapi({ref:"ElementContentAssertion"}),dp=V.object({type:V.literal("ELEMENT_ATTRIBUTE"),negated:V.boolean().optional(),operation:V.nativeEnum(ur),attr:V.string(),value:V.string()}).openapi({ref:"ElementAttributeValueAssertion"}),mr=(o=>(o.EXISTS="EXISTS",o.VISIBLE="VISIBLE",o.ENABLED="ENABLED",o.EDITABLE="EDITABLE",o))(mr||{}),up=V.object({type:V.literal("ELEMENT_EXISTENCE"),negated:V.boolean().optional(),condition:V.nativeEnum(mr)}).openapi({ref:"ElementExistenceAssertion"}),za=V.discriminatedUnion("type",[cp,dp,up]).openapi({ref:"ManualElementAssertion"});var mp=V.object({type:V.literal("CONTENT"),negated:V.boolean().optional(),value:V.string()}).openapi({ref:"PageContentAssertion"}),Wa=V.discriminatedUnion("type",[mp]).openapi({ref:"ManualPageAssertion"});import*as k from"zod";ne(k);var Yt=(i=>(i.AI="AI",i.AI_HEALED="AI_HEALED",i.CLICK_TO_FIND="CLICK_TO_FIND",i.XY_PERCENT="XY_PERCENT",i.RECORDING="RECORDING",i.USER_CSS_SELECTOR="USER_CSS_SELECTOR",i))(Yt||{}),Xt=k.object({id:k.number().int(),dataMomenticId:k.number().int().optional(),selector:k.string().optional(),generatedSelectors:k.string().array().optional(),role:k.string().optional(),name:k.string().optional(),numChildren:k.number().optional(),content:k.string().optional(),pathFromRoot:k.string().optional(),serializedForm:k.string().optional(),nodeOnlySerializedForm:k.string().optional(),serializedHtml:k.string().optional().describe("pruned html including 1 neighbor and 1 layer of children. value for text inputs pruned."),nodeOnlySerializedHtml:k.string().optional().describe("outerHtml of the element without any children. value for text inputs pruned."),screenshotUrl:k.string().url().optional(),boundingBox:k.object({x:k.number().optional(),y:k.number().optional(),width:k.number(),height:k.number()}).describe("css pixel bounding box").optional(),inputDescription:k.string().optional().describe("the description that generated this cache"),targetSource:k.nativeEnum(Yt).optional(),targetUpdateTime:k.string().optional()}).openapi({ref:"A11yTargetWithCache"});function yo(r){return!!(r.name||r.role||r.content||r.serializedForm||r.serializedHtml||r.screenshotUrl)}var pp=k.object({percentX:k.number().describe("between 0 and 1"),percentY:k.number()}),hp=k.object({type:k.literal("description"),elementDescriptor:k.string(),a11yData:Xt.optional().describe("DEPRECATED: new a11y cache is stored in DB and resolved into the 'cache' field")}).openapi({ref:"DescriptionTarget"});function xt(r){return r.type==="description"}function Jt(r){return r.type==="coordinates"}var Te=k.discriminatedUnion("type",[hp,k.object({type:k.literal("coordinates"),percentXYLocation:pp}).openapi({ref:"CoordinatesTarget"})]).openapi({ref:"ElementTarget"});function Xs(r){if(!r)return!1;switch(r.type){case"description":return!!r.elementDescriptor;case"coordinates":return r.percentXYLocation.percentX>=0||r.percentXYLocation.percentY>=0}return!0}function ve(r){if(!r)return"";switch(r.type){case"description":return r.elementDescriptor;case"coordinates":return`x: ${r.percentXYLocation.percentX}, y: ${r.percentXYLocation.percentY}`}}var ce=(N=>(N.AI_EXTRACT="AI_EXTRACT",N.AI_ASSERTION="AI_ASSERTION",N.AI_WAIT="AI_WAIT",N.AUTH_LOAD="AUTH_LOAD",N.AUTH_SAVE="AUTH_SAVE",N.BLUR="BLUR",N.CAPTCHA="CAPTCHA",N.CLICK="CLICK",N.COOKIE="COOKIE",N.DIALOG="DIALOG",N.DRAG="DRAG",N.ELEMENT_CHECK="ELEMENT_CHECK",N.FILE_UPLOAD="FILE_UPLOAD",N.FOCUS="FOCUS",N.GO_BACK="GO_BACK",N.GO_FORWARD="GO_FORWARD",N.HOVER="HOVER",N.JAVASCRIPT="JAVASCRIPT",N.LOCAL_STORAGE="LOCAL_STORAGE",N.MOUSE_DRAG="MOUSE_DRAG",N.NAVIGATE="NAVIGATE",N.NEW_TAB="NEW_TAB",N.PAGE_CHECK="PAGE_CHECK",N.PRESS="PRESS",N.REFRESH="REFRESH",N.REQUEST="REQUEST",N.SCROLL_DOWN="SCROLL_DOWN",N.SCROLL_UP="SCROLL_UP",N.SCROLL_LEFT="SCROLL_LEFT",N.SCROLL_RIGHT="SCROLL_RIGHT",N.SELECT_OPTION="SELECT_OPTION",N.TAB="TAB",N.TYPE="TYPE",N.VISUAL_DIFF="VISUAL_DIFF",N.WAIT="WAIT",N.WAIT_FOR_URL="WAIT_FOR_URL",N.SUCCESS="SUCCESS",N))(ce||{});ne(w);var U=w.object({thoughts:w.string().optional(),id:w.string().uuid().describe("unique identifier to this step, used for step cache")}),je=w.object({useSelector:w.boolean().optional(),useXY:w.boolean().optional(),force:w.boolean().optional(),disableCache:w.boolean().optional().describe("disable element caching for this step"),iframeUrl:w.string().optional().describe("url or url regex for the iframe")}).openapi({ref:"CommonTargetingOptions"}),mt=w.object({target:Xt}).optional().openapi({ref:"SingleTargetCache"}),So=w.object({loadTimeout:w.number().int().max(60).optional().describe("Max seconds for the page to load")}),fp=U.merge(So).merge(w.object({type:w.literal("NAVIGATE"),url:w.string()})).openapi({ref:"NavigateCommand"}),wo=je.merge(w.object({cache:mt})),wn=U.merge(wo.merge(w.object({target:Te.optional(),type:w.literal("SCROLL_UP"),deltaY:w.number().optional()}))).openapi({ref:"ScrollUpCommand"}),bn=U.merge(wo.merge(w.object({target:Te.optional(),type:w.literal("SCROLL_DOWN"),deltaY:w.number().optional()}))).openapi({ref:"ScrollDownCommand"}),Cn=U.merge(wo.merge(w.object({target:Te.optional(),type:w.literal("SCROLL_LEFT"),deltaX:w.number().optional()}))).openapi({ref:"ScrollLeftCommand"}),Tn=U.merge(wo.merge(w.object({target:Te.optional(),type:w.literal("SCROLL_RIGHT"),deltaX:w.number().optional()}))).openapi({ref:"ScrollRightCommand"}),Db=w.discriminatedUnion("type",[wn,bn,Cn,Tn]).openapi({ref:"AllScrollCommands"}),gp=U.merge(w.object({type:w.literal("DIALOG"),action:w.union([w.literal("ACCEPT"),w.literal("DISMISS")])})).openapi({ref:"DialogCommand"}),yp=U.merge(w.object({type:w.literal("WAIT"),delay:w.number()})).openapi({ref:"WaitCommand"}),Sp=U.merge(w.object({type:w.literal("WAIT_FOR_URL"),url:w.string(),timeout:w.number().int().optional().describe("Max seconds to wait for the URL to match")})).openapi({ref:"WaitUrlCommand"}),wp=U.merge(So).merge(w.object({type:w.literal("REFRESH")})).openapi({ref:"RefreshCommand"}),bp=U.merge(w.object({type:w.literal("GO_BACK")})).openapi({ref:"GoBackCommand"}),Cp=U.merge(w.object({type:w.literal("GO_FORWARD")})).openapi({ref:"GoForwardCommand"}),Tp=U.extend({type:w.literal("AUTH_SAVE")}).openapi({ref:"AuthSaveCommand"}),vp=U.extend({type:w.literal("AUTH_LOAD"),storageState:w.string().describe("JSON string auth state")}).openapi({ref:"AuthLoadCommand"}),Zs=U.merge(je).extend({type:w.literal("CAPTCHA")}).openapi({ref:"CaptchaCommand"}),Ep=U.merge(w.object({type:w.literal("JAVASCRIPT"),code:w.string(),fragment:w.boolean().optional(),envKey:w.string().optional(),environment:w.union([w.literal("NODE"),w.literal("BROWSER")]).optional().describe("default NODE"),timeout:w.number().int().max(60).optional().describe("Max seconds for the code to complete")})).openapi({ref:"JavaScriptCommand"}),pr=U.merge(je).merge(w.object({type:w.literal("CLICK"),target:Te,doubleClick:w.boolean().optional(),rightClick:w.boolean().optional(),waitForUrl:w.string().optional().describe("Wait for the click to trigger a page load or new tab that matches the provided URL or URL glob (e.g. https://google.com/**/*)."),waitForDownload:w.boolean().optional().describe("Wait for the click to trigger a file download and for the file download to complete."),cache:mt})).openapi({ref:"ClickCommand"}),hr=U.merge(je).merge(w.object({type:w.literal("DRAG"),fromTarget:Te,toTarget:Te,hoverSeconds:w.number().optional().describe("Seconds to hover the object before dropping"),cache:w.object({fromTarget:Xt.optional(),toTarget:Xt.optional()}).optional()})).openapi({ref:"DragCommand"}),fr=U.merge(je).merge(w.object({type:w.literal("MOUSE_DRAG"),target:Te.optional(),deltaX:w.string().describe("pixels to move horizontally, can be template"),deltaY:w.string().describe("pixels to move vertically, can be template"),steps:w.number().optional(),cache:mt})).openapi({ref:"MouseDragCommand"}),gr=U.merge(je).merge(w.object({type:w.literal("HOVER"),target:Te,cache:mt})).openapi({ref:"HoverCommand"}),yr=U.merge(je).merge(w.object({type:w.literal("FOCUS"),target:Te,cache:mt})).openapi({ref:"FocusCommand"}),Sr=U.merge(je).merge(w.object({type:w.literal("BLUR"),target:Te,cache:mt})).openapi({ref:"BlurCommand"}),xp=w.object({type:w.literal("URL"),url:w.string()}).describe("Accessible link to the file, either public http or local file://").openapi({ref:"UrlSource"}),Ap=U.extend({type:w.literal("FILE_UPLOAD"),fileSource:w.discriminatedUnion("type",[xp])}).openapi({ref:"FileUploadCommand"}),wr=U.merge(je).merge(w.object({type:w.literal("SELECT_OPTION"),target:Te,option:w.string(),cache:mt})).openapi({ref:"SelectOptionCommand"}),Qs=U.merge(w.object({type:w.literal("AI_ASSERTION"),assertion:w.string(),disableCache:w.boolean().optional(),iframeUrl:w.string().optional(),timeout:w.number().int().optional().describe("Max seconds to wait for assertion to be true")})).openapi({ref:"AIAssertionCommand"}),Rp=Qs.extend({type:w.literal("AI_WAIT")}).openapi({ref:"AIWaitCommand"}),Zt=5,ei=60,br=U.merge(je).extend({type:w.literal("ELEMENT_CHECK"),target:Te,assertion:za,cache:mt,timeout:w.number().int().min(0).max(ei).optional().describe("max seconds to wait for the assertion to be true")}).openapi({ref:"ElementAssertionCommand"}),Ip=U.extend({type:w.literal("PAGE_CHECK"),assertion:Wa,iframeUrl:w.string().optional().describe("url or url regex for the iframe"),timeout:w.number().int().min(0).max(ei).optional().describe("max seconds to wait for the assertion to be true")}).openapi({ref:"PageAssertionCommand"}),Pp=U.merge(w.object({type:w.literal("AI_EXTRACT"),goal:w.string(),schema:w.string().optional(),envKey:w.string().optional(),disableCache:w.boolean().optional(),iframeUrl:w.string().optional()})).openapi({ref:"AIExtractCommand"}),Op=w.object({clearContent:w.boolean().optional(),pressKeysSequentially:w.boolean().optional(),force:w.boolean().optional(),pressEnter:w.boolean().optional()}),Cr=U.merge(je).merge(Op).extend({type:w.literal("TYPE"),target:Te.optional(),value:w.string(),cache:mt}).openapi({ref:"TypeCommand"}),Lp=U.merge(w.object({type:w.literal("PRESS"),value:w.string()})).openapi({ref:"PressCommand"}),Mp=U.merge(So).merge(w.object({type:w.literal("TAB"),url:w.string()})).openapi({ref:"TabCommand"}),Np=U.merge(So).merge(w.object({type:w.literal("NEW_TAB"),url:w.string()})).openapi({ref:"NewTabCommand"}),_p=U.merge(w.object({type:w.literal("COOKIE"),value:w.string()})).openapi({ref:"CookieCommand"}),kp=U.merge(w.object({type:w.literal("LOCAL_STORAGE"),key:w.string(),value:w.string()})).openapi({ref:"LocalStorageCommand"}),Dp=U.merge(w.object({type:w.literal("REQUEST"),url:w.string(),method:w.union([w.literal("GET"),w.literal("POST"),w.literal("PUT"),w.literal("DELETE"),w.literal("PATCH")]),headers:w.record(w.string(),w.string()).optional(),params:w.record(w.string(),w.string()).optional(),body:w.string().optional(),timeout:w.number().int().optional().describe("Max seconds to wait for the request to complete")})).openapi({ref:"RequestCommand"}),Fp=U.merge(w.object({type:w.literal("SUCCESS"),condition:Qs.optional()})).openapi({ref:"SuccessCommand"}),Up=U.merge(w.object({type:w.literal("FAILURE")})).openapi({ref:"FailureCommand"}),$p=w.object({data:w.string().describe("s3 url to a jpg"),width:w.number(),height:w.number()}),Tr=U.merge(je).merge(w.object({type:w.literal("VISUAL_DIFF"),threshold:w.number().optional().describe("default 0.1"),target:Te.optional(),screenshot:$p.optional(),cache:mt})).openapi({ref:"VisualDiffCommand"}),bo=w.discriminatedUnion("type",[pr,Cr,Lp,wr,fp,bn,wn,Qs,Fp]),Bp=w.discriminatedUnion("type",[Rp,Pp,vp,Tp,Zs,_p,gp,hr,br,Ap,bp,Cp,gr,Ep,kp,fr,Np,Ip,wp,Dp,Cn,Tn,Mp,Tr,yp,yr,Sr,Sp]),Co=w.discriminatedUnion("type",[...bo.options,...Bp.options]).openapi({ref:"Command"}),ti=w.discriminatedUnion("type",[...bo.options,Up]);function Bt(r){let e;switch(r){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:ie(),type:r};break;case"AUTH_LOAD":{e={id:ie(),type:r,storageState:""};break}case"AI_EXTRACT":e={id:ie(),type:r,goal:""};break;case"DIALOG":e={id:ie(),type:r,action:"DISMISS"};break;case"DRAG":e={id:ie(),type:r,fromTarget:{type:"description",elementDescriptor:""},toTarget:{type:"description",elementDescriptor:""}};break;case"MOUSE_DRAG":e={id:ie(),type:r,deltaX:"0",deltaY:"0",steps:1};break;case"WAIT_FOR_URL":e={id:ie(),type:r,url:""};break;case"WAIT":e={id:ie(),type:r,delay:1};break;case"HOVER":case"BLUR":case"FOCUS":case"CLICK":e={id:ie(),type:r,target:{type:"description",elementDescriptor:""}};break;case"COOKIE":case"PRESS":case"TYPE":e={id:ie(),type:r,value:"",clearContent:!0};break;case"SELECT_OPTION":e={id:ie(),type:r,target:{type:"description",elementDescriptor:""},option:""};break;case"NAVIGATE":case"NEW_TAB":case"TAB":e={id:ie(),type:r,url:""};break;case"REQUEST":e={id:ie(),type:r,url:"",method:"GET"};break;case"LOCAL_STORAGE":e={id:ie(),type:r,key:"",value:""};break;case"JAVASCRIPT":e={id:ie(),type:r,code:""};break;case"AI_WAIT":case"AI_ASSERTION":e={id:ie(),type:r,assertion:""};break;case"FILE_UPLOAD":{e={id:ie(),type:r,fileSource:{type:"URL",url:""}};break}case"ELEMENT_CHECK":{e={id:ie(),type:r,target:{type:"description",elementDescriptor:""},assertion:{type:"ELEMENT_EXISTENCE",condition:"EXISTS"}};break}case"PAGE_CHECK":{e={id:ie(),type:r,assertion:{type:"CONTENT",value:""}};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}import{z as vr}from"zod";var Ge=vr.object({index:vr.number().optional().describe("global index within a test (in-order traversal)"),id:vr.string().optional(),skipped:vr.boolean().optional(),envKey:vr.string().optional().describe("key in the environment to save the result of this step to")});var q=(i=>(i.PRESET_ACTION="PRESET_ACTION",i.MODULE="MODULE",i.AI_ACTION="AI_ACTION",i.CONDITIONAL="CONDITIONAL",i.IFRAME="IFRAME",i.SECTION="SECTION",i))(q||{});ne(ni);var Ve=Ge.extend({type:ni.literal("PRESET_ACTION"),command:Co,skipped:ni.boolean().optional()}).openapi({ref:"PresetAction"});ne(ri);var vn=Ge.extend({type:ri.literal("AI_ACTION"),text:ri.string(),steps:Ve.array().optional()}).openapi({ref:"AIAction"});import{z as Q}from"zod";var zp=Q.object({cacheKey:Q.string(),cacheExpiryMs:Q.number()}),oi=Ge.extend({id:Q.string().uuid().describe("ID of the module step itself. Used to 'namespace' step cache entries."),inputs:Q.record(Q.string()).optional(),cacheConfig:zp.optional()}),En=oi.extend({type:Q.literal("MODULE"),moduleId:Q.string().uuid()}),Wp=Q.union([En.pick({type:!0,moduleId:!0}),Q.record(Q.unknown())]),qe=Q.object({moduleId:Q.string().uuid(),name:Q.string(),description:Q.string().nullish(),enabled:Q.boolean().nullish(),parameters:Q.string().array().nullish(),defaultParameters:Q.record(Q.string(),Q.string()).nullish(),defaultCacheKey:Q.string().nullish(),defaultCacheTtl:Q.number().nullish()});import{z as Se}from"zod";import{z as ja}from"zod";var Er=Ge.extend({type:ja.literal("CONDITIONAL"),skipped:ja.boolean().optional()});import{z as Ke}from"zod";var Hp=Ke.object({type:Ke.literal("attr"),name:Ke.string(),value:Ke.string()}),jp=Ke.object({type:Ke.literal("css"),selector:Ke.string()}),Gp=Ke.object({type:Ke.literal("url"),url:Ke.string()}),Vp=Ke.union([Hp,Gp,jp]),xr=Ge.extend({type:Ke.literal("IFRAME"),identifier:Vp});import{z as Ye}from"zod";var si=(n=>(n.ALWAYS="ALWAYS",n.ON_FAILURE="ON_FAILURE",n.ON_ACTION_FAILURE="ON_ACTION_FAILURE",n))(si||{});var qp=Ye.discriminatedUnion("type",[Ye.object({type:Ye.literal("NAVIGATE_URL"),url:Ye.string().url()}),Ye.object({type:Ye.literal("GO_TO_SECTION_START")})]),Kp=Ye.object({trigger:Ye.nativeEnum(si).optional(),attempts:Ye.number().int().optional(),restartBehavior:qp}),Ar=Ge.extend({type:Ye.literal("SECTION"),description:Ye.string().describe("user provided goal of what the section should accomplish"),plan:Ye.string().array().optional(),autohealingConfig:Kp.optional()});var Ga=qe.merge(oi).extend({type:Se.literal("RESOLVED_MODULE"),steps:Se.lazy(()=>de.array())}),ii=qe.extend({steps:Se.lazy(()=>de.array())}),Yp=xr.extend({steps:Se.lazy(()=>Xe.array())}),Xp=xr.extend({steps:Se.lazy(()=>de.array())}),Jp=Ar.extend({steps:Se.lazy(()=>Xe.array())}),Zp=Ar.extend({steps:Se.lazy(()=>de.array())}),Qp=Er.extend({blocks:Se.object({assertion:Se.lazy(()=>Ve),steps:Se.lazy(()=>Xe.array())}).array(),elseSteps:Se.lazy(()=>Xe.array().optional())}),eh=Er.extend({blocks:Se.object({assertion:Se.lazy(()=>Ve),steps:Se.lazy(()=>de.array())}).array(),elseSteps:Se.lazy(()=>de.array().optional())}),Xe=Se.discriminatedUnion("type",[Ve,vn,En,Qp,Yp,Jp]),de=Se.discriminatedUnion("type",[Ve,vn,Ga,eh,Xp,Zp]);var ke="1.0.13";import{z as en}from"zod";import{z as th}from"zod";var $C=th.discriminatedUnion("type",[Sr,Zs,pr,hr,yr,gr,fr,wn,bn,Cn,Tn,wr,Cr,Tr,br]);function Va(r){return["AI_ASSERTION","ELEMENT_CHECK","PAGE_CHECK"].includes(r)}import{z as nh}from"zod";var De={type:!0,cache:!0},Qt=nh.discriminatedUnion("type",[Sr.pick(De),pr.pick(De),hr.pick(De),br.pick(De),yr.pick(De),gr.pick(De),fr.pick(De),wn.pick(De),bn.pick(De),Cn.pick(De),Tn.pick(De),wr.pick(De),Cr.pick(De),Tr.pick(De)]),ai=Object.values(ce).filter(r=>Qt.options.some(e=>e.shape.type.safeParse(r).success));Co.options.forEach(r=>{if("target"in r.shape&&!ai.includes(r.shape.type.value))throw new Error(`Command ${r.shape.type.value} has a target but no cache`)});var li=en.object({key:en.string(),testId:en.string().optional(),moduleId:en.string().optional(),organizationId:en.string(),value:Qt}),qa=en.record(en.string(),li);var vT=To.object({testId:To.string(),orgId:To.string(),runId:To.string(),steps:de.array()});import{z as At}from"zod";var vo=At.object({x:At.number(),y:At.number(),correlation:At.number()}),AT=At.object({searchImageBase64String:At.string(),pageImageBase64String:At.string(),id:At.string().uuid(),timeoutMs:At.number().max(1e4).min(0).optional()});import zv from"string-argv";import{v4 as Hv}from"uuid";import{z as L}from"zod";import*as we from"zod";ne(we);var rh=we.object({url:we.string(),lineNumber:we.number(),columnNumber:we.number()}).openapi({ref:"CodeLocation"}),oh=we.object({timestamp:we.number(),text:we.string(),type:we.string(),tabIndex:we.number(),args:we.unknown().array().optional(),url:we.string().optional(),location:rh.optional()}).openapi({ref:"ConsoleLog"}),Ka=we.object({logsPerPage:oh.array().array()}).openapi({ref:"DebugData"});import{z as D}from"zod";import{isValidCron as sh}from"cron-validator";import{z as ee}from"zod";import{z as ci}from"zod";var Eo=ci.object({width:ci.number().min(200).max(1e4),height:ci.number().min(200).max(1e4)}),Ya={"Desktop Large":{width:1920,height:1080},"Desktop Small":{width:1280,height:800},iPad:{width:768,height:1024},"Pixel 8":{width:448,height:998},"iPhone 15":{width:393,height:852}},MT=Object.keys(Ya);var Rt=Ya["Desktop Large"];var Xa=1e4,Ja=6e4,Rr=ee.object({pageLoadTimeoutMs:ee.number().optional().refine(r=>r===void 0||r<=Ja&&r>=-1,{message:`Page load timeout must be between 0 and ${Ja/1e3} seconds`}),smartWaitingTimeoutMs:ee.number().optional().refine(r=>r===void 0||r<=Xa&&r>=-1,{message:`Smart waiting timeout must be between 0 and ${Xa/1e3} seconds`}),extraHeaders:ee.record(ee.string(),ee.string()).optional().describe("HTTP headers to be sent on every request"),userAgent:ee.string().optional()}),ih=ee.object({disableAICaching:ee.boolean().default(!1),viewport:Eo.optional()}),xn=ih.merge(Rr),Za=ee.object({cron:ee.string().refine(r=>sh(r),{message:"Invalid cron expression."}).default("0 0 */1 * *"),enabled:ee.boolean().default(!1),env:ee.string().optional(),timeZone:ee.string().default("America/Los_Angeles"),jobKey:ee.string().optional()}),Qa=ee.object({onSuccess:ee.boolean().default(!1),onFailure:ee.boolean().default(!0)}),ah=ee.object({name:ee.string(),required:ee.boolean().optional(),defaultValue:ee.string().describe("this is not optional because we need a value when the editor is first loaded")}),el=ah.array();import*as F from"zod";import{cloneDeep as In}from"lodash-es";import*as Je from"zod";import{z as An}from"zod";var ae="BASE_URL",xo="CURRENT_URL",Rn="ENV_NAME",$T={[ae]:"https://www.google.com"},tl=An.string().describe("Name of the fixture (must be available locally in the fixtures directory)."),zt=An.object({name:An.string(),variables:An.record(An.string().describe("variable name"),An.string().describe("variable value"))});ne(Je);var ui=Je.object({env:Je.record(Je.unknown()),results:Je.array(Je.unknown()),inputs:Je.record(Je.unknown()).optional()}).openapi({ref:"TestContextSnapshot"}),lh="\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022",nl=500,ch=[ae,Rn],rl=[xo,ae,Rn],le=class r{env={};inputs=void 0;results=[];varsFromMomenticEnvironment={};constructor(e){this.reset(e)}static dummyContext(e=void 0,t={}){return new r({baseUrl:"about:blank",currentUrl:"about:blank",envName:e,variablesFromEnvironment:t})}static fromSnapshot({snapshot:e,environmentVariables:t}){let n=e.env[ae]??"about:blank",o=e.env[xo]??"about:blank",s=e.env[Rn],i={};for(let[l,c]of Object.entries(e.env))rl.includes(l)||(t??{})[l]===void 0&&(i[l]=c);let a=new r({baseUrl:n,currentUrl:o,dynamicVariables:i,envName:s,variablesFromEnvironment:t??{}});return a.setInputs(e.inputs),a.setResults(e.results),a}setEnvVariables(e){let t=In(e);this.env=Object.assign(this.env,t)}setInputs(e){this.inputs=e}setResult(e,t){this.results[e]=t||null;for(let n=0;n<e;n++)this.results[n]===void 0&&(this.results[n]=null)}getResult(e){return this.results[e]}getResultsCopy(){return In(this.results)}setMomenticSystemVariable(e,t){this.varsFromMomenticEnvironment[e]=t}setResults(e){this.results=e}clearResults(){this.results=[]}getVariable(e){return this.env[e]}setVariable(e,t){ch.includes(e)||(this.env[e]=t)}getEnvName(){return this.env[Rn]}toObjectCopy(){let e={results:this.results,env:Object.assign({},this.env,this.varsFromMomenticEnvironment)};return this.inputs&&(e.inputs=this.inputs),In(e)}toRedactedDisplayCopy(){let e=this.toObjectCopy();return e.env=Object.fromEntries(Object.entries(e.env).map(([t,n])=>rl.includes(t)||this.varsFromMomenticEnvironment[t]===void 0?[t,n]:[t,lh])),mi(e),e}setCurrentUrl(e){this.env[xo]=e}reset(e){this.results=[],this.env={},this.varsFromMomenticEnvironment={},this.setEnvVariables(e.dynamicVariables??{}),this.setCurrentUrl(e.currentUrl),this.varsFromMomenticEnvironment=In(e.variablesFromEnvironment),this.setMomenticSystemVariable(ae,e.baseUrl),e.envName&&this.setMomenticSystemVariable(Rn,e.envName)}getDynamicVariablesCopy(){return In(this.env)}getVariablesFromEnvironmentCopy(){return In(this.varsFromMomenticEnvironment)}},jT=Object.getPrototypeOf(async function(){}).constructor;function di(r){if(r==null)return r;let e=typeof r=="string"?r:JSON.stringify(r);return e.length>nl?`${e.slice(0,nl)}...(TRUNCATED, original type: ${typeof r})`:r}function mi(r){r.env=Object.fromEntries(Object.entries(r.env).map(([e,t])=>[e,di(t)])),r.results=r.results.map(e=>di(e)),r.inputs=Object.fromEntries(Object.entries(r.inputs??{}).map(([e,t])=>[e,di(t)]))}import{z as tn}from"zod";ne(tn);var ue=(a=>(a.AI_PROVIDER="AIProviderError",a.ACTION_FAILURE="ActionFailureError",a.ASSERTION_FAILURE="AssertionFailureError",a.CONFIG_ERROR="UserConfigurationError",a.JOB_TIMEOUT="JobTimeoutError",a.WEB_AGENT_PLATFORM="InternalWebAgentError",a.UNKNOWN_PLATFORM="InternalPlatformError",a))(ue||{});var ol={ActionFailureError:"Action failure",AssertionFailureError:"Assertion failure",UserConfigurationError:"Configuration error",AIProviderError:"AI provider error",InternalWebAgentError:"Momentic AI agent error",InternalPlatformError:"Infrastructure error",JobTimeoutError:"Job timeout"},sl={ActionFailureError:"A browser action such as a click or type failed to execute because of the underlying page state is incorrect, suggesting a bug in the application itself.",AssertionFailureError:"An AI assertion or check failed for a legitimate reason, such as a missing element, a change in the page structure, or an unexpected state (e.g. loading state).",UserConfigurationError:"The error message suggests a misconfiguration in the test, such as a variable being undefined, an environment variable missing, or a typo in a step. Do not use this reason if the error is caused by a bug in the application being tested, or Momentic's AI software.",AIProviderError:"The AI provider failed to return a response or returned a malformed response.",InternalWebAgentError:"The AI testing framework failed to find the correct element or evaluate the assertion correctly, even though the test steps and application state look valid. In other words, the AI agent failed to understand the page.",InternalPlatformError:"A platform error occurred, such as the Chromium browser failing, the network being down, or an action timing out. The error is likely caused by a transient infrastructure issue such as lack of resources or network flakiness.",JobTimeoutError:"The test took too long to complete, suggesting a problem with the test itself."},pi=tn.object({reason:tn.nativeEnum(ue),summary:tn.string()}).openapi({ref:"TestResultClassification"}),il=tn.object({errorMessage:tn.string(),errorStack:tn.string().optional(),classification:pi.optional()}).openapi({ref:"TestFailureDetails"});ne(F);var ht=(s=>(s.SUCCESS="SUCCESS",s.FAILED="FAILED",s.RUNNING="RUNNING",s.IDLE="IDLE",s.CANCELLED="CANCELLED",s))(ht||{}),Ao=(n=>(n.SUCCESS="SUCCESS",n.FAILED="FAILED",n.CANCELLED="CANCELLED",n))(Ao||{}),al=F.object({beforeUrl:F.string().optional(),afterUrl:F.string().optional(),beforeScreenshot:F.string().optional(),afterScreenshot:F.string().optional(),startedAt:F.coerce.date(),finishedAt:F.coerce.date()}),dh=al.extend({viewport:F.object({height:F.number(),width:F.number()}),status:F.nativeEnum(Ao),message:F.string().optional(),elementInteracted:F.string().optional()}),nn=al.extend({status:F.nativeEnum(ht),message:F.string().optional(),data:F.unknown().optional(),beforeTestContext:ui.optional(),afterTestContext:ui.optional(),failureReason:F.nativeEnum(ue).optional(),details:F.unknown().describe("Parse using StepExecutionLogSchema.array() to get type safety. We don't explicitly type it because it's non-critical information.")}).openapi({ref:"StepResultMetadata"}),hi=nn.merge(Ve).extend({results:dh.array()}),uh=nn.merge(vn).extend({results:F.lazy(()=>hi.array())}),mh=nn.merge(En).extend({moduleName:F.string().optional(),results:F.lazy(()=>pt.array())}),ph=nn.merge(Er).extend({assertion:hi.optional(),results:F.lazy(()=>pt.array()).describe("results for the block actually executed")}),hh=nn.merge(xr).extend({results:F.lazy(()=>pt.array())}),fh=nn.merge(Ar).extend({results:F.lazy(()=>pt.array()),healingAttempts:F.lazy(()=>pt.array().array()).optional()}),pt=F.discriminatedUnion("type",[uh,hi,mh,ph,hh,fh]),Ro=nn.pick({startedAt:!0,finishedAt:!0,status:!0,message:!0,data:!0}),sv=F.object({results:pt.array(),errorMessage:F.string(),errorStack:F.string().optional()});ne(D);var Ir={WEBHOOK:"WEBHOOK",CRON:"CRON",MANUAL:"MANUAL",CLI:"CLI"},rn=(a=>(a.PENDING="PENDING",a.RUNNING="RUNNING",a.PASSED="PASSED",a.FAILED="FAILED",a.CANCELLED="CANCELLED",a.RETRYING="RETRYING",a.WAITING_FOR_USER="WAITING_FOR_USER",a))(rn||{}),It=D.string().pipe(D.coerce.date()).or(D.date()),Pr=D.object({id:D.string(),runKey:D.string(),organizationId:D.string(),createdAt:It,createdBy:D.string(),flake:D.boolean().nullish(),scheduledAt:It.or(D.null()),startedAt:It.or(D.null()),updatedAt:It.nullish(),finishedAt:It.or(D.null()),resolvedBaseUrl:D.string().nullish(),status:D.nativeEnum(rn),trigger:D.nativeEnum(Ir),attempts:D.number(),failureReason:D.nativeEnum(ue).nullish(),failureDetails:il.nullish(),testId:D.string().or(D.null()),testName:D.string().or(D.null()).optional(),test:D.object({name:D.string(),id:D.string()}).or(D.null()),suiteId:D.string().or(D.null()).optional()}).openapi({ref:"RunMetadata"}),gh={id:!0,status:!0,testName:!0,testId:!0,test:{select:{name:!0,id:!0}},failureReason:!0,failureDetails:!0},ll=Pr.pick({...gh,test:!0}),pv=Pr.omit({failureReason:!0,failureDetails:!0}),fi=Pr.merge(D.object({results:pt.array(),debugData:Ka.nullish().catch(void 0),resolvedInputs:D.record(D.string(),D.string()).nullish(),test:D.object({name:D.string(),id:D.string(),baseUrl:D.string().nullish(),advanced:xn.nullish()}).nullish()})),hv=D.object({id:D.string(),name:D.string()}),cl=r=>{let e=r.filter(t=>t==="PASSED"||t==="FAILED");return new Set(e).size>1};import{z as me}from"zod";import*as B from"zod";var wv=B.object({thoughts:B.string().optional().describe("only provided if a description was provided"),target:Xt.optional().describe("only provided if a description was provided"),pageState:B.string().optional().describe("serialized a11y tree, only provided if a description was provided"),options:B.array(B.string()).optional().describe("provided for <select> elements only"),screenshot:B.object({data:B.string(),height:B.number().int(),width:B.number().int()}).optional().describe("only provided if returnScreenshot is true")});function Or(r,e){if(!e||"useSelector"in r&&r.useSelector)return e;switch(r.type){case"SELECT_OPTION":return`<select> element: ${e}`;case"TYPE":return`text input element: ${e}`;default:return e}return e}var Pn=B.object({matched:B.boolean(),reason:B.string().optional().describe("Human understandable description")}),yh=Pn.extend({type:B.literal("A11Y_ID")}),Sh=Pn.extend({type:B.literal("USER_SELECTOR")}),wh=Pn.extend({type:B.literal("CSS_SELECTOR"),selectors:B.string().array()}),bh=Pn.extend({type:B.literal("A11Y_DISTANCE"),distance:B.number().optional(),closestElement:B.string().optional(),savedElement:B.string().optional()}),Ch=Pn.extend({type:B.literal("HTML_DISTANCE"),distance:B.number().optional(),closestElement:B.string().optional(),savedElement:B.string().optional()}),Th=Pn.extend({type:B.literal("TEMPLATE_MATCHING"),elementImageUrl:B.string().url()}),dl=B.discriminatedUnion("type",[yh,Sh,wh,bh,Ch,Th]);var vh=me.object({type:me.literal("TARGETING"),name:me.string().optional().describe("Target name for steps with multiple targets"),elementLocationDecisions:dl.array(),pageState:me.string().optional(),targetSource:me.nativeEnum(Yt).optional(),targetUpdateTime:me.string().optional()}),Eh=me.object({type:me.literal("AI_LOCATION"),matched:me.boolean(),pageState:me.string().optional(),ragUsed:me.boolean().optional(),thoughts:me.string().optional()}),xh=me.object({type:me.literal("ASSERTION"),relevantElementsSerialized:me.string().array().optional(),pageState:me.string().optional(),ragUsed:me.boolean().optional()}),Ah=me.discriminatedUnion("type",[vh,Eh,xh]);function Io(){return{details:[]}}import{z as ft}from"zod";var ul=ft.object({id:ft.string().uuid(),orgId:ft.string(),createdAt:It,startedAt:It.or(ft.null()),finishedAt:It.or(ft.null()),status:ft.nativeEnum(rn),trigger:ft.nativeEnum(Ir),suite:ft.object({id:ft.string(),name:ft.string()}).nullish(),runs:Pr.array()}),Rv=ul.pick({id:!0,createdAt:!0,startedAt:!0,finishedAt:!0,status:!0,trigger:!0,suite:!0}),ml=ul.extend({runs:ll.array()});var st=class extends Error{constructor(e,t={}){super(e,t),this.name="CancellationError"}};var Po=class extends Error{constructor(e,t,n,o={}){super(`The ${n} with id ${t} is invalid: ${e}`,o),this.name="InvalidEntityError"}};var Oo=class extends Error{constructor(e,t={}){super(e,t),this.name="TemplateMatcherThresholdError"}},I=class extends Error{reason;emitToUser;constructor(e,t,n={},o=!1){let s=!1;for(let i of Object.values(ue))if(t.startsWith(i)){s=!0,e=i;break}s?super(t,n):super(`${e}${t?`: ${t}`:""}`,n),this.name="TestFailureError",this.stack=this.stack?.slice(this.name.length+2),this.reason=e,this.emitToUser=o}toString(){return this.message}toJSON(){return{message:this.message}}},Pt=class extends Error{decisions;constructor(e,t,n={}){super(e,n),this.decisions=t,this.name="NoElementsFoundError"}toString(){return`${this.message}
|
|
3
3
|
Decisions:
|
|
4
4
|
${this.decisions.map(e=>e.toString()).join(`
|
|
5
|
-
`)}`}};var Lb=L.object({command:L.string(),thoughts:L.string()}),Mb=L.string().pipe(L.coerce.number());var Gi=L.object({phrase:L.string()}),ss=L.object({result:L.union([L.literal("NOT_FOUND"),L.string(),L.number(),L.array(L.unknown()),L.record(L.unknown(),L.unknown())])}),Vi=L.object({thoughts:L.string(),id:L.number().int()}),Nb=L.object({results:L.array(Ze),goal:L.string(),errorMessage:L.string()}),mm=L.discriminatedUnion("op",[L.object({op:L.literal("replace"),path:L.string(),value:L.string()}),L.object({op:L.literal("add"),path:L.string(),value:L.string()}),L.object({op:L.literal("remove"),path:L.string()})]),_b=L.object({thoughts:L.string(),patches:mm.array()}),pm=L.discriminatedUnion("op",[L.object({op:L.literal("replace"),path:L.string(),value:de}),L.object({op:L.literal("add"),path:L.string(),value:de}),L.object({op:L.literal("remove"),path:L.string()})]),qi=L.object({patches:pm.array(),thoughts:L.string()});import{z as ve}from"zod";var gm=ve.object({content:ve.string(),ids:ve.string().array(),tokenLength:ve.number()}),hm=ve.object({chunks:gm.array(),numRecs:ve.number()}),Fb=ve.object({ids:ve.string().array(),score:ve.number(),tokenLength:ve.number()}),Ub=ve.object({description:ve.string(),tokenLimit:ve.number()}).merge(hm),Ki=ve.object({ids:ve.number().array()});import{z as xe}from"zod";var fm=xe.object({type:xe.nativeEnum(Y),generatedStep:Ln.optional(),serializedCommand:xe.string().optional(),elementInteracted:xe.string().optional()}),gr=xe.object({goal:xe.string(),url:xe.string(),browserState:xe.string(),history:xe.string(),numPrevious:xe.number(),lastCommand:fm.or(xe.null())}),is=gr.extend({screenshot:xe.string()}),Yi=xe.object({goal:is.shape.goal,browserState:is.shape.browserState,returnSchema:xe.string().optional()}),Xi=is.pick({goal:!0,browserState:!0,screenshot:!0,url:!0}),Ji=gr.extend({screenshot:xe.string().optional()});import{z as hr}from"zod";var Gb=hr.object({goal:hr.string(),completionType:hr.string().describe("type of completion these keywords will be used for")}),Zi=hr.object({keywords:hr.array(hr.string())});var rC=new Set(Object.values(se));var as={AI_ACTION:"AI action",RESOLVED_MODULE:"Module",AI_ASSERTION:"AI check",AI_WAIT:"AI wait",AI_EXTRACT:"AI extract",CLICK:"Click",TYPE:"Type",JAVASCRIPT:"JavaScript",SELECT_OPTION:"Select",PRESS:"Press",NAVIGATE:"Navigate",SCROLL_UP:"Scroll up",SCROLL_DOWN:"Scroll down",SCROLL_LEFT:"Scroll left",SCROLL_RIGHT:"Scroll right",HOVER:"Hover",BLUR:"Blur",FILE_UPLOAD:"File upload",FOCUS:"Focus",GO_BACK:"Go back",GO_FORWARD:"Go forward",WAIT:"Wait",REFRESH:"Refresh",TAB:"Switch tab",NEW_TAB:"New tab",COOKIE:"Cookie",LOCAL_STORAGE:"Local storage",REQUEST:"Request",CAPTCHA:"CAPTCHA",DRAG:"Drag & drop",VISUAL_DIFF:"Visual diff",DIALOG:"Dialog",MOUSE_DRAG:"Mouse drag",AUTH_LOAD:"Load auth state",AUTH_SAVE:"Save auth state",ELEMENT_CHECK:"Element check",PAGE_CHECK:"Page check",WAIT_FOR_URL:"Wait for URL",SUCCESS:"Done"},nC={AI_ACTION:"Ask AI to plan and execute something on the page.",RESOLVED_MODULE:"A list of steps that can be reused in multiple tests.",AI_ASSERTION:"Ask AI whether something is true on the page, retrying until a configurable timeout.",AI_WAIT:"Wait until AI considers a condition to be true.",CLICK:"Click on an element on the page based on a description.",DIALOG:"Specify how native browser dialogs should be handled.",AI_EXTRACT:"Ask AI to extract data from the page based on a description.",HOVER:"Hover over an element on the page based on a description.",FILE_UPLOAD:"Automatically upload a file when the next file chooser is activated.",FOCUS:"Focus an element on the page based on a description.",BLUR:"Remove focus from an element on the page based on a description.",SELECT_OPTION:"Select an option from an HTML Select <select> element based on a description.",TYPE:"Type the specified text into an element.",PRESS:"Press the specified keys using the keyboard. (e.g. Ctrl+A)",NAVIGATE:"Navigate to the specified URL.",SCROLL_UP:"Scroll up by a specified height.",SCROLL_DOWN:"Scroll down by a specified height.",SCROLL_LEFT:"Scroll left by a specified width.",SCROLL_RIGHT:"Scroll right by a specified width.",GO_BACK:"Go back in browser history.",GO_FORWARD:"Go forward in browser history.",WAIT:"Wait for the specified number of seconds.",REFRESH:"Refresh the page. This will not clear cookies or session data.",TAB:"Switch to different tab in the browser.",NEW_TAB:"Create and switch to a new tab in the browser.",COOKIE:"Set a cookie that will persist throughout the browser session",LOCAL_STORAGE:"Set a local storage value that will persist throughout the browser session",CAPTCHA:"Solve CAPTCHAs on the page. This feature is only available on Momentic Cloud and may take up to 60 seconds. Disabling CAPTCHAs in non-production environments is strongly advised.",REQUEST:"Make an API request to a URL.",JAVASCRIPT:"Run JavaScript code in an isolated context.",DRAG:"Click and drag an element to another location.",VISUAL_DIFF:"Compare a screenshot of the page or a specific element to a baseline image.",MOUSE_DRAG:"Click and drag the mouse by a specified distance.",AUTH_LOAD:"Load auth state (cookies, local storage) from the JavaScript object format returned by 'Save auth state' and then refresh the page.",AUTH_SAVE:"Save auth state (cookies, local storage) into a JavaScript object format usable by 'Load auth state'.",ELEMENT_CHECK:"Assert on an element's state using pre-built conditions, including content, visibility, attribute value checks.",PAGE_CHECK:"Assert on the active page's state using pre-built conditions, including URL and content checks.",WAIT_FOR_URL:"Wait for the active page's URL to match a specific URL or glob pattern. If a new tab is opened, this command will wait for the new tab's URL to match instead.",SUCCESS:"Indicate the entire AI action has succeeded, optionally based on a condition."};import{z as V}from"zod";var iC=V.object({body:V.string(),to:V.string(),from:V.string()}),aC=V.object({from:V.string().optional(),to:V.string(),timeout:V.number().optional(),beforeDate:V.string().pipe(V.coerce.date()).or(V.date()).optional(),afterDate:V.string().pipe(V.coerce.date()).or(V.date()).optional()}),lC=V.object({inbox:V.string(),afterDate:V.string().pipe(V.coerce.date()).or(V.date()).optional(),timeout:V.number().optional(),trimWhitespace:V.boolean().optional()});var Qi=V.object({result:V.unknown(),variableUpdates:V.record(V.string(),V.unknown()).optional(),error:V.string().optional(),success:V.boolean()}),fr=15e3;import{parseString as ym,splitCookiesString as Sm}from"set-cookie-parser";import{z as ne}from"zod";var ea=ne.object({name:ne.string(),value:ne.string(),url:ne.string().optional(),domain:ne.string().optional(),path:ne.string().optional(),expires:ne.number().default(Date.now()/1e3+60*60*24*365),httpOnly:ne.boolean().optional(),secure:ne.boolean().default(!0),sameSite:ne.union([ne.literal("Strict"),ne.literal("Lax"),ne.literal("None")]).default("None")});function ta(r){let e=[],t=Sm(r);for(let n of t){let o=ym(n);if(!o.name)throw new Error("Name missing from cookie");if(!o.value)throw new Error("Value missing from cookie");let s;if(o.sameSite){let c=o.sameSite.trim().toLowerCase();if(c==="strict")s="Strict";else if(c==="lax")s="Lax";else if(c==="none")s="None";else throw new Error(`Invalid sameSite setting in cookie: ${c}`)}o.httpOnly===void 0&&(o.httpOnly=!1),!o.path&&o.domain&&(o.path="/");let i=ea.parse({...o,expires:o.expires?o.expires.getTime()/1e3:void 0,sameSite:s});e.push(i);let a=[i.name,...Object.keys(i)].map(c=>c.toLowerCase()),l=n.match(/\b(\w+)=([^;]*)/g);if(l)for(let c of l){let[u,d]=c.split("=");if(!u||!d)throw new Error(`Invalid key-value pair in cookie: ${c}`);a.includes(u.toLowerCase())||e.push({...i,name:u,value:d})}}return e}var wm=ne.object({origin:ne.string(),localStorage:ne.array(ne.object({name:ne.string(),value:ne.string()}))}),ra=ne.object({cookies:ea.array(),origins:wm.array()});import{z as Me}from"zod";var bm=Me.object({orgId:Me.string(),cacheKeys:Me.string().array()}),gC=Me.object({keyParams:bm,clientMetadata:Me.string(),lockAcquisitionTimeoutMs:Me.number().optional()}),na=Me.object({acquired:Me.boolean(),acquiredByMetadata:Me.string(),keyPrefix:Me.string()}),hC=Me.object({keyPrefix:Me.string(),result:Me.string(),ttlMs:Me.number()}),oa=0,sa=5*60*1e3;var Hn=class{flags;constructor(e){this.flags=e}isBooleanFlagEnabled(e){return this.flags[e]===!0}getAllFlags(){return this.flags}};import{z as je}from"zod";import{z as ae}from"zod";import{z as G}from"zod";var Pt="momentic",Ot="modules",Wn="fixtures",yr="environments",ls="chromium",jn=[Ot,Wn,yr,ls];var Cm=G.string().min(1).max(255).superRefine((r,e)=>{try{Qr(r)}catch(t){return e.addIssue({code:G.ZodIssueCode.custom,message:t.message,fatal:!0}),G.NEVER}}),Tm=G.object({name:G.string(),default:G.boolean().optional(),defaultOnLocal:G.boolean().optional().describe("DEPRECATED: migrated to default instead"),defaultOnCloud:G.boolean().optional().describe("DEPRECATED: migrated to default instead"),fixtures:Ni.array().optional()}),be=G.object({id:G.string(),name:Cm,baseUrl:G.preprocess(r=>r===null?"":r,G.union([G.string().url(),G.literal("")])).optional(),schemaVersion:G.string(),advanced:cr,retries:G.number(),envs:G.array(Tm).nullish(),parameters:Mi.nullish()}),vC=be.pick({name:!0,baseUrl:!0,retries:!0,advanced:!0,parameters:!0}),ia=G.object({createdAt:G.coerce.date(),updatedAt:G.coerce.date(),schedule:Oi,notification:Li,createdBy:G.string(),organizationId:G.string()}),xC=be.merge(ia),AC=be.merge(ia).merge(G.object({steps:G.array(de)})),Gn=be.merge(G.object({steps:G.array(de)})),RC=be.extend({steps:G.record(G.string(),G.unknown()).array()}),Em=/^[a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$/;function Qr(r){if(r=r.toLowerCase().trim(),r.length===0||r.length>255)throw new Error("Name must be between 1 and 255 characters long");if(/[<>:"\/\\|?*\x00]/.test(r))throw new Error('Name contains one of the following invalid characters: <>:"/\\|?*');if(/^(con|prn|aux|nul|com[0-9]|lpt[0-9])(\..*)?$/i.test(r))throw new Error(`"${r}" is a reserved name on Windows and cannot be used as a filename.`);if(/^\.+$/.test(r)||/^\s|\s$/.test(r))throw new Error("Name cannot start or end with a space or dot.");if(r.endsWith(".yaml"))throw new Error('Name cannot end with ".yaml".');if(r==="none")throw new Error("Name cannot be 'none'.");if(jn.includes(r))throw new Error("'modules' is a reserved folder name in Momentic. Please choose a different name.");if(r.match(Em))throw new Error("Name cannot be a UUID. Please choose a different name.")}var _C=qe.extend({fileType:ae.literal("momentic/module"),schemaVersion:ae.string(),steps:ae.record(ae.string(),ae.unknown()).array()}),en=qe.extend({steps:ae.array(ae.record(ae.string(),ae.unknown())),schemaVersion:ae.string()}),DC=be.extend({steps:ae.array(ae.record(ae.string(),ae.unknown()))}),kC=ae.object({test:ae.string().describe("YAML for the test, including metadata and steps"),modules:ae.record(ae.string(),ae.string()).describe("Map of module name to YAML for the module")});var vm="1.0.0",aa=je.object({run:je.string().describe("Run a single command in the shell. The working directory will be set to where the CLI was invoked from."),waitForCompletion:je.boolean().optional().describe("Defaults to true")}),la=je.object({type:je.literal("momentic/fixture"),schemaVersion:je.string(),name:je.string(),description:je.string().optional(),setup:je.object({steps:aa.array(),timeout:je.number().optional().describe("Timeout for all steps in seconds")}).optional(),teardown:je.object({steps:aa.array(),timeout:je.number().optional().describe("Timeout for all steps in seconds")}).optional()}),BC={type:"momentic/fixture",schemaVersion:vm,name:"example",description:"An example fixture",setup:{steps:[{run:"./scripts/seed_db.sh",waitForCompletion:!0},{run:"npm run start",waitForCompletion:!1}],timeout:30},teardown:{steps:[{run:"./scripts/shutdown_db.sh"}]}};import{z as q}from"zod";var KC=q.array(q.object({id:q.string(),name:q.string(),fullPathSegments:q.string().array(),testPath:q.string().describe("path relative to the root test directory, i.e. my-folder/my-test.yaml"),fileName:q.string(),lastModified:q.coerce.date(),createdAt:q.coerce.date()}));var ca=q.object({steps:de.array()}),da=be,ua=q.object({name:q.string(),baseUrl:q.string().url().optional(),environment:q.string().optional(),viewport:Dn.optional()}),YC=Gn.merge(q.object({testPath:q.string()})),ma=q.object({name:q.string(),description:q.string(),enabled:q.boolean(),steps:q.lazy(()=>de.array())});var XC=Yo.array(),JC=q.array(q.object({name:q.string(),moduleId:q.string().uuid()})),ZC=q.array(ke),pa=q.object({defaultEnv:q.string().optional().describe("name of the default env, or undefined to unset")});var xm={0:"DEBUG",1:"INFO",2:"WARN",3:"ERROR"},Am={0:"\x1B[90m",1:"\x1B[32m",2:"\x1B[33m",3:"\x1B[31m"},cs=class r{minLogLevel;logBindings;constructor(e,t){this.minLogLevel=e,this.logBindings=t}logWithLevel(e,...t){let n=xm[e],o;Array.isArray(t[0])?(o=t[0],t=t.slice(1)):typeof t[0]=="object"&&!(t[0]instanceof Error)&&(o={...t[0],...this.logBindings},t=t.slice(1));let s=Am[e],i=[`${s}[${new Date().toTimeString().slice(0,8)}][${n}]`];if(e!==0&&i.push("\x1B[39m"),i.push(...t),console.log(...i),o&&!Array.isArray(o))for(let[a,l]of Object.entries(o)){let c=l;l instanceof Error?c=l.message:typeof l=="object"&&(c=JSON.stringify(l,void 0,2),c=c.split(`
|
|
6
|
-
`).map((u,d)=>d>0?` ${u}`:u).join(`
|
|
7
|
-
`)),console.log(e===0?`${s} ${a}:`:` ${a}:`,c)}else if(o)for(let a of o){let l=a;typeof a=="object"&&(l=JSON.stringify(a,void 0,2),l=l.split(`
|
|
5
|
+
`)}`}};var Xv=L.object({command:L.string(),thoughts:L.string()}),Jv=L.string().pipe(L.coerce.number());var pl=L.object({phrase:L.string()}),gi=L.object({result:L.union([L.literal("NOT_FOUND"),L.string(),L.number(),L.array(L.unknown()),L.record(L.unknown(),L.unknown())])}),hl=L.object({thoughts:L.string(),id:L.number().int()}),Zv=L.object({results:L.array(pt),goal:L.string(),errorMessage:L.string()}),Rh=L.discriminatedUnion("op",[L.object({op:L.literal("replace"),path:L.string(),value:L.string()}),L.object({op:L.literal("add"),path:L.string(),value:L.string()}),L.object({op:L.literal("remove"),path:L.string()})]),Qv=L.object({thoughts:L.string(),patches:Rh.array()}),Ih=L.discriminatedUnion("op",[L.object({op:L.literal("replace"),path:L.string(),value:de}),L.object({op:L.literal("add"),path:L.string(),value:de}),L.object({op:L.literal("remove"),path:L.string()})]),fl=L.object({patches:Ih.array(),thoughts:L.string()});import{z as Ie}from"zod";var Ph=Ie.object({content:Ie.string(),ids:Ie.string().array(),tokenLength:Ie.number()}),Oh=Ie.object({chunks:Ph.array(),numRecs:Ie.number()}),nE=Ie.object({ids:Ie.string().array(),score:Ie.number(),tokenLength:Ie.number()}),rE=Ie.object({description:Ie.string(),tokenLimit:Ie.number()}).merge(Oh),gl=Ie.object({ids:Ie.number().array()});import{z as Pe}from"zod";var Lh=Pe.object({type:Pe.nativeEnum(q),generatedStep:bo.optional(),serializedCommand:Pe.string().optional(),elementInteracted:Pe.string().optional()}),On=Pe.object({goal:Pe.string(),url:Pe.string(),browserState:Pe.string(),history:Pe.string(),numPrevious:Pe.number(),lastCommand:Lh.or(Pe.null())}),yi=On.extend({screenshot:Pe.string()}),yl=Pe.object({goal:yi.shape.goal,browserState:yi.shape.browserState,returnSchema:Pe.string().optional()}),Sl=yi.pick({goal:!0,browserState:!0,screenshot:!0,url:!0}),wl=On.extend({screenshot:Pe.string().optional()});import{z as Ln}from"zod";var dE=Ln.object({goal:Ln.string(),completionType:Ln.string().describe("type of completion these keywords will be used for")}),bl=Ln.object({keywords:Ln.array(Ln.string())});var CE=new Set(Object.values(ce));var Si={AI_ACTION:"AI action",RESOLVED_MODULE:"Module",AI_ASSERTION:"AI check",AI_WAIT:"AI wait",AI_EXTRACT:"AI extract",CLICK:"Click",TYPE:"Type",JAVASCRIPT:"JavaScript",SELECT_OPTION:"Select",PRESS:"Press",NAVIGATE:"Navigate",SCROLL_UP:"Scroll up",SCROLL_DOWN:"Scroll down",SCROLL_LEFT:"Scroll left",SCROLL_RIGHT:"Scroll right",HOVER:"Hover",BLUR:"Blur",FILE_UPLOAD:"File upload",FOCUS:"Focus",GO_BACK:"Go back",GO_FORWARD:"Go forward",WAIT:"Wait",REFRESH:"Refresh",TAB:"Switch tab",NEW_TAB:"New tab",COOKIE:"Cookie",LOCAL_STORAGE:"Local storage",REQUEST:"Request",CAPTCHA:"CAPTCHA",DRAG:"Drag & drop",VISUAL_DIFF:"Visual diff",DIALOG:"Dialog",MOUSE_DRAG:"Mouse drag",AUTH_LOAD:"Load auth state",AUTH_SAVE:"Save auth state",ELEMENT_CHECK:"Element check",PAGE_CHECK:"Page check",WAIT_FOR_URL:"Wait for URL",SUCCESS:"Done"},TE={AI_ACTION:"Ask AI to plan and execute something on the page.",RESOLVED_MODULE:"A list of steps that can be reused in multiple tests.",AI_ASSERTION:"Ask AI whether something is true on the page, retrying until a configurable timeout.",AI_WAIT:"Wait until AI considers a condition to be true.",CLICK:"Click on an element on the page based on a description.",DIALOG:"Specify how native browser dialogs should be handled.",AI_EXTRACT:"Ask AI to extract data from the page based on a description.",HOVER:"Hover over an element on the page based on a description.",FILE_UPLOAD:"Automatically upload a file when the next file chooser is activated.",FOCUS:"Focus an element on the page based on a description.",BLUR:"Remove focus from an element on the page based on a description.",SELECT_OPTION:"Select an option from an HTML Select <select> element based on a description.",TYPE:"Type the specified text into an element.",PRESS:"Press the specified keys using the keyboard. (e.g. Ctrl+A)",NAVIGATE:"Navigate to the specified URL.",SCROLL_UP:"Scroll up by a specified height.",SCROLL_DOWN:"Scroll down by a specified height.",SCROLL_LEFT:"Scroll left by a specified width.",SCROLL_RIGHT:"Scroll right by a specified width.",GO_BACK:"Go back in browser history.",GO_FORWARD:"Go forward in browser history.",WAIT:"Wait for the specified number of seconds.",REFRESH:"Refresh the page. This will not clear cookies or session data.",TAB:"Switch to different tab in the browser.",NEW_TAB:"Create and switch to a new tab in the browser.",COOKIE:"Set a cookie that will persist throughout the browser session",LOCAL_STORAGE:"Set a local storage value that will persist throughout the browser session",CAPTCHA:"Solve CAPTCHAs on the page. This feature is only available on Momentic Cloud and may take up to 60 seconds. Disabling CAPTCHAs in non-production environments is strongly advised.",REQUEST:"Make an API request to a URL.",JAVASCRIPT:"Run JavaScript code in an isolated context.",DRAG:"Click and drag an element to another location.",VISUAL_DIFF:"Compare a screenshot of the page or a specific element to a baseline image.",MOUSE_DRAG:"Click and drag the mouse by a specified distance.",AUTH_LOAD:"Load auth state (cookies, local storage) from the JavaScript object format returned by 'Save auth state' and then refresh the page.",AUTH_SAVE:"Save auth state (cookies, local storage) into a JavaScript object format usable by 'Load auth state'.",ELEMENT_CHECK:"Assert on an element's state using pre-built conditions, including content, visibility, attribute value checks.",PAGE_CHECK:"Assert on the active page's state using pre-built conditions, including URL and content checks.",WAIT_FOR_URL:"Wait for the active page's URL to match a specific URL or glob pattern. If a new tab is opened, this command will wait for the new tab's URL to match instead.",SUCCESS:"Indicate the entire AI action has succeeded, optionally based on a condition."};import{z as G}from"zod";var xE=G.object({body:G.string(),to:G.string(),from:G.string()}),AE=G.object({from:G.string().optional(),to:G.string(),timeout:G.number().optional(),beforeDate:G.string().pipe(G.coerce.date()).or(G.date()).optional(),afterDate:G.string().pipe(G.coerce.date()).or(G.date()).optional()}),RE=G.object({inbox:G.string(),afterDate:G.string().pipe(G.coerce.date()).or(G.date()).optional(),timeout:G.number().optional(),trimWhitespace:G.boolean().optional()});var Cl=G.object({result:G.unknown(),variableUpdates:G.record(G.string(),G.unknown()).optional(),error:G.string().optional(),success:G.boolean()}),Mn=15e3;import{parseString as Mh,splitCookiesString as Nh}from"set-cookie-parser";import{z as se}from"zod";var Tl=se.object({name:se.string(),value:se.string(),url:se.string().optional(),domain:se.string().optional(),path:se.string().optional(),expires:se.number().default(Date.now()/1e3+60*60*24*365),httpOnly:se.boolean().optional(),secure:se.boolean().default(!0),sameSite:se.union([se.literal("Strict"),se.literal("Lax"),se.literal("None")]).default("None")});function vl(r){let e=[],t=Nh(r);for(let n of t){let o=Mh(n);if(!o.name)throw new Error("Name missing from cookie");if(!o.value)throw new Error("Value missing from cookie");let s;if(o.sameSite){let c=o.sameSite.trim().toLowerCase();if(c==="strict")s="Strict";else if(c==="lax")s="Lax";else if(c==="none")s="None";else throw new Error(`Invalid sameSite setting in cookie: ${c}`)}o.httpOnly===void 0&&(o.httpOnly=!1),!o.path&&o.domain&&(o.path="/");let i=Tl.parse({...o,expires:o.expires?o.expires.getTime()/1e3:void 0,sameSite:s});e.push(i);let a=[i.name,...Object.keys(i)].map(c=>c.toLowerCase()),l=n.match(/\b(\w+)=([^;]*)/g);if(l)for(let c of l){let[u,d]=c.split("=");if(!u||!d)throw new Error(`Invalid key-value pair in cookie: ${c}`);a.includes(u.toLowerCase())||e.push({...i,name:u,value:d})}}return e}var _h=se.object({origin:se.string(),localStorage:se.array(se.object({name:se.string(),value:se.string()}))}),El=se.object({cookies:Tl.array(),origins:_h.array()});import{z as Fe}from"zod";var kh=Fe.object({orgId:Fe.string(),cacheKeys:Fe.string().array()}),NE=Fe.object({keyParams:kh,clientMetadata:Fe.string(),lockAcquisitionTimeoutMs:Fe.number().optional()}),xl=Fe.object({acquired:Fe.boolean(),acquiredByMetadata:Fe.string(),keyPrefix:Fe.string()}),_E=Fe.object({keyPrefix:Fe.string(),result:Fe.string(),ttlMs:Fe.number()}),Al=0,Rl=5*60*1e3;var Lo=class{flags;constructor(e){this.flags=e}isBooleanFlagEnabled(e){return this.flags[e]===!0}getAllFlags(){return this.flags}};import{z as X}from"zod";import{z as j}from"zod";var Dh=j.string().min(1).max(255).superRefine((r,e)=>{try{Lr(r)}catch(t){return e.addIssue({code:j.ZodIssueCode.custom,message:t.message,fatal:!0}),j.NEVER}}),Fh=j.object({name:j.string(),default:j.boolean().optional(),defaultOnLocal:j.boolean().optional().describe("DEPRECATED: migrated to default instead"),defaultOnCloud:j.boolean().optional().describe("DEPRECATED: migrated to default instead"),fixtures:tl.array().optional()}),pe=j.object({id:j.string(),name:Dh,baseUrl:j.preprocess(r=>r===null?"":r,j.union([j.string().url(),j.literal("")])).optional(),schemaVersion:j.string(),advanced:xn,retries:j.number(),envs:j.array(Fh).nullish(),parameters:el.nullish()}),zE=pe.pick({name:!0,baseUrl:!0,retries:!0,advanced:!0,parameters:!0}),Il=j.object({createdAt:j.coerce.date(),updatedAt:j.coerce.date(),schedule:Za,notification:Qa,createdBy:j.string(),organizationId:j.string()}),WE=pe.merge(Il),HE=pe.merge(Il).merge(j.object({steps:j.array(de)})),Mo=pe.merge(j.object({steps:j.array(de)})),jE=pe.extend({steps:j.record(j.string(),j.unknown()).array()}),Uh=/^[a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$/;function Lr(r){if(r=r.toLowerCase().trim(),r.length===0||r.length>255)throw new Error("Name must be between 1 and 255 characters long");if(/[<>:"\/\\|?*\x00]/.test(r))throw new Error('Name contains one of the following invalid characters: <>:"/\\|?*');if(/^(con|prn|aux|nul|com[0-9]|lpt[0-9])(\..*)?$/i.test(r))throw new Error(`"${r}" is a reserved name on Windows and cannot be used as a filename.`);if(/^\.+$/.test(r)||/^\s|\s$/.test(r))throw new Error("Name cannot start or end with a space or dot.");if(r.endsWith(".yaml"))throw new Error('Name cannot end with ".yaml".');if(r==="none")throw new Error("Name cannot be 'none'.");if(r.match(Uh))throw new Error("Name cannot be a UUID. Please choose a different name.")}var ZE=X.array(X.object({id:X.string(),name:X.string(),platformSep:X.string(),fullPathSegments:X.string().array(),relativePath:X.string().describe("path relative to the root test directory, i.e. my-folder/my-test.yaml"),fileName:X.string(),lastModified:X.coerce.date(),createdAt:X.coerce.date()}));var Pl=X.object({steps:de.array()}),Ol=pe,Ll=X.object({name:X.string(),baseUrl:X.string().url().optional(),environment:X.string().optional(),viewport:Eo.optional()}),QE=Mo.merge(X.object({testPath:X.string()})),Ml=X.object({name:X.string(),description:X.string(),enabled:X.boolean(),steps:X.lazy(()=>de.array())});var ex=ii.array(),tx=X.array(zt),Nl=X.object({defaultEnv:X.string().optional().describe("name of the default env, or undefined to unset")});var Mr=["node_modules","dist","bin",".git",".npm",".next","out",".yarn","__pycache__","build",".env",".venv","venv","env","wheels"],_l=Mr.map(r=>`**/${r}/**`);import gt from"chalk";var wi=class r{minLogLevel;logBindings;constructor(e,t){this.minLogLevel=e,this.logBindings=t}logWithLevel(e,t,...n){if(e<this.minLogLevel)return;let o;Array.isArray(n[0])?(o=n[0],n=n.slice(1)):typeof n[0]=="object"&&!(n[0]instanceof Error)&&(o={...n[0],...this.logBindings},n=n.slice(1));let s=[];if(s.push(...n),console.log(t(...s)),o&&!Array.isArray(o))for(let[i,a]of Object.entries(o)){let l=a;a instanceof Error?l=a.message:typeof a=="object"&&(l=JSON.stringify(a,void 0,2),l=l.split(`
|
|
8
6
|
`).map((c,u)=>u>0?` ${c}`:c).join(`
|
|
9
|
-
`)),console.log(e===0?`${s} `:" ",l)}e===0&&process.stdout.write("\x1B[39m")}setMinLevel(e){this.minLogLevel=e}log(...e){this.info(...e)}info(...e){1<this.minLogLevel||this.logWithLevel(1,...e)}debug(...e){0<this.minLogLevel||this.logWithLevel(0,...e)}warn(...e){2<this.minLogLevel||this.logWithLevel(2,...e)}error(...e){3<this.minLogLevel||this.logWithLevel(3,...e)}child(e){return new r(this.minLogLevel,{...this.logBindings,...e})}flush(){}bindings(){return this.logBindings}},ga=new cs(1,{});var Vn={},Sr=({logger:r,logKey:e,maxCount:t,intervalMs:n},o,s,...i)=>{let a=Vn[e];a?clearTimeout(a.timer):(a={count:0,totalCount:0},Vn[e]=a),a.totalCount++,a.count<t&&(a.count++,r.debug(o,s,...i)),a.timer=setTimeout(()=>{let l=Vn[e];l?.totalCount!==l?.count&&r.debug({logKey:e,totalCount:l?.totalCount,count:l?.count},`Debug logs were rate-limited for ${e}`),delete Vn[e]},n)};import{z as Ce}from"zod";var Rm=Ce.object({id:Ce.string(),createdAt:Ce.coerce.date(),createdBy:Ce.string(),organizationId:Ce.string(),name:Ce.string(),description:Ce.string().nullish(),enabled:Ce.boolean(),schemaVersion:Ce.string().describe("Schema version for steps"),parameters:Ce.string().array().nullish().describe("Parameter list"),defaultParameters:Ce.record(Ce.string(),Ce.string()).nullish(),defaultCacheKey:Ce.string().nullish(),defaultCacheTtl:Ce.number().nullish()}),aT=Rm.extend({steps:Ce.lazy(()=>He.array())}),ha=5*60*1e3;import{formatInTimeZone as dT}from"date-fns-tz";var Te=r=>{let e=r.trim().toLowerCase().replace(/[^a-z0-9]/g,"-");for(;e.includes("--");)e=e.replaceAll("--","-");return e.startsWith("-")&&(e=e.slice(1)),e.endsWith("-")&&(e=e.slice(0,e.length-1)),e};import*as T from"zod";var wr=T.object({disableCache:T.boolean().optional()}),TT=T.object({error:T.boolean(),reason:T.string(),message:T.string()}),ET=Ji.merge(wr),fa=jo,vT=Xi.merge(wr),ya=Si,xT=gr.pick({browserState:!0,goal:!0}).merge(wr).extend({screenshot:T.string()}),Sa=Vi,AT=gr.pick({goal:!0,url:!0}).merge(wr),wa=T.string().array(),RT=gr.pick({goal:!0,browserState:!0}).merge(wr),ba=Gi,IT=Yi.merge(wr);var PT=T.object({testPaths:T.string().array().describe("can be either hyphenated, lowercase test names or UUIDs"),env:T.string().optional(),all:T.boolean().optional(),urlOverride:T.string().optional(),customHeaders:T.record(T.string(),T.string()).optional(),testInputMatrix:T.record(T.string(),T.string()).array().optional()}),Ca=T.object({message:T.string(),queuedTests:T.object({name:T.string(),id:T.string()}).array(),runIds:T.string().uuid().array()}),Ta=Gn,Ea=T.string().array(),OT=T.union([T.object({paths:T.string().array().describe("run specific test paths (e.g. todo-test)"),all:T.boolean().describe("run all tests").optional()}),T.object({path:T.string().describe("deprecated; present for backcompat")})]),va=T.object({tests:T.record(T.string().describe("Test name"),T.string().describe("Test YAML")),modules:T.record(T.string().describe("Module name"),T.string().describe("Module YAML"))}),Im=T.object({test:T.string().describe("test YAML"),modules:T.record(T.string().describe("moduleId"),T.string().describe("module YAML"))}),LT=Im.array(),MT=T.object({testId:T.string(),schemaVersion:T.string(),steps:T.array(T.record(T.unknown()))}),NT=T.object({entries:T.array(Jo),testId:T.string()}),_T=T.object({steps:T.array(T.record(T.unknown())),testId:T.string(),schemaVersion:T.string(),organizationId:T.string()}),xa=xi;var DT=T.object({testId:T.string(),testName:T.string(),resolvedBaseUrl:T.string().optional(),trigger:T.nativeEnum(Xr)}),Aa=T.object({id:T.string()}),Pm=os.pick({id:!0,status:!0,testName:!0,testId:!0,test:!0,failureReason:!0,failureDetails:!0}),Ra=Pm.array(),kT=os.pick({startedAt:!0,finishedAt:!0,results:!0,status:!0,failureDetails:!0,failureReason:!0,debugData:!0,resolvedBaseUrl:!0,resolvedInputs:!0,attempts:!0,flake:!0}).partial(),FT=T.object({screenshot:T.string()}),Ia=T.object({key:T.string()}),Pa=T.object({orgId:T.string()}),Oa=T.array(ke),UT=T.array(ke),La=T.record(T.string(),T.union([T.string(),T.boolean()])),$T=T.object({paths:T.string().array(),env:T.string().optional(),urlOverride:T.string().optional(),customHeaders:T.record(T.string(),T.string()).optional()}),Ma=T.object({suiteRunIds:T.string().array()});var Na=ji.array();import{validator as GT}from"@exodus/schemasafe";var _a=[".sh",".exe",".app",".bat",".cmd",".msi",".apk",".jar",".py",".js",".cron",".php",".asp"];var Da=r=>{r.extraHeaders&&(r.extraHeaders=Object.fromEntries(Object.entries(r.extraHeaders).filter(([e,t])=>e.trim()&&t.trim())))};import{z as rE}from"zod";var br=class extends Error{status;constructor(e,t,n={}){super(t,n),this.status=e}},Cr=class{baseUrl;apiKey;logger;constructor(e){this.baseUrl=e.baseUrl,this.apiKey=e.apiKey,this.logger=e.logger}async sendRequest(e,t,n=3,o=3e4){let s=new AbortController,i=setTimeout(()=>s.abort(),o),a=await fetch(`${this.baseUrl}${e}`,{method:t.method,body:t.body?JSON.stringify(t.body):void 0,headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`},signal:s.signal});if(clearTimeout(i),!a.ok){if(a.status>500&&n>0)return await new Promise(c=>setTimeout(c,1500*Math.random())),this.sendRequest(e,t,n-1);throw new br(a.status,`Request to ${e} failed with status ${a.status}: ${await a.text()}`)}let l;return a.status===204?l=await a.text():l=await a.json(),this.logger&&!t.noLog&&this.logger.debug({result:l,path:e,baseUrl:this.baseUrl,status:a.status},"Got response from Momentic server"),l}};var Z="v1",ye=class extends Cr{constructor(e){super(e)}getAppUrl(){return this.baseUrl.replace(/\/\/api/,"//app")}async getOrgId(){let e=await this.sendRequest(`/${Z}/auth/check`,{method:"GET",noLog:!0}),{orgId:t}=Pa.parse(e);return t}async bulkGetRunStatus(e){let t=await this.sendRequest(`/${Z}/runs/status`,{method:"POST",body:e,noLog:!0});return Ra.parse(t)}async createRun(e){let t=await this.sendRequest(`/${Z}/runs`,{method:"POST",body:e,noLog:!0});return Aa.parse(t)}async updateRun(e,t){await this.sendRequest(`/${Z}/runs/${e}`,{method:"PATCH",body:t,noLog:!0})}async getTest(e){let t=await this.sendRequest(`/${Z}/tests/${e}`,{method:"GET"});return Ta.parse(t)}async getAllTestIds(){let e=await this.sendRequest(`/${Z}/tests`,{method:"GET"});return Ea.parse(e)}async getTestYAMLExport(e){let t=await this.sendRequest(`/${Z}/tests/export`,{method:"POST",body:e});return va.parse(t)}async updateTestWithYAML(e){await this.sendRequest(`/${Z}/tests/update`,{method:"POST",body:e})}async updateStepCaches(e){await this.sendRequest(`/${Z}/cache`,{method:"PATCH",body:e})}async getStepCacheForTest(e){let t=await this.sendRequest(`/${Z}/cache`,{method:"POST",body:e});return xa.parse(t)}async queueTests(e){let t=await this.sendRequest(`/${Z}/tests/queue`,{method:"POST",body:e});return Ca.parse(t)}async uploadScreenshot(e){let t=await this.sendRequest(`/${Z}/screenshots`,{method:"POST",body:e,noLog:!0});return Ia.parse(t)}async getAllEnvironments(){let e=await this.sendRequest(`/${Z}/environments`,{method:"GET"});return Oa.parse(e)}async getEnvironment(e){let t=await this.sendRequest(`/${Z}/environments/${e}`,{method:"GET"});return ke.parse(t)}async updateEnvironments(e){await this.sendRequest(`/${Z}/environments`,{method:"POST",body:e})}async getAllFeatureFlags(){let e=await this.sendRequest(`/${Z}/auth/flags`,{method:"GET",noLog:!0});return La.parse(e)}async acquireCacheLock(e){let t=await this.sendRequest(`/${Z}/result-cache/entry`,{method:"POST",body:e});return na.parse(t)}async releaseCacheLock(e){await this.sendRequest(`/${Z}/result-cache/entry`,{method:"DELETE",body:{key:e}})}async setCacheResult(e){await this.sendRequest(`/${Z}/result-cache/entry`,{method:"PATCH",body:e})}async getCacheResult(e){try{return await this.sendRequest(`/${Z}/result-cache/entry`,{method:"POST",body:e})}catch(t){if(t instanceof Error&&t.message.includes("404"))return null;throw t}}async queueSuiteRuns(e){let t=await this.sendRequest(`/${Z}/suites/queue`,{method:"POST",body:e});return Ma.parse(t)}async bulkGetSuiteStatus(e){let t={suiteRunIds:e},n=await this.sendRequest(`/${Z}/suites/status`,{method:"POST",body:t,noLog:!0});return Na.parse(n)}async updateCacheLastUsedDate(e,t){try{await this.sendRequest(`/${Z}/cache/lastUsedAt`,{method:"PATCH",body:e})}catch(n){t.error({err:n},"Failed to update cache last used date")}}async uploadProposedSteps(e,t){try{await this.sendRequest(`/${Z}/runs/proposed-steps`,{method:"POST",body:e})}catch(n){t.error({err:n},"Failed to upload proposed steps")}}};function Tr({steps:r,topLevel:e=!0,...t}){let{stepCacheEntries:n,logger:o,keyPrefix:s}=t,i=[],a=[],l=0,c=(d,m)=>{try{let p=zt.parse(m.value);if(p.type!==d.type){o.warn({parsedCacheEntry:p,command:d},"Not using step cache due to type mismatch"),a.push(m.key);return}d.cache=p.cache,i.push(m.key)}catch(p){a.push(m.key),o.error({err:p,cacheEntry:m},"Not using step cache due to parsing error")}},u=(d,m)=>{let p=Om(d.id,m),h=p.find(g=>!!n[g]);h?c(d,n[h]):(a.push(p[0]),o.debug({command:d,possibleKeys:p},"Step cache miss"))};for(let d of r)switch(d.type){case"RESOLVED_MODULE":{l+=d.steps.length;let{hits:p,misses:h}=Tr({...t,steps:d.steps,keyPrefix:s?`${s}:${d.id}`:d.id,topLevel:!1});i=i.concat(p),a=a.concat(h);break}case"IFRAME":case"SECTION":case"AI_ACTION":{if(l+=d.steps?.length??0,!d.steps?.length)break;let{hits:p,misses:h}=Tr({...t,steps:d.steps,topLevel:!1});i=i.concat(p),a=a.concat(h);break}case"PRESET_ACTION":{if(!Xo.includes(d.command.type)||d.command.type==="TYPE"&&!d.command.target||d.command.type==="MOUSE_DRAG"&&!d.command.target||"cache"in d.command&&d.command.cache)continue;l++,u(d.command,s);break}case"CONDITIONAL":{for(let p of d.blocks){l++,u(p.assertion.command,s),l+=p.steps.length;let{hits:h,misses:g}=Tr({...t,steps:p.steps,topLevel:!1});i=i.concat(h),a=a.concat(g);break}if(d.elseSteps){l+=d.elseSteps.length;let{hits:p,misses:h}=Tr({...t,steps:d.elseSteps,topLevel:!1});i=i.concat(p),a=a.concat(h)}break}default:return(p=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(d)}return e&&l&&a.length>0&&o.debug({totalSteps:l,cacheMisses:a,cacheHits:i,cacheEntries:n.length},"Step cache did not fully resolve"),{hits:i,misses:a}}function ka(r,e){return e?`${e}:${r}`:r}function Om(r,e){let t=[],n=e?.split(":")??[];for(let o=n.length;o>=0;o--){let s=[...n.slice(o),r];t.push(s.join(":"))}return t}function Fa(r){let{moduleStepParents:e=[],moduleIdParents:t=[]}=r;if(e.length!==t.length)throw new Error(`Invalid cache entry parent length: ${JSON.stringify(e)}
|
|
10
|
-
${JSON.stringify(t)}`);let n=[];if(!r.skipIntermediateEntries)for(let o=e.length;o>0;o--){let s=t[o-1],i=e.slice(o,e.length).join(":");n.push({key:ka(r.id,i),moduleId:s,organizationId:r.orgId,value:r.value})}return n.push({key:ka(r.id,e.join(":")),organizationId:r.orgId,value:r.value,testId:r.testId}),n}function Ua(r){switch(r.type){case"DRAG":{if(r.fromTarget.type==="coordinates"||r.toTarget.type==="coordinates"||!r.fromTarget?.a11yData||!r.toTarget?.a11yData)return;r.cache={fromTarget:r.fromTarget.a11yData,toTarget:r.toTarget.a11yData},delete r.fromTarget.a11yData,delete r.toTarget.a11yData;return}case"MOUSE_DRAG":case"HOVER":case"SCROLL_UP":case"SCROLL_DOWN":case"SCROLL_LEFT":case"SCROLL_RIGHT":case"SELECT_OPTION":case"TYPE":case"VISUAL_DIFF":case"CLICK":case"FOCUS":case"BLUR":{if(r.target?.type==="coordinates"||!r.target?.a11yData)return;r.cache={target:r.target.a11yData},delete r.target.a11yData;return}default:return}}function rn(r,e){return r.length<e?r:r.slice(0,e-3)+"[...]"}var Vt={EQUALS:"equals",CONTAINS:"contains",STARTS_WITH:"starts with"},qt={EQUALS:"does not equal",CONTAINS:"does not contain",STARTS_WITH:"does not start with"},ds={EXISTS:"exists",VISIBLE:"is visible",ENABLED:"is enabled",EDITABLE:"is editable"},us={EXISTS:"does not exists",VISIBLE:"is not visible",ENABLED:"is disabled",EDITABLE:"is not editable"};function Lm(r){switch(r.type){case"ELEMENT_CONTENT":return`${r.negated?qt[r.operation]:Vt[r.operation]} '${r.value}'`;case"ELEMENT_ATTRIBUTE":{let t=r.negated?qt[r.operation]:Vt[r.operation];return`attribute '${r.attr}' ${t} '${r.value}'`}case"ELEMENT_EXISTENCE":return r.negated?us[r.condition]:ds[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 wv={CONTENT:"The page"};function Mm(r){switch(r.type){case"CONTENT":return`${r.negated?qt.CONTAINS:Vt.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 Lt(r){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: ${rn(r.url,30)}`;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: ${we(r.target)}`:""}`;case"SCROLL_UP":return`Scroll up ${r.deltaY?`${r.deltaY}px`:"1 page height"}${r.target?` in the container of: ${we(r.target)}`:""}`;case"SCROLL_LEFT":return`Scroll left ${r.deltaX?`${r.deltaX}px`:"1 page width"}${r.target?` in the container of: ${we(r.target)}`:""}`;case"SCROLL_RIGHT":return`Scroll right ${r.deltaX?`${r.deltaX}px`:"1 page width"}${r.target?` in the container of: ${we(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: ${we(r.target)}`;let o="";return r.target?.elementDescriptor.length?o=` on element: '${r.target.elementDescriptor}'`:r.cache?.target.nodeOnlySerializedHtml&&(o=` on element: '${r.cache?.target.nodeOnlySerializedHtml}'`),`Click${o}`}case"FOCUS":return`Focus ${we(r.target)}`;case"BLUR":return`Focus ${we(r.target)}`;case"DRAG":return`Drag ${we(r.fromTarget)} onto ${we(r.toTarget)}`;case"MOUSE_DRAG":return r.target?`Click and drag ${we(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 o="";return r.target?.type==="coordinates"?o=` in element at coordinates: ${we(r.target)}`:r.target?.elementDescriptor.length?o=` in element: '${r.target.elementDescriptor}'`:r.cache?.target.nodeOnlySerializedHtml&&(o=` in element: '${r.cache?.target.nodeOnlySerializedHtml}'`),`Type '${r.value}'${o||""}`}case"HOVER":{let o="";return r.target.type==="coordinates"?o=` over coordinates: ${we(r.target)}`:r.target.elementDescriptor.length>0?o=` over element: '${r.target.elementDescriptor}'`:r.cache?.target.nodeOnlySerializedHtml&&(o=` over element: '${r.cache?.target.nodeOnlySerializedHtml}'`),`Hover${o}`}case"PRESS":return`Press ${r.value}`;case"SELECT_OPTION":let e="";return r.target.type==="coordinates"?e=` from element at coordinates: ${we(r.target)}`:r.target.elementDescriptor.length>0?e=` from: '${r.target.elementDescriptor}'`:r.cache?.target.nodeOnlySerializedHtml&&(e=` from: '${r.cache?.target.nodeOnlySerializedHtml}'`),`Select option '${r.option}'${e}`;case"TAB":return`Switch to tab with substring: ${r.url}`;case"NEW_TAB":return`Open new tab to: ${r.url}`;case"REQUEST":return`Send ${r.method} 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: ${rn(r.code,30)}`;case"AI_ASSERTION":return`Assertion: '${r.assertion}'`;case"AI_WAIT":return`Wait until assertion is true: '${r.assertion}'`;case"VISUAL_DIFF":return`Visual diff against baseline ${r.target?`for element: ${we(r.target)}`:"for entire page"}`;case"FILE_UPLOAD":return`Upload file: ${r.fileSource.url}`;case"AUTH_LOAD":return"Load auth state";case"AUTH_SAVE":return"Save auth state";case"ELEMENT_CHECK":return`Assert the element ${we(r.target)} ${Lm(r.assertion)}`;case"PAGE_CHECK":return`Assert the page ${Mm(r.assertion)}`;case"WAIT_FOR_URL":return`Wait for the page URL to match: ${r.url}`;default:return(o=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(r)}}function $a(r){let e=[];for(let t of r){t.sort((i,a)=>i.timestamp-a.timestamp);let n=[],o,s=1;for(let i of t)o&&o.text===i.text&&o.type===i.type&&JSON.stringify(o.args??null)===JSON.stringify(i.args??null)?s++:(o&&(s>1?o.args&&o.args.length?o.args.push(`(repeated ${s} times)`):o.text+=` (repeated ${s} times)`:n.push(o)),o=i,s=1);o&&n.push(o),e.push(n)}return e}function pt(r){let{onPresetAction:e,onSimpleStepContainer:t,onConditional:n}=r;for(let o of r.steps)switch(o.type){case"PRESET_ACTION":e(o);break;case"CONDITIONAL":n?.(o);for(let i of o.blocks)e(i.assertion),pt({...r,steps:i.steps});pt({...r,steps:o.elseSteps??[]});break;case"RESOLVED_MODULE":case"IFRAME":case"SECTION":case"AI_ACTION":t?.(o),o.steps&&pt({...r,steps:o.steps});break;default:return(i=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(o)}}function qn(r){let e=0;pt({steps:r,onPresetAction:t=>{t.index=e++},onConditional:t=>{t.index=e++},onSimpleStepContainer:t=>{t.index=e++}})}function Ba(r){pt({steps:r,onPresetAction:e=>{delete e.index},onConditional:e=>{delete e.index},onSimpleStepContainer:e=>{delete e.index}})}var Nm=(r,e)=>{switch(r.type){case"RESOLVED_MODULE":return r.steps[e];case"AI_ACTION":return r.steps[e];case"CONDITIONAL":{let n=r.blocks.map(o=>[o.assertion,...o.steps]).flat();return r.elseSteps&&(n=n.concat(r.elseSteps)),n[e]}case"SECTION":case"IFRAME":return r.steps[e];case"PRESET_ACTION":default:throw new Error(`Cannot get a child step from step type ${r.type}`)}};function Kn(r,e){let t=r[e[0]];for(let n=1;n<e.length;n++)t=Nm(t,e[n]);return t}function Yn(r){let e=0;return pt({steps:r,onPresetAction:t=>{e=Math.max(e,t.index)},onConditional:t=>{e=Math.max(e,t.index)},onSimpleStepContainer:t=>{e=Math.max(e,t.index)}}),e}import{cloneDeep as kv,unset as Fv}from"lodash-es";function ms(r){switch(r.type){case"AI_ACTION":return`AI action: ${rn(r.text,100)}`;case"PRESET_ACTION":return Lt(r.command);case"MODULE":return`Module: ${r.id}`;case"RESOLVED_MODULE":return`Module: ${r.name}`;case"CONDITIONAL":return"Conditional";case"IFRAME":return"Frame step";case"SECTION":return`Section${r.description?`with goal: ${rn(r.description,100)}`:""}`;default:return(t=>{throw new Error("You missed a case in the switch above")})(r)}}function Xn(r){for(let e of r)switch(e.type){case"PRESET_ACTION":za(e);break;case"CONDITIONAL":e.assertion&&za(e.assertion),Xn(e.results);break;case"AI_ACTION":case"IFRAME":case"MODULE":case"SECTION":{Xn(e.results);break}default:return(n=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(e)}}function za(r){let e=r.command;"cache"in e&&e.cache&&(e.cache=void 0),r.details&&(r.details=void 0)}function Ha(r,e){if(!(!r.envs||!r.envs.length)){for(let t of r.envs)e in t&&(t[e]&&(t.default=!0),delete t.defaultOnCloud,delete t.defaultOnLocal);r.envs.some(t=>t.default)||(r.envs[0].default=!0)}}import Fm from"diff-lines";import Zn,{gte as Um}from"semver";var Wa={name:"Migrate to ai step v2",fromVersion:"1.0.4",toVersion:"1.0.5",recursiveKeys:new Set(["results","commands"]),stopOnFailure:!0,execute:async r=>(r=r.filter(e=>!(e.status!==void 0&&e.type==="AI_ACTION")),r=r.map(e=>(e.status===void 0||e.type==="PRESET_ACTION"&&(e.results=e.commands??e.results??[]),e)),r)};var ja={name:"Make sure ai step v2 has done command",fromVersion:"1.0.5",toVersion:"1.0.6",recursiveKeys:new Set(["results","commands"]),stopOnFailure:!0,execute:async r=>r.map(e=>{if(e.type!=="AI_ACTION"||e.status!==void 0||!e.commands||!e.commands.length)return e;let t=e.commands,n=t[t.length-1];return n&&n.type!=="SUCCESS"&&t.push({type:"SUCCESS"}),e})};var _m=["target","fromTarget","toTarget"];function Ga(r){for(let e of _m){if(r[e]===void 0)continue;let t=r[e];t.elementDescriptor!==void 0?t.type="description":r[e]={type:"description",elementDescriptor:""}}}var Va={name:"Migrate element target to discriminated union",fromVersion:"1.0.6",toVersion:"1.0.7",recursiveKeys:new Set(["results","steps"]),stopOnFailure:!0,execute:async r=>r.map(e=>{switch(e.type){case"PRESET_ACTION":return Ga(e.command),e;case"AI_ACTION":{let t=e.commands;for(let n of t??[])Ga(n);return e}default:return e}})};import{v4 as Dm}from"uuid";var qa={name:"Ensure module steps have ids",fromVersion:"1.0.7",toVersion:"1.0.8",recursiveKeys:new Set(["results","steps"]),stopOnFailure:!0,execute:async r=>r.map(e=>{switch(e.type){case"MODULE":return e.id||(e.id=Dm()),e;default:return e}})};import{v4 as Ka}from"uuid";var Ya={name:"Ensure module steps have ids",fromVersion:"1.0.8",toVersion:"1.0.9",recursiveKeys:new Set(["results","steps"]),stopOnFailure:!0,execute:async r=>r.map(e=>{switch(e.type){case"PRESET_ACTION":{if(!e.command)return e;let t=e.command;return t.id=t.id??Ka(),e}case"AI_ACTION":return e.commands&&(e.steps=e.commands.map(t=>({type:"PRESET_ACTION",command:{...t,id:t.id??Ka()}})),delete e.commands),e;default:return e}})};var Xa={name:"Migrate ai waits to checks",fromVersion:"1.0.9",toVersion:"1.0.10",recursiveKeys:new Set(["results","steps","blocks","elseSteps"]),stopOnFailure:!0,execute:async r=>r.map(e=>{switch(e.type){case"PRESET_ACTION":{if(!e.command)return e;let t=e.command;return typeof t.type!="string"||t.type!=="AI_WAIT"||(t.type="AI_ASSERTION",t.timeout||(t.timeout=10)),e}default:return e}})};import{v4 as km}from"uuid";var Ja={name:"Add ids to all steps",fromVersion:"1.0.10",toVersion:"1.0.11",recursiveKeys:new Set(["results","steps","blocks","elseSteps"]),stopOnFailure:!0,execute:async r=>r.map(e=>("id"in e&&typeof e.id=="string"||(e.id=km()),e))};import{v4 as Za}from"uuid";var Qa={name:"Add ids to all steps",fromVersion:"1.0.11",toVersion:"1.0.12",recursiveKeys:new Set(["results","steps","blocks","elseSteps"]),stopOnFailure:!0,execute:async r=>r.map(e=>{if("id"in e&&typeof e.id=="string")return e;if("condition"in e&&typeof e.condition=="object"&&e.condition){let t=e.condition;t.id||(t.id=Za())}return e.id=Za(),e})};var el={name:"Move env key to steps",fromVersion:"1.0.12",toVersion:"1.0.13",recursiveKeys:new Set(["results","steps","blocks","elseSteps"]),stopOnFailure:!0,execute:async r=>r.map(e=>{if(e.type!=="PRESET_ACTION")return e;let t=e.command;return!t||typeof t.envKey!="string"||(e.envKey=t.envKey,delete t.envKey),e})};var tl={name:"Migrate AI assertions to preset actions",fromVersion:"1.0.0",toVersion:"1.0.1",recursiveKeys:new Set,execute:async r=>r.map(e=>{if(e.type!=="AI_ASSERTION")return e;let n={type:"PRESET_ACTION",command:{type:"AI_ASSERTION",assertion:e.text,useVision:!1,disableCache:!0}},o={...e,...n};return delete o.text,o}),stopOnFailure:!0};var Jn=new Set(["CLICK","TYPE","SELECT_OPTION"]),rl={name:"Migrate element descriptor to live in a target object",fromVersion:"1.0.3",toVersion:"1.0.4",recursiveKeys:new Set,execute:async r=>r.map(e=>{let t=e.command,n=t?.type,o=t?.elementDescriptor;return(o!==void 0||Jn.has(n))&&(t.target={elementDescriptor:o??""}),e.commands&&Array.isArray(e.commands)&&e.commands.forEach(i=>{let a=i?.elementDescriptor,l=i?.type;(a!==void 0||Jn.has(l))&&(i.target={elementDescriptor:a??""})}),e.results&&Array.isArray(e.results)&&e.results.forEach(i=>{let a=i.command,l=a?.elementDescriptor,c=a?.type;(l!==void 0||Jn.has(c))&&(a.target={elementDescriptor:l??""}),i.commands&&Array.isArray(i.commands)&&i.commands.forEach(d=>{let m=d?.elementDescriptor,p=d?.type;(m!==void 0||Jn.has(p))&&(d.target={elementDescriptor:m??""})})}),e}),stopOnFailure:!0};var nl={name:"Migrate FAILURE status to FAILED",fromVersion:"1.0.1",toVersion:"1.0.2",recursiveKeys:new Set,execute:async r=>r.map(e=>{let t=e;return t.status==="FAILURE"&&(t.status="FAILED"),typeof t.commands=="object"&&Array.isArray(t.commands)&&t.commands.forEach(n=>{if(n&&typeof n=="object"){let o=n;o?.status==="FAILURE"&&(o.status="FAILED")}}),t}),stopOnFailure:!0};var ol={name:"Migrate preset step types to use the same",fromVersion:"1.0.2",toVersion:"1.0.3",recursiveKeys:new Set,execute:async r=>r.map(e=>{let t=e.command,n=t?.type;return n?.startsWith("PRESET_")&&(t.type=n.slice(7)),e.commands&&Array.isArray(e.commands)&&e.commands.forEach(s=>{let i=s.type;i?.startsWith("PRESET_")&&(s.type=i.slice(7))}),e.results&&Array.isArray(e.results)&&e.results.forEach(s=>{let i=s.command,a=i?.type;a?.startsWith("PRESET_")&&(i.type=a.slice(7)),s.commands&&Array.isArray(s.commands)&&s.commands.forEach(c=>{let u=c.type;u?.startsWith("PRESET_")&&(c.type=u.slice(7))})}),e}),stopOnFailure:!0};var Kt=[tl,nl,ol,rl,Wa,ja,Va,qa,Ya,Xa,Ja,Qa,el];if(Oe!==Kt[Kt.length-1].toVersion)throw new Error("Please bump LATEST_VERSION in types package after adding a migration");Kt.forEach((r,e)=>{if(!Zn.valid(r.toVersion)||!Zn.valid(r.fromVersion))throw new Error(`Migration '${r.name}' has invalid version`);if(!Zn.gt(r.toVersion,r.fromVersion))throw new Error(`Migration '${r.name}' has toVersion <= fromVersion`);if(e===0)return;if(Kt[e-1].toVersion!==r.fromVersion)throw new Error(`Migration '${r.name}' at index ${e} is not contiguous with previous migration`)});function $m(r){return r.every(e=>e&&typeof e=="object"&&!Array.isArray(e))}var ps=async({metadata:r,steps:e,logger:t,toVersion:n})=>{let o=e,{schemaVersion:s,id:i}=r,a=Kt.findIndex(u=>Zn.gt(u.toVersion,s));if(a===-1)return{steps:o,newVersion:s};let l=s;for(let u=a;u<Kt.length;u++){if(n&&Um(l,n)){t.debug("Stopping migration early because toVersion was reached");break}let d=Kt[u],m={id:i,migration:d.name,toVersion:d.toVersion};try{o=await sl(o,d),l=d.toVersion}catch(p){throw t.error({err:p,...m},"Migration failed"),new Error(`Step migration ${d.name} failed: ${p}`)}}let c=Fm(JSON.stringify(e,void 0,2),JSON.stringify(o,void 0,2),{n_surrounding:1});return c.trim()&&t.debug({diffs:c,id:i},"Migration diffs"),{newVersion:l,steps:o}};async function sl(r,e){let t=await e.execute(r);for(let n of t)for(let o of Object.keys(n)){if(!e.recursiveKeys.has(o))continue;let s=n[o];!s||!Array.isArray(s)||$m(s)&&(n[o]=await sl(s,e))}return t}async function il({rawSteps:r,metadata:e,logger:t,callbacks:n}){Ha(e,"defaultOnCloud");let o={},{resolvedSteps:s,newSchemaVersion:i}=await gs({rawSteps:r,metadata:e,logger:t,callbacks:n,resolvedModuleCache:o});return{resolvedTest:{...e,steps:s,schemaVersion:i},moduleIds:Array.from(Object.keys(o))}}async function gs({rawSteps:r,metadata:e,logger:t,callbacks:n,resolvedModuleCache:o={}}){let{newVersion:s,steps:i}=await ps({metadata:e,steps:r,logger:t}),a;try{a=He.array().parse(i)}catch(c){throw t.error({type:"zod",err:c,newVersion:s,id:e.id,steps:i},"Failed to parse test steps while migrating test"),new Bn(`Failed to parse test steps while migrating test: ${c}`,e.id,"entity",{cause:c})}let l=[];for(let c of a)l.push(await nn({step:c,callbacks:n,logger:t,resolvedModuleCache:o}));return{resolvedSteps:l,newSchemaVersion:s}}async function nn({step:r,callbacks:e,logger:t,resolvedModuleCache:n}){switch(r.type){case"AI_ACTION":return r;case"PRESET_ACTION":return r;case"MODULE":{let l=r.moduleId,c=n[l];if(c)return{...c,...r,type:"RESOLVED_MODULE"};let u=await e.onFetchModule({id:l,logger:t});if(!u)throw new Error(`Could not find module with id ${l}`);let{newVersion:d,steps:m}=await ps({metadata:{id:l,schemaVersion:u.schemaVersion},steps:u.steps,logger:t}),p;try{p=He.array().parse(m)}catch(f){throw t.error({type:"zod",err:f,steps:m,newVersion:d,id:l},"Module failed to parse"),f}let h;try{h=await Promise.all(p.map(f=>nn({step:f,callbacks:e,logger:t,resolvedModuleCache:n})))}catch(f){throw t.error({err:f,...r},`Failed to recursively resolve module '${u.name}': ${f}`),f}let g={...u,steps:h};return n[l]=g,{...g,...r,type:"RESOLVED_MODULE"}}case"CONDITIONAL":let o=[];for(let l of r.blocks){let c=[];for(let u of l.steps)c.push(await nn({step:u,callbacks:e,logger:t,resolvedModuleCache:n}));o.push({...l,steps:c})}let s;if(r.elseSteps){s=[];for(let l of r.elseSteps)s.push(await nn({step:l,callbacks:e,logger:t,resolvedModuleCache:n}))}return{...r,blocks:o,elseSteps:s};case"SECTION":case"IFRAME":let i=[];for(let l of r.steps)i.push(await nn({step:l,callbacks:e,logger:t,resolvedModuleCache:n}));return{...r,steps:i};default:return(l=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(r)}}import{cloneDeep as Bm}from"lodash-es";import{v4 as al}from"uuid";async function tt(r){let e=Bm(r.steps);return Er({...r,steps:e,moduleStepParents:[],moduleIdParents:[],moduleIdReplacements:new Map,seenModules:new Set})}async function Er({steps:r,...e}){let{seenModules:t,cacheCreationParams:n,moduleIdParents:o,moduleStepParents:s,moduleIdReplacements:i,shouldCreateNewModuleId:a}=e,l={cachesToSave:[],stepsToSave:[],moduleUpdates:[]};for(let c of r)switch(delete c.index,c.type){case"PRESET_ACTION":{let d=c.command;d.id=n?.createNewCacheIds?al():d.id,Ua(d),"cache"in d&&d.cache&&(n&&(l.cachesToSave=l.cachesToSave.concat(Fa({id:d.id,orgId:n.orgId,testId:n.testId,value:zt.parse(d),moduleIdParents:o,moduleStepParents:s,skipIntermediateEntries:e.skipCacheIntermediateEntries}))),delete d.cache),l.stepsToSave.push({...c,command:d});break}case"RESOLVED_MODULE":{let d=n?.createNewCacheIds?al():c.id,m=c.moduleId;if(i.has(m))m=i.get(m);else if(a){let y=await a(c);i.set(c.moduleId,y)}let{cachesToSave:p,stepsToSave:h,moduleUpdates:g}=await Er({...e,steps:c.steps,cacheCreationParams:n?{...n,createNewCacheIds:!1}:void 0,moduleStepParents:[...s,d],moduleIdParents:[...o,m],skipCacheIntermediateEntries:n?.createNewCacheIds});l.moduleUpdates=l.moduleUpdates.concat(g),l.cachesToSave=l.cachesToSave.concat(p),t.has(m)||(t.add(m),l.moduleUpdates.push({...qe.parse(c),steps:He.array().parse(h)}));let f={type:"MODULE",moduleId:m,inputs:c.inputs,id:d,skipped:c.skipped,cacheConfig:c.cacheConfig,envKey:c.envKey};l.stepsToSave.push(f);break}case"AI_ACTION":{if(!c.steps){l.stepsToSave.push(c);break}let{stepsToSave:d,cachesToSave:m}=await Er({...e,steps:c.steps});try{c.steps=$e.array().parse(d)}catch(p){throw new Error(`Only preset actions are allowed in AI actions at the moment: ${p}`)}l.stepsToSave.push(c),l.cachesToSave=l.cachesToSave.concat(m);break}case"CONDITIONAL":{let d=[];for(let p of c.blocks){let{stepsToSave:h,cachesToSave:g,moduleUpdates:f}=await Er({...e,steps:p.steps});d.push({...p,steps:h}),l.cachesToSave=l.cachesToSave.concat(g),l.moduleUpdates=l.moduleUpdates.concat(f)}let m={...c,elseSteps:void 0,blocks:d};if(c.elseSteps){let{stepsToSave:p,cachesToSave:h,moduleUpdates:g}=await Er({...e,steps:c.elseSteps});m.elseSteps=p,l.cachesToSave=l.cachesToSave.concat(h),l.moduleUpdates=l.moduleUpdates.concat(g)}l.stepsToSave.push(m);break}case"IFRAME":case"SECTION":{let{stepsToSave:d,cachesToSave:m,moduleUpdates:p}=await Er({...e,steps:c.steps}),h={...c,steps:d};l.moduleUpdates=l.moduleUpdates.concat(p),l.stepsToSave.push(h),l.cachesToSave=l.cachesToSave.concat(m);break}default:return(d=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(c)}return l}import{cloneDeep as zm}from"lodash-es";import{stringify as hs}from"yaml";async function ll(r,e=new Set){let t={id:r.id,name:r.name,baseUrl:r.baseUrl,schemaVersion:r.schemaVersion,advanced:r.advanced,retries:r.retries,envs:r.envs},n={},o=await Hm(r.steps,r.schemaVersion,n,e),s={fileType:"momentic/test",...t,steps:o};return{test:hs(s),modules:n}}async function Hm(r,e,t,n){let o=zm(r);Wm(o);let{stepsToSave:s,moduleUpdates:i}=await tt({steps:o});for(let a of i)n.has(a.name)||(t[a.name]=jm(a),n.add(a.name));return s}function Wm(r){pt({steps:r,onPresetAction:e=>{e.index=void 0,e.command.thoughts=void 0},onConditional:e=>{e.index=void 0},onSimpleStepContainer:e=>{e.index=void 0}})}function jm(r){let e=qe.parse(r),t={fileType:"momentic/module",...e,schemaVersion:Oe,steps:r.steps};return hs(t)}function fs(r){return hs({fileType:"momentic/environment",...r})}var vr=class{constructor(e,t){this.client=e;this.orgId=t}async acquireCacheLock(e){return this.client.acquireCacheLock(e)}async releaseCacheLock(e){return this.client.releaseCacheLock(e)}async setCacheResult(e){return this.client.setCacheResult(e)}async getCacheResult(e){return this.client.getCacheResult(e)}async saveStepCacheEntries(e,t,n){try{await this.client.updateStepCaches({entries:e,testId:t})}catch(o){n.error({err:o},"Failed to save step cache entries")}}async resolveStepCacheEntries(e){let t=await this.client.getStepCacheForTest({testId:e.testId,organizationId:e.organizationId,steps:e.steps,schemaVersion:e.schemaVersion}),{hits:n}=Tr({steps:e.steps,stepCacheEntries:t,logger:e.logger});this.client.updateCacheLastUsedDate(n,e.logger)}async getOrgId(e){return this.orgId}async uploadScreenshot(e){return(await this.client.uploadScreenshot({screenshot:e.toString("base64")})).key}async fetchEnvironment(e,t,n){try{return await this.client.getEnvironment(t)}catch(o){n.warn({err:o},"Error fetching environment, continuing...");return}}};var ys="v1",gt=class extends Cr{type="API_CLIENT";sms={send:this.sendSms.bind(this),fetchLatest:this.fetchLatestSms.bind(this)};email={fetchLatest:this.fetchLatestEmail.bind(this)};constructor(e){super(e)}async sendSms(e){await this.sendRequest(`/${ys}/tools/sms/send`,{method:"POST",body:e})}async fetchLatestSms(e){try{return await this.sendRequest(`/${ys}/tools/sms/fetchLatest`,{method:"POST",body:e})}catch(t){throw t instanceof br&&t.status===404?new Error("No recent SMS messages found."):t}}async fetchLatestEmail(e){try{return this.sendRequest(`/${ys}/tools/email/fetchLatest`,{method:"POST",body:e})}catch(t){throw t instanceof br&&t.status===404?new Error("No matching emails found."):new Error(`Failed to fetch latest emails: ${t.message}`)}}};import Uh from"body-parser";import $h from"cors";import Ys from"express";import{existsSync as qm,readFileSync as to,readdirSync as Km,statSync as Ym,writeFileSync as bs}from"fs";import ht from"path";import{parse as sn,stringify as Xm}from"yaml";var pe=process.env.MOMENTIC_DIR??Pt;import{readFileSync as on,readdirSync as Ss,writeFileSync as dl}from"fs";import Gm,{join as ws}from"path";import{v4 as Vm}from"uuid";import{parse as Qn,stringify as ul}from"yaml";var Mt=ws(pe,Ot);function ml(r){let e=eo(Mt,r.moduleId).path,t=on(e,"utf-8"),n=Qn(t),o={fileType:"momentic/module",...n,...r},s=ul(o);dl(e,s,"utf-8")}async function pl(r,e,t,n){let o=Te(r),s=ws(Mt,`${o}.yaml`),i=Vm(),{stepsToSave:a}=await tt({steps:n}),l={fileType:"momentic/module",schemaVersion:Oe,moduleId:i,name:r,description:e,enabled:t,steps:a},c=ul(l);return dl(s,c,"utf-8"),{moduleId:i,name:r,description:e,enabled:t,steps:n}}function gl(){let r=[];for(let e in Ss(Mt)){if(!e.endsWith(".yaml"))continue;let t=on(e,"utf-8"),n=Qn(t),o={name:n.name,moduleId:n.moduleId};r.push(o)}return r}async function hl(r){let e=new Set;for(let t of Ss(Mt)){if(!t.endsWith(".yaml"))continue;let n=ws(Mt,t),o=on(n,"utf-8"),s=Qn(o),i;try{i=en.parse(s)}catch(a){r.warn({err:a,filePath:t,moduleContents:o},`${t} does not parse as a valid module, skipping...`);continue}e.add(i.moduleId)}return yl(Array.from(e),r)}function cl(r,e){let t=eo(Mt,r).path,n=on(t,"utf-8"),o=Qn(n);try{return en.parse(o)}catch(s){throw e.error({err:s,moduleFilePath:t,moduleContents:n},`${t} does not parse as a valid module`),s}}async function fl(r,e){return(await yl([r],e)).find(n=>n.moduleId===r)}async function yl(r,e){let t={};return await Promise.all(r.map(async n=>{let o=cl(n,e),{resolvedSteps:s}=await gs({rawSteps:o.steps,metadata:{id:o.moduleId,schemaVersion:o.schemaVersion},resolvedModuleCache:t,logger:e,callbacks:{onFetchModule:async i=>cl(i.id,e)}});t[n]={...o,steps:s}})),Array.from(Object.values(t))}function eo(r,e){let t=Ss(r);for(let n of t){let o=Gm.join(r,n),s=on(o,"utf8");if(s.includes(e))return{path:o,content:s}}throw new Error(`Could not find module file for module ${e} in ${r}`)}var Sl=jn,Jm=new Set([...Sl,"node_modules","dist","bin",".git","logs",".npm",".next","out",".yarn","__pycache__","build",".env",".venv","venv","env","wheels"]);async function wl(r,e){let t=await ll(r);for(let[s,i]of Object.entries(t.modules)){let a=Te(s);bs(ht.join(pe,Ot,`${a}.yaml`),i,"utf-8")}let n=Te(e),o=ht.join(pe,`${n}.yaml`);return bs(o,t.test,"utf-8"),`${n}.yaml`}function ro(r,e){if(!qm(e))throw new Error(`Test not found at path: ${ht}`);let t=to(e,"utf-8"),o={...sn(t),...r},s=be.parse(o),i={fileType:"momentic/test",...s,steps:o.steps},a=Xm(i);bs(e,a,"utf-8")}function an(r,e,t=r){let n=r.split(ht.sep).pop()??"";if(Jm.has(n))return Sl.includes(n)||e.warn(`Skipping directory '${r}' because it is likely an artifact folder.`),[];let o=Km(r),s=[];return o.forEach(i=>{let a=ht.join(r,i),l;try{l=Ym(a)}catch(c){e.warn({err:c},`Skipping path '${a}' because it could not be read.`);return}if(l.isDirectory())s=s.concat(an(a,e,t));else if(i.endsWith(".yaml")){let c=to(a,"utf-8"),u=ht.relative(ht.resolve(t),ht.resolve(a));try{let d=sn(c),m=be.parse(d);s.push({id:m.id,name:m.name,fullPathSegments:a.split(ht.sep),testPath:u,fileName:i,lastModified:l.mtime,createdAt:l.ctime})}catch{e.warn(`Skipping file '${a}' because it does not parse as a valid Momentic test.`)}}}),s}function bl(r){let e;try{e=to(r,"utf8"),e=e.replace(/\r\n|\r/g,`
|
|
11
|
-
`)}catch(n){throw new Error(`Could not read test file ${r}: ${n}`)}let t;try{t=sn(e)}catch(n){throw new Error(`Could not parse test file ${r} as YAML: ${n}`)}return be.parse(t)}function Cs(r,e){let t;try{t=to(r,"utf8"),t=t.replace(/\r\n|\r/g,`
|
|
12
|
-
`)}catch(a){throw new Error(`Could not read test file ${r}: ${a}`)}let n=new Set,o=/moduleId: (.*)/g,s;for(;(s=o.exec(t))!==null;)n.add(s[1].trim());let i={};return n.size>0&&n.forEach(a=>{i[a]||(i[a]=eo(e,a).content)}),{test:t,modules:i}}async function no(r,e,t){let{test:n,modules:o}=Cs(r,e),s=sn(n);if(!s.steps||!Array.isArray(s.steps))throw new Error(`Test ${r} is missing steps`);let i;try{i=be.parse(s)}catch(c){throw new Error(`Test ${r} is missing metadata or has invalid metadata: ${c}`)}let a={};for(let[c,u]of Object.entries(o)){let d;try{d=sn(u)}catch(m){throw new Error(`Module ${c} is not valid YAML: ${m}`)}try{let m=en.parse(d);a[c]=m}catch(m){throw new Error(`Module ${c} is missing metadata or has invalid metadata: ${m}`)}}let{resolvedTest:l}=await il({rawSteps:s.steps,metadata:i,logger:t,callbacks:{onFetchModule:async({id:c})=>a[c]}});return l}import{existsSync as Zm,readFileSync as Qm,readdirSync as ep}from"fs";import{join as Cl}from"path";import{parse as tp}from"yaml";var Ts=Cl(pe,yr);function Tl(){let r=[];if(!Zm(Ts))return[];for(let e of ep(Ts)){if(!e.endsWith(".yaml"))continue;let t=Cl(Ts,e),n=Qm(t,"utf-8"),o=tp(n);try{let s=ke.parse(o);r.push(s)}catch(s){ga.warn({err:s},"Error parsing environment, skipping...")}}return r}import{existsSync as Bh,statSync as zh}from"fs";import Hh from"http";import Wh from"open";import jh from"path";import{Server as vh}from"socket.io";import{cloneDeep as rp}from"lodash-es";var Es=r=>{let e=[];for(let t of r){let n;switch(t.type){case"PRESET_ACTION":{n={before:t.beforeTestContext,after:t.afterTestContext};break}case"CONDITIONAL":case"IFRAME":case"SECTION":case"AI_ACTION":case"MODULE":{n={before:t.beforeTestContext,after:t.afterTestContext,nestedResults:Es(t.results)};break}default:return(s=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(t)}e.push(n)}return e},oo=class{results;constructor(){this.results=[]}setResults(e){this.results=Es(e)}setIndividualResult(e,t){let n=Es([e])[0],o=this.results;for(let i=0;i<t.length-1;i++){let a=t[i];o[a]===void 0&&(o[a]={nestedResults:[]});let l=o[a];l.nestedResults===void 0&&(l.nestedResults=[]),o=l.nestedResults}let s=t[t.length-1];o[s]=n}getContextCopyAtIndices(e){let t=this.getContextAtIndicesHelper(e);if(t!==void 0)return rp(t)}getContextAtIndicesHelper(e){let t=this.results;for(let o=0;o<e.length-1;o++){let s=e[o],i=t[s];if(i===void 0)return t.length>0?t[t.length-1].after:void 0;if(i.nestedResults===void 0)return i.before;t=i.nestedResults}let n=e[e.length-1];if(n>t.length&&(n=t.length),n===0)return t[0]?.before;for(let o=n-1;o>=0;o--)if(t[o]?.after)return t[o].after}};var np={showOverlay:!1},vs=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:s,browserbaseSessionId:i}){return this.sessions.set(s,{controller:e,context:t,cleanup:n,clientIp:o,executionCancelled:!1,resultsManager:new oo,browserbaseSessionId:i,browserBehavior:np}),s}removeSession(e,t){(async()=>{let o=this.sessions.get(e);if(!o)return;this.releaseCapacityByIp(o.clientIp);let{controller:s}=o;try{await s.browser.cleanup()}catch(i){t.error({err:i},"Error cleaning up browser in global state manager")}try{await o.cleanup?.()}catch(i){t.error({err:i},"Error running cleanup function in global state manager")}this.sessions.delete(e)})()}getSession(e){return this.sessions.get(e)}cancelExecution(e){let t=this.sessions.get(e);t&&(t.executionCancelled=!0)}resumeExecution(e){let t=this.sessions.get(e);t&&(t.executionCancelled=!1)}},_=new vs;var op=200;function El(r,e,t){let n=Date.now(),o=-1,s=0,i=Date.now(),a,l,c=async m=>{if(!m.closed){if(s>0&&Math.random()>=1/Math.max(s,8)){s<8&&t.error({sessionId:e},"Dropping screenshot due to previous failures");return}try{let p;(!a||!l||Date.now()-i>=1500)&&(a=await m.getViewport(),l=await m.getFrameSrcUrls(),i=Date.now(),p=m.retrieveAndClearConsoleLogs()),r.emit("browserState",{logsPerPage:p,viewport:a,buffer:await m.screenshot({retries:0,timeout:1e3,scale:"device",quality:75}),url:m.url(),iframeSrcUrls:l}),n=Date.now(),s=0}catch(p){if(!r.connected)return;let h=p instanceof Error?p.message:`${p}`;if(h.includes("Frame was detached")||h.includes("Not attached to an active page")||h.includes("browser has been closed"))return;s++,t.error({err:p,sessionId:e},"Error taking screenshot")}finally{r.connected&&Date.now()-n>15e3&&Date.now()-o>3e4&&(t.error({sessionId:e},"Screenshots to client are stale"),o=Date.now())}}},u={timer:void 0},d=()=>{let p=_.getSession(e)?.controller?.browser;if(!p||p.closed){t.debug("Clearing browser state socket cron due to the browser being closed"),clearInterval(u.timer);return}c(p)};return u.timer=setInterval(d,op),u}var sp=({metadata:r,logger:e})=>{let{sessionId:t}=r;return async()=>{if(e.info({sessionId:t},"Cancel event received"),!_.getSession(t))throw new Error("No active session found");_.cancelExecution(t)}},vl={event:"cancel",createHandler:sp};var ip=({metadata:r,logger:e})=>{let{sessionId:t}=r;return n=>{e.info({sessionId:t,reason:n},`Disconnect event received (${n})`),_.removeSession(t,e)}},xl={event:"disconnect",createHandler:ip};import{randomUUID as fp}from"crypto";import{faker as ap}from"@faker-js/faker";import lp from"assert";import cp from"axios";import dp from"moment";import*as up from"otpauth";import mp,{TimeoutError as pp}from"p-timeout";import gp from"pg";var hp=Object.getPrototypeOf(async function(){}).constructor;async function Al(r,e,t){let n=e.code;e.options.fragment&&(n=`return ${e.code}`);let{results:o,env:s,inputs:i}=e.bindings,a=e.tools,l={},c=(f,y)=>{s[f]=y,l[f]=y},u;n.includes("Octokit")&&(u=(await import("@octokit/rest")).Octokit);let d;n.includes("createAppAuth")&&(d=(await import("@octokit/auth-app")).createAppAuth);let m=async()=>await Promise.resolve(new hp("axios","moment","faker","assert","pg","Octokit","createAppAuth","OTPAuth","env","results","inputs","setVariable","sendSms","waitForLatestSms","email","sms",n)(cp,dp,ap,lp,gp,u,d,up,s,o,i??{},c,y=>a.sms.send(y),y=>a.sms.fetchLatest(y),a.email,a.sms)),p=!0,h,g;try{h=await mp(m(),{milliseconds:e.options.timeoutMs,message:`Timeout of ${e.options.timeoutMs}ms exceeded for code execution`}),t.debug(`[${r}] Got execution result: ${JSON.stringify(h)}`),t.debug(`[${r}] Got variable updates: ${JSON.stringify(l)}`)}catch(f){t.error(`[${r}] Error executing code: ${f}`),p=!1,f instanceof pp?g=`Timeout of ${e.options.timeoutMs}ms exceeded for code execution`:g=f instanceof Error?f.message:`${f}`}return{result:h,variableUpdates:l,success:p,error:g}}async function Rl({code:r,fragment:e,context:t,localTools:n,logger:o,timeoutMs:s=fr}){let i=fp();return Al(i,{code:r,options:{fragment:e,timeoutMs:s},bindings:t.toObjectCopy(),tools:n},o)}import{randomUUID as yp}from"crypto";import Sp from"p-timeout";var Il=process.env.GCP_JS_EVAL_FUNCTION_ENDPOINT;async function Pl({code:r,fragment:e,context:t,logger:n,timeoutMs:o=fr,retries:s=1}){if(!Il)throw new Error("GCP_JS_EVAL_FUNCTION_ENDPOINT environment variable not set");let i,a,l=0;for(;l<=s;){l++;let u={id:yp(),code:r,fragment:e,state:t.toObjectCopy(),timeoutMs:o};n.debug(u,"Sending request to code evaluation server");try{if(i=await Sp(fetch(Il,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(u)}),{milliseconds:o,message:`Timeout of ${o}ms exceeded for code execution`}),!i)throw new Error("Got empty response from code evaluation server");if(!i.ok)throw new Error(`Code evaluation server returned error code ${i.status}`);a=void 0;break}catch(d){a=d}}if(a)throw a;if(!i)throw new Error(`An unexpected code evaluation error occurred${a?`: ${a}`:""}`);let c;try{c=Qi.parse(await i.json()),n.debug({response:c},"Response from code evaluation server")}catch(u){throw new Error(`Code evaluation server returned invalid response: ${u}`)}if(c.error)throw new Error(`Code evaluation server returned error: ${c.error}`);return c}async function xr(r){let e;if(process.env.GCP_JS_EVAL_FUNCTION_ENDPOINT)e=await Pl(r);else if(r.localTools)e=await Rl({...r,localTools:r.localTools});else throw new Error("No code evaluation environment available");if(e.error)throw new Error(`Code evaluation returned error: ${e.error}`);if(e.variableUpdates)for(let[t,n]of Object.entries(e.variableUpdates))r.context.setVariable(t,n);return e.result}async function Ge(r){let{s:e,context:t,logger:n,timeoutMs:o=fr,retries:s=1}=r,i=/{{(.*?)}}/g,a=e.matchAll(i),l=e;for(let c of a){if(c.length<2)continue;let u=c[1].trim(),d;try{d=await xr({code:u,fragment:!0,context:t,timeoutMs:o,logger:n,retries:s,localTools:r.localTools})}catch(p){throw n.error({err:p,value:e},"Error evaluating template string"),p}let m=typeof d=="string"?d:`${d}`;m=m.replace(/\$/g,"$$$$"),m=m.replace(/\\/g,"\\\\"),l=l.replace(c[0],m)}return n.debug({s:e,result:l},"Substituted template string"),l}var fI=process.env.MAILINATOR_API_KEY;import wI from"p-timeout";import"twilio";import{diff as Fp}from"deep-object-diff";import{spawn as bp}from"child_process";async function Ol(r){return new Promise((e,t)=>{let n={stdio:"inherit",env:process.env,detached:!0},o=bp("bash",["-c",r],n),s=!1;process.on("exit",()=>o.pid!==void 0&&!s&&process.kill(-o.pid)),o.on("close",i=>{if(s=!0,i===0){e();return}t(`command exited with code ${i}`)})})}async function ln(r,e,t,n,o,s){try{let[i,a]=await Promise.all([t?o(t):void 0,n?o(n):void 0]);i&&(r&&(r.beforeScreenshot=i),e.beforeScreenshot=i),a&&(r&&(r.afterScreenshot=a),e.afterScreenshot=a)}catch(i){s.debug({err:i},"Error saving screenshot to S3")}}var so=async r=>{let e=r.presetParams.step,{logger:t,controller:n,context:o}=r.fixtures,{takeScreenshots:s}=r.options,{testMetadata:i}=r.inputs,a=r.callbacks.test,l=n.browser.url(),c=new Date,u;if(s)try{u=await n.browser.screenshot({retries:1,clearHighlights:!0})}catch(g){t.debug({err:g},"Failed to take screenshot before step, likely because the page is still loading. This is non-fatal and does not affect the test.")}let d,m,p,h=$n();try{let g=await n.executePresetStep(h,e.command,o,i.advanced.disableAICaching,r.callbacks.test.isExecutionCancelled);if(g.beforeScreenshotOverride&&(u=g.beforeScreenshotOverride),p=g.afterScreenshotOverride,g.fail)throw new R("ActionFailureError",g.thoughts||"Preset action failed.");let f=new Date,y=n.browser.url();m={beforeUrl:l,afterUrl:y,startedAt:c,finishedAt:f,viewport:await n.browser.getViewport(),status:"SUCCESS"},d={...e,message:g.thoughts??"Successfully executed preset action.",beforeUrl:l,afterUrl:y,finishedAt:f,startedAt:c,status:"SUCCESS",data:g.data,results:[m],details:h.details},"assertion"in e.command&&(d.message=g.thoughts||"Assertion passed."),(e.command.type==="AI_EXTRACT"||e.command.type==="JAVASCRIPT")&&e.command.envKey&&o.setVariable(e.command.envKey,d.data)}catch(g){t.error({err:g},`Failed executing preset step ${Lt(e.command)}`);let f=n.browser.url(),y=new Date,w=g instanceof Error?g.message:`${g}`;m={beforeUrl:l,afterUrl:f,startedAt:c,finishedAt:y,viewport:await n.browser.getViewport(),status:g instanceof Ke?"CANCELLED":"FAILED",message:w},d={...e,startedAt:c,finishedAt:y,beforeUrl:l,afterUrl:f,status:g instanceof Ke?"CANCELLED":"FAILED",message:w,failureReason:g instanceof R?g.reason:void 0,results:[m],details:h.details}}if(s&&!p)try{p=await n.browser.screenshot({retries:1})}catch(g){t.debug({err:g},"Failed to take screenshot after step, likely because the page is still loading. This is non-fatal and does not affect the test.")}return r.work.asyncTasks.push(ln(m,d,u,p,a.onSaveScreenshot,t)),d};function rt(r){let{result:e,nestedResults:t}=r;if(!r.nestedResults.length)return;let{firstMetadata:n,lastMetadata:o}=Cp(t);Tp(e,n,o);let s=[...r.asyncTasks];r.asyncTasks.push((async()=>{try{await Ep(s,e,n,o)}catch(i){r.logger.error({result:r.result,err:i},"Error hoisting scalar result metadata")}})())}function Cp(r){let e=r[0],t;for(;;){switch(e.type){case"PRESET_ACTION":{t=e;break}case"CONDITIONAL":if(e.assertion){t=e;break}break;case"AI_ACTION":case"MODULE":case"SECTION":case"IFRAME":if(!e.results.length){t=e;break}e=e.results[e.results.length-1];break;default:return(i=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(e)}if(t)break}let n=r[r.length-1],o;for(;;){switch(n.type){case"PRESET_ACTION":{o=n;break}case"CONDITIONAL":case"AI_ACTION":case"MODULE":case"SECTION":case"IFRAME":if(!n.results.length){o=n;break}n=n.results[n.results.length-1];break;default:return(i=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(n)}if(o)break}return{firstMetadata:t,lastMetadata:o}}function Tp(r,e,t){e&&(r.beforeUrl=e.beforeUrl),t&&(r.afterUrl=t.afterUrl,r.data=t.data,t.status!=="SUCCESS"&&(r.message=t.message))}async function Ep(r,e,t,n){await Promise.allSettled(r),t&&(e.beforeScreenshot=t.beforeScreenshot),n&&(e.afterScreenshot=n.afterScreenshot)}import xs from"os";function Ll(r){let e=()=>{try{let t=vp(),n=xp();r.debug({memory:t,cpu:n},"Got machine resource usage metrics")}catch{}};return e(),setInterval(e,15e3)}function vp(){let r=xs.totalmem(),e=xs.freemem(),t=r-e;return{totalMemory:r,freeMemory:e,usedMemory:t}}function xp(){let r=xs.cpus(),e=0,t=0,n=0,o=0,s=0,i=0;for(let a of r)e+=a.times.user,t+=a.times.nice,n+=a.times.sys,o+=a.times.idle,s+=a.times.irq;return i=e+t+n+o+s,{user:e/i*100,nice:t/i*100,sys:n/i*100,idle:o/i*100,irq:s/i*100,total:100-o/i*100}}var Ml=async r=>{let{step:e,resolvedInputs:t}=r.moduleParams,{logger:n,context:o,storage:s,codeEvalTools:i}=r.fixtures,{orgId:a,testMetadata:l}=r.inputs;Object.keys(t).length>0&&(o.setInputs(t),n.debug({inputs:t,moduleId:e.moduleId},"Set module inputs"));let c,u;if(e.cacheConfig){let d=e.cacheConfig.cacheKey||e.defaultCacheKey||"",m=await Ge({s:d,context:o,logger:n,localTools:i}),p={orgId:a,cacheKeys:[m,...Object.entries(t).map(([g,f])=>`${g}:${f}`)]};n.debug({cacheKey:d,keyParams:p},"Module cache key params");let h=Date.now();for(;Date.now()-h<ha;){let g=await s.getCacheResult(p);if(g){n.info({cacheResult:g},"Got result from module execution cache"),c=io(e,t,"SUCCESS"),c.message="Used cached module result.",c.data=JSON.parse(g);break}let f=await s.acquireCacheLock({keyParams:p,clientMetadata:`testId:${l.id}`});if(f.acquired){u=f.keyPrefix,n.info({cacheKeyPrefix:u,cacheKey:d,keyParams:p},"Acquired cache lock and proceeding with module execution");break}await new Promise(y=>setTimeout(y,2500+Math.random()*1e4))}}try{c||(c=await Ap(r))}finally{if(u!==void 0){let d=e.cacheConfig.cacheExpiryMs;if(d===oa&&(d=e.defaultCacheTtl??sa),c&&c.status==="SUCCESS"){let m=JSON.stringify(c.data===void 0?"":c.data);n.debug({cacheKeyPrefix:u,ttlMs:d,cacheResult:m},"Setting module cache result"),await s.setCacheResult({result:m,keyPrefix:u,ttlMs:d})}await s.releaseCacheLock(u)}}return c},Ap=async r=>{let{step:e}=r.moduleParams,t=io(e,r.moduleParams.resolvedInputs,"SUCCESS"),{status:n,results:o}=await r.executeStepList({...r,listParams:{steps:e.steps,containerName:`module ('${e.name}')`}});return t.results=o,t.status=n,t.finishedAt=new Date,rt({asyncTasks:r.work.asyncTasks,nestedResults:o,result:t,logger:r.fixtures.logger}),t};function io(r,e,t){let n={};return Object.entries(e).forEach(([s,i])=>{n[s]=JSON.stringify(i)}),{type:"MODULE",id:r.id,moduleId:r.moduleId,moduleName:r.name,startedAt:new Date,cacheConfig:r.cacheConfig,inputs:n,results:[],finishedAt:new Date,status:t}}async function Nl(r,e,t,n){let o={};try{for(let s of r.parameters??[]){let i=r.inputs?.[s]??r.defaultParameters?.[s];if(!i){t.warn(`No value or default found for parameter '${s}' that is required by module '${r.name}'`);continue}o[s]=await xr({code:i,fragment:!0,context:e,logger:t,localTools:n})}return o}catch(s){throw new R("UserConfigurationError",`Failed to evaluate module inputs: ${s}`)}}async function Yt(r,e){let t=new Date;try{return await e()}catch(n){let o=new Date,s;if(n instanceof R?s=`${n}`:s=`An unexpected error occurred: ${n.message}`,r.type==="RESOLVED_MODULE"){let i=io(r,{},"FAILED");return i.message=s,i.startedAt=t,i.finishedAt=o,i}return{...r,startedAt:t,finishedAt:o,status:"FAILED",data:null,message:s,results:[]}}}async function ao(r,e){let t=!1;try{return r&&!r.healingDisabled&&(r.healingDisabled=!0,t=!0),await e()}finally{r&&t&&(r.healingDisabled=void 0)}}import{randomUUID as lo}from"crypto";var Dl=async r=>{let e=await Rp(r);return rt({asyncTasks:r.work.asyncTasks,result:e,nestedResults:e.results,logger:r.fixtures.logger}),e},Rp=async r=>{let e=r.aiStepParams.step,t=e.index,{testMetadata:n,steps:o}=r.inputs,{takeScreenshots:s}=r.options,{controller:i,context:a,logger:l}=r.fixtures,{test:c,step:u}=r.callbacks;if(t===void 0)throw new Error("Attempted to execute AI action step without index");i.resetHistory();let d={...e,startedAt:new Date,finishedAt:new Date,results:[],status:"RUNNING",beforeTestContext:a.toRedactedDisplayCopy()};e.steps=e.steps||[];let m=e.steps&&e.steps.length>0&&e.steps[e.steps.length-1]?.command.type==="SUCCESS";if(m)try{let{status:h,results:g}=await r.executeStepList({...r,listParams:{steps:e.steps,containerName:"AI action"}});return d.finishedAt=new Date,d.status=h,d.results=g,d}catch(h){l.warn({err:h},"Failed executing saved AI action steps, attempting to re-generate...")}e.steps=[];let p=0;try{for(;;){if(p>12)throw new Error(`Exceeded max number of commands per step (${12})`);let h=t+p+1;if(c.isExecutionCancelled?.())return d.status="CANCELLED",d.finishedAt=new Date,u.onCancelled?.({index:h,message:d.message||"AI step cancelled.",output:d}),d;let g,f=new Date,y=a.toRedactedDisplayCopy(),w;if(s)try{w=await i.browser.screenshot({clearHighlights:!0})}catch(E){l.debug({err:E},"Failed to take screenshot before AI command, likely because the page is still loading. This is non-fatal.")}l.info(`Generating new sub-command ${p} within AI step`);let b;try{if(b=await i.promptToCommand(e.type,e.text,n.advanced.disableAICaching),b.command.type==="FAILURE")throw new Error(b.command.thoughts);g=b.command,l.debug({command:g},"Generated new command")}catch(E){if(l.error({err:E,commandIndex:p},"Failed to generate command within AI step"),p===0)throw E;{let I="Stopping command generation prematurely since no progress can be made";l.info({command:g},I),g={id:lo(),type:"SUCCESS",thoughts:I}}}let C={id:lo(),type:"PRESET_ACTION",index:h,command:g};Pp({newStep:C,controller:i,currentStep:e,pageContext:b?.context,logger:l,onCommandExecuted:u.onCommandExecuted,currentIndex:p,globalSubStepIndex:h}),u.onCommandGenerated?.({index:h,step:C,message:as[g.type]||`Unknown command (${g.type})`});let v={beforeUrl:i.browser.url(),startedAt:f,viewport:await i.browser.getViewport(),finishedAt:new Date,status:"SUCCESS"};l.info(`Executing sub-command ${p} within AI step: ${Lt(g)}`);try{let E=await i.executeCommand(g,a,m&&n.advanced.disableAICaching,m);l.info(`AI sub-command ${p} completed successfully`),v.elementInteracted=E.elementInteracted;let I;if(s)try{I=await i.browser.screenshot({})}catch(P){l.debug({err:P},"Failed to take screenshot after AI command, likely because the page is still loading. This is non-fatal.")}v.afterUrl=i.browser.url(),v.finishedAt=new Date;let x={status:"SUCCESS",startedAt:v.startedAt,finishedAt:v.finishedAt,data:E.data,results:[v],beforeTestContext:y,afterTestContext:a.toRedactedDisplayCopy(),...C};if(r.work.asyncTasks.push(ln(v,x,w,I,c.onSaveScreenshot,l)),d.results.push(x),e.steps[p]=C,Op(o,r.inputs,h),u.onCommandExecuted?.({index:h,output:{...x,message:g.thoughts??E.thoughts??"Successfully executed preset action."},step:C}),g.type==="SUCCESS"){d.finishedAt=new Date,d.status="SUCCESS",d.message=E.thoughts??"All commands completed.",d.afterTestContext=a.toRedactedDisplayCopy();break}if(E.succeedImmediately&&!m){d.finishedAt=new Date,d.status="SUCCESS",d.message=`Marked step as completed due to reason: ${E.succeedImmediatelyReason}`,d.afterTestContext=a.toRedactedDisplayCopy(),g={id:lo(),type:"SUCCESS",thoughts:E.succeedImmediatelyReason};let P={id:lo(),type:"PRESET_ACTION",command:g};e.steps.push(P),u.onCommandExecuted?.({index:h+1,output:{...x,message:d.message},step:P}),d.results.push({...x,...P});break}}catch(E){let I=E instanceof Error?E.message:`${E}`,x=E instanceof R?E.reason:void 0;v.status="FAILED",v.message=I,v.finishedAt=new Date,v.afterUrl=i.browser.url();let P;try{P=await i.browser.screenshot({})}catch(W){l.debug({err:W},"Failed to take screenshot after AI command error, likely because the page is still loading. This is non-fatal.")}let D={id:g.id,status:"FAILED",startedAt:v.startedAt,finishedAt:v.finishedAt,type:"PRESET_ACTION",results:[v],message:I,failureReason:x,command:g};r.work.asyncTasks.push(ln(v,D,w,P,c.onSaveScreenshot,l)),d.results.push(D),d.status="FAILED",d.finishedAt=new Date,d.message=I,d.failureReason=x;break}p++}}catch(h){d.message=h instanceof Error?h.message:`${h}`,d.finishedAt=new Date,d.status="FAILED"}return d.status==="SUCCESS"?(d.data=d.results[d.results.length-1]?.data,u.onSuccess?.({index:t,message:d.message||"AI step succeeded.",output:d})):u.onFailure?.({index:t,message:d.message||"AI step errored.",output:d}),d};async function Ip(r,e,t){let n=t.id;if(!n||t.id<=0)throw new Error("Attempted to get reverse mapping for command with no a11y id target");return r.getReverseMappedTarget(e,n,!0)}async function Pp({controller:r,currentIndex:e,globalSubStepIndex:t,currentStep:n,newStep:o,pageContext:s,onCommandExecuted:i,logger:a}){if(!s)return;let l=o.command;if("target"in l&&l.target&&"cache"in l&&l.cache){await new Promise(c=>setTimeout(()=>c(),100));try{let c=await Ip(r,s,l.cache.target);l.target={elementDescriptor:c,type:"description"},n.steps[e]=o,i?.({index:t,step:o})}catch(c){a.warn({err:c,currentIndex:e,currentStep:n},"Failed to generate element description, continuing...")}}}function Op(r,e,t){qn(r),e.toIndex&&e.toIndex>=t&&e.toIndex++}async function kl(r){let{step:e}=r.conditionalParams,{logger:t}=r.fixtures,n=new Date,o=e.elseSteps,s=!0,i=[],a,l=$n();for(let m=0;m<e.blocks.length;m++){t.info(`Evaluating condition ${m} in conditional step`);let p=e.blocks[m];try{let h=await so({...r,presetParams:{step:p.assertion}});i.push(h),t.info(`Condition ${m} resolved to true, executing the corresponding ${p.steps.length} steps`),s=!1,o=p.steps,a=h}catch(h){t.info({err:h},`Condition ${m} resolved to false`)}}if(o)s&&t.info("No conditions resolved to true, executing the else block steps");else return t.warn("No conditions resolved to true and no else block was provided, causing the entire conditional step to be skipped"),{...e,status:"SUCCESS",startedAt:n,data:i[i.length-1]?.data,message:i[i.length-1]?.message,results:[],finishedAt:new Date,details:l.details};t.info(`Executing ${o.length} steps in the selected conditional block`);let c=await r.executeStepList({...r,listParams:{steps:o,containerName:"conditional block"}}),d={...e,assertion:a,...c,startedAt:n,finishedAt:new Date};return rt({asyncTasks:r.work.asyncTasks,nestedResults:[...i,...c.results],result:d,logger:t}),d}async function Fl(r){let{step:e}=r.frameParams,{logger:t,controller:n}=r.fixtures,o=new Date,s=n.browser.getActiveFrame();n.browser.setActiveFrame(e.identifier);let i;try{i=await r.executeStepList({...r,listParams:{steps:e.steps,containerName:"frame step list"}})}finally{n.browser.setActiveFrame(s)}let l={...e,...i,startedAt:o,finishedAt:new Date};return rt({asyncTasks:r.work.asyncTasks,nestedResults:i.results,result:l,logger:t}),l}import{randomUUID as co}from"crypto";import Lp from"fast-json-patch";import{cloneDeep as Mp}from"lodash-es";async function Ul(r){let e=r.failedResults,t=[],{sectionParams:n,fixtures:o,work:s,startingUrl:i,startingContextSnapshot:a}=r,{step:l}=n,{controller:c}=o,u=l?.autohealingConfig,d=u?.restartBehavior??{type:"GO_TO_SECTION_START"},m=u?.attempts??1;for(let p=0;p<m;p++){if(!e.terminalResult?.message)throw new Error("No error message in terminal result");let h=Mp(l.steps);await Promise.allSettled(s.asyncTasks??[]);let g=await c.runSectionAutohealing({results:e.results,errorMessage:e.terminalResult?.message,goal:l.description});for(let w of g.patches)h=Lp.applyOperation(h,w).newDocument;let f=ie.fromSnapshot({snapshot:a,environmentVariables:o.context.getVariablesFromEnvironmentCopy()});await Np({controller:c,context:f,restartConfig:d,startingUrl:i});let y=await ao(r.work,()=>r.executeStepList({...r,fixtures:{...r.fixtures,context:f},listParams:{steps:h,containerName:"auto-healed step list"}}));if(t.push(y.results),y.status==="SUCCESS")return{successfulHealing:{proposedStep:{...l,steps:h},listResult:y,context:f},healingAttempts:t};e=y}return{healingAttempts:t}}async function Np({controller:r,restartConfig:e,context:t,startingUrl:n}){switch(e.type){case"NAVIGATE_URL":{let o={id:co(),type:"PRESET_ACTION",command:{id:co(),type:"NAVIGATE",url:e.url}};await r.executePresetStep(null,o.command,t,!1);break}case"GO_TO_SECTION_START":{let o={id:co(),type:"PRESET_ACTION",command:{id:co(),type:"NAVIGATE",url:n}};await r.executePresetStep(null,o.command,t,!1);break}}}function $l(r,e){switch(r||(r="ON_FAILURE"),r){case"ALWAYS":return!0;case"ON_FAILURE":return!0;case"ON_ACTION_FAILURE":return!(!e||e.type==="PRESET_ACTION"&&vi(e.command.type))}}async function Bl(r){let{step:e}=r.sectionParams,{logger:t,controller:n,context:o}=r.fixtures,s=new Date,i=n.browser.url(),a=o.toObjectCopy(),l=async()=>r.executeStepList({...r,listParams:{steps:e.steps,containerName:"section step list"}}),c=e.autohealingConfig?await ao(r.work,l):await l(),u,d;if(c.status==="FAILED"&&e.autohealingConfig&&!r.work.healingDisabled&&$l(e.autohealingConfig.trigger,c.terminalResult)){let p=await Ul({...r,startingContextSnapshot:a,startingUrl:i,failedResults:c});p.successfulHealing&&(u=p.successfulHealing.proposedStep,c=p.successfulHealing.listResult,r.fixtures.context=p.successfulHealing.context),d=p.healingAttempts}let m={...e,...c,startedAt:s,finishedAt:new Date,proposedStep:u,healingAttempts:d};return rt({asyncTasks:r.work.asyncTasks,nestedResults:c.results,result:m,logger:t}),m}async function Xt(r){let{results:e=[],containerName:t,steps:n}=r.listParams,{logger:o,context:s,controller:i,codeEvalTools:a}=r.fixtures,{step:l,test:c}=r.callbacks,{fromIndex:u,toIndex:d}=r.inputs,m=r.work,p=[],h="SUCCESS",g,f=0;for(f;f<n.length;f++){let y=n[f],w,b=ms(y),C=y.index;if(C===void 0)throw new Error(`Executing step without index: ${b}`);if(d&&C>d)break;if(c.isExecutionCancelled?.()){if(h="CANCELLED",l.onCancelled?.({index:C,output:{status:"CANCELLED",message:"Execution cancelled.",startedAt:new Date,finishedAt:new Date}}),e.length){let D=e[e.length-1];D.status="CANCELLED",D.message="Cancelled by user signal.",g=D}break}if(y.skipped)continue;if(u&&C<u&&(y.type==="PRESET_ACTION"||Yn([y])<u))continue;o.info(`Executing step ${f+1}/${n.length} in ${t}: ${b}`),l.onStarted?.(C);let v=s.toRedactedDisplayCopy(),E=i.browser.url(),I,x;switch(y.type){case"PRESET_ACTION":{I="Preset action",x=await Yt(y,()=>so({...r,presetParams:{step:y}}));break}case"AI_ACTION":{I="AI action",x=await Yt(y,()=>Dl({...r,aiStepParams:{step:y},executeStepList:Xt}));break}case"RESOLVED_MODULE":{I=`Module (${y.name})`;let D=new ie({baseUrl:i.browser.baseUrl,currentUrl:i.browser.url(),dynamicVariables:s.getDynamicVariablesCopy(),variablesFromEnvironment:s.getVariablesFromEnvironmentCopy(),envName:s.getEnvName()});x=await Yt(y,async()=>{let W=await Nl(y,s,o,a);return Ml({...r,executeStepList:Xt,fixtures:{...r.fixtures,context:D},moduleParams:{step:y,resolvedInputs:W}})});break}case"CONDITIONAL":{I="Conditional step",x=await Yt(y,()=>kl({...r,conditionalParams:{step:y},executeStepList:Xt}));break}case"IFRAME":{I="Frame step",x=await Yt(y,()=>Fl({...r,frameParams:{step:y},executeStepList:Xt}));break}case"SECTION":{I="Section";let D=await Yt(y,()=>Bl({...r,sectionParams:{step:y},executeStepList:Xt}));"proposedStep"in D&&D.proposedStep&&(w=D.proposedStep,D.proposedStep=void 0,m&&(m.autoHealed=!0)),x=D;break}default:return(W=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(y)}w?p.push(w):p.push(y),x.beforeUrl=x.beforeUrl??E,x.beforeTestContext=v,s.setResult(f,x.data),y.envKey&&s.setVariable(y.envKey,x.data);let P=i.browser.url();if(s.setCurrentUrl(P),x.afterUrl=x.afterUrl??P,x.afterTestContext=s.toRedactedDisplayCopy(),Dp(I,C,x,r.callbacks,o,r.work),e.push(x),x.status!=="SUCCESS"){h=x.status,g=x;break}}return{status:h,results:e,terminalResult:g,proposedSteps:p}}async function _p(r,e){r&&e?.({results:r.results})}function Dp(r,e,t,n,o,s){let{step:i,test:a}=n,l=r.toLowerCase(),c=r.charAt(0).toUpperCase()+r.slice(1);switch(t.status){case"SUCCESS":i.onSuccess?.({index:e,step:"command"in t?t:void 0,message:t.message??`${c} executed successfully.`,output:Un.parse(t)});break;case"FAILED":i.onFailure?.({index:e,message:t.message??`${c} failed.`,output:Un.parse(t)});break;case"CANCELLED":i.onCancelled?.({index:e,message:t.message??`${c} cancelled.`,output:Un.parse(t)});break;default:throw new Error(`Unexpected ${l} status: ${t.status}`)}t.status==="SUCCESS"&&s&&_p(s,a.onUpdateRun)}var cn=async r=>{r.fixtures.logger=r.fixtures.logger.child({orgId:r.inputs.orgId,runId:r.inputs.runId,testId:r.inputs.testMetadata.id});let e;e=Ll(r.fixtures.logger),qn(r.inputs.steps);let t;try{return t=await kp(r),t}finally{if(clearInterval(e),Ba(r.inputs.steps),await r.callbacks.test.onTestComplete?.(),t?.status==="PASSED")try{await r.callbacks.test.onTestSuccess?.(r.inputs.steps)}catch(n){r.fixtures.logger.warn({err:n},"Error running test success handler, continuing...")}}},kp=async r=>{let{runId:e,testMetadata:t,fromIndices:n,toIndices:o,indicesFilter:s,steps:i}=r.inputs,{logger:a,controller:l}=r.fixtures;a.info(`Starting run ${e} for test '${t.name}'`);let c=i,u="test";if(n){let y=Kn(i,n);if(!y)throw new Error(`Could not find starting step using indices: ${n}`);r.inputs.fromIndex=y.index,a.debug({fromIndices:n,fromStep:y},"Identified starting step using fromIndices"),u="partial steps list"}if(o){let y=Kn(i,o);if(!y)throw new Error(`Could not find step at indices: ${o}`);let w=Yn([y]);r.inputs.toIndex=w,a.debug({toIndices:o,toStep:y,maxIndexUnderToStep:w},"Identified ending step using toIndices"),u="partial steps list"}if(s){let y=Kn(i,s);if(!y)throw new Error(`Could not find ending step at indices: ${r.inputs.indicesFilter}`);c=[y],a.debug({steps:i,indicesFilter:s},"Filtered steps to run based on exact indices filter"),u="filtered step"}let d=[],m={results:d,healingDisabled:!!s||!!n||!!o||void 0,asyncTasks:[]},{status:p,terminalResult:h,proposedSteps:g}=await Xt({...r,work:m,listParams:{steps:c,containerName:u,results:d}});if(r.options.takeScreenshots&&await Promise.allSettled(m.asyncTasks),s&&d.length){let y=d[0];if(y.beforeTestContext&&y.afterTestContext){let w=ie.fromSnapshot({snapshot:y.beforeTestContext,environmentVariables:r.fixtures.context.getVariablesFromEnvironmentCopy()}),b=r.fixtures.context.getResult(0);w.setResult(s[s.length-1],b),y.afterTestContext={...y.afterTestContext,results:w.getResultsCopy()}}}let f;return r.options.consumeDebuggingData&&(f={logsPerPage:$a(l.browser.retrieveAndClearConsoleLogs())}),r.callbacks.test.onUpdateRun?.({results:d,debugData:f}),p==="FAILED"?{status:"FAILED",results:d,failedStepResult:h}:(g&&m.autoHealed&&await r.callbacks.test.onProposedTestSteps?.({testId:t.id,orgId:r.inputs.orgId,runId:r.inputs.runId,steps:g}),{status:"PASSED",results:d})};import{cloneDeep as Up}from"lodash-es";var As={currentlyExecutingRequests:{}},$p=r=>async(e,t)=>{let n,{testId:o}=r.metadata,{baseUrl:s}=e,i=`${o}|${s}`;try{let a=As.currentlyExecutingRequests[i]??0;As.currentlyExecutingRequests[i]=a+1,n=await Bp({...r,...e,done:t})}finally{r.logger.info({result:n,sessionId:r.metadata.sessionId},"Test execution complete"),As.currentlyExecutingRequests[i]--}},Bp=async({socket:r,steps:e,baseUrl:t,testMetadata:n,reInitialize:o,indicesFilter:s,toIndices:i,fromIndices:a,storage:l,metadata:c,logger:u,envName:d,environmentVariables:m,testInputs:p,authorization:h,done:g})=>{let{testId:f,sessionId:y,orgId:w}=c,b=y,C=_.getSession(y);if(!C)throw new Error("No active session found");_.resumeExecution(y);let{controller:v,context:E}=C;v.setOpen();let I=h?.type==="API_KEY"?new gt(h):void 0;u=u.child({testId:f,orgId:w,baseUrl:t,sessionId:y,runId:b}),u.info({steps:e.map(j=>`${j.type}${"command"in j?` - ${j.command.type}`:""}`),indicesFilter:s,fromIndices:a,toIndices:i,reInitialize:o,envName:d,baseUrl:t},"Starting execution"),u.debug({steps:e,context:E,flags:v.flagStore.getAllFlags()},"Execution parameters");let x=m??{};await Promise.all((n.parameters??[]).map(async j=>{let it=(p??{})[j.name]??j.defaultValue;if(it===void 0)return;let kt=await Ge({s:it,context:ie.dummyContext(d),logger:u,localTools:I});x[j.name]=kt}));let P=async()=>{if(o){let j={url:t,clearCookies:!0,clearStorage:!0};await v.resetState(j),v.setOpen(),E.reset({baseUrl:t,currentUrl:v.browser.url(),variablesFromEnvironment:x,envName:d})}},D=async()=>{try{await l.resolveStepCacheEntries({schemaVersion:Oe,organizationId:w,testId:f,steps:e,logger:u})}catch(j){u.error({err:j},"Failed to fetch step cache entries from Momentic server. This can drastically reduce test reliability and performance.")}};await Promise.all([P(),D()]);let W=Up(e),A={takeScreenshots:!1,consumeDebuggingData:!1},H={orgId:w,runId:b,testMetadata:n,steps:e,indicesFilter:s,fromIndices:a,toIndices:i},J={controller:v,context:E,storage:l,codeEvalTools:I,logger:u},Q=(j,it)=>{r.emit(it,j)},Rt={test:{onTestComplete:async()=>{r.emit("finished")},onSaveScreenshot:zp,isExecutionCancelled:()=>_.getSession(y)?.executionCancelled||v.browser.closed||v.isClosed()||r.disconnected,onTestSuccess:async j=>{let it=Fp(W,j);if(Object.keys(it).length>0){u.debug({changes:it},"Updating steps post-run success");let{cachesToSave:kt}=await tt({steps:e,cacheCreationParams:{testId:f,orgId:w}});try{await l.saveStepCacheEntries(kt,n.id,u)}catch(N){u.warn({err:N},"Failed to save step cache entries after execution success")}}}},step:{onStarted:j=>r.emit("started",{globalIndex:j}),onSuccess:j=>Q(j,"success"),onFailure:j=>Q(j,"failure"),onCancelled:j=>Q(j,"cancelled"),onCommandGenerated:j=>{r.emit("commandGenerated",{...j,message:j.message??"AI action sub-step generated"})},onCommandExecuted:j=>{r.emit("commandExecuted",j)}}};if(s?.length){u.info({indicesFilter:s},"Starting individual step");let j=C.resultsManager.getContextCopyAtIndices(s)??E.toObjectCopy(),it=ie.fromSnapshot({snapshot:j,environmentVariables:E.getVariablesFromEnvironmentCopy()}),kt=await cn({fixtures:{...J,context:it},options:A,callbacks:Rt,inputs:H}),N=kt.results[0];return N?C.resultsManager.setIndividualResult(N,s):u.warn(kt,"No result found for individual step"),kt.status}let rr=await cn({fixtures:J,options:A,callbacks:Rt,inputs:H});return C.resultsManager.setResults(rr.results),g?.(rr),rr.status},zp=async r=>r.toString("base64");var zl={event:"execute",createHandler:$p};var Hp=({metadata:r,logger:e,storage:t})=>{let{sessionId:n}=r;return async(o,s)=>{let{command:i,testMetadata:a,returnScreenshot:l,indices:c}=o,u=Zr(i,o.description);e.debug({description:u,params:o},"Locate handler params"),e.info({description:u},"Locate handler called");let d=_.getSession(n);if(!d)throw new Error("No active session found");let{controller:m,context:p}=d,h=d.resultsManager.getContextCopyAtIndices(c)??p.toObjectCopy(),g=ie.fromSnapshot({snapshot:h,environmentVariables:p.getVariablesFromEnvironmentCopy()}),f=cr.parse(a.advanced??{}),y={},w;if(u){if("useSelector"in i&&i.useSelector)try{let b=await m.locateElementWithSelector(u,"iframeUrl"in i?i.iframeUrl:void 0);w=b.resolution.locator,y={target:b.target,thoughts:b.thoughts}}catch(b){e.warn({err:b},"Failed resolving target with selector"),s({err:`Failed locating element with CSS selector: ${b.message}`,decisions:b instanceof mt?b.decisions:void 0});return}else try{let b=await m.locateElement({description:u,disableCache:f.disableAICaching,iframeUrl:"iframeUrl"in i?i.iframeUrl:void 0,testContext:g,returnConflicts:!0});y={target:b.target,thoughts:b.thoughts},w=b.resolution.locator}catch(b){e.warn({err:b},"Failed locating element with AI"),s({err:`Failed locating element with AI: ${b.message}`});return}if(i.type==="SELECT_OPTION"&&w)try{y.options=await m.browser.getSelectOptions(w)}catch(b){e.warn({err:b},"Failed getting select options"),s({err:`Failed getting select options: ${b.message}`});return}e.info({result:y},"Locate handler result")}if(l)try{let{buffer:b,width:C,height:v}=await m.screenshotWithDimensions({scale:"css",clearHighlights:!0,target:y?.target,hideCaret:!0}),E=await t.uploadScreenshot(b);y.screenshot={data:E,width:C,height:v}}catch(b){e.error({err:b},"Error capturing screenshot during locate"),s({err:`Error taking screenshot: ${b.message}`});return}if(s({result:y}),w)try{await Promise.all([m.browser.scrollIntoView(w),m.browser.highlightTarget(w)])}catch(b){e.warn({err:b},"Error highlighting element, continuing...")}}},Hl={event:"locate",createHandler:Hp};var Wp=({metadata:r,logger:e})=>{let{sessionId:t}=r;return async({percentX:n,percentY:o},s)=>{let i=_.getSession(t);if(!i)throw new Error("No active session found");let a=i.controller.browser;try{await a.clickMouseFromPositionPercentages(n,o)}catch(l){e.error({err:l},"Error performing click during cloud recording in control mode"),s({err:l.message})}}},Wl={event:"cloudClick",createHandler:Wp};var jp=({metadata:r,logger:e})=>{let{sessionId:t}=r;return async(n,o)=>{let s=_.getSession(t);if(!s)throw new Error("No active session found");let{controller:i}=s;s.browserBehavior.showOverlay=!0;try{let a=await i.browser.captureTargetFromClick();o({result:a})}catch(a){e.error({err:a},"Record click failed"),o({err:a instanceof Error?a.message:`${a}`})}finally{s.browserBehavior.showOverlay=!1}}},jl={event:"recordTargetClick",createHandler:jp};var Gp=({metadata:r,logger:e})=>{let{sessionId:t}=r,n,o=0,s=(a,l)=>{let c=async()=>{n=void 0;try{await a.highlightFromPositionPercentages(l),o=0}catch(u){e.error({err:u},"Error highlighting element on mouse move"),o++}};clearTimeout(n),n=setTimeout(c,50*(o+1))},i=0;return async a=>{let l=_.getSession(t);if(!l)throw new Error("No active session found");let{controller:c,browserBehavior:u}=l,d=c.browser;if(!d.closed){if(d.getActivePage().isClosed()){e.warn("Ignoring mouse move because the page is closed");return}u.showOverlay&&s(d,a);try{await d.moveMouseFromPositionPercentages(a.percentX,a.percentY),i=0}catch(m){i++,i%5===0&&e.warn({err:m,mouseErrors:i},"Error in socket mouse move handler")}}}},Gl={event:"cloudMouseMove",createHandler:Gp};var Vp=({metadata:r})=>{let{sessionId:e}=r;return async({percentDeltaX:t,percentDeltaY:n})=>{let o=_.getSession(e);if(!o)throw new Error("No active session found");let s=o.controller.browser;if(s.closed)return;let i=await s.scrollFromPositionPercentages(t,n);if(!i)return;let a=o.browserBehavior.recordingState?.transformer;a&&a.recordScroll({...i,url:s.url()})}},Vl={event:"cloudScroll",createHandler:Vp};var qp=({metadata:r,generator:e,socket:t,storage:n,logger:o})=>{let{sessionId:s,orgId:i,testId:a}=r;return async({indices:l})=>{let c=_.getSession(s);if(!c)throw new Error("No active session found");let{controller:u,browserBehavior:d}=c;o.info("Starting cloud recording");let m=await u.startRecordMode({generator:e,initialIndices:l,storage:n,logger:o,testId:a,orgId:i,onStepRecord:(p,h)=>{t.emit("stepRecorded",{step:p,indices:h})}});d.recordingState={transformer:m},d.showOverlay=!0}},ql={event:"cloudStartRecording",createHandler:qp};var Kp=({metadata:r,logger:e})=>{let{sessionId:t}=r;return async()=>{let n=_.getSession(t);if(!n)throw new Error("No active session found");e.info("Stopping cloud recording"),await n.controller.stopRecordMode(),n.browserBehavior.recordingState=void 0,n.browserBehavior.showOverlay=!1}},Kl={event:"cloudStopRecording",createHandler:Kp};var Yp=["Dead","Meta","AudioVolumeUp","AudioVolumeDown"],Xp=({metadata:r,logger:e})=>{let{sessionId:t}=r;return async({key:n})=>{let o=_.getSession(t);if(!o)throw new Error("No active session found");if(Yp.includes(n))return;let{controller:s}=o;if(s.browser.closed||s.browser.getActivePage().isClosed()){e.debug({sessionId:t},"Browser is closed, ignoring typing action");return}n.length>1?await s.browser.press(n):await s.browser.type(n,{clearContent:!1,pressKeysSequentially:!0})}},Yl={event:"cloudType",createHandler:Xp};var dn={vimiumJs:'var K=Object.defineProperty;var P=Object.getOwnPropertySymbols;var z=Object.prototype.hasOwnProperty,B=Object.prototype.propertyIsEnumerable;var F=(t,e,n)=>e in t?K(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n,D=(t,e)=>{for(var n in e||(e={}))z.call(e,n)&&F(t,n,e[n]);if(P)for(var n of P(e))B.call(e,n)&&F(t,n,e[n]);return t};var g=(t,e,n)=>(F(t,typeof e!="symbol"?e+"":e,n),n);var _=(t,e,n)=>new Promise((o,r)=>{var i=s=>{try{d(n.next(s))}catch(l){r(l)}},a=s=>{try{d(n.throw(s))}catch(l){r(l)}},d=s=>s.done?o(s.value):Promise.resolve(s.value).then(i,a);d((n=n.apply(t,e)).next())});var E=t=>function(e){return e&&e.isTrusted?t.apply(this,arguments):!0};globalThis.forTrusted==null&&(globalThis.forTrusted=E);var k={create(t,e,n,o){return{bottom:o,top:e,left:t,right:n,width:n-t,height:o-e}},copy(t){return{bottom:t.bottom,top:t.top,left:t.left,right:t.right,width:t.width,height:t.height}},translate(t,e,n){return e==null&&(e=0),n==null&&(n=0),{bottom:t.bottom+n,top:t.top+n,left:t.left+e,right:t.right+e,width:t.width,height:t.height}},subtract(t,e){return e=this.create(Math.max(t.left,e.left),Math.max(t.top,e.top),Math.min(t.right,e.right),Math.min(t.bottom,e.bottom)),e.width<0||e.height<0?[k.copy(t)]:[this.create(t.left,t.top,e.left,e.top),this.create(e.left,t.top,e.right,e.top),this.create(e.right,t.top,t.right,e.top),this.create(t.left,e.top,e.left,e.bottom),this.create(e.right,e.top,t.right,e.bottom),this.create(t.left,e.bottom,e.left,t.bottom),this.create(e.left,e.bottom,e.right,t.bottom),this.create(e.right,e.bottom,t.right,t.bottom)].filter(o=>o.height>0&&o.width>0)},intersects(t,e){return t.right>e.left&&t.left<e.right&&t.bottom>e.top&&t.top<e.bottom},intersectsStrict(t,e){return t.right>=e.left&&t.left<=e.right&&t.bottom>=e.top&&t.top<=e.bottom},equals(t,e){for(let n of["top","bottom","left","right","width","height"])if(t[n]!==e[n])return!1;return!0},intersect(t,e){return this.create(Math.max(t.left,e.left),Math.max(t.top,e.top),Math.min(t.right,e.right),Math.min(t.bottom,e.bottom))}};var N={_browserInfoLoaded:!0,_firefoxVersion:null,_isFirefox:!1,isFirefox(){if(!this._browserInfoLoaded)throw Error("browserInfo has not yet loaded.");return this._isFirefox},firefoxVersion(){if(!this._browserInfoLoaded)throw Error("browserInfo has not yet loaded.");return this._firefoxVersion},isString(t){return typeof t=="string"||t instanceof String}};var f={isReady(){return document.readyState!=="loading"},documentReady:function(){let t=document.readyState!=="loading",e=[];if(!t){let n;globalThis.addEventListener("DOMContentLoaded",n=E(function(){globalThis.removeEventListener("DOMContentLoaded",n,!0),t=!0;for(let o of e)o();e=null}),!0)}return function(n){if(t)return n();e.push(n)}}(),documentComplete:function(){let t=document.readyState==="complete",e=[];if(!t){let n;globalThis.addEventListener("load",n=E(function(o){if(o.target===document){globalThis.removeEventListener("load",n,!0),t=!0;for(let r of e)r();e=null}}),!0)}return function(n){t?n():e.push(n)}}(),createElement(t){let e=document.createElement(t);return e instanceof HTMLElement?(this.createElement=n=>document.createElement(n),e):(this.createElement=n=>document.createElementNS("http://www.w3.org/1999/xhtml",n),this.createElement(t))},addElementsToPage(t,e){let n=this.createElement("div");e.id!=null&&(n.id=e.id),e.className!=null&&(n.className=e.className);for(let o of t)n.appendChild(o);return document.body.appendChild(n),n},removeElement(t){return t.parentNode.removeChild(t)},isTopFrame(){return globalThis.top===globalThis.self},makeXPath(t){let e=[];for(let n of t)e.push(".//"+n,".//xhtml:"+n);return e.join(" | ")},evaluateXPath(t,e){let n=document.webkitIsFullScreen?document.webkitFullscreenElement:document.documentElement,o=function(r){return r==="xhtml"?"http://www.w3.org/1999/xhtml":null};return document.evaluate(t,n,o,e,null)},getVisibleClientRect(t,e){let n;e==null&&(e=!1);let o=(()=>{let i=[];for(n of t.getClientRects())i.push(k.copy(n));return i})(),r=function(){let i=window.getComputedStyle(t,null),a=i.getPropertyValue("display").indexOf("inline")===0&&i.getPropertyValue("font-size")==="0px";return r=()=>a,a};for(n of o){let i;if((n.width===0||n.height===0)&&e)for(let a of Array.from(t.children)){i=window.getComputedStyle(a,null);let d=i.getPropertyValue("position");if(i.getPropertyValue("float")==="none"&&!["absolute","fixed"].includes(d)&&!(n.height===0&&r()&&i.getPropertyValue("display").indexOf("inline")===0))continue;let s=this.getVisibleClientRect(a,!0);if(!(s===null||s.width<3||s.height<3))return s}else{if(n=this.cropRectToVisible(n),n===null||n.width<3||n.height<3||(i=window.getComputedStyle(t,null),i.getPropertyValue("visibility")!=="visible"))continue;return n}}return null},cropRectToVisible(t){let e=k.create(Math.max(t.left,0),Math.max(t.top,0),t.right,t.bottom);return e.top>=window.innerHeight-4||e.left>=window.innerWidth-4?null:e},getClientRectsForAreas(t,e){let n=[];for(let o of e){let r,i,a,d,s=o.coords.split(",").map(p=>parseInt(p,10)),l=o.shape.toLowerCase();if(["rect","rectangle"].includes(l))s.length==4&&([r,a,i,d]=s);else if(["circle","circ"].includes(l)){if(s.length==3){let[p,w,v]=s,u=v/Math.sqrt(2);r=p-u,i=p+u,a=w-u,d=w+u}}else l==="default"?s.length==2&&([r,a,i,d]=[0,0,t.width,t.height]):s.length>=4&&([r,a,i,d]=s);let c=k.translate(k.create(r,a,i,d),t.left,t.top);c=this.cropRectToVisible(c),c&&!isNaN(c.top)&&!isNaN(c.left)&&!isNaN(c.width)&&!isNaN(c.height)&&n.push({element:o,rect:c})}return n},isSelectable(t){if(!(t instanceof Element))return!1;let e=["button","checkbox","color","file","hidden","image","radio","reset","submit"];return t.nodeName.toLowerCase()==="input"&&e.indexOf(t.type)===-1||t.nodeName.toLowerCase()==="textarea"||t.isContentEditable},isEditable(t){return this.isSelectable(t)||(t.nodeName!=null?t.nodeName.toLowerCase():void 0)==="select"},isEmbed(t){let e=t.nodeName!=null?t.nodeName.toLowerCase():null;return["embed","object"].includes(e)},isFocusable(t){return t&&(this.isEditable(t)||this.isEmbed(t))},isDOMDescendant(t,e){let n=e;for(;n!==null;){if(n===t)return!0;n=n.parentNode}return!1},isSelected(t){let e=document.getSelection();if(t.isContentEditable){let n=e.anchorNode;return n&&this.isDOMDescendant(t,n)}else if(f.getSelectionType(e)==="Range"&&e.isCollapsed){let n=e.anchorNode.childNodes[e.anchorOffset];return t===n}else return!1},simulateSelect(t){if(t===document.activeElement&&f.isEditable(document.activeElement))return handlerStack.bubbleEvent("click",{target:t});if(t.focus(),t.tagName.toLowerCase()!=="textarea"||t.value.indexOf(`\n`)<0)try{if(t.selectionStart===0&&t.selectionEnd===0)return t.setSelectionRange(t.value.length,t.value.length)}catch(e){}},simulateClick(t,e){e==null&&(e={});let n=["mouseover","mousedown","mouseup","click"],o=[];for(let r of n){let i=this.simulateMouseEvent(r,t,e);o.push(i)}return o},simulateMouseEvent(t,e,n){if(n==null&&(n={}),t==="mouseout"){if(e==null&&(e=this.lastHoveredElement),this.lastHoveredElement=void 0,e==null)return}else t==="mouseover"&&(this.simulateMouseEvent("mouseout",void 0,n),this.lastHoveredElement=e);let o=new MouseEvent(t,{bubbles:!0,cancelable:!0,composed:!0,view:window,detail:1,ctrlKey:n.ctrlKey,altKey:n.altKey,shiftKey:n.shiftKey,metaKey:n.metaKey});return e.dispatchEvent(o)},simulateClickDefaultAction(t,e){let n;if(e==null&&(e={}),(t.tagName!=null?t.tagName.toLowerCase():void 0)!=="a"||!t.href)return;let{ctrlKey:o,shiftKey:r,metaKey:i,altKey:a}=e;KeyboardUtils.platform==="Mac"?n=i===!0&&o===!1:n=i===!1&&o===!0,n?chrome.runtime.sendMessage({handler:"openUrlInNewTab",url:t.href,active:r===!0}):r===!0&&i===!1&&o===!1&&a===!1?chrome.runtime.sendMessage({handler:"openUrlInNewWindow",url:t.href}):t.target==="_blank"&&chrome.runtime.sendMessage({handler:"openUrlInNewTab",url:t.href,active:!0})},simulateHover(t,e){return e==null&&(e={}),this.simulateMouseEvent("mouseover",t,e)},simulateUnhover(t,e){return e==null&&(e={}),this.simulateMouseEvent("mouseout",t,e)},addFlashRect(t){let e=this.createElement("div");return e.classList.add("vimiumReset"),e.classList.add("vimiumFlash"),e.style.left=t.left+"px",e.style.top=t.top+"px",e.style.width=t.width+"px",e.style.height=t.height+"px",document.documentElement.appendChild(e),e},getViewportTopLeft(){let t=document.documentElement,e=getComputedStyle(t),n=t.getBoundingClientRect();if(e.position==="static"&&!/content|paint|strict/.test(e.contain||"")){let o=parseInt(e.marginTop),r=parseInt(e.marginLeft);return{top:-n.top+o,left:-n.left+r}}else{let o,r;return N.isFirefox()?(r=parseInt(e.borderTopWidth),o=parseInt(e.borderLeftWidth)):{clientTop:r,clientLeft:o}=t,{top:-n.top-r,left:-n.left-o}}},suppressPropagation(t){t.stopImmediatePropagation()},suppressEvent(t){t.preventDefault(),this.suppressPropagation(t)},consumeKeyup:function(){let t=null;return function(e,n=null,o){if(!e.repeat){t!=null&&handlerStack.remove(t);let{code:r}=e;t=handlerStack.push({_name:"dom_utils/consumeKeyup",keyup(i){return i.code!==r||(this.remove(),o?f.suppressPropagation(i):f.suppressEvent(i)),handlerStack.continueBubbling},blur(i){return i.target===window&&this.remove(),handlerStack.continueBubbling}})}return typeof n=="function"&&n(),o?(f.suppressPropagation(e),handlerStack.suppressPropagation):(f.suppressEvent(e),handlerStack.suppressEvent)}}(),getSelectionType(t){return t==null&&(t=document.getSelection()),t.type?t.type:t.rangeCount===0?"None":t.isCollapsed?"Caret":"Range"},getElementWithFocus(t,e){let n,o=n=t.getRangeAt(0);f.getSelectionType(t)==="Range"&&(o=n.cloneRange(),o.collapse(e)),n=o.startContainer,n.nodeType===1&&(n=n.childNodes[o.startOffset]);let r=n;for(;r&&r.nodeType!==1;)r=r.previousSibling;return n=r||(n!=null?n.parentNode:void 0),n},getSelectionFocusElement(){let t=window.getSelection(),e=t.focusNode;return e==null?null:(e===t.anchorNode&&t.focusOffset===t.anchorOffset&&(e=e.childNodes[t.focusOffset]||e),e.nodeType!==Node.ELEMENT_NODE?e.parentElement:e)},getContainingElement(t){return(typeof t.getDestinationInsertionPoints=="function"?t.getDestinationInsertionPoints()[0]:void 0)||t.parentElement},windowIsTooSmall(){return window.innerWidth<3||window.innerHeight<3},injectUserCss(){let t=document.createElement("style");t.type="text/css",t.textContent=Settings.get("userDefinedLinkHintCss"),document.head.appendChild(t)}};var O={MAX_CONTENT_LENGTH:1e3,MAX_ATTRIBUTE_LENGTH:500,MAX_NUM_DATA_ATTRIBUTES:10,commonAttributes:["id","className","title","aria-label","aria-labelledby"],attributeNamesMapping:new Map([["a",["href","title","rel","target"]],["label",["for"]],["input",["type","name","placeholder","checked","maximumLength"]],["textarea",["placeholder","maximumLength"]],["button",["type"]],["select",["name","multiple"]],["div",["role"]],["iframe",["src"]],["img",["src","alt"]]]),describe(t){var r,i;let e={};this.addAttributes(t,this.commonAttributes,e);let n=((i=(r=t.tagName).toLowerCase)==null?void 0:i.call(r))||"";this.attributeNamesMapping.has(n)&&this.addAttributes(t,this.attributeNamesMapping.get(n),e),this.addDataAttrs(t,e);let o=this.getContent(t);return this.additionalHandling(t,D({tag:n,attributes:e},o&&{content:o}))},getContent(t){var n,o;let e=((o=(n=t.tagName).toLowerCase)==null?void 0:o.call(n))||"";return["input","textarea"].includes(e)?t.value:["div","iframe","img","body"].includes(e)?null:(["a","button","select","label"].includes(e),t.innerText)},additionalHandling(t,e){var o,r;if((((r=(o=t.tagName).toLowerCase)==null?void 0:r.call(o))||"")=="label"&&t.hasAttribute("for")){let i=t.getAttribute("for"),a=document.getElementById(i);a&&(e.target=this.describe(a))}return e},addAttributes(t,e,n){n||(n={});for(let o of e)t.hasAttribute(o)&&(n[o]=t.getAttribute(o).substring(0,this.MAX_ATTRIBUTE_LENGTH));return n},addDataAttrs(t,e){let n=0;for(let o in t.dataset)if(e[`data-${o}`]=t.dataset[o].substring(0,this.MAX_ATTRIBUTE_LENGTH),n++,n>this.MAX_NUM_DATA_ATTRIBUTES)return e;return e}};var x=null,C=()=>G()||document.scrollingElement||document.body,W=function(t){return t?t<0?-1:1:0},U={x:{axisName:"scrollLeft",max:"scrollWidth",viewSize:"clientWidth"},y:{axisName:"scrollTop",max:"scrollHeight",viewSize:"clientHeight"}},X=function(t,e,n){if(N.isString(n)){let o=n;return o==="viewSize"&&t===C()?e==="x"?window.innerWidth:window.innerHeight:t[U[e][o]]}else return n},V=function(t,e,n){let o=U[e].axisName,r=t[o];if(t.scrollBy){let i={behavior:"instant"};i[e==="x"?"left":"top"]=n,t.scrollBy(i)}else t[o]+=n;return t[o]!==r},q=function(t,e){let n=window.getComputedStyle(t);return!(n.getPropertyValue(`overflow-${e}`)==="hidden"||["hidden","collapse"].includes(n.getPropertyValue("visibility"))||n.getPropertyValue("display")==="none")},T=function(t,e,n,o){let r=o*X(t,e,n)||-1;return r=W(r),V(t,e,r)&&V(t,e,-r)},$=function(t,e,n,o){return e==null&&(e="y"),n==null&&(n=1),o==null&&(o=1),T(t,e,n,o)&&q(t,e)},j=function(t=null){let e;if(!t){let n=C();if(T(n,"y",1,1)||T(n,"y",-1,1))return n;t=document.body||C()}if(T(t,"y",1,1)||T(t,"y",-1,1))return t;{let n=Array.from(t.children).map(o=>({element:o,rect:f.getVisibleClientRect(o)})).filter(o=>o.rect);n.map(o=>o.area=o.rect.width*o.rect.height);for(e of n.sort((o,r)=>r.area-o.area)){let o=j(e.element);if(o)return o}return null}},L={init(){x=null},isScrollableElement(t){return x||(x=C()&&j()||C()),t!==x&&$(t)}},G=function(){let t=J[window.location.host];if(t)return document.querySelector(t)},J={"twitter.com":"div.permalink-container div.permalink[role=main]","reddit.com":"#overlayScrollContainer","new.reddit.com":"#overlayScrollContainer","www.reddit.com":"#overlayScrollContainer","web.telegram.org":".MessageList"};window.Scroller=L;var A=function(){let t=null;return f.documentReady(()=>t=document.hasFocus()),globalThis.addEventListener("focus",E(function(e){return e.target===window&&(t=!0),!0}),!0),globalThis.addEventListener("blur",E(function(e){return e.target===window&&(t=!1),!0}),!0),()=>t}();Object.assign(globalThis,{windowIsFocused:A});var R=class{constructor(e){g(this,"element");g(this,"image");g(this,"rect");g(this,"linkText");g(this,"showLinkText");g(this,"reason");g(this,"secondClassCitizen");g(this,"possibleFalsePositive");Object.seal(this),e&&Object.assign(this,e)}},M={getLocalHintsForElement(t){var p,w,v;let e=((w=(p=t.tagName).toLowerCase)==null?void 0:w.call(p))||"",n=!1,o=!1,r=!1,i=[],a=[],d=null;if(e==="img"){let u=t.getAttribute("usemap");if(u){let h=t.getClientRects();u=u.replace(/^#/,"").replace(\'"\',\'\\\\"\');let m=document.querySelector(`map[name="${u}"]`);if(m&&h.length>0){n=!0;let y=m.getElementsByTagName("area"),S=f.getClientRectsForAreas(h[0],y);S=S.map(I=>Object.assign(I,{image:t})),a.push(...S)}}}let s=t.getAttribute("aria-disabled");if(s&&["","true"].includes(s.toLowerCase()))return[];if(this.checkForAngularJs||(this.checkForAngularJs=function(){if(document.getElementsByClassName("ng-scope").length===0)return()=>!1;{let h=[];for(let m of["","data-","x-"])for(let y of["-",":","_"])h.push(`${m}ng${y}click`);return function(m){for(let y of h)if(m.hasAttribute(y))return!0;return!1}}}()),n||(n=this.checkForAngularJs(t)),t.hasAttribute("onclick"))n=!0;else{let u=t.getAttribute("role"),h=["button","tab","link","checkbox","menuitem","menuitemcheckbox","menuitemradio","radio"];if(u!=null&&h.includes(u.toLowerCase()))n=!0;else{let m=t.getAttribute("contentEditable");m!=null&&["","contenteditable","true","plaintext-only"].includes(m.toLowerCase())&&(n=!0)}}if(!n&&t.hasAttribute("jsaction")){let u=t.getAttribute("jsaction").split(";");for(let h of u){let m=h.trim().split(":");if(m.length>=1&&m.length<=2){let[y,S,I]=m.length===1?["click",...m[0].trim().split("."),"_"]:[m[0],...m[1].trim().split("."),"_"];n||(n=y==="click"&&S!=="none"&&I!=="_")}}}switch(e){case"a":n=!0;break;case"textarea":n||(n=!t.disabled&&!t.readOnly);break;case"input":n||(n=!(((v=t.getAttribute("type"))==null?void 0:v.toLowerCase())=="hidden"||t.disabled||t.readOnly&&f.isSelectable(t)));break;case"button":case"select":n||(n=!t.disabled);break;case"object":case"embed":n=!0;break;case"label":n||(n=t.control!=null&&!t.control.disabled&&this.getLocalHintsForElement(t.control).length===0);break;case"body":n||(n=t===document.body&&!A()&&window.innerWidth>3&&window.innerHeight>3&&(document.body!=null?document.body.tagName.toLowerCase():void 0)!=="frameset"?d="Frame.":void 0),n||(n=t===document.body&&A()&&L.isScrollableElement(t)?d="Scroll.":void 0);break;case"img":n||(n=["zoom-in","zoom-out"].includes(t.style.cursor));break;case"div":case"ol":case"ul":n||(n=t.clientHeight<t.scrollHeight&&L.isScrollableElement(t)?d="Scroll.":void 0);break;case"details":n=!0,d="Open.";break}let l=t.getAttribute("class");!n&&(l!=null&&l.toLowerCase().includes("button"))&&(n=!0,r=!0);let c=t.getAttribute("tabindex"),b=c?parseInt(c):-1;if(!n&&!(b<0)&&!isNaN(b)&&(n=!0,o=!0),n)if(a.length>0){let u=a.map(h=>new R({element:h.element,image:t,rect:h.rect,secondClassCitizen:o,possibleFalsePositive:r,reason:d}));i.push(...u)}else{let u=f.getVisibleClientRect(t,!0);if(u!==null){let h=new R({element:t,rect:u,secondClassCitizen:o,possibleFalsePositive:r,reason:d});i.push(h)}}return i},getElementFromPoint(t,e,n,o){n==null&&(n=document),o==null&&(o=[]);let r=n.elementsFromPoint?n.elementsFromPoint(t,e)[0]:n.elementFromPoint(t,e);return o.includes(r)?r:(o.push(r),r&&r.shadowRoot?M.getElementFromPoint(t,e,r.shadowRoot,o):r)},getLocalHints(t){if(!document.body)return[];let e=(s,l)=>{l==null&&(l=[]);for(let c of Array.from(s.querySelectorAll("*")))l.push(c),c.shadowRoot&&e(c.shadowRoot,l);return l},n=e(document.body),o=[];for(let s of Array.from(n))if(!t||s.href){let l=this.getLocalHintsForElement(s);o.push(...l)}o=o.reverse();let r=[1,2,3];o=o.filter((s,l)=>{if(!s.possibleFalsePositive)return!0;let b=Math.max(0,l-6);for(;b<l;){let p=o[b].element;for(let w of r)if(p=p==null?void 0:p.parentElement,p===s.element)return!1;b+=1}return!0});let i=o.filter(s=>{if(s.secondClassCitizen)return!1;let l=s.rect,c=M.getElementFromPoint(l.left+l.width*.5,l.top+l.height*.5);if(c&&(s.element.contains(c)||c.contains(s.element))||s.element.localName=="area"&&c==s.image)return!0;let p=[l.top+.1,l.bottom-.1],w=[l.left+.1,l.right-.1];for(let v of p)for(let u of w){let h=M.getElementFromPoint(u,v);if(h&&(s.element.contains(h)||h.contains(s.element)))return!0}});i.reverse();let{top:a,left:d}=f.getViewportTopLeft();for(let s of i)s.rect.top+=a,s.rect.left+=d;return i}};var H=class{constructor(){this.hints=null;this.hintMarkers=null;this.markersDiv=null;this.enrichedMarkers=null}reset(){this.removeMarkers(),this.hints=null,this.hintMarkers=null,this.markersDiv=null}capture(){return _(this,null,function*(){this.reset(),this.createMarkers(),this.displayMarkers()})}createMarkers(){this.hints=M.getLocalHints(),this.hintMarkers=new Map,this.hints.forEach((e,n)=>{var i,a;let o=f.createElement("div"),r=(a=(i=e.element.attributes["data-momentic-id"])==null?void 0:i.value)!=null?a:void 0;if(!r){console.warn(`[MOMENTIC] No data-momentic-id found for interactive element ${e.element.outerHTML}`);return}o.style.left=e.rect.left+"px",o.style.top=e.rect.top+"px",o.style.zIndex=214e7+n,o.className="vimiumReset internalVimiumHintMarker vimiumHintMarker",Z(o,r),this.hintMarkers.set(r,{hint:e,marker:o})})}enrichMarkers(){if(this.hintMarkers){this.enrichedMarkers=[];for(let[e,n]of this.hintMarkers)this.enrichedMarkers.push(Object.assign(O.describe(n.hint.element),{hintString:e}))}}displayMarkers(){this.hintMarkers&&(this.markersDiv||(this.markersDiv=f.addElementsToPage(Array.from(this.hintMarkers.values()).map(e=>e.marker),{id:"vimiumHintMarkerContainer",className:"vimiumReset"})))}removeMarkers(){this.markersDiv&&(f.removeElement(this.markersDiv),this.markersDiv=null)}toggleMarkers(){this.markersDiv?this.removeMarkers():this.displayMarkers()}},Z=(t,e)=>{for(let n of e){let o=document.createElement("span");o.className="vimiumReset",o.textContent=n,t.appendChild(o)}};window.HintManager=H;\n',vimiumCss:'.vimiumReset,a.vimiumReset,a:hover.vimiumReset,a:link.vimiumReset,a:visited.vimiumReset,div.vimiumReset,span.vimiumReset,table.vimiumReset,td.vimiumReset,tr.vimiumReset{background:none;border:none;bottom:auto;box-shadow:none;color:#000;cursor:auto;display:inline;float:none;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-size:inherit;font-style:normal;font-variant:normal;font-weight:400;height:auto;left:auto;letter-spacing:0;line-height:100%;margin:0;max-height:none;max-width:none;min-height:0;min-width:0;opacity:1;padding:0;position:static;right:auto;text-align:left;text-decoration:none;text-indent:0;text-shadow:none;text-transform:none;top:auto;vertical-align:baseline;white-space:normal;width:auto;z-index:2140000000}tbody.vimiumReset,thead.vimiumReset{display:table-header-group}tbody.vimiumReset{display:table-row-group}div.internalVimiumHintMarker{background:linear-gradient(180deg,#fff785 0,#ffc542);border:1px solid #c38a22;border-radius:3px;box-shadow:0 3px 7px 0 rgba(0,0,0,.3);display:block;font-size:11px;left:-1px;overflow:hidden;padding:1px 3px 0;position:absolute;top:-1px;white-space:nowrap}div.internalVimiumHintMarker span{color:#302505;font-family:Helvetica,Arial,sans-serif;font-size:11px;font-weight:700;text-shadow:0 1px 0 hsla(0,0%,100%,.6)}div.internalVimiumHintMarker>.matchingCharacter{color:#d4ac3a}div>.vimiumActiveHintMarker span{color:#a07555!important}div.internalVimiumInputHint{background-color:rgba(255,247,133,.3);border:1px solid #c38a22;display:block;pointer-events:none;position:absolute}div.internalVimiumSelectedInputHint{background-color:hsla(0,100%,70%,.3);border:1px solid #933!important}div.internalVimiumSelectedInputHint span{color:#fff!important}div.vimiumHighlightedFrame{border:5px solid #ff0;box-sizing:border-box;margin:0;pointer-events:none}div.vimiumHighlightedFrame,iframe.vimiumHelpDialogFrame{height:100%;left:0;padding:0;position:fixed;top:0;width:100%}iframe.vimiumHelpDialogFrame{background-color:hsla(0,0%,4%,.6);border:none;display:block;z-index:2139999997}div#vimiumHelpDialogContainer{background-color:#fff;border:2px solid #b3b3b3;border-radius:6px;margin:50px auto;max-height:calc(100% - 100px);max-width:calc(100% - 100px);opacity:1;overflow-x:auto;overflow-y:auto;width:840px}div#vimiumHelpDialog{min-width:600px;padding:8px 12px}span#vimiumTitle,span#vimiumTitle *,span#vimiumTitle span{font-size:20px}#vimiumTitle{display:block;line-height:130%;white-space:nowrap}td.vimiumHelpDialogTopButtons{text-align:right;width:100%}#helpDialogOptionsPage,#helpDialogWikiPage{font-size:14px;padding-left:5px;padding-right:5px}div.vimiumColumn{float:left;font-size:11px;line-height:130%;width:50%}div.vimiumColumn tr{display:table-row}div.vimiumColumn td{display:table-cell;font-size:11px;line-height:130%}div.vimiumColumn table,div.vimiumColumn td,div.vimiumColumn tr{margin:0;padding:0}div.vimiumColumn table{table-layout:auto;width:100%}div.vimiumColumn td{padding:1px;vertical-align:top}div#vimiumHelpDialog div.vimiumColumn tr>td:first-of-type{font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-size:14px;text-align:right;white-space:nowrap}span.vimiumHelpDialogKey{background-color:#f3f3f3;border:1px solid;border-color:#ccc #ccc #bbb;border-radius:3px;box-shadow:inset 0 -1px 0 #bbb;color:#212121;font-family:monospace;font-size:11px;margin-left:2px;padding:1px 4px}div#vimiumHelpDialog div.vimiumColumn tr>td:nth-of-type(3){width:100%}div#vimiumHelpDialog div.vimiumDivider{background-color:#9a9a9a;display:block;height:1px;margin:10px auto;width:100%}div#vimiumHelpDialog td.vimiumHelpSectionTitle{font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-size:16px;font-weight:700;padding-top:3px}div#vimiumHelpDialog td.vimiumHelpDescription{font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-size:14px}div#vimiumHelpDialog span.vimiumCopyCommandNameName{cursor:pointer;font-size:12px;font-style:italic}div#vimiumHelpDialog tr.advanced{display:none}div#vimiumHelpDialog.showAdvanced tr.advanced{display:table-row}div#vimiumHelpDialog div.advanced td:nth-of-type(3){color:#555}div#vimiumHelpDialog a.closeButton{color:#555;cursor:pointer;font-family:courier new;font-size:24px;font-weight:700;padding-left:5px;position:relative;text-decoration:none;top:3px}div#vimiumHelpDialog a{text-decoration:underline}div#vimiumHelpDialog a.closeButton:hover{color:#000;-webkit-user-select:none}div#vimiumHelpDialogFooter{display:block;margin-bottom:37px;position:relative}table.helpDialogBottom{width:100%}td.helpDialogBottomRight{float:right;text-align:right;width:100%}td.helpDialogBottomLeft,td.helpDialogBottomRight{padding:0}div#vimiumHelpDialogFooter *{font-size:10px}a#toggleAdvancedCommands,span#help-dialog-tip{font-size:10px;position:relative;top:19px;white-space:nowrap}a#toggleAdvancedCommands,a:active.vimiumHelDialogLink,a:hover.vimiumHelDialogLink,a:link.vimiumHelDialogLink,a:visited.vimiumHelDialogLink{color:#2f508e;cursor:pointer;text-decoration:underline}div.vimiumHUD{background:#f1f1f1;border:1px solid #aaa;border-radius:4px;bottom:8px;box-shadow:0 2px 10px rgba(0,0,0,.8);display:block;left:8px;position:fixed;text-align:left;width:calc(100% - 20px);z-index:2139999999}iframe.vimiumHUDFrame{background-color:transparent;border:none;bottom:-14px;display:block;height:58px;margin:0 0 0 -40%;min-width:300px;opacity:0;overflow:hidden;padding:0;position:fixed;right:20px;width:20%;z-index:2139999998}div.vimiumHUD .vimiumHUDSearchArea{background-color:#f1f1f1;border-radius:4px 4px 0 0;display:block;padding:3px}div.vimiumHUD .vimiumHUDSearchAreaInner{border-radius:3px;box-sizing:border-box;color:#777;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-size:14px;height:30px;line-height:20px;margin-bottom:0;outline:none;padding:2px 4px;width:100%}div.vimiumHUD .hud-find{background:#fff;border:1px solid #ccc}div.vimiumHUD span#hud-find-input,div.vimiumHUD span#hud-match-count{color:#000;display:inline;outline:none;overflow-y:hidden;white-space:nowrap}div.vimiumHUD span#hud-find-input:before{content:"/"}div.vimiumHUD span#hud-match-count{color:#aaa;font-size:12px}div.vimiumHUD span#hud-find-input br{display:none}div.vimiumHUD span#hud-find-input *{display:inline;white-space:nowrap}body.vimiumFindMode ::selection{background:#ff9632}iframe.vomnibarFrame{background-color:transparent;border:none;display:block;font-family:sans-serif;height:calc(100% - 70px);left:50%;margin:0 0 0 -40%;min-width:400px;overflow:hidden;padding:0;position:fixed;top:70px;width:calc(80% + 20px);z-index:2139999998}div.vimiumFlash{background-color:transparent;box-shadow:0 0 4px 2px #4183c4;padding:1px;position:absolute;z-index:2140000000}iframe.vimiumUIComponentHidden{display:none}iframe.vimiumUIComponentVisible{color-scheme:light dark;display:block}iframe.vimiumUIComponentReactivated{border:5px solid #ff0}iframe.vimiumNonClickable{pointer-events:none}@media (prefers-color-scheme:dark){iframe.reverseDarkReaderFilter{-webkit-filter:invert(100%) hue-rotate(180deg)!important;filter:invert(100%) hue-rotate(180deg)!important}body.vimiumBody{background-color:#292a2d;color:#fff}body.vimiumBody a,body.vimiumBody a:visited{color:#8ab4f8}body.vimiumBody input,body.vimiumBody textarea{background-color:#1d1d1f;border-color:#1d1d1f;color:#e8eaed}body.vimiumBody div.example{color:#9aa0a6}body.vimiumBody div#footer,body.vimiumBody div#state,div#vimiumHelpDialogContainer{background-color:#202124;border-color:hsla(0,0%,100%,.1)}div#vimiumHelpDialog{background-color:#292a2d;color:#fff}div#vimiumHelpDialog td.vimiumHelpDescription{color:#c9cccf}div#vimiumHelpDialog td.vimiumHelpSectionTitle,span#vimiumTitle{color:#fff}#vimiumTitle>span:first-child{color:#8ab4f8!important}div#vimiumHelpDialog a{color:#8ab4f8}div#vimiumHelpDialog div.vimiumDivider{background-color:hsla(0,0%,100%,.1)}span.vimiumHelpDialogKey{background-color:#1d1d1f;border:1px solid #000;box-shadow:none;color:#fff}}',htmlUtilsLibJs:`var __defProp = Object.defineProperty;
|
|
7
|
+
`)),console.log(t(` ${i}:`,l))}else if(o)for(let i of o){let a=i;typeof i=="object"&&(a=JSON.stringify(i,void 0,2),a=a.split(`
|
|
8
|
+
`).map((l,c)=>c>0?` ${l}`:l).join(`
|
|
9
|
+
`)),console.log(" ",t(a))}}setMinLevel(e){this.minLogLevel=e}log(...e){this.logWithLevel(1,gt.reset,...e)}info(...e){this.logWithLevel(1,gt.blue,...e)}debug(...e){this.logWithLevel(0,gt.dim,...e)}warn(...e){this.logWithLevel(2,gt.yellow,...e)}error(...e){this.logWithLevel(3,gt.red,...e)}success(...e){this.logWithLevel(4,gt.green,...e)}dimmed(...e){this.logWithLevel(1,gt.dim,...e)}underline(...e){this.logWithLevel(2,gt.underline,...e)}bold(...e){this.logWithLevel(2,gt.bold,...e)}grey(...e){this.logWithLevel(0,gt.grey,...e)}child(e){return new r(this.minLogLevel,{...this.logBindings,...e})}flush(){}bindings(){return this.logBindings}},T=new wi(0,{});var No={},Nn=({logger:r,logKey:e,maxCount:t,intervalMs:n},o,s,...i)=>{let a=No[e];a?clearTimeout(a.timer):(a={count:0,totalCount:0},No[e]=a),a.totalCount++,a.count<t&&(a.count++,r.debug(o,s,...i)),a.timer=setTimeout(()=>{let l=No[e];l?.totalCount!==l?.count&&r.debug({logKey:e,totalCount:l?.totalCount,count:l?.count},`Debug logs were rate-limited for ${e}`),delete No[e]},n)};import{z as Ee}from"zod";var $h=Ee.object({id:Ee.string(),createdAt:Ee.coerce.date(),createdBy:Ee.string(),organizationId:Ee.string(),name:Ee.string(),description:Ee.string().nullish(),enabled:Ee.boolean(),schemaVersion:Ee.string().describe("Schema version for steps"),parameters:Ee.string().array().nullish().describe("Parameter list"),defaultParameters:Ee.record(Ee.string(),Ee.string()).nullish(),defaultCacheKey:Ee.string().nullish(),defaultCacheTtl:Ee.number().nullish()}),mx=$h.extend({steps:Ee.lazy(()=>Xe.array())}),kl=5*60*1e3;import{formatInTimeZone as fx}from"date-fns-tz";var xe=r=>{let e=r.trim().toLowerCase().replace(/[^a-z0-9]/g,"-");for(;e.includes("--");)e=e.replaceAll("--","-");return e.startsWith("-")&&(e=e.slice(1)),e.endsWith("-")&&(e=e.slice(0,e.length-1)),e};import*as x from"zod";var _n=x.object({disableCache:x.boolean().optional()}),Rx=x.object({error:x.boolean(),reason:x.string(),message:x.string()}),Ix=wl.merge(_n),Dl=ti,Px=Sl.merge(_n),Fl=Ba,Ox=On.pick({browserState:!0,goal:!0}).merge(_n).extend({screenshot:x.string()}),Ul=hl,Lx=On.pick({goal:!0,url:!0}).merge(_n),$l=x.string().array(),Mx=On.pick({goal:!0,browserState:!0}).merge(_n),Bl=pl,Nx=yl.merge(_n);var _x=x.object({testPaths:x.string().array().describe("can be either hyphenated, lowercase test names or UUIDs"),env:x.string().optional(),all:x.boolean().optional(),urlOverride:x.string().optional(),customHeaders:x.record(x.string(),x.string()).optional(),testInputMatrix:x.record(x.string(),x.string()).array().optional()}),zl=x.object({message:x.string(),queuedTests:x.object({name:x.string(),id:x.string()}).array(),runIds:x.string().uuid().array()}),Wl=Mo,Hl=x.string().array(),kx=x.union([x.object({paths:x.string().array().describe("run specific test paths (e.g. todo-test)"),all:x.boolean().describe("run all tests").optional()}),x.object({path:x.string().describe("deprecated; present for backcompat")})]),jl=x.object({tests:x.record(x.string().describe("Test name"),x.string().describe("Test YAML")),modules:x.record(x.string().describe("Module name"),x.string().describe("Module YAML"))}),Bh=x.object({test:x.string().describe("test YAML"),modules:x.record(x.string().describe("moduleId"),x.string().describe("module YAML"))}),Dx=Bh.array(),Fx=x.object({testId:x.string(),schemaVersion:x.string(),steps:x.array(x.record(x.unknown()))}),Ux=x.object({entries:x.array(li),testId:x.string()}),$x=x.object({steps:x.array(x.record(x.unknown())),testId:x.string(),schemaVersion:x.string(),organizationId:x.string()}),Gl=qa,Bx=x.object({testId:x.string(),testName:x.string(),resolvedBaseUrl:x.string().optional(),trigger:x.nativeEnum(Ir)}),Vl=x.object({id:x.string()}),zh=fi.pick({id:!0,status:!0,testName:!0,testId:!0,test:!0,failureReason:!0,failureDetails:!0}),ql=zh.array(),zx=fi.pick({startedAt:!0,finishedAt:!0,results:!0,status:!0,failureDetails:!0,failureReason:!0,debugData:!0,resolvedBaseUrl:!0,resolvedInputs:!0,attempts:!0,flake:!0}).partial(),Wx=x.object({screenshot:x.string()}),Kl=x.object({key:x.string()}),Yl=x.object({orgId:x.string()}),Xl=x.array(zt),Jl=x.record(x.string(),x.union([x.string(),x.boolean()])),Hx=x.object({paths:x.string().array(),env:x.string().optional(),urlOverride:x.string().optional(),customHeaders:x.record(x.string(),x.string()).optional()}),Zl=x.object({suiteRunIds:x.string().array()});var Ql=ml.array();import{z as Oe}from"zod";var bi="test",Ci="module",te=(o=>(o.TEST=`momentic/${bi}`,o.MODULE=`momentic/${Ci}`,o.FIXTURE="momentic/fixture",o.ENVIRONMENT="momentic/environment",o))(te||{}),Xx=pe.extend({steps:Oe.array(Oe.record(Oe.string(),Oe.unknown()))}),Ti=qe.extend({steps:Oe.array(Oe.record(Oe.string(),Oe.unknown())),schemaVersion:Oe.string()}),Jx=Ti.extend({fileType:Oe.literal(te.MODULE)}),Zx=Oe.object({test:Oe.string().describe("YAML for the test, including metadata and steps"),modules:Oe.record(Oe.string(),Oe.string()).describe("Map of module name to YAML for the module")});import{validator as oA}from"@exodus/schemasafe";var ec=[".sh",".exe",".app",".bat",".cmd",".msi",".apk",".jar",".py",".js",".cron",".php",".asp"];var tc=r=>{r.extraHeaders&&(r.extraHeaders=Object.fromEntries(Object.entries(r.extraHeaders).filter(([e,t])=>e.trim()&&t.trim())))};import{z as fA}from"zod";var kn=class extends Error{status;constructor(e,t,n={}){super(t,n),this.status=e}},Dn=class{baseUrl;apiKey;logger;constructor(e){this.baseUrl=e.baseUrl,this.apiKey=e.apiKey,this.logger=e.logger}async sendRequest(e,t,n=3,o=3e4){let s=new AbortController,i=setTimeout(()=>s.abort(),o),a=await fetch(`${this.baseUrl}${e}`,{method:t.method,body:t.body?JSON.stringify(t.body):void 0,headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`},signal:s.signal});if(clearTimeout(i),!a.ok){if(a.status>500&&n>0)return await new Promise(c=>setTimeout(c,1500*Math.random())),this.sendRequest(e,t,n-1);throw new kn(a.status,`Request to ${e} failed with status ${a.status}: ${await a.text()}`)}let l;return a.status===204?l=await a.text():l=await a.json(),this.logger&&!t.noLog&&this.logger.debug({result:l,path:e,baseUrl:this.baseUrl,status:a.status},"Got response from Momentic server"),l}};var J="v1",Ue=class extends Dn{constructor(e){super(e)}getAppUrl(){return this.baseUrl.replace(/\/\/api/,"//app")}async getOrgId(){let e=await this.sendRequest(`/${J}/auth/check`,{method:"GET",noLog:!0}),{orgId:t}=Yl.parse(e);return t}async bulkGetRunStatus(e){let t=await this.sendRequest(`/${J}/runs/status`,{method:"POST",body:e,noLog:!0});return ql.parse(t)}async createRun(e){let t=await this.sendRequest(`/${J}/runs`,{method:"POST",body:e,noLog:!0});return Vl.parse(t)}async updateRun(e,t){await this.sendRequest(`/${J}/runs/${e}`,{method:"PATCH",body:t,noLog:!0})}async getTest(e){let t=await this.sendRequest(`/${J}/tests/${e}`,{method:"GET"});return Wl.parse(t)}async getAllTestIds(){let e=await this.sendRequest(`/${J}/tests`,{method:"GET"});return Hl.parse(e)}async getTestYAMLExport(e){let t=await this.sendRequest(`/${J}/tests/export`,{method:"POST",body:e});return jl.parse(t)}async updateTestWithYAML(e){await this.sendRequest(`/${J}/tests/update`,{method:"POST",body:e})}async updateStepCaches(e){await this.sendRequest(`/${J}/cache`,{method:"PATCH",body:e})}async getStepCacheForTest(e){let t=await this.sendRequest(`/${J}/cache`,{method:"POST",body:e});return Gl.parse(t)}async queueTests(e){let t=await this.sendRequest(`/${J}/tests/queue`,{method:"POST",body:e});return zl.parse(t)}async uploadScreenshot(e){let t=await this.sendRequest(`/${J}/screenshots`,{method:"POST",body:e,noLog:!0});return Kl.parse(t)}async getAllEnvironments(){let e=await this.sendRequest(`/${J}/environments`,{method:"GET"});return Xl.parse(e)}async getEnvironment(e){let t=await this.sendRequest(`/${J}/environments/${e}`,{method:"GET"});return zt.parse(t)}async getAllFeatureFlags(){let e=await this.sendRequest(`/${J}/auth/flags`,{method:"GET",noLog:!0});return Jl.parse(e)}async acquireCacheLock(e){let t=await this.sendRequest(`/${J}/result-cache/entry`,{method:"POST",body:e});return xl.parse(t)}async releaseCacheLock(e){await this.sendRequest(`/${J}/result-cache/entry`,{method:"DELETE",body:{key:e}})}async setCacheResult(e){await this.sendRequest(`/${J}/result-cache/entry`,{method:"PATCH",body:e})}async getCacheResult(e){try{return await this.sendRequest(`/${J}/result-cache/entry`,{method:"POST",body:e})}catch(t){if(t instanceof Error&&t.message.includes("404"))return null;throw t}}async queueSuiteRuns(e){let t=await this.sendRequest(`/${J}/suites/queue`,{method:"POST",body:e});return Zl.parse(t)}async bulkGetSuiteStatus(e){let t={suiteRunIds:e},n=await this.sendRequest(`/${J}/suites/status`,{method:"POST",body:t,noLog:!0});return Ql.parse(n)}async updateCacheLastUsedDate(e,t){try{await this.sendRequest(`/${J}/cache/lastUsedAt`,{method:"PATCH",body:e})}catch(n){t.error({err:n},"Failed to update cache last used date")}}async uploadProposedSteps(e,t){try{await this.sendRequest(`/${J}/runs/proposed-steps`,{method:"POST",body:e})}catch(n){t.error({err:n},"Failed to upload proposed steps")}}};function Fn({steps:r,topLevel:e=!0,...t}){let{stepCacheEntries:n,logger:o,keyPrefix:s}=t,i=[],a=[],l=0,c=(d,m)=>{try{let p=Qt.parse(m.value);if(p.type!==d.type){o.warn({parsedCacheEntry:p,command:d},"Not using step cache due to type mismatch"),a.push(m.key);return}d.cache=p.cache,i.push(m.key)}catch(p){a.push(m.key),o.error({err:p,cacheEntry:m},"Not using step cache due to parsing error")}},u=(d,m)=>{let p=Wh(d.id,m),f=p.find(h=>!!n[h]);f?c(d,n[f]):(a.push(p[0]),o.debug({command:d,possibleKeys:p},"Step cache miss"))};for(let d of r)switch(d.type){case"RESOLVED_MODULE":{l+=d.steps.length;let{hits:p,misses:f}=Fn({...t,steps:d.steps,keyPrefix:s?`${s}:${d.id}`:d.id,topLevel:!1});i=i.concat(p),a=a.concat(f);break}case"IFRAME":case"SECTION":case"AI_ACTION":{if(l+=d.steps?.length??0,!d.steps?.length)break;let{hits:p,misses:f}=Fn({...t,steps:d.steps,topLevel:!1});i=i.concat(p),a=a.concat(f);break}case"PRESET_ACTION":{if(!ai.includes(d.command.type)||d.command.type==="TYPE"&&!d.command.target||d.command.type==="MOUSE_DRAG"&&!d.command.target||"cache"in d.command&&d.command.cache)continue;l++,u(d.command,s);break}case"CONDITIONAL":{for(let p of d.blocks){l++,u(p.assertion.command,s),l+=p.steps.length;let{hits:f,misses:h}=Fn({...t,steps:p.steps,topLevel:!1});i=i.concat(f),a=a.concat(h);break}if(d.elseSteps){l+=d.elseSteps.length;let{hits:p,misses:f}=Fn({...t,steps:d.elseSteps,topLevel:!1});i=i.concat(p),a=a.concat(f)}break}default:return(p=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(d)}return e&&l&&a.length>0&&o.debug({totalSteps:l,cacheMisses:a,cacheHits:i,cacheEntries:n.length},"Step cache did not fully resolve"),{hits:i,misses:a}}function nc(r,e){return e?`${e}:${r}`:r}function Wh(r,e){let t=[],n=e?.split(":")??[];for(let o=n.length;o>=0;o--){let s=[...n.slice(o),r];t.push(s.join(":"))}return t}function rc(r){let{moduleStepParents:e=[],moduleIdParents:t=[]}=r;if(e.length!==t.length)throw new Error(`Invalid cache entry parent length: ${JSON.stringify(e)}
|
|
10
|
+
${JSON.stringify(t)}`);let n=[];if(!r.skipIntermediateEntries)for(let o=e.length;o>0;o--){let s=t[o-1],i=e.slice(o,e.length).join(":");n.push({key:nc(r.id,i),moduleId:s,organizationId:r.orgId,value:r.value})}return n.push({key:nc(r.id,e.join(":")),organizationId:r.orgId,value:r.value,testId:r.testId}),n}function oc(r){switch(r.type){case"DRAG":{if(r.fromTarget.type==="coordinates"||r.toTarget.type==="coordinates"||!r.fromTarget?.a11yData||!r.toTarget?.a11yData)return;r.cache={fromTarget:r.fromTarget.a11yData,toTarget:r.toTarget.a11yData},delete r.fromTarget.a11yData,delete r.toTarget.a11yData;return}case"MOUSE_DRAG":case"HOVER":case"SCROLL_UP":case"SCROLL_DOWN":case"SCROLL_LEFT":case"SCROLL_RIGHT":case"SELECT_OPTION":case"TYPE":case"VISUAL_DIFF":case"CLICK":case"FOCUS":case"BLUR":{if(r.target?.type==="coordinates"||!r.target?.a11yData)return;r.cache={target:r.target.a11yData},delete r.target.a11yData;return}default:return}}function Nr(r,e){return r.length<e?r:r.slice(0,e-3)+"[...]"}var on={EQUALS:"equals",CONTAINS:"contains",STARTS_WITH:"starts with"},sn={EQUALS:"does not equal",CONTAINS:"does not contain",STARTS_WITH:"does not start with"},vi={EXISTS:"exists",VISIBLE:"is visible",ENABLED:"is enabled",EDITABLE:"is editable"},Ei={EXISTS:"does not exists",VISIBLE:"is not visible",ENABLED:"is disabled",EDITABLE:"is not editable"};function Hh(r){switch(r.type){case"ELEMENT_CONTENT":return`${r.negated?sn[r.operation]:on[r.operation]} '${r.value}'`;case"ELEMENT_ATTRIBUTE":{let t=r.negated?sn[r.operation]:on[r.operation];return`attribute '${r.attr}' ${t} '${r.value}'`}case"ELEMENT_EXISTENCE":return r.negated?Ei[r.condition]:vi[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 LR={CONTENT:"The page"};function jh(r){switch(r.type){case"CONTENT":return`${r.negated?sn.CONTAINS:on.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 Wt(r){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: ${Nr(r.url,30)}`;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: ${ve(r.target)}`:""}`;case"SCROLL_UP":return`Scroll up ${r.deltaY?`${r.deltaY}px`:"1 page height"}${r.target?` in the container of: ${ve(r.target)}`:""}`;case"SCROLL_LEFT":return`Scroll left ${r.deltaX?`${r.deltaX}px`:"1 page width"}${r.target?` in the container of: ${ve(r.target)}`:""}`;case"SCROLL_RIGHT":return`Scroll right ${r.deltaX?`${r.deltaX}px`:"1 page width"}${r.target?` in the container of: ${ve(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: ${ve(r.target)}`;let o="";return r.target?.elementDescriptor.length?o=` on element: '${r.target.elementDescriptor}'`:r.cache?.target.nodeOnlySerializedHtml&&(o=` on element: '${r.cache?.target.nodeOnlySerializedHtml}'`),`Click${o}`}case"FOCUS":return`Focus ${ve(r.target)}`;case"BLUR":return`Focus ${ve(r.target)}`;case"DRAG":return`Drag ${ve(r.fromTarget)} onto ${ve(r.toTarget)}`;case"MOUSE_DRAG":return r.target?`Click and drag ${ve(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 o="";return r.target?.type==="coordinates"?o=` in element at coordinates: ${ve(r.target)}`:r.target?.elementDescriptor.length?o=` in element: '${r.target.elementDescriptor}'`:r.cache?.target.nodeOnlySerializedHtml&&(o=` in element: '${r.cache?.target.nodeOnlySerializedHtml}'`),`Type '${r.value}'${o||""}`}case"HOVER":{let o="";return r.target.type==="coordinates"?o=` over coordinates: ${ve(r.target)}`:r.target.elementDescriptor.length>0?o=` over element: '${r.target.elementDescriptor}'`:r.cache?.target.nodeOnlySerializedHtml&&(o=` over element: '${r.cache?.target.nodeOnlySerializedHtml}'`),`Hover${o}`}case"PRESS":return`Press ${r.value}`;case"SELECT_OPTION":let e="";return r.target.type==="coordinates"?e=` from element at coordinates: ${ve(r.target)}`:r.target.elementDescriptor.length>0?e=` from: '${r.target.elementDescriptor}'`:r.cache?.target.nodeOnlySerializedHtml&&(e=` from: '${r.cache?.target.nodeOnlySerializedHtml}'`),`Select option '${r.option}'${e}`;case"TAB":return`Switch to tab with substring: ${r.url}`;case"NEW_TAB":return`Open new tab to: ${r.url}`;case"REQUEST":return`Send ${r.method} 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: ${Nr(r.code,30)}`;case"AI_ASSERTION":return`Assertion: '${r.assertion}'`;case"AI_WAIT":return`Wait until assertion is true: '${r.assertion}'`;case"VISUAL_DIFF":return`Visual diff against baseline ${r.target?`for element: ${ve(r.target)}`:"for entire page"}`;case"FILE_UPLOAD":return`Upload file: ${r.fileSource.url}`;case"AUTH_LOAD":return"Load auth state";case"AUTH_SAVE":return"Save auth state";case"ELEMENT_CHECK":return`Assert the element ${ve(r.target)} ${Hh(r.assertion)}`;case"PAGE_CHECK":return`Assert the page ${jh(r.assertion)}`;case"WAIT_FOR_URL":return`Wait for the page URL to match: ${r.url}`;default:return(o=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(r)}}function sc(r){let e=[];for(let t of r){t.sort((i,a)=>i.timestamp-a.timestamp);let n=[],o,s=1;for(let i of t)o&&o.text===i.text&&o.type===i.type&&JSON.stringify(o.args??null)===JSON.stringify(i.args??null)?s++:(o&&(s>1?o.args&&o.args.length?o.args.push(`(repeated ${s} times)`):o.text+=` (repeated ${s} times)`:n.push(o)),o=i,s=1);o&&n.push(o),e.push(n)}return e}function Ot(r){let{onPresetAction:e,onSimpleStepContainer:t,onConditional:n}=r;for(let o of r.steps)switch(o.type){case"PRESET_ACTION":e(o);break;case"CONDITIONAL":n?.(o);for(let i of o.blocks)e(i.assertion),Ot({...r,steps:i.steps});Ot({...r,steps:o.elseSteps??[]});break;case"RESOLVED_MODULE":case"IFRAME":case"SECTION":case"AI_ACTION":t?.(o),o.steps&&Ot({...r,steps:o.steps});break;default:return(i=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(o)}}function _o(r){let e=0;Ot({steps:r,onPresetAction:t=>{t.index=e++},onConditional:t=>{t.index=e++},onSimpleStepContainer:t=>{t.index=e++}})}function ic(r){Ot({steps:r,onPresetAction:e=>{delete e.index},onConditional:e=>{delete e.index},onSimpleStepContainer:e=>{delete e.index}})}var Gh=(r,e)=>{switch(r.type){case"RESOLVED_MODULE":return r.steps[e];case"AI_ACTION":return r.steps[e];case"CONDITIONAL":{let n=r.blocks.map(o=>[o.assertion,...o.steps]).flat();return r.elseSteps&&(n=n.concat(r.elseSteps)),n[e]}case"SECTION":case"IFRAME":return r.steps[e];case"PRESET_ACTION":default:throw new Error(`Cannot get a child step from step type ${r.type}`)}};function ko(r,e){let t=r[e[0]];for(let n=1;n<e.length;n++)t=Gh(t,e[n]);return t}function Do(r){let e=0;return Ot({steps:r,onPresetAction:t=>{e=Math.max(e,t.index)},onConditional:t=>{e=Math.max(e,t.index)},onSimpleStepContainer:t=>{e=Math.max(e,t.index)}}),e}import{cloneDeep as KR,unset as YR}from"lodash-es";function xi(r){switch(r.type){case"AI_ACTION":return`AI action: ${Nr(r.text,100)}`;case"PRESET_ACTION":return Wt(r.command);case"MODULE":return`Module: ${r.id}`;case"RESOLVED_MODULE":return`Module: ${r.name}`;case"CONDITIONAL":return"Conditional";case"IFRAME":return"Frame step";case"SECTION":return`Section${r.description?`with goal: ${Nr(r.description,100)}`:""}`;default:return(t=>{throw new Error("You missed a case in the switch above")})(r)}}function Fo(r){for(let e of r)switch(e.type){case"PRESET_ACTION":ac(e);break;case"CONDITIONAL":e.assertion&&ac(e.assertion),Fo(e.results);break;case"AI_ACTION":case"IFRAME":case"MODULE":case"SECTION":{Fo(e.results);break}default:return(n=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(e)}}function ac(r){let e=r.command;"cache"in e&&e.cache&&(e.cache=void 0),r.details&&(r.details=void 0)}function lc(r,e){if(!(!r.envs||!r.envs.length)){for(let t of r.envs)e in t&&(t[e]&&(t.default=!0),delete t.defaultOnCloud,delete t.defaultOnLocal);r.envs.some(t=>t.default)||(r.envs[0].default=!0)}}import Yh from"diff-lines";import $o,{gte as Xh}from"semver";var cc={name:"Migrate to ai step v2",fromVersion:"1.0.4",toVersion:"1.0.5",recursiveKeys:new Set(["results","commands"]),stopOnFailure:!0,execute:async r=>(r=r.filter(e=>!(e.status!==void 0&&e.type==="AI_ACTION")),r=r.map(e=>(e.status===void 0||e.type==="PRESET_ACTION"&&(e.results=e.commands??e.results??[]),e)),r)};var dc={name:"Make sure ai step v2 has done command",fromVersion:"1.0.5",toVersion:"1.0.6",recursiveKeys:new Set(["results","commands"]),stopOnFailure:!0,execute:async r=>r.map(e=>{if(e.type!=="AI_ACTION"||e.status!==void 0||!e.commands||!e.commands.length)return e;let t=e.commands,n=t[t.length-1];return n&&n.type!=="SUCCESS"&&t.push({type:"SUCCESS"}),e})};var Vh=["target","fromTarget","toTarget"];function uc(r){for(let e of Vh){if(r[e]===void 0)continue;let t=r[e];t.elementDescriptor!==void 0?t.type="description":r[e]={type:"description",elementDescriptor:""}}}var mc={name:"Migrate element target to discriminated union",fromVersion:"1.0.6",toVersion:"1.0.7",recursiveKeys:new Set(["results","steps"]),stopOnFailure:!0,execute:async r=>r.map(e=>{switch(e.type){case"PRESET_ACTION":return uc(e.command),e;case"AI_ACTION":{let t=e.commands;for(let n of t??[])uc(n);return e}default:return e}})};import{v4 as qh}from"uuid";var pc={name:"Ensure module steps have ids",fromVersion:"1.0.7",toVersion:"1.0.8",recursiveKeys:new Set(["results","steps"]),stopOnFailure:!0,execute:async r=>r.map(e=>{switch(e.type){case"MODULE":return e.id||(e.id=qh()),e;default:return e}})};import{v4 as hc}from"uuid";var fc={name:"Ensure module steps have ids",fromVersion:"1.0.8",toVersion:"1.0.9",recursiveKeys:new Set(["results","steps"]),stopOnFailure:!0,execute:async r=>r.map(e=>{switch(e.type){case"PRESET_ACTION":{if(!e.command)return e;let t=e.command;return t.id=t.id??hc(),e}case"AI_ACTION":return e.commands&&(e.steps=e.commands.map(t=>({type:"PRESET_ACTION",command:{...t,id:t.id??hc()}})),delete e.commands),e;default:return e}})};var gc={name:"Migrate ai waits to checks",fromVersion:"1.0.9",toVersion:"1.0.10",recursiveKeys:new Set(["results","steps","blocks","elseSteps"]),stopOnFailure:!0,execute:async r=>r.map(e=>{switch(e.type){case"PRESET_ACTION":{if(!e.command)return e;let t=e.command;return typeof t.type!="string"||t.type!=="AI_WAIT"||(t.type="AI_ASSERTION",t.timeout||(t.timeout=10)),e}default:return e}})};import{v4 as Kh}from"uuid";var yc={name:"Add ids to all steps",fromVersion:"1.0.10",toVersion:"1.0.11",recursiveKeys:new Set(["results","steps","blocks","elseSteps"]),stopOnFailure:!0,execute:async r=>r.map(e=>("id"in e&&typeof e.id=="string"||(e.id=Kh()),e))};import{v4 as Sc}from"uuid";var wc={name:"Add ids to all steps",fromVersion:"1.0.11",toVersion:"1.0.12",recursiveKeys:new Set(["results","steps","blocks","elseSteps"]),stopOnFailure:!0,execute:async r=>r.map(e=>{if("id"in e&&typeof e.id=="string")return e;if("condition"in e&&typeof e.condition=="object"&&e.condition){let t=e.condition;t.id||(t.id=Sc())}return e.id=Sc(),e})};var bc={name:"Move env key to steps",fromVersion:"1.0.12",toVersion:"1.0.13",recursiveKeys:new Set(["results","steps","blocks","elseSteps"]),stopOnFailure:!0,execute:async r=>r.map(e=>{if(e.type!=="PRESET_ACTION")return e;let t=e.command;return!t||typeof t.envKey!="string"||(e.envKey=t.envKey,delete t.envKey),e})};var Cc={name:"Migrate AI assertions to preset actions",fromVersion:"1.0.0",toVersion:"1.0.1",recursiveKeys:new Set,execute:async r=>r.map(e=>{if(e.type!=="AI_ASSERTION")return e;let n={type:"PRESET_ACTION",command:{type:"AI_ASSERTION",assertion:e.text,useVision:!1,disableCache:!0}},o={...e,...n};return delete o.text,o}),stopOnFailure:!0};var Uo=new Set(["CLICK","TYPE","SELECT_OPTION"]),Tc={name:"Migrate element descriptor to live in a target object",fromVersion:"1.0.3",toVersion:"1.0.4",recursiveKeys:new Set,execute:async r=>r.map(e=>{let t=e.command,n=t?.type,o=t?.elementDescriptor;return(o!==void 0||Uo.has(n))&&(t.target={elementDescriptor:o??""}),e.commands&&Array.isArray(e.commands)&&e.commands.forEach(i=>{let a=i?.elementDescriptor,l=i?.type;(a!==void 0||Uo.has(l))&&(i.target={elementDescriptor:a??""})}),e.results&&Array.isArray(e.results)&&e.results.forEach(i=>{let a=i.command,l=a?.elementDescriptor,c=a?.type;(l!==void 0||Uo.has(c))&&(a.target={elementDescriptor:l??""}),i.commands&&Array.isArray(i.commands)&&i.commands.forEach(d=>{let m=d?.elementDescriptor,p=d?.type;(m!==void 0||Uo.has(p))&&(d.target={elementDescriptor:m??""})})}),e}),stopOnFailure:!0};var vc={name:"Migrate FAILURE status to FAILED",fromVersion:"1.0.1",toVersion:"1.0.2",recursiveKeys:new Set,execute:async r=>r.map(e=>{let t=e;return t.status==="FAILURE"&&(t.status="FAILED"),typeof t.commands=="object"&&Array.isArray(t.commands)&&t.commands.forEach(n=>{if(n&&typeof n=="object"){let o=n;o?.status==="FAILURE"&&(o.status="FAILED")}}),t}),stopOnFailure:!0};var Ec={name:"Migrate preset step types to use the same",fromVersion:"1.0.2",toVersion:"1.0.3",recursiveKeys:new Set,execute:async r=>r.map(e=>{let t=e.command,n=t?.type;return n?.startsWith("PRESET_")&&(t.type=n.slice(7)),e.commands&&Array.isArray(e.commands)&&e.commands.forEach(s=>{let i=s.type;i?.startsWith("PRESET_")&&(s.type=i.slice(7))}),e.results&&Array.isArray(e.results)&&e.results.forEach(s=>{let i=s.command,a=i?.type;a?.startsWith("PRESET_")&&(i.type=a.slice(7)),s.commands&&Array.isArray(s.commands)&&s.commands.forEach(c=>{let u=c.type;u?.startsWith("PRESET_")&&(c.type=u.slice(7))})}),e}),stopOnFailure:!0};var an=[Cc,vc,Ec,Tc,cc,dc,mc,pc,fc,gc,yc,wc,bc];if(ke!==an[an.length-1].toVersion)throw new Error("Please bump LATEST_VERSION in types package after adding a migration");an.forEach((r,e)=>{if(!$o.valid(r.toVersion)||!$o.valid(r.fromVersion))throw new Error(`Migration '${r.name}' has invalid version`);if(!$o.gt(r.toVersion,r.fromVersion))throw new Error(`Migration '${r.name}' has toVersion <= fromVersion`);if(e===0)return;if(an[e-1].toVersion!==r.fromVersion)throw new Error(`Migration '${r.name}' at index ${e} is not contiguous with previous migration`)});function Jh(r){return r.every(e=>e&&typeof e=="object"&&!Array.isArray(e))}var Ai=async({metadata:r,steps:e,logger:t,toVersion:n})=>{let o=e,{schemaVersion:s,id:i}=r,a=an.findIndex(u=>$o.gt(u.toVersion,s));if(a===-1)return{steps:o,newVersion:s};let l=s;for(let u=a;u<an.length;u++){if(n&&Xh(l,n)){t.debug("Stopping migration early because toVersion was reached");break}let d=an[u],m={id:i,migration:d.name,toVersion:d.toVersion};try{o=await xc(o,d),l=d.toVersion}catch(p){throw t.error({err:p,...m},"Migration failed"),new Error(`Step migration ${d.name} failed: ${p}`)}}let c=Yh(JSON.stringify(e,void 0,2),JSON.stringify(o,void 0,2),{n_surrounding:1});return c.trim()&&t.debug({diffs:c,id:i},"Migration diffs"),{newVersion:l,steps:o}};async function xc(r,e){let t=await e.execute(r);for(let n of t)for(let o of Object.keys(n)){if(!e.recursiveKeys.has(o))continue;let s=n[o];!s||!Array.isArray(s)||Jh(s)&&(n[o]=await xc(s,e))}return t}async function Ac({rawSteps:r,metadata:e,logger:t,callbacks:n}){lc(e,"defaultOnCloud");let o={},{resolvedSteps:s,newSchemaVersion:i}=await Ri({rawSteps:r,metadata:e,logger:t,callbacks:n,resolvedModuleCache:o});return{resolvedTest:{...e,steps:s,schemaVersion:i},moduleIds:Array.from(Object.keys(o))}}async function Ri({rawSteps:r,metadata:e,logger:t,callbacks:n,resolvedModuleCache:o={}}){let{newVersion:s,steps:i}=await Ai({metadata:e,steps:r,logger:t}),a;try{a=Xe.array().parse(i)}catch(c){throw t.error({type:"zod",err:c,newVersion:s,id:e.id,steps:i},"Failed to parse test steps while migrating test"),new Po(`Failed to parse test steps while migrating test: ${c}`,e.id,"entity",{cause:c})}let l=[];for(let c of a)l.push(await _r({step:c,callbacks:n,logger:t,resolvedModuleCache:o}));return{resolvedSteps:l,newSchemaVersion:s}}async function _r({step:r,callbacks:e,logger:t,resolvedModuleCache:n}){switch(r.type){case"AI_ACTION":return r;case"PRESET_ACTION":return r;case"MODULE":{let l=r.moduleId,c=n[l];if(c)return{...c,...r,type:"RESOLVED_MODULE"};let u=await e.onFetchModule({id:l,logger:t});if(!u)throw new Error(`Could not find module with id ${l}`);let{newVersion:d,steps:m}=await Ai({metadata:{id:l,schemaVersion:u.schemaVersion},steps:u.steps,logger:t}),p;try{p=Xe.array().parse(m)}catch(g){throw t.error({type:"zod",err:g,steps:m,newVersion:d,id:l},"Module failed to parse"),g}let f;try{f=await Promise.all(p.map(g=>_r({step:g,callbacks:e,logger:t,resolvedModuleCache:n})))}catch(g){throw t.error({err:g,...r},`Failed to recursively resolve module '${u.name}': ${g}`),g}let h={...u,steps:f};return n[l]=h,{...h,...r,type:"RESOLVED_MODULE"}}case"CONDITIONAL":let o=[];for(let l of r.blocks){let c=[];for(let u of l.steps)c.push(await _r({step:u,callbacks:e,logger:t,resolvedModuleCache:n}));o.push({...l,steps:c})}let s;if(r.elseSteps){s=[];for(let l of r.elseSteps)s.push(await _r({step:l,callbacks:e,logger:t,resolvedModuleCache:n}))}return{...r,blocks:o,elseSteps:s};case"SECTION":case"IFRAME":let i=[];for(let l of r.steps)i.push(await _r({step:l,callbacks:e,logger:t,resolvedModuleCache:n}));return{...r,steps:i};default:return(l=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(r)}}import{cloneDeep as Zh}from"lodash-es";import{v4 as Rc}from"uuid";async function yt(r){let e=Zh(r.steps);return Un({...r,steps:e,moduleStepParents:[],moduleIdParents:[],moduleIdReplacements:new Map,seenModules:new Set})}async function Un({steps:r,...e}){let{seenModules:t,cacheCreationParams:n,moduleIdParents:o,moduleStepParents:s,moduleIdReplacements:i,shouldCreateNewModuleId:a}=e,l={cachesToSave:[],stepsToSave:[],moduleUpdates:[]};for(let c of r)switch(delete c.index,c.type){case"PRESET_ACTION":{let d=c.command;d.id=n?.createNewCacheIds?Rc():d.id,oc(d),"cache"in d&&d.cache&&(n&&(l.cachesToSave=l.cachesToSave.concat(rc({id:d.id,orgId:n.orgId,testId:n.testId,value:Qt.parse(d),moduleIdParents:o,moduleStepParents:s,skipIntermediateEntries:e.skipCacheIntermediateEntries}))),delete d.cache),l.stepsToSave.push({...c,command:d});break}case"RESOLVED_MODULE":{let d=n?.createNewCacheIds?Rc():c.id,m=c.moduleId;if(i.has(m))m=i.get(m);else if(a){let y=await a(c);i.set(c.moduleId,y)}let{cachesToSave:p,stepsToSave:f,moduleUpdates:h}=await Un({...e,steps:c.steps,cacheCreationParams:n?{...n,createNewCacheIds:!1}:void 0,moduleStepParents:[...s,d],moduleIdParents:[...o,m],skipCacheIntermediateEntries:n?.createNewCacheIds});l.moduleUpdates=l.moduleUpdates.concat(h),l.cachesToSave=l.cachesToSave.concat(p),t.has(m)||(t.add(m),l.moduleUpdates.push({...qe.parse(c),steps:Xe.array().parse(f)}));let g={type:"MODULE",moduleId:m,inputs:c.inputs,id:d,skipped:c.skipped,cacheConfig:c.cacheConfig,envKey:c.envKey};l.stepsToSave.push(g);break}case"AI_ACTION":{if(!c.steps){l.stepsToSave.push(c);break}let{stepsToSave:d,cachesToSave:m}=await Un({...e,steps:c.steps});try{c.steps=Ve.array().parse(d)}catch(p){throw new Error(`Only preset actions are allowed in AI actions at the moment: ${p}`)}l.stepsToSave.push(c),l.cachesToSave=l.cachesToSave.concat(m);break}case"CONDITIONAL":{let d=[];for(let p of c.blocks){let{stepsToSave:f,cachesToSave:h,moduleUpdates:g}=await Un({...e,steps:p.steps});d.push({...p,steps:f}),l.cachesToSave=l.cachesToSave.concat(h),l.moduleUpdates=l.moduleUpdates.concat(g)}let m={...c,elseSteps:void 0,blocks:d};if(c.elseSteps){let{stepsToSave:p,cachesToSave:f,moduleUpdates:h}=await Un({...e,steps:c.elseSteps});m.elseSteps=p,l.cachesToSave=l.cachesToSave.concat(f),l.moduleUpdates=l.moduleUpdates.concat(h)}l.stepsToSave.push(m);break}case"IFRAME":case"SECTION":{let{stepsToSave:d,cachesToSave:m,moduleUpdates:p}=await Un({...e,steps:c.steps}),f={...c,steps:d};l.moduleUpdates=l.moduleUpdates.concat(p),l.stepsToSave.push(f),l.cachesToSave=l.cachesToSave.concat(m);break}default:return(d=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(c)}return l}import{cloneDeep as Qh}from"lodash-es";import{stringify as Ic}from"yaml";async function Pc(r,e=new Set){let t={id:r.id,name:r.name,baseUrl:r.baseUrl,schemaVersion:r.schemaVersion,advanced:r.advanced,retries:r.retries,envs:r.envs},n={},o=await ef(r.steps,r.schemaVersion,n,e),s={fileType:te.TEST,...t,steps:o};return{test:Ic(s),modules:n}}async function ef(r,e,t,n){let o=Qh(r);tf(o);let{stepsToSave:s,moduleUpdates:i}=await yt({steps:o});for(let a of i)n.has(a.name)||(t[a.name]=nf(a),n.add(a.name));return s}function tf(r){Ot({steps:r,onPresetAction:e=>{e.index=void 0,e.command.thoughts=void 0},onConditional:e=>{e.index=void 0},onSimpleStepContainer:e=>{e.index=void 0}})}function nf(r){let e=qe.parse(r),t={fileType:te.MODULE,...e,schemaVersion:ke,steps:r.steps};return Ic(t)}var $n=class{constructor(e,t){this.client=e;this.orgId=t}async acquireCacheLock(e){return this.client.acquireCacheLock(e)}async releaseCacheLock(e){return this.client.releaseCacheLock(e)}async setCacheResult(e){return this.client.setCacheResult(e)}async getCacheResult(e){return this.client.getCacheResult(e)}async saveStepCacheEntries(e,t,n){try{await this.client.updateStepCaches({entries:e,testId:t})}catch(o){n.error({err:o},"Failed to save step cache entries")}}async resolveStepCacheEntries(e){let t=await this.client.getStepCacheForTest({testId:e.testId,organizationId:e.organizationId,steps:e.steps,schemaVersion:e.schemaVersion}),{hits:n}=Fn({steps:e.steps,stepCacheEntries:t,logger:e.logger});this.client.updateCacheLastUsedDate(n,e.logger)}async getOrgId(e){return this.orgId}async uploadScreenshot(e){return(await this.client.uploadScreenshot({screenshot:e.toString("base64")})).key}async fetchEnvironment(e,t,n){try{return await this.client.getEnvironment(t)}catch(o){n.warn({err:o},"Error fetching environment, continuing...");return}}};var Ii="v1",Lt=class extends Dn{type="API_CLIENT";sms={send:this.sendSms.bind(this),fetchLatest:this.fetchLatestSms.bind(this)};email={fetchLatest:this.fetchLatestEmail.bind(this)};constructor(e){super(e)}async sendSms(e){await this.sendRequest(`/${Ii}/tools/sms/send`,{method:"POST",body:e})}async fetchLatestSms(e){try{return await this.sendRequest(`/${Ii}/tools/sms/fetchLatest`,{method:"POST",body:e})}catch(t){throw t instanceof kn&&t.status===404?new Error("No recent SMS messages found."):t}}async fetchLatestEmail(e){try{return this.sendRequest(`/${Ii}/tools/email/fetchLatest`,{method:"POST",body:e})}catch(t){throw t instanceof kn&&t.status===404?new Error("No matching emails found."):new Error(`Failed to fetch latest emails: ${t.message}`)}}};import Rw from"body-parser";import Iw from"cors";import Ea from"express";import Pw from"http";import Ow from"open";import{Server as Ey}from"socket.io";import{cloneDeep as rf}from"lodash-es";var Pi=r=>{let e=[];for(let t of r){let n;switch(t.type){case"PRESET_ACTION":{n={before:t.beforeTestContext,after:t.afterTestContext};break}case"CONDITIONAL":case"IFRAME":case"SECTION":case"AI_ACTION":case"MODULE":{n={before:t.beforeTestContext,after:t.afterTestContext,nestedResults:Pi(t.results)};break}default:return(s=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(t)}e.push(n)}return e},Bo=class{results;constructor(){this.results=[]}setResults(e){this.results=Pi(e)}setIndividualResult(e,t){let n=Pi([e])[0],o=this.results;for(let i=0;i<t.length-1;i++){let a=t[i];o[a]===void 0&&(o[a]={nestedResults:[]});let l=o[a];l.nestedResults===void 0&&(l.nestedResults=[]),o=l.nestedResults}let s=t[t.length-1];o[s]=n}getContextCopyAtIndices(e){let t=this.getContextAtIndicesHelper(e);if(t!==void 0)return rf(t)}getContextAtIndicesHelper(e){let t=this.results;for(let o=0;o<e.length-1;o++){let s=e[o],i=t[s];if(i===void 0)return t.length>0?t[t.length-1].after:void 0;if(i.nestedResults===void 0)return i.before;t=i.nestedResults}let n=e[e.length-1];if(n>t.length&&(n=t.length),n===0)return t[0]?.before;for(let o=n-1;o>=0;o--)if(t[o]?.after)return t[o].after}};var of={showOverlay:!1},Oi=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:s,browserbaseSessionId:i}){return this.sessions.set(s,{controller:e,context:t,cleanup:n,clientIp:o,executionCancelled:!1,resultsManager:new Bo,browserbaseSessionId:i,browserBehavior:of}),s}removeSession(e,t){(async()=>{let o=this.sessions.get(e);if(!o)return;this.releaseCapacityByIp(o.clientIp);let{controller:s}=o;try{await s.browser.cleanup()}catch(i){t.error({err:i},"Error cleaning up browser in global state manager")}try{await o.cleanup?.()}catch(i){t.error({err:i},"Error running cleanup function in global state manager")}this.sessions.delete(e)})()}getSession(e){return this.sessions.get(e)}cancelExecution(e){let t=this.sessions.get(e);t&&(t.executionCancelled=!0)}resumeExecution(e){let t=this.sessions.get(e);t&&(t.executionCancelled=!1)}},_=new Oi;var sf=200;function Oc(r,e,t){let n=Date.now(),o=-1,s=0,i=Date.now(),a,l,c=async m=>{if(!m.closed){if(s>0&&Math.random()>=1/Math.max(s,8)){s<8&&t.error({sessionId:e},"Dropping screenshot due to previous failures");return}try{let p;(!a||!l||Date.now()-i>=1500)&&(a=await m.getViewport(),l=await m.getFrameSrcUrls(),i=Date.now(),p=m.retrieveAndClearConsoleLogs()),r.emit("browserState",{logsPerPage:p,viewport:a,buffer:await m.screenshot({retries:0,timeout:1e3,scale:"device",quality:75}),url:m.url(),iframeSrcUrls:l}),n=Date.now(),s=0}catch(p){if(!r.connected)return;let f=p instanceof Error?p.message:`${p}`;if(f.includes("Frame was detached")||f.includes("Not attached to an active page")||f.includes("browser has been closed"))return;s++,t.error({err:p,sessionId:e},"Error taking screenshot")}finally{r.connected&&Date.now()-n>15e3&&Date.now()-o>3e4&&(t.error({sessionId:e},"Screenshots to client are stale"),o=Date.now())}}},u={timer:void 0},d=()=>{let p=_.getSession(e)?.controller?.browser;if(!p||p.closed){t.debug("Clearing browser state socket cron due to the browser being closed"),clearInterval(u.timer);return}c(p)};return u.timer=setInterval(d,sf),u}var af=({metadata:r,logger:e})=>{let{sessionId:t}=r;return async()=>{if(e.info({sessionId:t},"Cancel event received"),!_.getSession(t))throw new Error("No active session found");_.cancelExecution(t)}},Lc={event:"cancel",createHandler:af};var lf=({metadata:r,logger:e})=>{let{sessionId:t}=r;return n=>{e.info({sessionId:t,reason:n},`Disconnect event received (${n})`),_.removeSession(t,e)}},Mc={event:"disconnect",createHandler:lf};import{randomUUID as Sf}from"crypto";import{faker as cf}from"@faker-js/faker";import df from"assert";import uf from"axios";import mf from"moment";import*as pf from"otpauth";import hf,{TimeoutError as ff}from"p-timeout";import gf from"pg";var yf=Object.getPrototypeOf(async function(){}).constructor;async function Nc(r,e,t){let n=e.code;e.options.fragment&&(n=`return ${e.code}`);let{results:o,env:s,inputs:i}=e.bindings,a=e.tools,l={},c=(g,y)=>{s[g]=y,l[g]=y},u;n.includes("Octokit")&&(u=(await import("@octokit/rest")).Octokit);let d;n.includes("createAppAuth")&&(d=(await import("@octokit/auth-app")).createAppAuth);let m=async()=>await Promise.resolve(new yf("axios","moment","faker","assert","pg","Octokit","createAppAuth","OTPAuth","env","results","inputs","setVariable","sendSms","waitForLatestSms","email","sms",n)(uf,mf,cf,df,gf,u,d,pf,s,o,i??{},c,y=>a.sms.send(y),y=>a.sms.fetchLatest(y),a.email,a.sms)),p=!0,f,h;try{f=await hf(m(),{milliseconds:e.options.timeoutMs,message:`Timeout of ${e.options.timeoutMs}ms exceeded for code execution`}),t.debug(`[${r}] Got execution result: ${JSON.stringify(f)}`),t.debug(`[${r}] Got variable updates: ${JSON.stringify(l)}`)}catch(g){t.error(`[${r}] Error executing code: ${g}`),p=!1,g instanceof ff?h=`Timeout of ${e.options.timeoutMs}ms exceeded for code execution`:h=g instanceof Error?g.message:`${g}`}return{result:f,variableUpdates:l,success:p,error:h}}async function _c({code:r,fragment:e,context:t,localTools:n,logger:o,timeoutMs:s=Mn}){let i=Sf();return Nc(i,{code:r,options:{fragment:e,timeoutMs:s},bindings:t.toObjectCopy(),tools:n},o)}import{randomUUID as wf}from"crypto";import bf from"p-timeout";var kc=process.env.GCP_JS_EVAL_FUNCTION_ENDPOINT;async function Dc({code:r,fragment:e,context:t,logger:n,timeoutMs:o=Mn,retries:s=1}){if(!kc)throw new Error("GCP_JS_EVAL_FUNCTION_ENDPOINT environment variable not set");let i,a,l=0;for(;l<=s;){l++;let u={id:wf(),code:r,fragment:e,state:t.toObjectCopy(),timeoutMs:o};n.debug(u,"Sending request to code evaluation server");try{if(i=await bf(fetch(kc,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(u)}),{milliseconds:o,message:`Timeout of ${o}ms exceeded for code execution`}),!i)throw new Error("Got empty response from code evaluation server");if(!i.ok)throw new Error(`Code evaluation server returned error code ${i.status}`);a=void 0;break}catch(d){a=d}}if(a)throw a;if(!i)throw new Error(`An unexpected code evaluation error occurred${a?`: ${a}`:""}`);let c;try{c=Cl.parse(await i.json()),n.debug({response:c},"Response from code evaluation server")}catch(u){throw new Error(`Code evaluation server returned invalid response: ${u}`)}if(c.error)throw new Error(`Code evaluation server returned error: ${c.error}`);return c}async function Bn(r){let e;if(process.env.GCP_JS_EVAL_FUNCTION_ENDPOINT)e=await Dc(r);else if(r.localTools)e=await _c({...r,localTools:r.localTools});else throw new Error("No code evaluation environment available");if(e.error)throw new Error(`Code evaluation returned error: ${e.error}`);if(e.variableUpdates)for(let[t,n]of Object.entries(e.variableUpdates))r.context.setVariable(t,n);return e.result}async function Ze(r){let{s:e,context:t,logger:n,timeoutMs:o=Mn,retries:s=1}=r,i=/{{(.*?)}}/g,a=e.matchAll(i),l=e;for(let c of a){if(c.length<2)continue;let u=c[1].trim(),d;try{d=await Bn({code:u,fragment:!0,context:t,timeoutMs:o,logger:n,retries:s,localTools:r.localTools})}catch(p){throw n.error({err:p,value:e},"Error evaluating template string"),p}let m=typeof d=="string"?d:`${d}`;m=m.replace(/\$/g,"$$$$"),m=m.replace(/\\/g,"\\\\"),l=l.replace(c[0],m)}return n.debug({s:e,result:l},"Substituted template string"),l}var DO=process.env.MAILINATOR_API_KEY;import $O from"p-timeout";import"twilio";import{diff as Uf}from"deep-object-diff";async function kr(r,e,t,n,o,s){try{let[i,a]=await Promise.all([t?o(t):void 0,n?o(n):void 0]);i&&(r&&(r.beforeScreenshot=i),e.beforeScreenshot=i),a&&(r&&(r.afterScreenshot=a),e.afterScreenshot=a)}catch(i){s.debug({err:i},"Error saving screenshot to S3")}}var zo=async r=>{let e=r.presetParams.step,{logger:t,controller:n,context:o}=r.fixtures,{takeScreenshots:s}=r.options,{testMetadata:i}=r.inputs,a=r.callbacks.test,l=n.browser.url(),c=new Date,u;if(s)try{u=await n.browser.screenshot({retries:1,clearHighlights:!0})}catch(h){t.debug({err:h},"Failed to take screenshot before step, likely because the page is still loading. This is non-fatal and does not affect the test.")}let d,m,p,f=Io();try{let h=await n.executePresetStep(f,e.command,o,i.advanced.disableAICaching,r.callbacks.test.isExecutionCancelled);if(h.beforeScreenshotOverride&&(u=h.beforeScreenshotOverride),p=h.afterScreenshotOverride,h.fail)throw new I("ActionFailureError",h.thoughts||"Preset action failed.");let g=new Date,y=n.browser.url();m={beforeUrl:l,afterUrl:y,startedAt:c,finishedAt:g,viewport:await n.browser.getViewport(),status:"SUCCESS"},d={...e,message:h.thoughts??"Successfully executed preset action.",beforeUrl:l,afterUrl:y,finishedAt:g,startedAt:c,status:"SUCCESS",data:h.data,results:[m],details:f.details},"assertion"in e.command&&(d.message=h.thoughts||"Assertion passed."),(e.command.type==="AI_EXTRACT"||e.command.type==="JAVASCRIPT")&&e.command.envKey&&o.setVariable(e.command.envKey,d.data)}catch(h){t.error({err:h},`Failed executing preset step ${Wt(e.command)}`);let g=n.browser.url(),y=new Date,S=h instanceof Error?h.message:`${h}`;m={beforeUrl:l,afterUrl:g,startedAt:c,finishedAt:y,viewport:await n.browser.getViewport(),status:h instanceof st?"CANCELLED":"FAILED",message:S},d={...e,startedAt:c,finishedAt:y,beforeUrl:l,afterUrl:g,status:h instanceof st?"CANCELLED":"FAILED",message:S,failureReason:h instanceof I?h.reason:void 0,results:[m],details:f.details}}if(s&&!p)try{p=await n.browser.screenshot({retries:1})}catch(h){t.debug({err:h},"Failed to take screenshot after step, likely because the page is still loading. This is non-fatal and does not affect the test.")}return r.work.asyncTasks.push(kr(m,d,u,p,a.onSaveScreenshot,t)),d};function St(r){let{result:e,nestedResults:t}=r;if(!r.nestedResults.length)return;let{firstMetadata:n,lastMetadata:o}=Tf(t);vf(e,n,o);let s=[...r.asyncTasks];r.asyncTasks.push((async()=>{try{await Ef(s,e,n,o)}catch(i){r.logger.error({result:r.result,err:i},"Error hoisting scalar result metadata")}})())}function Tf(r){let e=r[0],t;for(;;){switch(e.type){case"PRESET_ACTION":{t=e;break}case"CONDITIONAL":if(e.assertion){t=e;break}break;case"AI_ACTION":case"MODULE":case"SECTION":case"IFRAME":if(!e.results.length){t=e;break}e=e.results[e.results.length-1];break;default:return(i=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(e)}if(t)break}let n=r[r.length-1],o;for(;;){switch(n.type){case"PRESET_ACTION":{o=n;break}case"CONDITIONAL":case"AI_ACTION":case"MODULE":case"SECTION":case"IFRAME":if(!n.results.length){o=n;break}n=n.results[n.results.length-1];break;default:return(i=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(n)}if(o)break}return{firstMetadata:t,lastMetadata:o}}function vf(r,e,t){e&&(r.beforeUrl=e.beforeUrl),t&&(r.afterUrl=t.afterUrl,r.data=t.data,t.status!=="SUCCESS"&&(r.message=t.message))}async function Ef(r,e,t,n){await Promise.allSettled(r),t&&(e.beforeScreenshot=t.beforeScreenshot),n&&(e.afterScreenshot=n.afterScreenshot)}import Li from"os";function Fc(r){let e=()=>{try{let t=xf(),n=Af();r.debug({memory:t,cpu:n},"Got machine resource usage metrics")}catch{}};return e(),setInterval(e,15e3)}function xf(){let r=Li.totalmem(),e=Li.freemem(),t=r-e;return{totalMemory:r,freeMemory:e,usedMemory:t}}function Af(){let r=Li.cpus(),e=0,t=0,n=0,o=0,s=0,i=0;for(let a of r)e+=a.times.user,t+=a.times.nice,n+=a.times.sys,o+=a.times.idle,s+=a.times.irq;return i=e+t+n+o+s,{user:e/i*100,nice:t/i*100,sys:n/i*100,idle:o/i*100,irq:s/i*100,total:100-o/i*100}}var Uc=async r=>{let{step:e,resolvedInputs:t}=r.moduleParams,{logger:n,context:o,storage:s,codeEvalTools:i}=r.fixtures,{orgId:a,testMetadata:l}=r.inputs;Object.keys(t).length>0&&(o.setInputs(t),n.debug({inputs:t,moduleId:e.moduleId},"Set module inputs"));let c,u;if(e.cacheConfig){let d=e.cacheConfig.cacheKey||e.defaultCacheKey||"",m=await Ze({s:d,context:o,logger:n,localTools:i}),p={orgId:a,cacheKeys:[m,...Object.entries(t).map(([h,g])=>`${h}:${g}`)]};n.debug({cacheKey:d,keyParams:p},"Module cache key params");let f=Date.now();for(;Date.now()-f<kl;){let h=await s.getCacheResult(p);if(h){n.info({cacheResult:h},"Got result from module execution cache"),c=Wo(e,t,"SUCCESS"),c.message="Used cached module result.",c.data=JSON.parse(h);break}let g=await s.acquireCacheLock({keyParams:p,clientMetadata:`testId:${l.id}`});if(g.acquired){u=g.keyPrefix,n.info({cacheKeyPrefix:u,cacheKey:d,keyParams:p},"Acquired cache lock and proceeding with module execution");break}await new Promise(y=>setTimeout(y,2500+Math.random()*1e4))}}try{c||(c=await Rf(r))}finally{if(u!==void 0){let d=e.cacheConfig.cacheExpiryMs;if(d===Al&&(d=e.defaultCacheTtl??Rl),c&&c.status==="SUCCESS"){let m=JSON.stringify(c.data===void 0?"":c.data);n.debug({cacheKeyPrefix:u,ttlMs:d,cacheResult:m},"Setting module cache result"),await s.setCacheResult({result:m,keyPrefix:u,ttlMs:d})}await s.releaseCacheLock(u)}}return c},Rf=async r=>{let{step:e}=r.moduleParams,t=Wo(e,r.moduleParams.resolvedInputs,"SUCCESS"),{status:n,results:o}=await r.executeStepList({...r,listParams:{steps:e.steps,containerName:`module ('${e.name}')`}});return t.results=o,t.status=n,t.finishedAt=new Date,St({asyncTasks:r.work.asyncTasks,nestedResults:o,result:t,logger:r.fixtures.logger}),t};function Wo(r,e,t){let n={};return Object.entries(e).forEach(([s,i])=>{n[s]=JSON.stringify(i)}),{type:"MODULE",id:r.id,moduleId:r.moduleId,moduleName:r.name,startedAt:new Date,cacheConfig:r.cacheConfig,inputs:n,results:[],finishedAt:new Date,status:t}}async function $c(r,e,t,n){let o={};try{for(let s of r.parameters??[]){let i=r.inputs?.[s]??r.defaultParameters?.[s];if(!i){t.warn(`No value or default found for parameter '${s}' that is required by module '${r.name}'`);continue}o[s]=await Bn({code:i,fragment:!0,context:e,logger:t,localTools:n})}return o}catch(s){throw new I("UserConfigurationError",`Failed to evaluate module inputs: ${s}`)}}async function ln(r,e){let t=new Date;try{return await e()}catch(n){let o=new Date,s;if(n instanceof I?s=`${n}`:s=`An unexpected error occurred: ${n.message}`,r.type==="RESOLVED_MODULE"){let i=Wo(r,{},"FAILED");return i.message=s,i.startedAt=t,i.finishedAt=o,i}return{...r,startedAt:t,finishedAt:o,status:"FAILED",data:null,message:s,results:[]}}}async function Ho(r,e){let t=!1;try{return r&&!r.healingDisabled&&(r.healingDisabled=!0,t=!0),await e()}finally{r&&t&&(r.healingDisabled=void 0)}}import{randomUUID as jo}from"crypto";var zc=async r=>{let e=await If(r);return St({asyncTasks:r.work.asyncTasks,result:e,nestedResults:e.results,logger:r.fixtures.logger}),e},If=async r=>{let e=r.aiStepParams.step,t=e.index,{testMetadata:n,steps:o}=r.inputs,{takeScreenshots:s}=r.options,{controller:i,context:a,logger:l}=r.fixtures,{test:c,step:u}=r.callbacks;if(t===void 0)throw new Error("Attempted to execute AI action step without index");i.resetHistory();let d={...e,startedAt:new Date,finishedAt:new Date,results:[],status:"RUNNING",beforeTestContext:a.toRedactedDisplayCopy()};e.steps=e.steps||[];let m=e.steps&&e.steps.length>0&&e.steps[e.steps.length-1]?.command.type==="SUCCESS";if(m)try{let{status:f,results:h}=await r.executeStepList({...r,listParams:{steps:e.steps,containerName:"AI action"}});return d.finishedAt=new Date,d.status=f,d.results=h,d}catch(f){l.warn({err:f},"Failed executing saved AI action steps, attempting to re-generate...")}e.steps=[];let p=0;try{for(;;){if(p>12)throw new Error(`Exceeded max number of commands per step (${12})`);let f=t+p+1;if(c.isExecutionCancelled?.())return d.status="CANCELLED",d.finishedAt=new Date,u.onCancelled?.({index:f,message:d.message||"AI step cancelled.",output:d}),d;let h,g=new Date,y=a.toRedactedDisplayCopy(),S;if(s)try{S=await i.browser.screenshot({clearHighlights:!0})}catch(E){l.debug({err:E},"Failed to take screenshot before AI command, likely because the page is still loading. This is non-fatal.")}l.info(`Generating new sub-command ${p} within AI step`);let b;try{if(b=await i.promptToCommand(e.type,e.text,n.advanced.disableAICaching),b.command.type==="FAILURE")throw new Error(b.command.thoughts);h=b.command,l.debug({command:h},"Generated new command")}catch(E){if(l.error({err:E,commandIndex:p},"Failed to generate command within AI step"),p===0)throw E;{let P="Stopping command generation prematurely since no progress can be made";l.info({command:h},P),h={id:jo(),type:"SUCCESS",thoughts:P}}}let C={id:jo(),type:"PRESET_ACTION",index:f,command:h};Of({newStep:C,controller:i,currentStep:e,pageContext:b?.context,logger:l,onCommandExecuted:u.onCommandExecuted,currentIndex:p,globalSubStepIndex:f}),u.onCommandGenerated?.({index:f,step:C,message:Si[h.type]||`Unknown command (${h.type})`});let v={beforeUrl:i.browser.url(),startedAt:g,viewport:await i.browser.getViewport(),finishedAt:new Date,status:"SUCCESS"};l.info(`Executing sub-command ${p} within AI step: ${Wt(h)}`);try{let E=await i.executeCommand(h,a,m&&n.advanced.disableAICaching,m);l.info(`AI sub-command ${p} completed successfully`),v.elementInteracted=E.elementInteracted;let P;if(s)try{P=await i.browser.screenshot({})}catch(O){l.debug({err:O},"Failed to take screenshot after AI command, likely because the page is still loading. This is non-fatal.")}v.afterUrl=i.browser.url(),v.finishedAt=new Date;let A={status:"SUCCESS",startedAt:v.startedAt,finishedAt:v.finishedAt,data:E.data,results:[v],beforeTestContext:y,afterTestContext:a.toRedactedDisplayCopy(),...C};if(r.work.asyncTasks.push(kr(v,A,S,P,c.onSaveScreenshot,l)),d.results.push(A),e.steps[p]=C,Lf(o,r.inputs,f),u.onCommandExecuted?.({index:f,output:{...A,message:h.thoughts??E.thoughts??"Successfully executed preset action."},step:C}),h.type==="SUCCESS"){d.finishedAt=new Date,d.status="SUCCESS",d.message=E.thoughts??"All commands completed.",d.afterTestContext=a.toRedactedDisplayCopy();break}if(E.succeedImmediately&&!m){d.finishedAt=new Date,d.status="SUCCESS",d.message=`Marked step as completed due to reason: ${E.succeedImmediatelyReason}`,d.afterTestContext=a.toRedactedDisplayCopy(),h={id:jo(),type:"SUCCESS",thoughts:E.succeedImmediatelyReason};let O={id:jo(),type:"PRESET_ACTION",command:h};e.steps.push(O),u.onCommandExecuted?.({index:f+1,output:{...A,message:d.message},step:O}),d.results.push({...A,...O});break}}catch(E){let P=E instanceof Error?E.message:`${E}`,A=E instanceof I?E.reason:void 0;v.status="FAILED",v.message=P,v.finishedAt=new Date,v.afterUrl=i.browser.url();let O;try{O=await i.browser.screenshot({})}catch(Z){l.debug({err:Z},"Failed to take screenshot after AI command error, likely because the page is still loading. This is non-fatal.")}let M={id:h.id,status:"FAILED",startedAt:v.startedAt,finishedAt:v.finishedAt,type:"PRESET_ACTION",results:[v],message:P,failureReason:A,command:h};r.work.asyncTasks.push(kr(v,M,S,O,c.onSaveScreenshot,l)),d.results.push(M),d.status="FAILED",d.finishedAt=new Date,d.message=P,d.failureReason=A;break}p++}}catch(f){d.message=f instanceof Error?f.message:`${f}`,d.finishedAt=new Date,d.status="FAILED"}return d.status==="SUCCESS"?(d.data=d.results[d.results.length-1]?.data,u.onSuccess?.({index:t,message:d.message||"AI step succeeded.",output:d})):u.onFailure?.({index:t,message:d.message||"AI step errored.",output:d}),d};async function Pf(r,e,t){let n=t.id;if(!n||t.id<=0)throw new Error("Attempted to get reverse mapping for command with no a11y id target");return r.getReverseMappedTarget(e,n,!0)}async function Of({controller:r,currentIndex:e,globalSubStepIndex:t,currentStep:n,newStep:o,pageContext:s,onCommandExecuted:i,logger:a}){if(!s)return;let l=o.command;if("target"in l&&l.target&&"cache"in l&&l.cache){await new Promise(c=>setTimeout(()=>c(),100));try{let c=await Pf(r,s,l.cache.target);l.target={elementDescriptor:c,type:"description"},n.steps[e]=o,i?.({index:t,step:o})}catch(c){a.warn({err:c,currentIndex:e,currentStep:n},"Failed to generate element description, continuing...")}}}function Lf(r,e,t){_o(r),e.toIndex&&e.toIndex>=t&&e.toIndex++}async function Wc(r){let{step:e}=r.conditionalParams,{logger:t}=r.fixtures,n=new Date,o=e.elseSteps,s=!0,i=[],a,l=Io();for(let m=0;m<e.blocks.length;m++){t.info(`Evaluating condition ${m} in conditional step`);let p=e.blocks[m];try{let f=await zo({...r,presetParams:{step:p.assertion}});i.push(f),t.info(`Condition ${m} resolved to true, executing the corresponding ${p.steps.length} steps`),s=!1,o=p.steps,a=f}catch(f){t.info({err:f},`Condition ${m} resolved to false`)}}if(o)s&&t.info("No conditions resolved to true, executing the else block steps");else return t.warn("No conditions resolved to true and no else block was provided, causing the entire conditional step to be skipped"),{...e,status:"SUCCESS",startedAt:n,data:i[i.length-1]?.data,message:i[i.length-1]?.message,results:[],finishedAt:new Date,details:l.details};t.info(`Executing ${o.length} steps in the selected conditional block`);let c=await r.executeStepList({...r,listParams:{steps:o,containerName:"conditional block"}}),d={...e,assertion:a,...c,startedAt:n,finishedAt:new Date};return St({asyncTasks:r.work.asyncTasks,nestedResults:[...i,...c.results],result:d,logger:t}),d}async function Hc(r){let{step:e}=r.frameParams,{logger:t,controller:n}=r.fixtures,o=new Date,s=n.browser.getActiveFrame();n.browser.setActiveFrame(e.identifier);let i;try{i=await r.executeStepList({...r,listParams:{steps:e.steps,containerName:"frame step list"}})}finally{n.browser.setActiveFrame(s)}let l={...e,...i,startedAt:o,finishedAt:new Date};return St({asyncTasks:r.work.asyncTasks,nestedResults:i.results,result:l,logger:t}),l}import{randomUUID as Go}from"crypto";import Mf from"fast-json-patch";import{cloneDeep as Nf}from"lodash-es";async function jc(r){let e=r.failedResults,t=[],{sectionParams:n,fixtures:o,work:s,startingUrl:i,startingContextSnapshot:a}=r,{step:l}=n,{controller:c}=o,u=l?.autohealingConfig,d=u?.restartBehavior??{type:"GO_TO_SECTION_START"},m=u?.attempts??1;for(let p=0;p<m;p++){if(!e.terminalResult?.message)throw new Error("No error message in terminal result");let f=Nf(l.steps);await Promise.allSettled(s.asyncTasks??[]);let h=await c.runSectionAutohealing({results:e.results,errorMessage:e.terminalResult?.message,goal:l.description});for(let S of h.patches)f=Mf.applyOperation(f,S).newDocument;let g=le.fromSnapshot({snapshot:a,environmentVariables:o.context.getVariablesFromEnvironmentCopy()});await _f({controller:c,context:g,restartConfig:d,startingUrl:i});let y=await Ho(r.work,()=>r.executeStepList({...r,fixtures:{...r.fixtures,context:g},listParams:{steps:f,containerName:"auto-healed step list"}}));if(t.push(y.results),y.status==="SUCCESS")return{successfulHealing:{proposedStep:{...l,steps:f},listResult:y,context:g},healingAttempts:t};e=y}return{healingAttempts:t}}async function _f({controller:r,restartConfig:e,context:t,startingUrl:n}){switch(e.type){case"NAVIGATE_URL":{let o={id:Go(),type:"PRESET_ACTION",command:{id:Go(),type:"NAVIGATE",url:e.url}};await r.executePresetStep(null,o.command,t,!1);break}case"GO_TO_SECTION_START":{let o={id:Go(),type:"PRESET_ACTION",command:{id:Go(),type:"NAVIGATE",url:n}};await r.executePresetStep(null,o.command,t,!1);break}}}function Gc(r,e){switch(r||(r="ON_FAILURE"),r){case"ALWAYS":return!0;case"ON_FAILURE":return!0;case"ON_ACTION_FAILURE":return!(!e||e.type==="PRESET_ACTION"&&Va(e.command.type))}}async function Vc(r){let{step:e}=r.sectionParams,{logger:t,controller:n,context:o}=r.fixtures,s=new Date,i=n.browser.url(),a=o.toObjectCopy(),l=async()=>r.executeStepList({...r,listParams:{steps:e.steps,containerName:"section step list"}}),c=e.autohealingConfig?await Ho(r.work,l):await l(),u,d;if(c.status==="FAILED"&&e.autohealingConfig&&!r.work.healingDisabled&&Gc(e.autohealingConfig.trigger,c.terminalResult)){let p=await jc({...r,startingContextSnapshot:a,startingUrl:i,failedResults:c});p.successfulHealing&&(u=p.successfulHealing.proposedStep,c=p.successfulHealing.listResult,r.fixtures.context=p.successfulHealing.context),d=p.healingAttempts}let m={...e,...c,startedAt:s,finishedAt:new Date,proposedStep:u,healingAttempts:d};return St({asyncTasks:r.work.asyncTasks,nestedResults:c.results,result:m,logger:t}),m}async function cn(r){let{results:e=[],containerName:t,steps:n}=r.listParams,{logger:o,context:s,controller:i,codeEvalTools:a}=r.fixtures,{step:l,test:c}=r.callbacks,{fromIndex:u,toIndex:d}=r.inputs,m=r.work,p=[],f="SUCCESS",h,g=0;for(g;g<n.length;g++){let y=n[g],S,b=xi(y),C=y.index;if(C===void 0)throw new Error(`Executing step without index: ${b}`);if(d&&C>d)break;if(c.isExecutionCancelled?.()){if(f="CANCELLED",l.onCancelled?.({index:C,output:{status:"CANCELLED",message:"Execution cancelled.",startedAt:new Date,finishedAt:new Date}}),e.length){let M=e[e.length-1];M.status="CANCELLED",M.message="Cancelled by user signal.",h=M}break}if(y.skipped)continue;if(u&&C<u&&(y.type==="PRESET_ACTION"||Do([y])<u))continue;o.info(`Executing step ${g+1}/${n.length} in ${t}: ${b}`),l.onStarted?.(C);let v=s.toRedactedDisplayCopy(),E=i.browser.url(),P,A;switch(y.type){case"PRESET_ACTION":{P="Preset action",A=await ln(y,()=>zo({...r,presetParams:{step:y}}));break}case"AI_ACTION":{P="AI action",A=await ln(y,()=>zc({...r,aiStepParams:{step:y},executeStepList:cn}));break}case"RESOLVED_MODULE":{P=`Module (${y.name})`;let M=new le({baseUrl:i.browser.baseUrl,currentUrl:i.browser.url(),dynamicVariables:s.getDynamicVariablesCopy(),variablesFromEnvironment:s.getVariablesFromEnvironmentCopy(),envName:s.getEnvName()});A=await ln(y,async()=>{let Z=await $c(y,s,o,a);return Uc({...r,executeStepList:cn,fixtures:{...r.fixtures,context:M},moduleParams:{step:y,resolvedInputs:Z}})});break}case"CONDITIONAL":{P="Conditional step",A=await ln(y,()=>Wc({...r,conditionalParams:{step:y},executeStepList:cn}));break}case"IFRAME":{P="Frame step",A=await ln(y,()=>Hc({...r,frameParams:{step:y},executeStepList:cn}));break}case"SECTION":{P="Section";let M=await ln(y,()=>Vc({...r,sectionParams:{step:y},executeStepList:cn}));"proposedStep"in M&&M.proposedStep&&(S=M.proposedStep,M.proposedStep=void 0,m&&(m.autoHealed=!0)),A=M;break}default:return(Z=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(y)}S?p.push(S):p.push(y),A.beforeUrl=A.beforeUrl??E,A.beforeTestContext=v,s.setResult(g,A.data),y.envKey&&s.setVariable(y.envKey,A.data);let O=i.browser.url();if(s.setCurrentUrl(O),A.afterUrl=A.afterUrl??O,A.afterTestContext=s.toRedactedDisplayCopy(),Df(P,C,A,r.callbacks,o,r.work),e.push(A),A.status!=="SUCCESS"){f=A.status,h=A;break}}return{status:f,results:e,terminalResult:h,proposedSteps:p}}async function kf(r,e){r&&e?.({results:r.results})}function Df(r,e,t,n,o,s){let{step:i,test:a}=n,l=r.toLowerCase(),c=r.charAt(0).toUpperCase()+r.slice(1);switch(t.status){case"SUCCESS":i.onSuccess?.({index:e,step:"command"in t?t:void 0,message:t.message??`${c} executed successfully.`,output:Ro.parse(t)});break;case"FAILED":i.onFailure?.({index:e,message:t.message??`${c} failed.`,output:Ro.parse(t)});break;case"CANCELLED":i.onCancelled?.({index:e,message:t.message??`${c} cancelled.`,output:Ro.parse(t)});break;default:throw new Error(`Unexpected ${l} status: ${t.status}`)}t.status==="SUCCESS"&&s&&kf(s,a.onUpdateRun)}var Dr=async r=>{r.fixtures.logger=r.fixtures.logger.child({orgId:r.inputs.orgId,runId:r.inputs.runId,testId:r.inputs.testMetadata.id});let e;e=Fc(r.fixtures.logger),_o(r.inputs.steps);let t;try{return t=await Ff(r),t}finally{if(clearInterval(e),ic(r.inputs.steps),await r.callbacks.test.onTestComplete?.(),t?.status==="PASSED")try{await r.callbacks.test.onTestSuccess?.(r.inputs.steps)}catch(n){r.fixtures.logger.warn({err:n},"Error running test success handler, continuing...")}}},Ff=async r=>{let{runId:e,testMetadata:t,fromIndices:n,toIndices:o,indicesFilter:s,steps:i}=r.inputs,{logger:a,controller:l}=r.fixtures;a.info(`Starting run ${e} for test '${t.name}'`);let c=i,u="test";if(n){let y=ko(i,n);if(!y)throw new Error(`Could not find starting step using indices: ${n}`);r.inputs.fromIndex=y.index,a.debug({fromIndices:n,fromStep:y},"Identified starting step using fromIndices"),u="partial steps list"}if(o){let y=ko(i,o);if(!y)throw new Error(`Could not find step at indices: ${o}`);let S=Do([y]);r.inputs.toIndex=S,a.debug({toIndices:o,toStep:y,maxIndexUnderToStep:S},"Identified ending step using toIndices"),u="partial steps list"}if(s){let y=ko(i,s);if(!y)throw new Error(`Could not find ending step at indices: ${r.inputs.indicesFilter}`);c=[y],a.debug({steps:i,indicesFilter:s},"Filtered steps to run based on exact indices filter"),u="filtered step"}let d=[],m={results:d,healingDisabled:!!s||!!n||!!o||void 0,asyncTasks:[]},{status:p,terminalResult:f,proposedSteps:h}=await cn({...r,work:m,listParams:{steps:c,containerName:u,results:d}});if(r.options.takeScreenshots&&await Promise.allSettled(m.asyncTasks),s&&d.length){let y=d[0];if(y.beforeTestContext&&y.afterTestContext){let S=le.fromSnapshot({snapshot:y.beforeTestContext,environmentVariables:r.fixtures.context.getVariablesFromEnvironmentCopy()}),b=r.fixtures.context.getResult(0);S.setResult(s[s.length-1],b),y.afterTestContext={...y.afterTestContext,results:S.getResultsCopy()}}}let g;return r.options.consumeDebuggingData&&(g={logsPerPage:sc(l.browser.retrieveAndClearConsoleLogs())}),r.callbacks.test.onUpdateRun?.({results:d,debugData:g}),p==="FAILED"?{status:"FAILED",results:d,failedStepResult:f}:(h&&m.autoHealed&&await r.callbacks.test.onProposedTestSteps?.({testId:t.id,orgId:r.inputs.orgId,runId:r.inputs.runId,steps:h}),{status:"PASSED",results:d})};import{cloneDeep as $f}from"lodash-es";var Mi={currentlyExecutingRequests:{}},Bf=r=>async(e,t)=>{let n,{testId:o}=r.metadata,{baseUrl:s}=e,i=`${o}|${s}`;try{let a=Mi.currentlyExecutingRequests[i]??0;Mi.currentlyExecutingRequests[i]=a+1,n=await zf({...r,...e,done:t})}finally{r.logger.info({result:n,sessionId:r.metadata.sessionId},"Test execution complete"),Mi.currentlyExecutingRequests[i]--}},zf=async({socket:r,steps:e,baseUrl:t,testMetadata:n,reInitialize:o,indicesFilter:s,toIndices:i,fromIndices:a,storage:l,metadata:c,logger:u,envName:d,environmentVariables:m,testInputs:p,authorization:f,done:h})=>{let{testId:g,sessionId:y,orgId:S}=c,b=y,C=_.getSession(y);if(!C)throw new Error("No active session found");_.resumeExecution(y);let{controller:v,context:E}=C;v.setOpen();let P=f?.type==="API_KEY"?new Lt(f):void 0;u=u.child({testId:g,orgId:S,baseUrl:t,sessionId:y,runId:b}),u.info({steps:e.map(W=>`${W.type}${"command"in W?` - ${W.command.type}`:""}`),indicesFilter:s,fromIndices:a,toIndices:i,reInitialize:o,envName:d,baseUrl:t},"Starting execution"),u.debug({steps:e,context:E,flags:v.flagStore.getAllFlags()},"Execution parameters");let A=m??{};await Promise.all((n.parameters??[]).map(async W=>{let Et=(p??{})[W.name]??W.defaultValue;if(Et===void 0)return;let Kt=await Ze({s:Et,context:le.dummyContext(d),logger:u,localTools:P});A[W.name]=Kt}));let O=async()=>{if(o){let W={url:t,clearCookies:!0,clearStorage:!0};await v.resetState(W),v.setOpen(),E.reset({baseUrl:t,currentUrl:v.browser.url(),variablesFromEnvironment:A,envName:d})}},M=async()=>{try{await l.resolveStepCacheEntries({schemaVersion:ke,organizationId:S,testId:g,steps:e,logger:u})}catch(W){u.error({err:W},"Failed to fetch step cache entries from Momentic server. This can drastically reduce test reliability and performance.")}};await Promise.all([O(),M()]);let Z=$f(e),R={takeScreenshots:!1,consumeDebuggingData:!1},H={orgId:S,runId:b,testMetadata:n,steps:e,indicesFilter:s,fromIndices:a,toIndices:i},Y={controller:v,context:E,storage:l,codeEvalTools:P,logger:u},oe=(W,Et)=>{r.emit(Et,W)},He={test:{onTestComplete:async()=>{r.emit("finished")},onSaveScreenshot:Wf,isExecutionCancelled:()=>_.getSession(y)?.executionCancelled||v.browser.closed||v.isClosed()||r.disconnected,onTestSuccess:async W=>{let Et=Uf(Z,W);if(Object.keys(Et).length>0){u.debug({changes:Et},"Updating steps post-run success");let{cachesToSave:Kt}=await yt({steps:e,cacheCreationParams:{testId:g,orgId:S}});try{await l.saveStepCacheEntries(Kt,n.id,u)}catch(N){u.warn({err:N},"Failed to save step cache entries after execution success")}}}},step:{onStarted:W=>r.emit("started",{globalIndex:W}),onSuccess:W=>oe(W,"success"),onFailure:W=>oe(W,"failure"),onCancelled:W=>oe(W,"cancelled"),onCommandGenerated:W=>{r.emit("commandGenerated",{...W,message:W.message??"AI action sub-step generated"})},onCommandExecuted:W=>{r.emit("commandExecuted",W)}}};if(s?.length){u.info({indicesFilter:s},"Starting individual step");let W=C.resultsManager.getContextCopyAtIndices(s)??E.toObjectCopy(),Et=le.fromSnapshot({snapshot:W,environmentVariables:E.getVariablesFromEnvironmentCopy()}),Kt=await Dr({fixtures:{...Y,context:Et},options:R,callbacks:He,inputs:H}),N=Kt.results[0];return N?C.resultsManager.setIndividualResult(N,s):u.warn(Kt,"No result found for individual step"),Kt.status}let Sn=await Dr({fixtures:Y,options:R,callbacks:He,inputs:H});return C.resultsManager.setResults(Sn.results),h?.(Sn),Sn.status},Wf=async r=>r.toString("base64");var qc={event:"execute",createHandler:Bf};var Hf=({metadata:r,logger:e,storage:t})=>{let{sessionId:n}=r;return async(o,s)=>{let{command:i,testMetadata:a,returnScreenshot:l,indices:c}=o,u=Or(i,o.description);e.debug({description:u,params:o},"Locate handler params"),e.info({description:u},"Locate handler called");let d=_.getSession(n);if(!d)throw new Error("No active session found");let{controller:m,context:p}=d,f=d.resultsManager.getContextCopyAtIndices(c)??p.toObjectCopy(),h=le.fromSnapshot({snapshot:f,environmentVariables:p.getVariablesFromEnvironmentCopy()}),g=xn.parse(a.advanced??{}),y={},S;if(u){if("useSelector"in i&&i.useSelector)try{let b=await m.locateElementWithSelector(u,"iframeUrl"in i?i.iframeUrl:void 0);S=b.resolution.locator,y={target:b.target,thoughts:b.thoughts}}catch(b){e.warn({err:b},"Failed resolving target with selector"),s({err:`Failed locating element with CSS selector: ${b.message}`,decisions:b instanceof Pt?b.decisions:void 0});return}else try{let b=await m.locateElement({description:u,disableCache:g.disableAICaching,iframeUrl:"iframeUrl"in i?i.iframeUrl:void 0,testContext:h,returnConflicts:!0});y={target:b.target,thoughts:b.thoughts},S=b.resolution.locator}catch(b){e.warn({err:b},"Failed locating element with AI"),s({err:`Failed locating element with AI: ${b.message}`});return}if(i.type==="SELECT_OPTION"&&S)try{y.options=await m.browser.getSelectOptions(S)}catch(b){e.warn({err:b},"Failed getting select options"),s({err:`Failed getting select options: ${b.message}`});return}e.info({result:y},"Locate handler result")}if(l)try{let{buffer:b,width:C,height:v}=await m.screenshotWithDimensions({scale:"css",clearHighlights:!0,target:y?.target,hideCaret:!0}),E=await t.uploadScreenshot(b);y.screenshot={data:E,width:C,height:v}}catch(b){e.error({err:b},"Error capturing screenshot during locate"),s({err:`Error taking screenshot: ${b.message}`});return}if(s({result:y}),S)try{await Promise.all([m.browser.scrollIntoView(S),m.browser.highlightTarget(S)])}catch(b){e.warn({err:b},"Error highlighting element, continuing...")}}},Kc={event:"locate",createHandler:Hf};var jf=({metadata:r,logger:e})=>{let{sessionId:t}=r;return async({percentX:n,percentY:o},s)=>{let i=_.getSession(t);if(!i)throw new Error("No active session found");let a=i.controller.browser;try{await a.clickMouseFromPositionPercentages(n,o)}catch(l){e.error({err:l},"Error performing click during cloud recording in control mode"),s({err:l.message})}}},Yc={event:"cloudClick",createHandler:jf};var Gf=({metadata:r,logger:e})=>{let{sessionId:t}=r;return async(n,o)=>{let s=_.getSession(t);if(!s)throw new Error("No active session found");let{controller:i}=s;s.browserBehavior.showOverlay=!0;try{let a=await i.browser.captureTargetFromClick();o({result:a})}catch(a){e.error({err:a},"Record click failed"),o({err:a instanceof Error?a.message:`${a}`})}finally{s.browserBehavior.showOverlay=!1}}},Xc={event:"recordTargetClick",createHandler:Gf};var Vf=({metadata:r,logger:e})=>{let{sessionId:t}=r,n,o=0,s=(a,l)=>{let c=async()=>{n=void 0;try{await a.highlightFromPositionPercentages(l),o=0}catch(u){e.error({err:u},"Error highlighting element on mouse move"),o++}};clearTimeout(n),n=setTimeout(c,50*(o+1))},i=0;return async a=>{let l=_.getSession(t);if(!l)throw new Error("No active session found");let{controller:c,browserBehavior:u}=l,d=c.browser;if(!d.closed){if(d.getActivePage().isClosed()){e.warn("Ignoring mouse move because the page is closed");return}u.showOverlay&&s(d,a);try{await d.moveMouseFromPositionPercentages(a.percentX,a.percentY),i=0}catch(m){i++,i%5===0&&e.warn({err:m,mouseErrors:i},"Error in socket mouse move handler")}}}},Jc={event:"cloudMouseMove",createHandler:Vf};var qf=({metadata:r})=>{let{sessionId:e}=r;return async({percentDeltaX:t,percentDeltaY:n})=>{let o=_.getSession(e);if(!o)throw new Error("No active session found");let s=o.controller.browser;if(s.closed)return;let i=await s.scrollFromPositionPercentages(t,n);if(!i)return;let a=o.browserBehavior.recordingState?.transformer;a&&a.recordScroll({...i,url:s.url()})}},Zc={event:"cloudScroll",createHandler:qf};var Kf=({metadata:r,generator:e,socket:t,storage:n,logger:o})=>{let{sessionId:s,orgId:i,testId:a}=r;return async({indices:l})=>{let c=_.getSession(s);if(!c)throw new Error("No active session found");let{controller:u,browserBehavior:d}=c;o.info("Starting cloud recording");let m=await u.startRecordMode({generator:e,initialIndices:l,storage:n,logger:o,testId:a,orgId:i,onStepRecord:(p,f)=>{t.emit("stepRecorded",{step:p,indices:f})}});d.recordingState={transformer:m},d.showOverlay=!0}},Qc={event:"cloudStartRecording",createHandler:Kf};var Yf=({metadata:r,logger:e})=>{let{sessionId:t}=r;return async()=>{let n=_.getSession(t);if(!n)throw new Error("No active session found");e.info("Stopping cloud recording"),await n.controller.stopRecordMode(),n.browserBehavior.recordingState=void 0,n.browserBehavior.showOverlay=!1}},ed={event:"cloudStopRecording",createHandler:Yf};var Xf=["Dead","Meta","AudioVolumeUp","AudioVolumeDown"],Jf=({metadata:r,logger:e})=>{let{sessionId:t}=r;return async({key:n})=>{let o=_.getSession(t);if(!o)throw new Error("No active session found");if(Xf.includes(n))return;let{controller:s}=o;if(s.browser.closed||s.browser.getActivePage().isClosed()){e.debug({sessionId:t},"Browser is closed, ignoring typing action");return}n.length>1?await s.browser.press(n):await s.browser.type(n,{clearContent:!1,pressKeysSequentially:!0})}},td={event:"cloudType",createHandler:Jf};var Fr={vimiumJs:'var K=Object.defineProperty;var P=Object.getOwnPropertySymbols;var z=Object.prototype.hasOwnProperty,B=Object.prototype.propertyIsEnumerable;var F=(t,e,n)=>e in t?K(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n,D=(t,e)=>{for(var n in e||(e={}))z.call(e,n)&&F(t,n,e[n]);if(P)for(var n of P(e))B.call(e,n)&&F(t,n,e[n]);return t};var g=(t,e,n)=>(F(t,typeof e!="symbol"?e+"":e,n),n);var _=(t,e,n)=>new Promise((o,r)=>{var i=s=>{try{d(n.next(s))}catch(l){r(l)}},a=s=>{try{d(n.throw(s))}catch(l){r(l)}},d=s=>s.done?o(s.value):Promise.resolve(s.value).then(i,a);d((n=n.apply(t,e)).next())});var E=t=>function(e){return e&&e.isTrusted?t.apply(this,arguments):!0};globalThis.forTrusted==null&&(globalThis.forTrusted=E);var k={create(t,e,n,o){return{bottom:o,top:e,left:t,right:n,width:n-t,height:o-e}},copy(t){return{bottom:t.bottom,top:t.top,left:t.left,right:t.right,width:t.width,height:t.height}},translate(t,e,n){return e==null&&(e=0),n==null&&(n=0),{bottom:t.bottom+n,top:t.top+n,left:t.left+e,right:t.right+e,width:t.width,height:t.height}},subtract(t,e){return e=this.create(Math.max(t.left,e.left),Math.max(t.top,e.top),Math.min(t.right,e.right),Math.min(t.bottom,e.bottom)),e.width<0||e.height<0?[k.copy(t)]:[this.create(t.left,t.top,e.left,e.top),this.create(e.left,t.top,e.right,e.top),this.create(e.right,t.top,t.right,e.top),this.create(t.left,e.top,e.left,e.bottom),this.create(e.right,e.top,t.right,e.bottom),this.create(t.left,e.bottom,e.left,t.bottom),this.create(e.left,e.bottom,e.right,t.bottom),this.create(e.right,e.bottom,t.right,t.bottom)].filter(o=>o.height>0&&o.width>0)},intersects(t,e){return t.right>e.left&&t.left<e.right&&t.bottom>e.top&&t.top<e.bottom},intersectsStrict(t,e){return t.right>=e.left&&t.left<=e.right&&t.bottom>=e.top&&t.top<=e.bottom},equals(t,e){for(let n of["top","bottom","left","right","width","height"])if(t[n]!==e[n])return!1;return!0},intersect(t,e){return this.create(Math.max(t.left,e.left),Math.max(t.top,e.top),Math.min(t.right,e.right),Math.min(t.bottom,e.bottom))}};var N={_browserInfoLoaded:!0,_firefoxVersion:null,_isFirefox:!1,isFirefox(){if(!this._browserInfoLoaded)throw Error("browserInfo has not yet loaded.");return this._isFirefox},firefoxVersion(){if(!this._browserInfoLoaded)throw Error("browserInfo has not yet loaded.");return this._firefoxVersion},isString(t){return typeof t=="string"||t instanceof String}};var f={isReady(){return document.readyState!=="loading"},documentReady:function(){let t=document.readyState!=="loading",e=[];if(!t){let n;globalThis.addEventListener("DOMContentLoaded",n=E(function(){globalThis.removeEventListener("DOMContentLoaded",n,!0),t=!0;for(let o of e)o();e=null}),!0)}return function(n){if(t)return n();e.push(n)}}(),documentComplete:function(){let t=document.readyState==="complete",e=[];if(!t){let n;globalThis.addEventListener("load",n=E(function(o){if(o.target===document){globalThis.removeEventListener("load",n,!0),t=!0;for(let r of e)r();e=null}}),!0)}return function(n){t?n():e.push(n)}}(),createElement(t){let e=document.createElement(t);return e instanceof HTMLElement?(this.createElement=n=>document.createElement(n),e):(this.createElement=n=>document.createElementNS("http://www.w3.org/1999/xhtml",n),this.createElement(t))},addElementsToPage(t,e){let n=this.createElement("div");e.id!=null&&(n.id=e.id),e.className!=null&&(n.className=e.className);for(let o of t)n.appendChild(o);return document.body.appendChild(n),n},removeElement(t){return t.parentNode.removeChild(t)},isTopFrame(){return globalThis.top===globalThis.self},makeXPath(t){let e=[];for(let n of t)e.push(".//"+n,".//xhtml:"+n);return e.join(" | ")},evaluateXPath(t,e){let n=document.webkitIsFullScreen?document.webkitFullscreenElement:document.documentElement,o=function(r){return r==="xhtml"?"http://www.w3.org/1999/xhtml":null};return document.evaluate(t,n,o,e,null)},getVisibleClientRect(t,e){let n;e==null&&(e=!1);let o=(()=>{let i=[];for(n of t.getClientRects())i.push(k.copy(n));return i})(),r=function(){let i=window.getComputedStyle(t,null),a=i.getPropertyValue("display").indexOf("inline")===0&&i.getPropertyValue("font-size")==="0px";return r=()=>a,a};for(n of o){let i;if((n.width===0||n.height===0)&&e)for(let a of Array.from(t.children)){i=window.getComputedStyle(a,null);let d=i.getPropertyValue("position");if(i.getPropertyValue("float")==="none"&&!["absolute","fixed"].includes(d)&&!(n.height===0&&r()&&i.getPropertyValue("display").indexOf("inline")===0))continue;let s=this.getVisibleClientRect(a,!0);if(!(s===null||s.width<3||s.height<3))return s}else{if(n=this.cropRectToVisible(n),n===null||n.width<3||n.height<3||(i=window.getComputedStyle(t,null),i.getPropertyValue("visibility")!=="visible"))continue;return n}}return null},cropRectToVisible(t){let e=k.create(Math.max(t.left,0),Math.max(t.top,0),t.right,t.bottom);return e.top>=window.innerHeight-4||e.left>=window.innerWidth-4?null:e},getClientRectsForAreas(t,e){let n=[];for(let o of e){let r,i,a,d,s=o.coords.split(",").map(p=>parseInt(p,10)),l=o.shape.toLowerCase();if(["rect","rectangle"].includes(l))s.length==4&&([r,a,i,d]=s);else if(["circle","circ"].includes(l)){if(s.length==3){let[p,w,v]=s,u=v/Math.sqrt(2);r=p-u,i=p+u,a=w-u,d=w+u}}else l==="default"?s.length==2&&([r,a,i,d]=[0,0,t.width,t.height]):s.length>=4&&([r,a,i,d]=s);let c=k.translate(k.create(r,a,i,d),t.left,t.top);c=this.cropRectToVisible(c),c&&!isNaN(c.top)&&!isNaN(c.left)&&!isNaN(c.width)&&!isNaN(c.height)&&n.push({element:o,rect:c})}return n},isSelectable(t){if(!(t instanceof Element))return!1;let e=["button","checkbox","color","file","hidden","image","radio","reset","submit"];return t.nodeName.toLowerCase()==="input"&&e.indexOf(t.type)===-1||t.nodeName.toLowerCase()==="textarea"||t.isContentEditable},isEditable(t){return this.isSelectable(t)||(t.nodeName!=null?t.nodeName.toLowerCase():void 0)==="select"},isEmbed(t){let e=t.nodeName!=null?t.nodeName.toLowerCase():null;return["embed","object"].includes(e)},isFocusable(t){return t&&(this.isEditable(t)||this.isEmbed(t))},isDOMDescendant(t,e){let n=e;for(;n!==null;){if(n===t)return!0;n=n.parentNode}return!1},isSelected(t){let e=document.getSelection();if(t.isContentEditable){let n=e.anchorNode;return n&&this.isDOMDescendant(t,n)}else if(f.getSelectionType(e)==="Range"&&e.isCollapsed){let n=e.anchorNode.childNodes[e.anchorOffset];return t===n}else return!1},simulateSelect(t){if(t===document.activeElement&&f.isEditable(document.activeElement))return handlerStack.bubbleEvent("click",{target:t});if(t.focus(),t.tagName.toLowerCase()!=="textarea"||t.value.indexOf(`\n`)<0)try{if(t.selectionStart===0&&t.selectionEnd===0)return t.setSelectionRange(t.value.length,t.value.length)}catch(e){}},simulateClick(t,e){e==null&&(e={});let n=["mouseover","mousedown","mouseup","click"],o=[];for(let r of n){let i=this.simulateMouseEvent(r,t,e);o.push(i)}return o},simulateMouseEvent(t,e,n){if(n==null&&(n={}),t==="mouseout"){if(e==null&&(e=this.lastHoveredElement),this.lastHoveredElement=void 0,e==null)return}else t==="mouseover"&&(this.simulateMouseEvent("mouseout",void 0,n),this.lastHoveredElement=e);let o=new MouseEvent(t,{bubbles:!0,cancelable:!0,composed:!0,view:window,detail:1,ctrlKey:n.ctrlKey,altKey:n.altKey,shiftKey:n.shiftKey,metaKey:n.metaKey});return e.dispatchEvent(o)},simulateClickDefaultAction(t,e){let n;if(e==null&&(e={}),(t.tagName!=null?t.tagName.toLowerCase():void 0)!=="a"||!t.href)return;let{ctrlKey:o,shiftKey:r,metaKey:i,altKey:a}=e;KeyboardUtils.platform==="Mac"?n=i===!0&&o===!1:n=i===!1&&o===!0,n?chrome.runtime.sendMessage({handler:"openUrlInNewTab",url:t.href,active:r===!0}):r===!0&&i===!1&&o===!1&&a===!1?chrome.runtime.sendMessage({handler:"openUrlInNewWindow",url:t.href}):t.target==="_blank"&&chrome.runtime.sendMessage({handler:"openUrlInNewTab",url:t.href,active:!0})},simulateHover(t,e){return e==null&&(e={}),this.simulateMouseEvent("mouseover",t,e)},simulateUnhover(t,e){return e==null&&(e={}),this.simulateMouseEvent("mouseout",t,e)},addFlashRect(t){let e=this.createElement("div");return e.classList.add("vimiumReset"),e.classList.add("vimiumFlash"),e.style.left=t.left+"px",e.style.top=t.top+"px",e.style.width=t.width+"px",e.style.height=t.height+"px",document.documentElement.appendChild(e),e},getViewportTopLeft(){let t=document.documentElement,e=getComputedStyle(t),n=t.getBoundingClientRect();if(e.position==="static"&&!/content|paint|strict/.test(e.contain||"")){let o=parseInt(e.marginTop),r=parseInt(e.marginLeft);return{top:-n.top+o,left:-n.left+r}}else{let o,r;return N.isFirefox()?(r=parseInt(e.borderTopWidth),o=parseInt(e.borderLeftWidth)):{clientTop:r,clientLeft:o}=t,{top:-n.top-r,left:-n.left-o}}},suppressPropagation(t){t.stopImmediatePropagation()},suppressEvent(t){t.preventDefault(),this.suppressPropagation(t)},consumeKeyup:function(){let t=null;return function(e,n=null,o){if(!e.repeat){t!=null&&handlerStack.remove(t);let{code:r}=e;t=handlerStack.push({_name:"dom_utils/consumeKeyup",keyup(i){return i.code!==r||(this.remove(),o?f.suppressPropagation(i):f.suppressEvent(i)),handlerStack.continueBubbling},blur(i){return i.target===window&&this.remove(),handlerStack.continueBubbling}})}return typeof n=="function"&&n(),o?(f.suppressPropagation(e),handlerStack.suppressPropagation):(f.suppressEvent(e),handlerStack.suppressEvent)}}(),getSelectionType(t){return t==null&&(t=document.getSelection()),t.type?t.type:t.rangeCount===0?"None":t.isCollapsed?"Caret":"Range"},getElementWithFocus(t,e){let n,o=n=t.getRangeAt(0);f.getSelectionType(t)==="Range"&&(o=n.cloneRange(),o.collapse(e)),n=o.startContainer,n.nodeType===1&&(n=n.childNodes[o.startOffset]);let r=n;for(;r&&r.nodeType!==1;)r=r.previousSibling;return n=r||(n!=null?n.parentNode:void 0),n},getSelectionFocusElement(){let t=window.getSelection(),e=t.focusNode;return e==null?null:(e===t.anchorNode&&t.focusOffset===t.anchorOffset&&(e=e.childNodes[t.focusOffset]||e),e.nodeType!==Node.ELEMENT_NODE?e.parentElement:e)},getContainingElement(t){return(typeof t.getDestinationInsertionPoints=="function"?t.getDestinationInsertionPoints()[0]:void 0)||t.parentElement},windowIsTooSmall(){return window.innerWidth<3||window.innerHeight<3},injectUserCss(){let t=document.createElement("style");t.type="text/css",t.textContent=Settings.get("userDefinedLinkHintCss"),document.head.appendChild(t)}};var O={MAX_CONTENT_LENGTH:1e3,MAX_ATTRIBUTE_LENGTH:500,MAX_NUM_DATA_ATTRIBUTES:10,commonAttributes:["id","className","title","aria-label","aria-labelledby"],attributeNamesMapping:new Map([["a",["href","title","rel","target"]],["label",["for"]],["input",["type","name","placeholder","checked","maximumLength"]],["textarea",["placeholder","maximumLength"]],["button",["type"]],["select",["name","multiple"]],["div",["role"]],["iframe",["src"]],["img",["src","alt"]]]),describe(t){var r,i;let e={};this.addAttributes(t,this.commonAttributes,e);let n=((i=(r=t.tagName).toLowerCase)==null?void 0:i.call(r))||"";this.attributeNamesMapping.has(n)&&this.addAttributes(t,this.attributeNamesMapping.get(n),e),this.addDataAttrs(t,e);let o=this.getContent(t);return this.additionalHandling(t,D({tag:n,attributes:e},o&&{content:o}))},getContent(t){var n,o;let e=((o=(n=t.tagName).toLowerCase)==null?void 0:o.call(n))||"";return["input","textarea"].includes(e)?t.value:["div","iframe","img","body"].includes(e)?null:(["a","button","select","label"].includes(e),t.innerText)},additionalHandling(t,e){var o,r;if((((r=(o=t.tagName).toLowerCase)==null?void 0:r.call(o))||"")=="label"&&t.hasAttribute("for")){let i=t.getAttribute("for"),a=document.getElementById(i);a&&(e.target=this.describe(a))}return e},addAttributes(t,e,n){n||(n={});for(let o of e)t.hasAttribute(o)&&(n[o]=t.getAttribute(o).substring(0,this.MAX_ATTRIBUTE_LENGTH));return n},addDataAttrs(t,e){let n=0;for(let o in t.dataset)if(e[`data-${o}`]=t.dataset[o].substring(0,this.MAX_ATTRIBUTE_LENGTH),n++,n>this.MAX_NUM_DATA_ATTRIBUTES)return e;return e}};var x=null,C=()=>G()||document.scrollingElement||document.body,W=function(t){return t?t<0?-1:1:0},U={x:{axisName:"scrollLeft",max:"scrollWidth",viewSize:"clientWidth"},y:{axisName:"scrollTop",max:"scrollHeight",viewSize:"clientHeight"}},X=function(t,e,n){if(N.isString(n)){let o=n;return o==="viewSize"&&t===C()?e==="x"?window.innerWidth:window.innerHeight:t[U[e][o]]}else return n},V=function(t,e,n){let o=U[e].axisName,r=t[o];if(t.scrollBy){let i={behavior:"instant"};i[e==="x"?"left":"top"]=n,t.scrollBy(i)}else t[o]+=n;return t[o]!==r},q=function(t,e){let n=window.getComputedStyle(t);return!(n.getPropertyValue(`overflow-${e}`)==="hidden"||["hidden","collapse"].includes(n.getPropertyValue("visibility"))||n.getPropertyValue("display")==="none")},T=function(t,e,n,o){let r=o*X(t,e,n)||-1;return r=W(r),V(t,e,r)&&V(t,e,-r)},$=function(t,e,n,o){return e==null&&(e="y"),n==null&&(n=1),o==null&&(o=1),T(t,e,n,o)&&q(t,e)},j=function(t=null){let e;if(!t){let n=C();if(T(n,"y",1,1)||T(n,"y",-1,1))return n;t=document.body||C()}if(T(t,"y",1,1)||T(t,"y",-1,1))return t;{let n=Array.from(t.children).map(o=>({element:o,rect:f.getVisibleClientRect(o)})).filter(o=>o.rect);n.map(o=>o.area=o.rect.width*o.rect.height);for(e of n.sort((o,r)=>r.area-o.area)){let o=j(e.element);if(o)return o}return null}},L={init(){x=null},isScrollableElement(t){return x||(x=C()&&j()||C()),t!==x&&$(t)}},G=function(){let t=J[window.location.host];if(t)return document.querySelector(t)},J={"twitter.com":"div.permalink-container div.permalink[role=main]","reddit.com":"#overlayScrollContainer","new.reddit.com":"#overlayScrollContainer","www.reddit.com":"#overlayScrollContainer","web.telegram.org":".MessageList"};window.Scroller=L;var A=function(){let t=null;return f.documentReady(()=>t=document.hasFocus()),globalThis.addEventListener("focus",E(function(e){return e.target===window&&(t=!0),!0}),!0),globalThis.addEventListener("blur",E(function(e){return e.target===window&&(t=!1),!0}),!0),()=>t}();Object.assign(globalThis,{windowIsFocused:A});var R=class{constructor(e){g(this,"element");g(this,"image");g(this,"rect");g(this,"linkText");g(this,"showLinkText");g(this,"reason");g(this,"secondClassCitizen");g(this,"possibleFalsePositive");Object.seal(this),e&&Object.assign(this,e)}},M={getLocalHintsForElement(t){var p,w,v;let e=((w=(p=t.tagName).toLowerCase)==null?void 0:w.call(p))||"",n=!1,o=!1,r=!1,i=[],a=[],d=null;if(e==="img"){let u=t.getAttribute("usemap");if(u){let h=t.getClientRects();u=u.replace(/^#/,"").replace(\'"\',\'\\\\"\');let m=document.querySelector(`map[name="${u}"]`);if(m&&h.length>0){n=!0;let y=m.getElementsByTagName("area"),S=f.getClientRectsForAreas(h[0],y);S=S.map(I=>Object.assign(I,{image:t})),a.push(...S)}}}let s=t.getAttribute("aria-disabled");if(s&&["","true"].includes(s.toLowerCase()))return[];if(this.checkForAngularJs||(this.checkForAngularJs=function(){if(document.getElementsByClassName("ng-scope").length===0)return()=>!1;{let h=[];for(let m of["","data-","x-"])for(let y of["-",":","_"])h.push(`${m}ng${y}click`);return function(m){for(let y of h)if(m.hasAttribute(y))return!0;return!1}}}()),n||(n=this.checkForAngularJs(t)),t.hasAttribute("onclick"))n=!0;else{let u=t.getAttribute("role"),h=["button","tab","link","checkbox","menuitem","menuitemcheckbox","menuitemradio","radio"];if(u!=null&&h.includes(u.toLowerCase()))n=!0;else{let m=t.getAttribute("contentEditable");m!=null&&["","contenteditable","true","plaintext-only"].includes(m.toLowerCase())&&(n=!0)}}if(!n&&t.hasAttribute("jsaction")){let u=t.getAttribute("jsaction").split(";");for(let h of u){let m=h.trim().split(":");if(m.length>=1&&m.length<=2){let[y,S,I]=m.length===1?["click",...m[0].trim().split("."),"_"]:[m[0],...m[1].trim().split("."),"_"];n||(n=y==="click"&&S!=="none"&&I!=="_")}}}switch(e){case"a":n=!0;break;case"textarea":n||(n=!t.disabled&&!t.readOnly);break;case"input":n||(n=!(((v=t.getAttribute("type"))==null?void 0:v.toLowerCase())=="hidden"||t.disabled||t.readOnly&&f.isSelectable(t)));break;case"button":case"select":n||(n=!t.disabled);break;case"object":case"embed":n=!0;break;case"label":n||(n=t.control!=null&&!t.control.disabled&&this.getLocalHintsForElement(t.control).length===0);break;case"body":n||(n=t===document.body&&!A()&&window.innerWidth>3&&window.innerHeight>3&&(document.body!=null?document.body.tagName.toLowerCase():void 0)!=="frameset"?d="Frame.":void 0),n||(n=t===document.body&&A()&&L.isScrollableElement(t)?d="Scroll.":void 0);break;case"img":n||(n=["zoom-in","zoom-out"].includes(t.style.cursor));break;case"div":case"ol":case"ul":n||(n=t.clientHeight<t.scrollHeight&&L.isScrollableElement(t)?d="Scroll.":void 0);break;case"details":n=!0,d="Open.";break}let l=t.getAttribute("class");!n&&(l!=null&&l.toLowerCase().includes("button"))&&(n=!0,r=!0);let c=t.getAttribute("tabindex"),b=c?parseInt(c):-1;if(!n&&!(b<0)&&!isNaN(b)&&(n=!0,o=!0),n)if(a.length>0){let u=a.map(h=>new R({element:h.element,image:t,rect:h.rect,secondClassCitizen:o,possibleFalsePositive:r,reason:d}));i.push(...u)}else{let u=f.getVisibleClientRect(t,!0);if(u!==null){let h=new R({element:t,rect:u,secondClassCitizen:o,possibleFalsePositive:r,reason:d});i.push(h)}}return i},getElementFromPoint(t,e,n,o){n==null&&(n=document),o==null&&(o=[]);let r=n.elementsFromPoint?n.elementsFromPoint(t,e)[0]:n.elementFromPoint(t,e);return o.includes(r)?r:(o.push(r),r&&r.shadowRoot?M.getElementFromPoint(t,e,r.shadowRoot,o):r)},getLocalHints(t){if(!document.body)return[];let e=(s,l)=>{l==null&&(l=[]);for(let c of Array.from(s.querySelectorAll("*")))l.push(c),c.shadowRoot&&e(c.shadowRoot,l);return l},n=e(document.body),o=[];for(let s of Array.from(n))if(!t||s.href){let l=this.getLocalHintsForElement(s);o.push(...l)}o=o.reverse();let r=[1,2,3];o=o.filter((s,l)=>{if(!s.possibleFalsePositive)return!0;let b=Math.max(0,l-6);for(;b<l;){let p=o[b].element;for(let w of r)if(p=p==null?void 0:p.parentElement,p===s.element)return!1;b+=1}return!0});let i=o.filter(s=>{if(s.secondClassCitizen)return!1;let l=s.rect,c=M.getElementFromPoint(l.left+l.width*.5,l.top+l.height*.5);if(c&&(s.element.contains(c)||c.contains(s.element))||s.element.localName=="area"&&c==s.image)return!0;let p=[l.top+.1,l.bottom-.1],w=[l.left+.1,l.right-.1];for(let v of p)for(let u of w){let h=M.getElementFromPoint(u,v);if(h&&(s.element.contains(h)||h.contains(s.element)))return!0}});i.reverse();let{top:a,left:d}=f.getViewportTopLeft();for(let s of i)s.rect.top+=a,s.rect.left+=d;return i}};var H=class{constructor(){this.hints=null;this.hintMarkers=null;this.markersDiv=null;this.enrichedMarkers=null}reset(){this.removeMarkers(),this.hints=null,this.hintMarkers=null,this.markersDiv=null}capture(){return _(this,null,function*(){this.reset(),this.createMarkers(),this.displayMarkers()})}createMarkers(){this.hints=M.getLocalHints(),this.hintMarkers=new Map,this.hints.forEach((e,n)=>{var i,a;let o=f.createElement("div"),r=(a=(i=e.element.attributes["data-momentic-id"])==null?void 0:i.value)!=null?a:void 0;if(!r){console.warn(`[MOMENTIC] No data-momentic-id found for interactive element ${e.element.outerHTML}`);return}o.style.left=e.rect.left+"px",o.style.top=e.rect.top+"px",o.style.zIndex=214e7+n,o.className="vimiumReset internalVimiumHintMarker vimiumHintMarker",Z(o,r),this.hintMarkers.set(r,{hint:e,marker:o})})}enrichMarkers(){if(this.hintMarkers){this.enrichedMarkers=[];for(let[e,n]of this.hintMarkers)this.enrichedMarkers.push(Object.assign(O.describe(n.hint.element),{hintString:e}))}}displayMarkers(){this.hintMarkers&&(this.markersDiv||(this.markersDiv=f.addElementsToPage(Array.from(this.hintMarkers.values()).map(e=>e.marker),{id:"vimiumHintMarkerContainer",className:"vimiumReset"})))}removeMarkers(){this.markersDiv&&(f.removeElement(this.markersDiv),this.markersDiv=null)}toggleMarkers(){this.markersDiv?this.removeMarkers():this.displayMarkers()}},Z=(t,e)=>{for(let n of e){let o=document.createElement("span");o.className="vimiumReset",o.textContent=n,t.appendChild(o)}};window.HintManager=H;\n',vimiumCss:'.vimiumReset,a.vimiumReset,a:hover.vimiumReset,a:link.vimiumReset,a:visited.vimiumReset,div.vimiumReset,span.vimiumReset,table.vimiumReset,td.vimiumReset,tr.vimiumReset{background:none;border:none;bottom:auto;box-shadow:none;color:#000;cursor:auto;display:inline;float:none;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-size:inherit;font-style:normal;font-variant:normal;font-weight:400;height:auto;left:auto;letter-spacing:0;line-height:100%;margin:0;max-height:none;max-width:none;min-height:0;min-width:0;opacity:1;padding:0;position:static;right:auto;text-align:left;text-decoration:none;text-indent:0;text-shadow:none;text-transform:none;top:auto;vertical-align:baseline;white-space:normal;width:auto;z-index:2140000000}tbody.vimiumReset,thead.vimiumReset{display:table-header-group}tbody.vimiumReset{display:table-row-group}div.internalVimiumHintMarker{background:linear-gradient(180deg,#fff785 0,#ffc542);border:1px solid #c38a22;border-radius:3px;box-shadow:0 3px 7px 0 rgba(0,0,0,.3);display:block;font-size:11px;left:-1px;overflow:hidden;padding:1px 3px 0;position:absolute;top:-1px;white-space:nowrap}div.internalVimiumHintMarker span{color:#302505;font-family:Helvetica,Arial,sans-serif;font-size:11px;font-weight:700;text-shadow:0 1px 0 hsla(0,0%,100%,.6)}div.internalVimiumHintMarker>.matchingCharacter{color:#d4ac3a}div>.vimiumActiveHintMarker span{color:#a07555!important}div.internalVimiumInputHint{background-color:rgba(255,247,133,.3);border:1px solid #c38a22;display:block;pointer-events:none;position:absolute}div.internalVimiumSelectedInputHint{background-color:hsla(0,100%,70%,.3);border:1px solid #933!important}div.internalVimiumSelectedInputHint span{color:#fff!important}div.vimiumHighlightedFrame{border:5px solid #ff0;box-sizing:border-box;margin:0;pointer-events:none}div.vimiumHighlightedFrame,iframe.vimiumHelpDialogFrame{height:100%;left:0;padding:0;position:fixed;top:0;width:100%}iframe.vimiumHelpDialogFrame{background-color:hsla(0,0%,4%,.6);border:none;display:block;z-index:2139999997}div#vimiumHelpDialogContainer{background-color:#fff;border:2px solid #b3b3b3;border-radius:6px;margin:50px auto;max-height:calc(100% - 100px);max-width:calc(100% - 100px);opacity:1;overflow-x:auto;overflow-y:auto;width:840px}div#vimiumHelpDialog{min-width:600px;padding:8px 12px}span#vimiumTitle,span#vimiumTitle *,span#vimiumTitle span{font-size:20px}#vimiumTitle{display:block;line-height:130%;white-space:nowrap}td.vimiumHelpDialogTopButtons{text-align:right;width:100%}#helpDialogOptionsPage,#helpDialogWikiPage{font-size:14px;padding-left:5px;padding-right:5px}div.vimiumColumn{float:left;font-size:11px;line-height:130%;width:50%}div.vimiumColumn tr{display:table-row}div.vimiumColumn td{display:table-cell;font-size:11px;line-height:130%}div.vimiumColumn table,div.vimiumColumn td,div.vimiumColumn tr{margin:0;padding:0}div.vimiumColumn table{table-layout:auto;width:100%}div.vimiumColumn td{padding:1px;vertical-align:top}div#vimiumHelpDialog div.vimiumColumn tr>td:first-of-type{font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-size:14px;text-align:right;white-space:nowrap}span.vimiumHelpDialogKey{background-color:#f3f3f3;border:1px solid;border-color:#ccc #ccc #bbb;border-radius:3px;box-shadow:inset 0 -1px 0 #bbb;color:#212121;font-family:monospace;font-size:11px;margin-left:2px;padding:1px 4px}div#vimiumHelpDialog div.vimiumColumn tr>td:nth-of-type(3){width:100%}div#vimiumHelpDialog div.vimiumDivider{background-color:#9a9a9a;display:block;height:1px;margin:10px auto;width:100%}div#vimiumHelpDialog td.vimiumHelpSectionTitle{font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-size:16px;font-weight:700;padding-top:3px}div#vimiumHelpDialog td.vimiumHelpDescription{font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-size:14px}div#vimiumHelpDialog span.vimiumCopyCommandNameName{cursor:pointer;font-size:12px;font-style:italic}div#vimiumHelpDialog tr.advanced{display:none}div#vimiumHelpDialog.showAdvanced tr.advanced{display:table-row}div#vimiumHelpDialog div.advanced td:nth-of-type(3){color:#555}div#vimiumHelpDialog a.closeButton{color:#555;cursor:pointer;font-family:courier new;font-size:24px;font-weight:700;padding-left:5px;position:relative;text-decoration:none;top:3px}div#vimiumHelpDialog a{text-decoration:underline}div#vimiumHelpDialog a.closeButton:hover{color:#000;-webkit-user-select:none}div#vimiumHelpDialogFooter{display:block;margin-bottom:37px;position:relative}table.helpDialogBottom{width:100%}td.helpDialogBottomRight{float:right;text-align:right;width:100%}td.helpDialogBottomLeft,td.helpDialogBottomRight{padding:0}div#vimiumHelpDialogFooter *{font-size:10px}a#toggleAdvancedCommands,span#help-dialog-tip{font-size:10px;position:relative;top:19px;white-space:nowrap}a#toggleAdvancedCommands,a:active.vimiumHelDialogLink,a:hover.vimiumHelDialogLink,a:link.vimiumHelDialogLink,a:visited.vimiumHelDialogLink{color:#2f508e;cursor:pointer;text-decoration:underline}div.vimiumHUD{background:#f1f1f1;border:1px solid #aaa;border-radius:4px;bottom:8px;box-shadow:0 2px 10px rgba(0,0,0,.8);display:block;left:8px;position:fixed;text-align:left;width:calc(100% - 20px);z-index:2139999999}iframe.vimiumHUDFrame{background-color:transparent;border:none;bottom:-14px;display:block;height:58px;margin:0 0 0 -40%;min-width:300px;opacity:0;overflow:hidden;padding:0;position:fixed;right:20px;width:20%;z-index:2139999998}div.vimiumHUD .vimiumHUDSearchArea{background-color:#f1f1f1;border-radius:4px 4px 0 0;display:block;padding:3px}div.vimiumHUD .vimiumHUDSearchAreaInner{border-radius:3px;box-sizing:border-box;color:#777;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-size:14px;height:30px;line-height:20px;margin-bottom:0;outline:none;padding:2px 4px;width:100%}div.vimiumHUD .hud-find{background:#fff;border:1px solid #ccc}div.vimiumHUD span#hud-find-input,div.vimiumHUD span#hud-match-count{color:#000;display:inline;outline:none;overflow-y:hidden;white-space:nowrap}div.vimiumHUD span#hud-find-input:before{content:"/"}div.vimiumHUD span#hud-match-count{color:#aaa;font-size:12px}div.vimiumHUD span#hud-find-input br{display:none}div.vimiumHUD span#hud-find-input *{display:inline;white-space:nowrap}body.vimiumFindMode ::selection{background:#ff9632}iframe.vomnibarFrame{background-color:transparent;border:none;display:block;font-family:sans-serif;height:calc(100% - 70px);left:50%;margin:0 0 0 -40%;min-width:400px;overflow:hidden;padding:0;position:fixed;top:70px;width:calc(80% + 20px);z-index:2139999998}div.vimiumFlash{background-color:transparent;box-shadow:0 0 4px 2px #4183c4;padding:1px;position:absolute;z-index:2140000000}iframe.vimiumUIComponentHidden{display:none}iframe.vimiumUIComponentVisible{color-scheme:light dark;display:block}iframe.vimiumUIComponentReactivated{border:5px solid #ff0}iframe.vimiumNonClickable{pointer-events:none}@media (prefers-color-scheme:dark){iframe.reverseDarkReaderFilter{-webkit-filter:invert(100%) hue-rotate(180deg)!important;filter:invert(100%) hue-rotate(180deg)!important}body.vimiumBody{background-color:#292a2d;color:#fff}body.vimiumBody a,body.vimiumBody a:visited{color:#8ab4f8}body.vimiumBody input,body.vimiumBody textarea{background-color:#1d1d1f;border-color:#1d1d1f;color:#e8eaed}body.vimiumBody div.example{color:#9aa0a6}body.vimiumBody div#footer,body.vimiumBody div#state,div#vimiumHelpDialogContainer{background-color:#202124;border-color:hsla(0,0%,100%,.1)}div#vimiumHelpDialog{background-color:#292a2d;color:#fff}div#vimiumHelpDialog td.vimiumHelpDescription{color:#c9cccf}div#vimiumHelpDialog td.vimiumHelpSectionTitle,span#vimiumTitle{color:#fff}#vimiumTitle>span:first-child{color:#8ab4f8!important}div#vimiumHelpDialog a{color:#8ab4f8}div#vimiumHelpDialog div.vimiumDivider{background-color:hsla(0,0%,100%,.1)}span.vimiumHelpDialogKey{background-color:#1d1d1f;border:1px solid #000;box-shadow:none;color:#fff}}',htmlUtilsLibJs:`var __defProp = Object.defineProperty;
|
|
13
11
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
14
12
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
15
13
|
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
@@ -1724,17 +1722,17 @@ function registerAllMomenticListeners() {
|
|
|
1724
1722
|
|
|
1725
1723
|
// src/html/index.ts
|
|
1726
1724
|
registerAllMomenticListeners();
|
|
1727
|
-
`,cssGeneratorLibJs:'// Taken from https://cdn.jsdelivr.net/npm/css-selector-generator@3.6.7/build/index.min.js\n!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.CssSelectorGenerator=e():t.CssSelectorGenerator=e()}(self,(()=>(()=>{"use strict";var t={d:(e,n)=>{for(var r in n)t.o(n,r)&&!t.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:n[r]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};function n(t){return t&&t instanceof Element}t.r(e),t.d(e,{default:()=>K,getCssSelector:()=>J});const r={NONE:"",DESCENDANT:" ",CHILD:" > "},o={id:"id",class:"class",tag:"tag",attribute:"attribute",nthchild:"nthchild",nthoftype:"nthoftype"},i="CssSelectorGenerator";function c(t="unknown problem",...e){console.warn(`${i}: ${t}`,...e)}const u={selectors:[o.id,o.class,o.tag,o.attribute],includeTag:!1,whitelist:[],blacklist:[],combineWithinSelector:!0,combineBetweenSelectors:!0,root:null,maxCombinations:Number.POSITIVE_INFINITY,maxCandidates:Number.POSITIVE_INFINITY};function s(t){return t instanceof RegExp}function a(t){return["string","function"].includes(typeof t)||s(t)}function l(t){return Array.isArray(t)?t.filter(a):[]}function f(t){const e=[Node.DOCUMENT_NODE,Node.DOCUMENT_FRAGMENT_NODE,Node.ELEMENT_NODE];return function(t){return t instanceof Node}(t)&&e.includes(t.nodeType)}function d(t,e){if(f(t))return t.contains(e)||c("element root mismatch","Provided root does not contain the element. This will most likely result in producing a fallback selector using element\'s real root node. If you plan to use the selector using provided root (e.g. `root.querySelector`), it will nto work as intended."),t;const n=e.getRootNode({composed:!1});return f(n)?(n!==document&&c("shadow root inferred","You did not provide a root and the element is a child of Shadow DOM. This will produce a selector using ShadowRoot as a root. If you plan to use the selector using document as a root (e.g. `document.querySelector`), it will not work as intended."),n):e.ownerDocument.querySelector(":root")}function m(t){return"number"==typeof t?t:Number.POSITIVE_INFINITY}function p(t=[]){const[e=[],...n]=t;return 0===n.length?e:n.reduce(((t,e)=>t.filter((t=>e.includes(t)))),e)}function h(t){return[].concat(...t)}function g(t){const e=t.map((t=>{if(s(t))return e=>t.test(e);if("function"==typeof t)return e=>{const n=t(e);return"boolean"!=typeof n?(c("pattern matcher function invalid","Provided pattern matching function does not return boolean. It\'s result will be ignored.",t),!1):n};if("string"==typeof t){const e=new RegExp("^"+t.replace(/[|\\\\{}()[\\]^$+?.]/g,"\\\\$&").replace(/\\*/g,".+")+"$");return t=>e.test(t)}return c("pattern matcher invalid","Pattern matching only accepts strings, regular expressions and/or functions. This item is invalid and will be ignored.",t),()=>!1}));return t=>e.some((e=>e(t)))}function b(t,e,n){const r=Array.from(d(n,t[0]).querySelectorAll(e));return r.length===t.length&&t.every((t=>r.includes(t)))}function y(t,e){e=null!=e?e:function(t){return t.ownerDocument.querySelector(":root")}(t);const r=[];let o=t;for(;n(o)&&o!==e;)r.push(o),o=o.parentElement;return r}function N(t,e){return p(t.map((t=>y(t,e))))}const S=", ",E=new RegExp(["^$","\\\\s"].join("|")),w=new RegExp(["^$"].join("|")),I=[o.nthoftype,o.tag,o.id,o.class,o.attribute,o.nthchild],v=g(["class","id","ng-*"]);function C({name:t}){return`[${t}]`}function T({name:t,value:e}){return`[${t}=\'${e}\']`}function O({nodeName:t,nodeValue:e}){return{name:V(t),value:V(e)}}function x(t){const e=Array.from(t.attributes).filter((e=>function({nodeName:t},e){const n=e.tagName.toLowerCase();return!(["input","option"].includes(n)&&"value"===t||v(t))}(e,t))).map(O);return[...e.map(C),...e.map(T)]}function j(t){return(t.getAttribute("class")||"").trim().split(/\\s+/).filter((t=>!w.test(t))).map((t=>`.${V(t)}`))}function A(t){const e=t.getAttribute("id")||"",n=`#${V(e)}`,r=t.getRootNode({composed:!1});return!E.test(e)&&b([t],n,r)?[n]:[]}function $(t){const e=t.parentNode;if(e){const r=Array.from(e.childNodes).filter(n).indexOf(t);if(r>-1)return[`:nth-child(${r+1})`]}return[]}function D(t){return[V(t.tagName.toLowerCase())]}function R(t){const e=[...new Set(h(t.map(D)))];return 0===e.length||e.length>1?[]:[e[0]]}function P(t){const e=R([t])[0],n=t.parentElement;if(n){const r=Array.from(n.children).filter((t=>t.tagName.toLowerCase()===e)),o=r.indexOf(t);if(o>-1)return[`${e}:nth-of-type(${o+1})`]}return[]}function _(t=[],{maxResults:e=Number.POSITIVE_INFINITY}={}){return Array.from(function*(t=[],{maxResults:e=Number.POSITIVE_INFINITY}={}){let n=0,r=L(1);for(;r.length<=t.length&&n<e;){n+=1;const e=r.map((e=>t[e]));yield e,r=k(r,t.length-1)}}(t,{maxResults:e}))}function k(t=[],e=0){const n=t.length;if(0===n)return[];const r=[...t];r[n-1]+=1;for(let t=n-1;t>=0;t--)if(r[t]>e){if(0===t)return L(n+1);r[t-1]++,r[t]=r[t-1]+1}return r[n-1]>e?L(n+1):r}function L(t=1){return Array.from(Array(t).keys())}const M=":".charCodeAt(0).toString(16).toUpperCase(),F=/[ !"#$%&\'()\\[\\]{|}<>*+,./;=?@^`~\\\\]/;function V(t=""){var e,n;return null!==(n=null===(e=null===CSS||void 0===CSS?void 0:CSS.escape)||void 0===e?void 0:e.call(CSS,t))&&void 0!==n?n:function(t=""){return t.split("").map((t=>":"===t?`\\\\${M} `:F.test(t)?`\\\\${t}`:escape(t).replace(/%/g,"\\\\"))).join("")}(t)}const Y={tag:R,id:function(t){return 0===t.length||t.length>1?[]:A(t[0])},class:function(t){return p(t.map(j))},attribute:function(t){return p(t.map(x))},nthchild:function(t){return p(t.map($))},nthoftype:function(t){return p(t.map(P))}},q={tag:D,id:A,class:j,attribute:x,nthchild:$,nthoftype:P};function B(t){return t.includes(o.tag)||t.includes(o.nthoftype)?[...t]:[...t,o.tag]}function G(t={}){const e=[...I];return t[o.tag]&&t[o.nthoftype]&&e.splice(e.indexOf(o.tag),1),e.map((e=>{return(r=t)[n=e]?r[n].join(""):"";var n,r})).join("")}function H(t,e,n="",o){const i=function(t,e){return""===e?t:function(t,e){return[...t.map((t=>e+r.DESCENDANT+t)),...t.map((t=>e+r.CHILD+t))]}(t,e)}(function(t,e,n){const r=function(t,e){const{blacklist:n,whitelist:r,combineWithinSelector:o,maxCombinations:i}=e,c=g(n),u=g(r);return function(t){const{selectors:e,includeTag:n}=t,r=[].concat(e);return n&&!r.includes("tag")&&r.push("tag"),r}(e).reduce(((e,n)=>{const r=function(t,e){var n;return(null!==(n=Y[e])&&void 0!==n?n:()=>[])(t)}(t,n),s=function(t=[],e,n){return t.filter((t=>n(t)||!e(t)))}(r,c,u),a=function(t=[],e){return t.sort(((t,n)=>{const r=e(t),o=e(n);return r&&!o?-1:!r&&o?1:0}))}(s,u);return e[n]=o?_(a,{maxResults:i}):a.map((t=>[t])),e}),{})}(t,n),o=function(t,e){return function(t){const{selectors:e,combineBetweenSelectors:n,includeTag:r,maxCandidates:o}=t,i=n?_(e,{maxResults:o}):e.map((t=>[t]));return r?i.map(B):i}(e).map((e=>function(t,e){const n={};return t.forEach((t=>{const r=e[t];r.length>0&&(n[t]=r)})),function(t={}){let e=[];return Object.entries(t).forEach((([t,n])=>{e=n.flatMap((n=>0===e.length?[{[t]:n}]:e.map((e=>Object.assign(Object.assign({},e),{[t]:n})))))})),e}(n).map(G)}(e,t))).filter((t=>t.length>0))}(r,n),i=h(o);return[...new Set(i)]}(t,o.root,o),n);for(const e of i)if(b(t,e,o.root))return e;return null}function W(t){return{value:t,include:!1}}function U({selectors:t,operator:e}){let n=[...I];t[o.tag]&&t[o.nthoftype]&&(n=n.filter((t=>t!==o.tag)));let r="";return n.forEach((e=>{(t[e]||[]).forEach((({value:t,include:e})=>{e&&(r+=t)}))})),e+r}function z(t){return[":root",...y(t).reverse().map((t=>{const e=function(t,e,n=r.NONE){const o={};return e.forEach((e=>{Reflect.set(o,e,function(t,e){return q[e](t)}(t,e).map(W))})),{element:t,operator:n,selectors:o}}(t,[o.nthchild],r.CHILD);return e.selectors.nthchild.forEach((t=>{t.include=!0})),e})).map(U)].join("")}function J(t,e={}){const r=function(t){(t instanceof NodeList||t instanceof HTMLCollection)&&(t=Array.from(t));const e=(Array.isArray(t)?t:[t]).filter(n);return[...new Set(e)]}(t),i=function(t,e={}){const n=Object.assign(Object.assign({},u),e);return{selectors:(r=n.selectors,Array.isArray(r)?r.filter((t=>{return e=o,n=t,Object.values(e).includes(n);var e,n})):[]),whitelist:l(n.whitelist),blacklist:l(n.blacklist),root:d(n.root,t),combineWithinSelector:!!n.combineWithinSelector,combineBetweenSelectors:!!n.combineBetweenSelectors,includeTag:!!n.includeTag,maxCombinations:m(n.maxCombinations),maxCandidates:m(n.maxCandidates)};var r}(r[0],e);let c="",s=i.root;function a(){return function(t,e,n="",r){if(0===t.length)return null;const o=[t.length>1?t:[],...N(t,e).map((t=>[t]))];for(const t of o){const e=H(t,0,n,r);if(e)return{foundElements:t,selector:e}}return null}(r,s,c,i)}let f=a();for(;f;){const{foundElements:t,selector:e}=f;if(b(r,e,i.root))return e;s=t[0],c=e,f=a()}return r.length>1?r.map((t=>J(t,i))).join(S):function(t){return t.map(z).join(S)}(r)}const K=J;return e})()));'};import{randomUUID as Og}from"crypto";import Lg from"dedent";import{distance as Mg}from"fastest-levenshtein";import{existsSync as Pc,readFileSync as Ng,rmSync as Oc}from"fs";import{Jimp as _g}from"jimp";import Dg from"js-beautify";import{cloneDeep as kg}from"lodash-es";import{homedir as Fg}from"os";import bo from"p-timeout";import{basename as Lc,join as Nc}from"path";import{chromium as Ug,devices as $g,errors as Bg}from"playwright";import{addExtra as zg}from"playwright-extra";import Hg from"puppeteer-extra-plugin-recaptcha";import{v4 as Wg}from"uuid";var un=(r,e)=>{try{let{hostname:t,pathname:n}=new URL(r),{hostname:o,pathname:s}=new URL(e);return t!==o||n!==s}catch{return!1}},uo=r=>{try{return new URL(r),!0}catch{return!1}},Xl=r=>!r.toLowerCase().startsWith("http"),mo=(r,e)=>{try{return new URL(r,e),!0}catch{return!1}};function Jt(r,e){try{return!!new URL(r).origin.trim()}catch(t){return e?.error({url:r,err:t},"Invalid URL in check"),!1}}var Jl={bannedClassSubstrings:["relative","flex","center","justify","auto","sticky","absolute","top","right","left","bottom","items-center"],bannedElementTagNames:["html","head","title","meta","iframe","script","style","path","svg","br","::marker","noscript"],bannedElementAttributes:["data-momentic-id","aria-keyshortcuts","data-ved","aria-controls"],relevantElementAttributes:["name","id","value","type","class","height","width","target","title","href","src","alt","role","headers","scope","checked","required","action","min","max","minlength","maxlength","multiple","pattern","placeholder","accept","data-value","data-testid","data-cy","data-test-id","data-test","data-role","data-type","data-action","data-aria-hidden","data-hidden","data-handleid","data-handlepos","aria-label","aria-role","aria-selected","aria-disabled","aria-hidden","aria-valuenow","aria-valuemin","aria-valuemax"]};function Zl(r){if(r[0]?.match(/[0-9a-zA-Z]/)===null)return!0;if(r.length>10){let d=Math.floor(r.length/8);if((r.match(/[-_:/ ]/g)??[]).length<d)return!0}if((r.match(/[^0-9a-zA-Z.]/g)??[]).length/r.length>.2)return!0;let t=(r.match(/[0-9]/g)??[]).length;if(t/r.length>.3)return!0;let n=(r.toLowerCase().match(/[aeiou]/gi)??[]).length;if((r.toLowerCase().match(/[bcdfghjklmnpqrstvwxyz]/gi)??[]).length/n>5)return!0;let s=new Set(["a","e","i","o","u","y"]),i=0,a=0;for(let d of r.toLowerCase())d>="a"&&d<="z"&&!s.has(d)?(a++,a>i&&(i=a)):a=0;if(i>4)return!0;let l=(r.match(/[A-Z]/g)??[]).length,c=(r.match(/[a-z]/g)??[]).length,u=Math.ceil(r.length*.3);return!!(c&&t&&Math.abs(c-t)<u||c&&l&&Math.abs(c-l)<u)}import{randomUUID as rc}from"crypto";import{distance as Ps}from"fastest-levenshtein";import{cloneDeep as nc}from"lodash-es";import Zp from"p-timeout";var Ql=new Set(["about:blank","chrome-error://chromewebdata/"]),ec=3,Ye="data-momentic-id",tc=1e3,Rs=["button","image","generic","graphics-symbol","tab","link","menuitem","group"],Is=1e4,mn=500;var Qp=["focusable","keyshortcuts","controls","live","relevant","orientation"],eg=["selected","readonly","modal","required","invalid"],tg=["id","name","role","content"],rg=["textbox","checkbox","combobox","table","caption","columnheader","rowheader","gridcell","row","rowgroup","cell","image","svgroot","button","link","list","listitem","tablist","tabpanel","tab","searchbox","menu","menubar","form","dialog","alertdialog","banner","navigation","main","menuitem","menuitemcheckbox","menuitemradio","option","radio","progressbar","switch"],ng=["activeAriaModalDialog","activeFullscreenElement","activeModalDialog","ariaHiddenElement","ariaHiddenSubtree","hiddenByChildTree","inertElement","inertSubtree","notRendered","notVisible"],og=["menulistpopup","statictext","inlinetextbox"],sg=80,po=["StaticText","ListMarker","RootWebArea","LineBreak","emphasis","::before","::after"],ig=["cite"],ag={LabelText:["label"],listitem:["li"],image:["img","svg"],link:["a"],RootWebArea:["#document"],paragraph:["p"],LineBreak:["br"],separator:["hr"]},oc={indentLevel:0,noID:!1,noChildren:!1,noProperties:!1,noContent:!1,maxLevel:void 0,neighbors:void 0},Os=class r{id;role;name;tagName;content;properties;dataMomenticId;pathFromRoot;parent;children;domNode;backendNodeID;ignoredByCDP;constructor(e){if(this.id=e.id,this.role=e.role,this.name=e.name,this.content=e.content,this.properties={},this.pathFromRoot=e.pathFromRoot,this.children=e.children,this.backendNodeID=e.backendNodeID,this.ignoredByCDP=e.ignoredByCDP,e.properties&&e.properties.forEach(t=>{t.name==="keyshortcuts"?this.dataMomenticId=parseInt(t.value.value):this.properties[t.name]=t.value.value}),e.domNode){this.domNode=e.domNode,this.tagName=e.domNode.tagName||void 0;let t=e.domNode.attributes.id;this.name=this.name||e.domNode.attributes.name||(t&&!Zl(t)?t:""),this.role=this.role||(e.domNode.attributes.role??""),mg(this.properties,e.domNode)}}getSerializedFormWithContext(){return this.serialize({noID:!0,maxLevel:1,neighbors:1})}getNodeOnlySerializedForm(){return this.serialize({noID:!0,noChildren:!0,noContent:!0})}getLogForm(){return JSON.stringify({id:this.id,name:this.name??"",role:this.role??"",backendNodeId:this.backendNodeID})}isInteresting(){return rg.includes(this.role.toLowerCase())||!this.properties.hidden&&(this.properties.focusable||this.properties.settable)||this.children.some(e=>e.role==="StaticText")?!0:!!this.name.trim()||!!this.content||Object.keys(this.properties).some(e=>e.startsWith("data"))}serialize(e=oc){let t=Object.assign({},oc,e),{indentLevel:n,noChildren:o,noProperties:s,noID:i,noContent:a}=t,l=nc(this.properties),c=" ".repeat(n),u=this.role||"",d=this.tagName??"unknown",m=this.name;u==="heading"&&m==="heading"&&(m="");let p=po.includes(this.role)||ig.includes(this.tagName||"");if(this.role==="StaticText"||this.role==="ListMarker")return`${c}${m}
|
|
1728
|
-
`;let
|
|
1729
|
-
`;else{let
|
|
1730
|
-
`)?
|
|
1731
|
-
`:
|
|
1732
|
-
${
|
|
1733
|
-
`}if(e.neighbors!==void 0&&e.neighbors>0&&this.parent){let
|
|
1734
|
-
${
|
|
1735
|
-
${
|
|
1725
|
+
`,cssGeneratorLibJs:'// Taken from https://cdn.jsdelivr.net/npm/css-selector-generator@3.6.7/build/index.min.js\n!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.CssSelectorGenerator=e():t.CssSelectorGenerator=e()}(self,(()=>(()=>{"use strict";var t={d:(e,n)=>{for(var r in n)t.o(n,r)&&!t.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:n[r]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};function n(t){return t&&t instanceof Element}t.r(e),t.d(e,{default:()=>K,getCssSelector:()=>J});const r={NONE:"",DESCENDANT:" ",CHILD:" > "},o={id:"id",class:"class",tag:"tag",attribute:"attribute",nthchild:"nthchild",nthoftype:"nthoftype"},i="CssSelectorGenerator";function c(t="unknown problem",...e){console.warn(`${i}: ${t}`,...e)}const u={selectors:[o.id,o.class,o.tag,o.attribute],includeTag:!1,whitelist:[],blacklist:[],combineWithinSelector:!0,combineBetweenSelectors:!0,root:null,maxCombinations:Number.POSITIVE_INFINITY,maxCandidates:Number.POSITIVE_INFINITY};function s(t){return t instanceof RegExp}function a(t){return["string","function"].includes(typeof t)||s(t)}function l(t){return Array.isArray(t)?t.filter(a):[]}function f(t){const e=[Node.DOCUMENT_NODE,Node.DOCUMENT_FRAGMENT_NODE,Node.ELEMENT_NODE];return function(t){return t instanceof Node}(t)&&e.includes(t.nodeType)}function d(t,e){if(f(t))return t.contains(e)||c("element root mismatch","Provided root does not contain the element. This will most likely result in producing a fallback selector using element\'s real root node. If you plan to use the selector using provided root (e.g. `root.querySelector`), it will nto work as intended."),t;const n=e.getRootNode({composed:!1});return f(n)?(n!==document&&c("shadow root inferred","You did not provide a root and the element is a child of Shadow DOM. This will produce a selector using ShadowRoot as a root. If you plan to use the selector using document as a root (e.g. `document.querySelector`), it will not work as intended."),n):e.ownerDocument.querySelector(":root")}function m(t){return"number"==typeof t?t:Number.POSITIVE_INFINITY}function p(t=[]){const[e=[],...n]=t;return 0===n.length?e:n.reduce(((t,e)=>t.filter((t=>e.includes(t)))),e)}function h(t){return[].concat(...t)}function g(t){const e=t.map((t=>{if(s(t))return e=>t.test(e);if("function"==typeof t)return e=>{const n=t(e);return"boolean"!=typeof n?(c("pattern matcher function invalid","Provided pattern matching function does not return boolean. It\'s result will be ignored.",t),!1):n};if("string"==typeof t){const e=new RegExp("^"+t.replace(/[|\\\\{}()[\\]^$+?.]/g,"\\\\$&").replace(/\\*/g,".+")+"$");return t=>e.test(t)}return c("pattern matcher invalid","Pattern matching only accepts strings, regular expressions and/or functions. This item is invalid and will be ignored.",t),()=>!1}));return t=>e.some((e=>e(t)))}function b(t,e,n){const r=Array.from(d(n,t[0]).querySelectorAll(e));return r.length===t.length&&t.every((t=>r.includes(t)))}function y(t,e){e=null!=e?e:function(t){return t.ownerDocument.querySelector(":root")}(t);const r=[];let o=t;for(;n(o)&&o!==e;)r.push(o),o=o.parentElement;return r}function N(t,e){return p(t.map((t=>y(t,e))))}const S=", ",E=new RegExp(["^$","\\\\s"].join("|")),w=new RegExp(["^$"].join("|")),I=[o.nthoftype,o.tag,o.id,o.class,o.attribute,o.nthchild],v=g(["class","id","ng-*"]);function C({name:t}){return`[${t}]`}function T({name:t,value:e}){return`[${t}=\'${e}\']`}function O({nodeName:t,nodeValue:e}){return{name:V(t),value:V(e)}}function x(t){const e=Array.from(t.attributes).filter((e=>function({nodeName:t},e){const n=e.tagName.toLowerCase();return!(["input","option"].includes(n)&&"value"===t||v(t))}(e,t))).map(O);return[...e.map(C),...e.map(T)]}function j(t){return(t.getAttribute("class")||"").trim().split(/\\s+/).filter((t=>!w.test(t))).map((t=>`.${V(t)}`))}function A(t){const e=t.getAttribute("id")||"",n=`#${V(e)}`,r=t.getRootNode({composed:!1});return!E.test(e)&&b([t],n,r)?[n]:[]}function $(t){const e=t.parentNode;if(e){const r=Array.from(e.childNodes).filter(n).indexOf(t);if(r>-1)return[`:nth-child(${r+1})`]}return[]}function D(t){return[V(t.tagName.toLowerCase())]}function R(t){const e=[...new Set(h(t.map(D)))];return 0===e.length||e.length>1?[]:[e[0]]}function P(t){const e=R([t])[0],n=t.parentElement;if(n){const r=Array.from(n.children).filter((t=>t.tagName.toLowerCase()===e)),o=r.indexOf(t);if(o>-1)return[`${e}:nth-of-type(${o+1})`]}return[]}function _(t=[],{maxResults:e=Number.POSITIVE_INFINITY}={}){return Array.from(function*(t=[],{maxResults:e=Number.POSITIVE_INFINITY}={}){let n=0,r=L(1);for(;r.length<=t.length&&n<e;){n+=1;const e=r.map((e=>t[e]));yield e,r=k(r,t.length-1)}}(t,{maxResults:e}))}function k(t=[],e=0){const n=t.length;if(0===n)return[];const r=[...t];r[n-1]+=1;for(let t=n-1;t>=0;t--)if(r[t]>e){if(0===t)return L(n+1);r[t-1]++,r[t]=r[t-1]+1}return r[n-1]>e?L(n+1):r}function L(t=1){return Array.from(Array(t).keys())}const M=":".charCodeAt(0).toString(16).toUpperCase(),F=/[ !"#$%&\'()\\[\\]{|}<>*+,./;=?@^`~\\\\]/;function V(t=""){var e,n;return null!==(n=null===(e=null===CSS||void 0===CSS?void 0:CSS.escape)||void 0===e?void 0:e.call(CSS,t))&&void 0!==n?n:function(t=""){return t.split("").map((t=>":"===t?`\\\\${M} `:F.test(t)?`\\\\${t}`:escape(t).replace(/%/g,"\\\\"))).join("")}(t)}const Y={tag:R,id:function(t){return 0===t.length||t.length>1?[]:A(t[0])},class:function(t){return p(t.map(j))},attribute:function(t){return p(t.map(x))},nthchild:function(t){return p(t.map($))},nthoftype:function(t){return p(t.map(P))}},q={tag:D,id:A,class:j,attribute:x,nthchild:$,nthoftype:P};function B(t){return t.includes(o.tag)||t.includes(o.nthoftype)?[...t]:[...t,o.tag]}function G(t={}){const e=[...I];return t[o.tag]&&t[o.nthoftype]&&e.splice(e.indexOf(o.tag),1),e.map((e=>{return(r=t)[n=e]?r[n].join(""):"";var n,r})).join("")}function H(t,e,n="",o){const i=function(t,e){return""===e?t:function(t,e){return[...t.map((t=>e+r.DESCENDANT+t)),...t.map((t=>e+r.CHILD+t))]}(t,e)}(function(t,e,n){const r=function(t,e){const{blacklist:n,whitelist:r,combineWithinSelector:o,maxCombinations:i}=e,c=g(n),u=g(r);return function(t){const{selectors:e,includeTag:n}=t,r=[].concat(e);return n&&!r.includes("tag")&&r.push("tag"),r}(e).reduce(((e,n)=>{const r=function(t,e){var n;return(null!==(n=Y[e])&&void 0!==n?n:()=>[])(t)}(t,n),s=function(t=[],e,n){return t.filter((t=>n(t)||!e(t)))}(r,c,u),a=function(t=[],e){return t.sort(((t,n)=>{const r=e(t),o=e(n);return r&&!o?-1:!r&&o?1:0}))}(s,u);return e[n]=o?_(a,{maxResults:i}):a.map((t=>[t])),e}),{})}(t,n),o=function(t,e){return function(t){const{selectors:e,combineBetweenSelectors:n,includeTag:r,maxCandidates:o}=t,i=n?_(e,{maxResults:o}):e.map((t=>[t]));return r?i.map(B):i}(e).map((e=>function(t,e){const n={};return t.forEach((t=>{const r=e[t];r.length>0&&(n[t]=r)})),function(t={}){let e=[];return Object.entries(t).forEach((([t,n])=>{e=n.flatMap((n=>0===e.length?[{[t]:n}]:e.map((e=>Object.assign(Object.assign({},e),{[t]:n})))))})),e}(n).map(G)}(e,t))).filter((t=>t.length>0))}(r,n),i=h(o);return[...new Set(i)]}(t,o.root,o),n);for(const e of i)if(b(t,e,o.root))return e;return null}function W(t){return{value:t,include:!1}}function U({selectors:t,operator:e}){let n=[...I];t[o.tag]&&t[o.nthoftype]&&(n=n.filter((t=>t!==o.tag)));let r="";return n.forEach((e=>{(t[e]||[]).forEach((({value:t,include:e})=>{e&&(r+=t)}))})),e+r}function z(t){return[":root",...y(t).reverse().map((t=>{const e=function(t,e,n=r.NONE){const o={};return e.forEach((e=>{Reflect.set(o,e,function(t,e){return q[e](t)}(t,e).map(W))})),{element:t,operator:n,selectors:o}}(t,[o.nthchild],r.CHILD);return e.selectors.nthchild.forEach((t=>{t.include=!0})),e})).map(U)].join("")}function J(t,e={}){const r=function(t){(t instanceof NodeList||t instanceof HTMLCollection)&&(t=Array.from(t));const e=(Array.isArray(t)?t:[t]).filter(n);return[...new Set(e)]}(t),i=function(t,e={}){const n=Object.assign(Object.assign({},u),e);return{selectors:(r=n.selectors,Array.isArray(r)?r.filter((t=>{return e=o,n=t,Object.values(e).includes(n);var e,n})):[]),whitelist:l(n.whitelist),blacklist:l(n.blacklist),root:d(n.root,t),combineWithinSelector:!!n.combineWithinSelector,combineBetweenSelectors:!!n.combineBetweenSelectors,includeTag:!!n.includeTag,maxCombinations:m(n.maxCombinations),maxCandidates:m(n.maxCandidates)};var r}(r[0],e);let c="",s=i.root;function a(){return function(t,e,n="",r){if(0===t.length)return null;const o=[t.length>1?t:[],...N(t,e).map((t=>[t]))];for(const t of o){const e=H(t,0,n,r);if(e)return{foundElements:t,selector:e}}return null}(r,s,c,i)}let f=a();for(;f;){const{foundElements:t,selector:e}=f;if(b(r,e,i.root))return e;s=t[0],c=e,f=a()}return r.length>1?r.map((t=>J(t,i))).join(S):function(t){return t.map(z).join(S)}(r)}const K=J;return e})()));'};import{randomUUID as Lg}from"crypto";import Mg from"dedent";import{distance as Ng}from"fastest-levenshtein";import{existsSync as kd,readFileSync as _g,rmSync as Dd}from"fs";import{Jimp as kg}from"jimp";import Dg from"js-beautify";import{cloneDeep as Fg}from"lodash-es";import{homedir as Ug}from"os";import ts from"p-timeout";import{basename as Fd,join as $d}from"path";import{chromium as $g,devices as Bg,errors as zg}from"playwright";import{addExtra as Wg}from"playwright-extra";import Hg from"puppeteer-extra-plugin-recaptcha";import{v4 as jg}from"uuid";var Ur=(r,e)=>{try{let{hostname:t,pathname:n}=new URL(r),{hostname:o,pathname:s}=new URL(e);return t!==o||n!==s}catch{return!1}},Vo=r=>{try{return new URL(r),!0}catch{return!1}},nd=r=>!r.toLowerCase().startsWith("http"),qo=(r,e)=>{try{return new URL(r,e),!0}catch{return!1}};function dn(r,e){try{return!!new URL(r).origin.trim()}catch(t){return e?.error({url:r,err:t},"Invalid URL in check"),!1}}var rd={bannedClassSubstrings:["relative","flex","center","justify","auto","sticky","absolute","top","right","left","bottom","items-center"],bannedElementTagNames:["html","head","title","meta","iframe","script","style","path","svg","br","::marker","noscript"],bannedElementAttributes:["data-momentic-id","aria-keyshortcuts","data-ved","aria-controls"],relevantElementAttributes:["name","id","value","type","class","height","width","target","title","href","src","alt","role","headers","scope","checked","required","action","min","max","minlength","maxlength","multiple","pattern","placeholder","accept","data-value","data-testid","data-cy","data-test-id","data-test","data-role","data-type","data-action","data-aria-hidden","data-hidden","data-handleid","data-handlepos","aria-label","aria-role","aria-selected","aria-disabled","aria-hidden","aria-valuenow","aria-valuemin","aria-valuemax"]};function od(r){if(r[0]?.match(/[0-9a-zA-Z]/)===null)return!0;if(r.length>10){let d=Math.floor(r.length/8);if((r.match(/[-_:/ ]/g)??[]).length<d)return!0}if((r.match(/[^0-9a-zA-Z.]/g)??[]).length/r.length>.2)return!0;let t=(r.match(/[0-9]/g)??[]).length;if(t/r.length>.3)return!0;let n=(r.toLowerCase().match(/[aeiou]/gi)??[]).length;if((r.toLowerCase().match(/[bcdfghjklmnpqrstvwxyz]/gi)??[]).length/n>5)return!0;let s=new Set(["a","e","i","o","u","y"]),i=0,a=0;for(let d of r.toLowerCase())d>="a"&&d<="z"&&!s.has(d)?(a++,a>i&&(i=a)):a=0;if(i>4)return!0;let l=(r.match(/[A-Z]/g)??[]).length,c=(r.match(/[a-z]/g)??[]).length,u=Math.ceil(r.length*.3);return!!(c&&t&&Math.abs(c-t)<u||c&&l&&Math.abs(c-l)<u)}import{randomUUID as ld}from"crypto";import{distance as ki}from"fastest-levenshtein";import{cloneDeep as cd}from"lodash-es";import Qf from"p-timeout";var sd=new Set(["about:blank","chrome-error://chromewebdata/"]),id=3,it="data-momentic-id",ad=1e3,Ni=["button","image","generic","graphics-symbol","tab","link","menuitem","group"],_i=1e4,$r=500;var eg=["focusable","keyshortcuts","controls","live","relevant","orientation"],tg=["selected","readonly","modal","required","invalid"],ng=["id","name","role","content"],rg=["textbox","checkbox","combobox","table","caption","columnheader","rowheader","gridcell","row","rowgroup","cell","image","svgroot","button","link","list","listitem","tablist","tabpanel","tab","searchbox","menu","menubar","form","dialog","alertdialog","banner","navigation","main","menuitem","menuitemcheckbox","menuitemradio","option","radio","progressbar","switch"],og=["activeAriaModalDialog","activeFullscreenElement","activeModalDialog","ariaHiddenElement","ariaHiddenSubtree","hiddenByChildTree","inertElement","inertSubtree","notRendered","notVisible"],sg=["menulistpopup","statictext","inlinetextbox"],ig=80,Ko=["StaticText","ListMarker","RootWebArea","LineBreak","emphasis","::before","::after"],ag=["cite"],lg={LabelText:["label"],listitem:["li"],image:["img","svg"],link:["a"],RootWebArea:["#document"],paragraph:["p"],LineBreak:["br"],separator:["hr"]},dd={indentLevel:0,noID:!1,noChildren:!1,noProperties:!1,noContent:!1,maxLevel:void 0,neighbors:void 0},Di=class r{id;role;name;tagName;content;properties;dataMomenticId;pathFromRoot;parent;children;domNode;backendNodeID;ignoredByCDP;constructor(e){if(this.id=e.id,this.role=e.role,this.name=e.name,this.content=e.content,this.properties={},this.pathFromRoot=e.pathFromRoot,this.children=e.children,this.backendNodeID=e.backendNodeID,this.ignoredByCDP=e.ignoredByCDP,e.properties&&e.properties.forEach(t=>{t.name==="keyshortcuts"?this.dataMomenticId=parseInt(t.value.value):this.properties[t.name]=t.value.value}),e.domNode){this.domNode=e.domNode,this.tagName=e.domNode.tagName||void 0;let t=e.domNode.attributes.id;this.name=this.name||e.domNode.attributes.name||(t&&!od(t)?t:""),this.role=this.role||(e.domNode.attributes.role??""),pg(this.properties,e.domNode)}}getSerializedFormWithContext(){return this.serialize({noID:!0,maxLevel:1,neighbors:1})}getNodeOnlySerializedForm(){return this.serialize({noID:!0,noChildren:!0,noContent:!0})}getLogForm(){return JSON.stringify({id:this.id,name:this.name??"",role:this.role??"",backendNodeId:this.backendNodeID})}isInteresting(){return rg.includes(this.role.toLowerCase())||!this.properties.hidden&&(this.properties.focusable||this.properties.settable)||this.children.some(e=>e.role==="StaticText")?!0:!!this.name.trim()||!!this.content||Object.keys(this.properties).some(e=>e.startsWith("data"))}serialize(e=dd){let t=Object.assign({},dd,e),{indentLevel:n,noChildren:o,noProperties:s,noID:i,noContent:a}=t,l=cd(this.properties),c=" ".repeat(n),u=this.role||"",d=this.tagName??"unknown",m=this.name;u==="heading"&&m==="heading"&&(m="");let p=Ko.includes(this.role)||ag.includes(this.tagName||"");if(this.role==="StaticText"||this.role==="ListMarker")return`${c}${m}
|
|
1726
|
+
`;let f=`${c}<${d}`;if(!i&&!p&&(f+=` id="${this.id}"`),u&&u!=="generic"&&u!==d&&!(lg[u]??[]).includes(d)&&(f+=` role=${JSON.stringify(u)}`),m&&(f+=` name=${JSON.stringify(m)}`),this.content&&!a&&(f+=` content=${JSON.stringify(this.content)}`),Object.keys(l).length>0&&!s&&Object.entries(l).forEach(([g,y])=>{if(!eg.includes(g)){if(tg.includes(g)&&(!y||y==="false"))return;if(g==="value"&&a&&(l.type==="text"||this.role==="textbox"))return;if(g==="editable"&&y==="plaintext")return;if(g==="type"&&y===d)return;typeof y=="string"?f+=` ${g}="${y}"`:typeof y=="boolean"?y?f+=` ${g}`:f+=` ${g}={false}`:typeof y<"u"&&(f+=` ${g}={${JSON.stringify(y)}}`)}}),d==="::before"||d==="::after"){let g="";for(let y of this.children)g+=y.serialize({...e,indentLevel:n,neighbors:0});return g}let h=e.maxLevel!==void 0&&n/2>=e.maxLevel;if(this.children.length===0||o||h)f+=` />
|
|
1727
|
+
`;else{let g="";for(let S of this.children)g+=S.serialize({...e,indentLevel:n+2,neighbors:0});let y=g.trim();y.length<=ig&&!y.includes(`
|
|
1728
|
+
`)?f+=`>${y}</${d}>
|
|
1729
|
+
`:f+=`>
|
|
1730
|
+
${g}${c}</${d}>
|
|
1731
|
+
`}if(e.neighbors!==void 0&&e.neighbors>0&&this.parent){let g=this.parent.children.findIndex(b=>b.id===this.id),y=g>0?this.parent.children[g-1]?.serialize({...e,neighbors:0}):"",S=g<this.parent.children.length-1?this.parent.children[g+1]?.serialize({...e,neighbors:0}):"";return`${y||""}
|
|
1732
|
+
${f}
|
|
1733
|
+
${S||""}`}return f}shallowClone(){let e=new r({id:this.id,role:this.role,name:this.name,content:this.content,properties:[],pathFromRoot:this.pathFromRoot,children:[],backendNodeID:this.backendNodeID,ignoredByCDP:this.ignoredByCDP});return e.tagName=this.tagName,e.dataMomenticId=this.dataMomenticId,e.properties=cd(this.properties),e}},Fi=class r{constructor(e,t,n){this.root=e;this.a11yIdNodeMap=t;this.dataMomenticIdMap=n}serialize(){return this.root?this.root.serialize():""}pruneUsingRelevantIds(e){let t=this.root;if(!t)throw new Error("Cannot prune a11y tree with no root");function n(s,i=!1){let a=e.has(s.id)||s.id===t?.id,l=s.shallowClone(),c=s.children,u=!1,d=[];for(let m of c){let p=n(m,a||u);p&&(d.push(p),p.parent=l,u=!0)}if(l.children=d,a||u)return l;if(Ko.includes(s.role)&&i)return l}let o=n(t);return new r(o,this.a11yIdNodeMap,this.dataMomenticIdMap)}};function cg(r){return r.name?.value?`"${r.name.value}"`:r.role?.value&&r.role.value!=="none"&&r.role.value!=="generic"?`"${r.role.value}"`:`"${r.nodeId}"`}function dg(r,e,t,n){return r.bounds.x===null||r.bounds.y===null||r.bounds.height===null||r.bounds.width===null||r.bounds.width===0||r.bounds.height===0?!0:r.bounds.x+r.bounds.width<e.leftBound||r.bounds.x>e.rightBound?(Nn({logger:t,logKey:n,maxCount:5,intervalMs:3e3},{domNode:r,logKey:n},"Filtering out node since it is not in the viewport horizontally"),!1):r.bounds.y+r.bounds.height<e.upperBound||r.bounds.y>e.lowerBound?(Nn({logger:t,logKey:n,maxCount:5,intervalMs:3e3},{domNode:r,logKey:n},"Filtering out node since it is not in the viewport vertically"),!1):r.computedStyles.display==="none"?(t.debug({domNode:r},"Filtering out node since it has display none"),!1):!0}async function ud({node:r,parent:e,domGraph:t,inputNodeMap:n,cdpClient:o,logger:s,callId:i,filterByViewport:a,viewportDetails:l}){if(!e&&r.parentId)throw new Error(`Got no parent for accessibility node ${r.nodeId}: ${JSON.stringify(r)}`);let c=(S,b={})=>{},u=r.backendDOMNodeId,d=sg.includes((r.role?.value).toLowerCase());if(!d&&u===void 0)return c("Filtering out node since it doesn't exist in the DOM"),[];let m=u?t.backendIdToNode[u]:void 0;if(!d&&!m)try{let S=await Qf(o.send("DOM.describeNode",{backendNodeId:u}),{milliseconds:500,fallback:()=>{s.debug("Timeout getting node from CDP while processing a11y tree")}});if(S&&S.node.nodeName.toLowerCase()==="slot"&&S.node.distributedNodes?.length)s.debug({redirectedDomNode:m,parentAXNode:e?.getNodeOnlySerializedForm(),originalAXNode:r,cdpResult:S},"Redirected to assigned slot");else return c("Filtering out node since it doesn't exist in the DOM",{cdpResult:S}),[]}catch(S){return c("Filtering out node since it doesn't exist in the DOM",{err:S}),[]}if(m&&e&&a&&l&&r.backendDOMNodeId&&!dg(m,l,s,i))return m&&(m.momenticIgnored=!0),[];let p=r.name?.value?typeof r.name.value=="string"?r.name.value:`${r.name.value}`:"",f=r.value?.value?typeof r.value.value=="string"?r.value.value:`${r.value.value}`:"";if(p==="momentic_cursor"||p.includes("chakra"))return m&&(m.momenticIgnored=!0),[];let h=new Di({domNode:m,id:parseInt(r.nodeId),role:r.role?.value||"",name:p,content:f,properties:r.properties,children:[],pathFromRoot:(e?`${e.pathFromRoot} `:"")+cg(r),backendNodeID:r.backendDOMNodeId,ignoredByCDP:r.ignored});for(let S of r.childIds??[]){if(!S)continue;let b=n.get(parseInt(S));if(!b)continue;let C=await ud({node:b,parent:h,domGraph:t,inputNodeMap:n,cdpClient:o,logger:s,callId:i,filterByViewport:a,viewportDetails:l});C.length&&(h.children=h.children.concat(C))}if(h.role==="StaticText"&&(h.children=[]),h.children.length===1&&h.children[0].role==="StaticText"){let S=h.name,b=h.children[0]?.name;(S===b||!b)&&(h.children=[])}let g=[];for(let S=h.children.length-1;S>=0;S--){let b=h.children[S];if(b.role!=="StaticText"){g.push(b);continue}if(S===0||h.children[S-1].role!=="StaticText"){g.push(b);continue}h.children[S-1].name+=` ${b.name}`}if(h.children=g.reverse(),h.role==="generic"&&h.children.length===1){let S=h.children[0];if(h.name&&!Ko.includes(S.role)&&h.name===S.name)return m&&(m.momenticIgnored=!0),h.children}if(!h.isInteresting()&&r.parentId)return m&&(m.momenticIgnored=!0),h.children;for(let S of h.children)S.parent=h;return[h]}function md({node:r,a11yIdNodeMap:e,dataMomenticIdMap:t,logger:n,callId:o,startId:s=1}){r.id=s,s+=1,e.set(r.id,r),r.dataMomenticId?t.set(r.dataMomenticId,r):Ko.includes(r.role);for(let i of r.children)s=md({node:i,a11yIdNodeMap:e,dataMomenticIdMap:t,logger:n,callId:o,startId:s});return s}async function pd({a11yGraph:r,domGraph:e,logger:t,cdpClient:n,filterByViewport:o,viewportDetails:s}){if(!r.root)throw new Error("A11y tree has no root");let i=ld();r.allNodes=r.allNodes.filter(d=>d.ignored?!d.ignoredReasons?.find(p=>og.includes(p.name)):!0);let a=new Map;for(let d of r.allNodes)a.set(parseInt(d.nodeId),d);let l=await ud({node:r.root,domGraph:e,parent:null,inputNodeMap:a,cdpClient:n,logger:t,callId:ld(),filterByViewport:o,viewportDetails:s});if(l.length>1)throw new Error(`Something went horribly wrong processing the a11y tree, we got: ${JSON.stringify(l)}`);if(l.length===0)throw new Error("There are no accessible elements on this page or frame. Are you sure this website loads properly?");let c=new Map,u=new Map;return md({node:l[0],a11yIdNodeMap:c,dataMomenticIdMap:u,logger:t,callId:i}),new Fi(l[0],c,u)}var Ui=(r,e)=>{let t=1,n=["name","role","content"];for(let o of n){let s=r[o];if(typeof s!="string"||!s.trim()||e[o]===void 0)continue;let i=ki(s,e[o])/Math.min(s.length,e[o].length);i===0?t+=2:i<=.1&&t++}if(e.numChildren!==void 0&&(r.children.length===e.numChildren&&e.numChildren>0?t++:t--),e.nodeOnlySerializedForm){let o=r.getNodeOnlySerializedForm(),s=ki(o,e.nodeOnlySerializedForm)/Math.min(o.length,e.nodeOnlySerializedForm.length);s===0?t+=2:s<=.1&&t++}if(e.serializedForm){let o=r.serialize({noID:!0,maxLevel:1,neighbors:1}),s=ki(o,e.serializedForm)/Math.min(o.length,e.serializedForm.length);s===0?t+=2:s<=.1&&t++}return t},ug=["href","src"];function mg(r,e){if(e==="true")return!0;if(e==="false")return!1;try{let t=parseInt(e);if(!isNaN(t))return t}catch{}return ug.includes(r)&&e.length>60?e.slice(0,50)+"...":r==="src"&&e.includes("base64")?e.slice(0,e.indexOf("base64")+6)+"...":e}function pg(r,e){e&&Object.entries(e.attributes).forEach(([t,n])=>{rd.relevantElementAttributes.includes(t)&&!ng.includes(t)&&!r[t]&&!t.startsWith("aria")&&t!=="class"&&(r[t]=mg(t,n))})}function hd(r,e,t=4e3){let n=[],o=Math.floor(t/2),s=`id="${r}"`,i=0,a=e.indexOf(s,i);for(;a!==-1;){let l=Math.max(i,a-o),c=Math.min(e.length,a+o),u=e.slice(l,c);n.push(u),i=c,a=e.indexOf(s,i)}return n.join(`
|
|
1736
1734
|
...
|
|
1737
|
-
`)}var
|
|
1735
|
+
`)}var un={r:147,g:196,b:125,a:.55},fd={showRulers:!1,showStyles:!1,showExtensionLines:!1,contrastAlgorithm:"aa",contentColor:un,paddingColor:un,borderColor:un,marginColor:un,eventTargetColor:un,shapeColor:un,shapeMarginColor:un,showInfo:!0,showAccessibilityInfo:!0};var Yo=["display","opacity","visibility","height","max-height","overflow"];function gd({snapshot:r,devicePixelRatio:e,pageFrameId:t}){let n=r.strings,o=r.documents,s=o[0];t&&(s=o.find(l=>n[l.frameId]===t));let i={};return{root:hg(s,n,e,i),backendIdToNode:i}}function hg(r,e,t,n){let o=r.layout,s={};o.nodeIndex.forEach((f,h)=>{s[f]=h});let i=o.styles,a=o.bounds??[],l=r.nodes,c=l.backendNodeId??[],u=l.attributes??[],d=l.parentIndex??[],m=l.nodeName??[],p=l.inputChecked??{index:[]};for(let f=0;f<c.length;f++){let h=c[f],g=u[f]??[],y=d[f]&&d[f]>=0?d[f]:null,S=s[f],b;S?b=a[S]??[]:b=[];let C={backendNodeId:h,bounds:{x:b[0]??null,y:b[1]??null,width:b[2]??null,height:b[3]??null},computedStyles:{},attributes:{},parentBackendNodeId:y?c[y]:null,tagName:m[f]!==void 0?e[m[f]]?.toLowerCase():void 0,children:[],momenticIgnored:void 0};C.parentBackendNodeId&&n[C.parentBackendNodeId].children.push(h);for(let E of Object.keys(C.bounds)){let P=E;C.bounds[P]!==null&&(C.bounds[P]/=t)}let v=i[f]??[];for(let E=0;E<v.length&&!(E>=Yo.length);E++){let P=v[E];if(!P||isNaN(P))continue;let A=e[P];if(!A)continue;let O=Yo[E];C.computedStyles[O]=A}for(let E=0;E<g.length;E+=2){let P=g[E],A=g[E+1];if(!P||!A)continue;let O=e[P],M=e[A];!O||!M||(C.attributes[O]=M)}p.index.includes(f)&&(C.attributes.checked="true"),n[C.backendNodeId]=C}return n[c[0]]}async function Wr(r){return r.evaluate(e=>{let t=Array.from(e.attributes).reduce((n,o)=>{let s=`${n} ${o.name}="${o.value}"`;return s.length<=50?s:n},"");return`<${e.tagName.toLowerCase()}${t.length>0?t+" ":""}/>`},void 0,{timeout:750})}var K=async(r=1e3,e)=>{for(;r>0;){if(e?.())throw new st("Operation cancelled by user");let t=Math.min(r,15e3);r-=t,await new Promise(n=>setTimeout(()=>n(),t))}};function yd(){return window.lastCursorPos}function Sd(){window.globalHintManager||(window.globalHintManager=new window.HintManager),window.globalHintManager.capture()}function wd(){window.globalHintManager&&window.globalHintManager.reset()}async function Hr(r,e){let t=Date.now();for(;Date.now()-t<8e3;){try{if(await r.evaluate(()=>{let o=window;return!!(o.generateCssSelectors&&o.evaluateCssSelectors&&o.generateHtmlCacheAttributes&&o.ldist)},{timeout:1e3}))return}catch{}e.debug("Waiting for momentic browser scripts to load..."),await K(500)}throw new Error(`Failed to load momentic browser scripts on page ${r.url()}`)}var bd=`(function () {
|
|
1738
1736
|
if (document.__customCookieSetterApplied__) {
|
|
1739
1737
|
return;
|
|
1740
1738
|
}
|
|
@@ -1760,43 +1758,45 @@ ${w||""}`}return h}shallowClone(){let e=new r({id:this.id,role:this.role,name:th
|
|
|
1760
1758
|
originalCookieProperty.set.apply(document, [value]);
|
|
1761
1759
|
},
|
|
1762
1760
|
});
|
|
1763
|
-
})()`;var
|
|
1761
|
+
})()`;var Cd=({nodeOnlySerializedHtml:r})=>{let e=window;if(!e.ldist||!e.serializeElementOnlyWithText||!e.getAllElements)return{error:"Momentic core libraries not found"};let t=e.getAllElements(),n,o,s=1/0,i;for(let a of t){let l=e.serializeElementOnlyWithText(a),c=e.ldist(r,l);c<s?(s=c,o=l,n=a.getAttribute("data-momentic-id")??void 0,i=void 0):c===s&&(i=l)}return i?{error:`[MOMENTIC] Multiple HTML elements with same distance (${s}) found:
|
|
1764
1762
|
${i}
|
|
1765
1763
|
==================
|
|
1766
1764
|
${o}
|
|
1767
|
-
`}:{dataMomenticId:n,closestDistance:s,closestNodeSerialized:o}};import{mkdirSync as gg,rmSync as fc,statSync as hg}from"fs";import fg from"nodejs-file-downloader";import{tmpdir as yg}from"os";import Sg from"p-timeout";import Ar,{basename as yc,dirname as wg}from"path";var yn="file://",Sc=Ar.join(yg(),"momentic","downloads"),Ns=1e4,bg=50*1024*1024;async function wc({uri:r,logger:e,orgId:t}){if(r.startsWith(yn)){let h=Ar.join(Sc,t,r.slice(yn.length));return{filePath:h,momenticUri:r,cleanup:()=>{fc(wg(h),{recursive:!0,force:!0})}}}let n=new URL(r);n.search&&(n.search="");let o=yc(n.href),s=ks(o),i=Ar.extname(s);if(_a.includes(i))throw new Error(`Downloading files with extension ${i} is not allowed.`);let a=Ds(t),l=new fg({url:r,fileName:s,directory:a,maxAttempts:2,headers:{"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36"},timeout:Ns}),{downloadStatus:c,filePath:u}=await Sg(l.download(),{milliseconds:Ns,message:`Download timed out after ${Ns}ms`});if(c!=="COMPLETE")throw new Error(`Download ended in non-success status: ${c}`);if(!u)throw new Error("File path of successfully downloaded file was empty");let m=hg(u).size;if(m>bg)throw new Error("File size exceeds the maximum limit of 50MB");e.info({fileSizeInBytes:m,filePath:u,fileName:s},"Downloaded file to disk");let p;return{filePath:u,momenticUri:_s(yc(a),s),cleanup:()=>{clearTimeout(p),p=setTimeout(()=>fc(a,{recursive:!0,force:!0}),10*60*1e3)}}}function _s(r,e){return`${yn}${r}/${e}`}function Ds(r){let e=Math.random().toString(36).substring(4),t=Ar.join(Sc,r,e);return gg(t,{recursive:!0}),t}function ks(r){let e=Ar.extname(r),t=Ar.basename(r,e);return r=(t.length>100?t.slice(t.length-100):t)+e,r=r.trim().replaceAll(" ","_"),r}async function bc({locator:r,logger:e}){let[t,n]=await r.evaluate(s=>[s.tagName.toLowerCase(),s.getAttribute("class")??""],{timeout:1e3});if(t!=="input"||!n.toLowerCase().includes("chakra"))return;let o=await r.boundingBox({timeout:2e3});if(o===null){e.warn({elementDisplayString:await hn(r)},"Attempting to click on element with no bounding box");return}if(!(o.width!==1||o.height!==1))try{await fn(r.page(),e);let s=await r.evaluate(a=>{let l=window;if(!l.CssSelectorGenerator)return{type:"error",error:"[MOMENTIC] Missing CSS selector libraries"};let c=a.parentElement;if(!c)return{type:"error",error:"Input click target has no parent for redirection"};let u=l.CssSelectorGenerator.getCssSelector(c,{}),d=a.getBoundingClientRect(),m=c.getBoundingClientRect(),p={x:Math.min(Math.max(1,d.left-m.left),m.width-1),y:Math.min(Math.max(1,d.top-m.top),m.height-1)};return{type:"result",selector:u,relativePoint:p,serializedForm:c.outerHTML.slice(0,500)}},{timeout:1e3});if(s.type==="error")throw new Error(s.error);let i=r.page().locator(s.selector);return await i.waitFor({state:"attached",timeout:2e3}),e.info(s,`Redirected click to parent element with selector: ${s.selector}`),{locator:i,relativePoint:s.relativePoint}}catch(s){e.error({err:s},"Failed finding parent label for Chakra element");return}}var Tc=["date","datetime-local","month","time","week"],Cc={date:/^\d{4}-\d{2}-\d{2}$/,"datetime-local":/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}$/,month:/^\d{4}-\d{2}$/,time:/^\d{2}:\d{2}$/,week:/^\d{4}-W\d{2}$/};async function Ec(r,e,t,n){let o=(await r.evaluate(()=>document.activeElement?.getAttribute("type"))??"").toLowerCase();return Cc[o]&&(Cc[o].test(e)&&n.warn(`Detected datetime input (${e}) in normalized format - this may fail to fill correctly as it is not how the user would input the value`),t.pressKeysSequentially=!0,t.clearContent=!1,n.debug("Transforming datetime input to use sequential key presses")),!1}async function vc(r,e,t,n,o){try{await Cg(r,e,t,n)}catch(s){o.error({err:s,tabIndex:e},"Error handling new console log")}}async function Cg(r,e,t,n){let o=n.text();o.length>mn&&(o=o.slice(0,mn)+"...(TRUNCATED)");let s=[];for(let i of n.args())try{let a=await i.jsonValue(),l=JSON.stringify(a);l.length>mn?s.push(l.slice(0,mn)+"...(TRUNCATED)"):(typeof a!="object"||Object.keys(a).length>0)&&s.push(a)}catch{}Fs(r,t,e,{url:r.url(),location:n.location(),type:n.type(),text:n.text(),args:s})}function Fs(r,e,t,n){let o=Date.now(),s=e.logsPerPage;if(s.length<=t||s[t]===void 0){s[t]=[];for(let i=0;i<t;i++)s[i]===void 0&&(s[i]=[])}s[t].length>Is&&(s[t]=s[t].slice(Math.floor(Is/2)),s[t]?.push({url:r.url(),timestamp:o,type:"warning",text:"[MOMENTIC] Truncated console logs due to buffer overflow",tabIndex:t})),s[t].push({...n,tabIndex:t,timestamp:o})}async function ot(r,e,t){let n=Date.now(),o=await r(),s=Date.now();return t[e]=s-n,o}function xc(){return async r=>{let{fragment:e,code:t,context:n}=r,{env:o,results:s,inputs:i}=n||{},a=Object.getPrototypeOf(async function(){}).constructor;return{result:await Promise.resolve(new a("env","results","inputs",e?`return ${t}`:t)(o,s,i))}}}var jg=Nc(Fg(),"momentic","chromium"),Rr=process.env.TWO_CAPTCHA_KEY,Co=zg(Ug);Co.use(Hg({provider:{id:"2captcha",token:Rr},visualFeedback:!0}));async function Us(r,e){let t,n;for(let o=0;o<4;o++)try{return t=r.pages(),(await Promise.all(t.map(async s=>({title:await s.title(),url:s.url()})))).filter(s=>Jt(s.url,e))}catch(s){n=s,await X(500)}throw new Error(`Failed to get tab titles after all retries: ${n?.message}`)}var st=class r{static USER_AGENT=$g["Desktop Chrome"].userAgent;contextInitialized=!1;browser;context;page;systemDevicePixelRatio;userControlledBrowserSettings;pageLoadPromise=null;lastTabChangeEventTimeout=void 0;a11yIdToNodeMap=new Map;dataMomenticIdToNodeMap=new Map;mostRecentA11yTree;domGraph=void 0;cdpClient;debugData={logsPerPage:[]};enricher;storage;logger;localMode;activeFrame;activeFrameCache;transformer;baseUrl;originsVisited=new Set;viewport;onTabsChange=void 0;constructor({storage:e,enricher:t,browser:n,context:o,page:s,baseUrl:i,logger:a,localMode:l,cdpClient:c,userBrowserSettings:u,viewport:d,onTabsChange:m,systemDevicePixelRatio:p}){Da(u),this.storage=e,this.enricher=t,this.browser=n,this.context=o,this.cdpClient=c,this.page=s,this.baseUrl=i,this.logger=a,this.userControlledBrowserSettings=u,this.localMode=!!l,this.viewport=d||ct,this.onTabsChange=m,this.systemDevicePixelRatio=p}async initializeContext(){if(this.contextInitialized)return;this.userControlledBrowserSettings.extraHeaders&&await this.context.setExtraHTTPHeaders(this.userControlledBrowserSettings.extraHeaders),await this.context.grantPermissions(["clipboard-read","clipboard-write","microphone","camera"]);let e=[this.context.addInitScript({content:dn.cssGeneratorLibJs}),this.context.addInitScript({content:dn.htmlUtilsLibJs}),this.context.addInitScript({content:"window._MOMENTIC_BROWSER = true;"})];this.localMode&&e.push(this.context.addInitScript({content:gc}));let t=n=>this.handleNewPageEvent(n);this.context.on("page",t),await this.handleNewPageEventHelper(this.page),this.context.on("close",()=>{this.logger.debug("Chrome browser context was closed"),this.context.off("page",t)}),await Promise.all(e),this.contextInitialized=!0}static async init({baseUrl:e,logger:t,storage:n,enricher:o,userBrowserSettings:s,browserArgs:i,contextArgs:a,onClose:l,waitForLoad:c=!0,localMode:u,localAppUrl:d,extensionPath:m,skipPageSetup:p,timeout:h,browserbaseConnectUrl:g,onTabsChange:f}){process.env.PW_TEST_SCREENSHOT_NO_FONTS_READY="1";let y={headless:!0,handleSIGTERM:!1,chromiumSandbox:!1,...i??{}},w={viewport:ct,userAgent:s.userAgent??r.USER_AGENT,geolocation:{latitude:37.7749,longitude:-122.4194},locale:"en-US",timezoneId:"America/Los_Angeles",...a??{}},b=null,C,v;if(u)C=await Co.launchPersistentContext(jg,{...y,...w,ignoreDefaultArgs:["--enable-automation","--enable-strict-mixed-content-checking"],ignoreHTTPSErrors:!0,bypassCSP:!0,args:["--allow-insecure-localhost","--disable-site-isolation-for-policy","--disable-site-isolation-trials",`--unsafely-treat-insecure-origin-as-secure=${d}`,`--load-extension=${m}`,"--test-type=browser","--use-fake-device-for-media-stream","--use-fake-ui-for-media-stream"],baseURL:e}),v=C.pages()[0],l&&v.on("close",()=>{l()});else if(g){b=await Co.connectOverCDP(g);let P=b.contexts()[0];if(!P)throw new Error("Failed to get browserbase default context");let D=P.pages()[0];if(!D)throw new Error("Failed to get browserbase default page");C=P,v=D}else{b=await Co.launch({...y,args:["--disable-dev-shm-usage","--no-first-run","--renderer-process-limit=4","--disable-site-isolation-for-policy","--disable-site-isolation-trials","--autoplay-policy=user-gesture-required","--disable-add-to-shelf","--disable-desktop-notifications","--use-fake-device-for-media-stream","--use-fake-ui-for-media-stream"]});let P={...w,baseURL:e};C=await b.newContext(P),t.debug({contextArgs:P},"Browser initialization context args"),v=await C.newPage()}let E=await r.initCDPSession(C,v,t,h),I=new r({browser:b,context:C,page:v,baseUrl:e,logger:t,storage:n,enricher:o,localMode:u,userBrowserSettings:s,cdpClient:E,viewport:w.viewport||ct,onTabsChange:f,systemDevicePixelRatio:w.deviceScaleFactor});await I.initializeContext();let x=async()=>{try{await I.navigate({url:e,initialNavigation:!p,loadTimeoutMs:h})}catch(P){if(t.error({err:P},"Failed to initialize Chrome browser"),c)throw P}};return c?await x():x(),I}async handleAvailableTabsChangeHelper(){try{let e=await Us(this.context,this.logger),t=this.page.url();this.onTabsChange?.(e,t)}catch(e){this.logger.error({err:e},"Error sending available tabs to frontend")}}async handleAvailableTabsChange(){try{clearTimeout(this.lastTabChangeEventTimeout),this.lastTabChangeEventTimeout=setTimeout(()=>this.handleAvailableTabsChangeHelper(),1500)}catch(e){this.logger.warn({err:e},"Error handling available tabs change")}}async handlePageErrorEvent(e){}handlePageClosedEvent(e){if(!this.browser||!this.browser.isConnected())return;let t=async()=>{try{if(this.page!==e){this.logger.info({url:e.url()},"Detected background page was closed"),this.handleAvailableTabsChange();return}this.logger.info({url:e.url()},"Detected active page was closed, switching to another tab");let n=this.context.pages();for(let o=n.length-1;o>=0;o--){let s=n[o];if(!(!s||s.isClosed()||!Jt(s.url()))){this.logger.info(`Automatically switching to tab ${o} after close: ${s.url()}`),await this.switchToPageByIndex(s,o);break}}}catch(n){this.logger.warn({err:n},"Error in page close event handler")}};this.pageLoadPromise=t()}async handleNewPageEvent(e){let t=e.url();if(!(!t.trim()||t==="about:blank"))try{this.logger.debug({url:t},"Detected new page event, registering handlers and waiting for load to complete"),await this.handleNewPageEventHelper(e)}catch(n){this.logger.warn({err:n},"Error handling new page open, continuing....")}}async handleNewPageEventHelper(e){e.on("close",o=>this.handlePageClosedEvent(o)),e.on("pageerror",async o=>this.handlePageErrorEvent(o)),e.on("framenavigated",async o=>{o===e.mainFrame()&&await this.handleFrameNavigationEvent(o)});let t=this.context.pages().indexOf(e);e.on("console",o=>{vc(e,t,this.debugData,o,this.logger)});let n=this.pageLoadPromise;this.pageLoadPromise=(async()=>{try{await Promise.resolve(n),await this.loadFrameAndRecordUrl(e),this.handleAvailableTabsChange()}catch(o){this.logger.error({err:o},"Failed to wait for new page to load")}finally{this.pageLoadPromise=null}})()}async handleFrameNavigationEvent(e){let t=e.url();if(!t||t==="about:blank")return;let n=this.pageLoadPromise;this.pageLoadPromise=(async()=>{try{await Promise.resolve(n),await this.loadFrameAndRecordUrl(e),this.handleAvailableTabsChange()}catch(o){this.logger.error({err:o},"Failed to wait for frame navigation to finish")}finally{this.pageLoadPromise=null}})()}async getLocatorFromCdpFrame(e,t){let n=this.page;for(let a of t)n=n.frameLocator(`iframe[src=${JSON.stringify(a)}]`);let o=this.getAttributeFromStringArray(e.attributes??[],"src");if(!o)throw new Error(`Got iframe without src attribute: ${JSON.stringify(e)}`);let s=n.locator(`iframe[src=${JSON.stringify(o)}]`),i=await(await s.evaluateHandle(a=>a,{timeout:1e3})).asElement().contentFrame();if(!i)throw new Error(`Got null frame from locator: ${s}`);return await this.loadFrameAndRecordUrl(i),i}async getMatchingFrame(e){if(e.type!=="url")throw new Error("Only url frame identifiers are supported now");let t=e.url,o=[{node:(await this.cdpClient.send("DOM.getDocument",{pierce:!0,depth:-1})).root,srcChain:[]}],s=[];for(;o.length>0;){let i=o.pop(),a=i.node,l=i.srcChain;if(a.nodeName.toLowerCase()==="iframe"){let c=this.getAttributeFromStringArray(a.attributes??[],"src");if(!c)continue;t.startsWith("/")&&t.endsWith("/")?new RegExp(t.slice(1,-1)).test(c)&&s.push({node:a,frame:await this.getLocatorFromCdpFrame(a,l)}):t.trim()===c.trim()&&s.push({node:a,frame:await this.getLocatorFromCdpFrame(a,l)}),l=[...l,c]}for(let c of a.children??[])o.push({node:c,srcChain:l});a.contentDocument&&o.push({node:a.contentDocument,srcChain:l})}if(s.length===1)return s[0];throw s.length>1?new Error(`Found multiple frames with src matching '${t}'. Please use a more specific selector.`):new Error(`Failed to find frame with src matching: ${t}`)}async getActivePageOrFrameHelper(){if(!this.activeFrame)return this.page;let e,t="";if(this.activeFrame.type==="url")t=this.activeFrame.url,e=(await this.getMatchingFrame(this.activeFrame)).frame;else throw new Error(`Frame identifier type ${this.activeFrame.type} is not yet supported`);if(e)return e;throw new R("InternalWebAgentError",`Failed to find frame with src matching '${t}' on page`)}static async initCDPSession(e,t,n,o=8e3){let s=2,i=async()=>{try{let l=await e.newCDPSession(t);return l.on("Target.targetCrashed",c=>{n.error({payload:c},"CDP session crashed, Momentic will likely not function correctly")}),l.on("Inspector.targetCrashed",c=>{n.error({payload:c},"CDP inspector session crashed, Momentic will likely not function correctly")}),await l.send("Accessibility.enable"),await l.send("DOM.enable"),await l.send("Overlay.enable"),l}catch(l){if(s>0)return n.debug({err:l},"Failed to initialize CDP session, re-creating CDP client"),await X(500),s--,i();throw l}};return await bo(i(),{milliseconds:o,fallback:()=>{throw new Error(`Failed to initialize session within page load timeout (${t.url()})`)}})}ping(){if(this.closed)throw new Error("Page has been closed");if(this.browser&&!this.browser.isConnected())throw new Error("Browser is not connected")}setActiveFrame(e){e?(this.activeFrame=e,this.activeFrameCache=void 0):(this.activeFrame=void 0,this.activeFrameCache=void 0)}async reset(e){this.debugData.logsPerPage=[],this.a11yIdToNodeMap.clear(),this.dataMomenticIdToNodeMap.clear(),e.clearCookies&&await this.context.clearCookies();let t=this.context.pages();for(let s=0;s<t.length;s++){if(e.clearStorage){let i=t[s].url();try{this.originsVisited.delete(new URL(i).origin)}catch{}try{await t[s].evaluate(async()=>{window.localStorage.clear(),window.sessionStorage.clear(),await indexedDB.databases().then(a=>{a.forEach(l=>{l.name&&indexedDB.deleteDatabase(l.name)})})},{timeout:1e3})}catch(a){this.logger.debug({err:a},"Failed clearing site data, continuing...")}}s!==0&&!this.localMode&&(this.logger.debug(`Closing tab ${t[s].url()}`),await t[s].close())}if(this.page=this.context.pages()[0],this.page.isClosed()){this.logger.debug("Page is closed, exiting reset early");return}let n=await r.initCDPSession(this.context,this.page,this.logger,e.timeout),o=this.cdpClient;this.cdpClient=n;try{await o.detach()}catch{}if(e.clearStorage)for(let s of this.originsVisited)this.logger.debug({origin:s},"Clearing data using CDP"),await this.cdpClient.send("Storage.clearDataForOrigin",{origin:s,storageTypes:"all"}),this.originsVisited.delete(s);await this.navigate({url:e.url??this.baseUrl,initialNavigation:!0,loadTimeoutMs:e.timeout})}async toggleHints(e){let t=this.page;e.state==="on"?(await t.addStyleTag({content:dn.vimiumCss}),await t.addScriptTag({content:dn.vimiumJs}),await t.evaluate(mc,{timeout:1e3})):await t.evaluate(pc,{timeout:1e3})}async showHints(){await this.toggleHints({state:"on"});let e=async()=>{try{await this.toggleHints({state:"off"})}catch(t){this.logger.debug({err:t},"Failed to remove vision hints")}};setTimeout(()=>{e()},3e3)}async cleanup(){if(!this.browser)return;let e=this.browser;this.browser=null;try{this.originsVisited.clear(),await this.page.close(),await this.context.close(),await e.close()}catch(t){throw new Error(`Error cleaning up browser: ${t}`)}finally{this.browser=null}}get closed(){return!this.browser||!this.browser.isConnected()}async html(){return(await this.getActivePageOrFrame()).content()}url(){return this.page.url()}async screenshotWithHints(e){let t=e.saveToDiskPath?.split("."),n=t?.slice(0,-1).join("."),o=t?.slice(-1)[0],s=Buffer.from("");await this.showHints();let i=await this.screenshot({...e,saveToDiskPath:e.saveToDiskPath?`${n}-after-hint.${o}`:void 0});return{before:s,after:i}}async screenshot(e){let{retries:t=1}=e;try{let n=await this.screenshotHelper({...e,retries:t});if(n.byteLength>5e6)this.logger.error("Page screenshot is greater than 5MB, which may cause performance issues with some AI models");else if(n.length===0)throw new Error("Got empty screenshot");return n}catch(n){if(t>0)return this.logger.debug({err:n},"Failed taking screenshot, retrying..."),await X(500),this.screenshot({...e,retries:t-1});throw n}}async screenshotHelper({target:e,quality:t,scale:n="device",saveToDiskPath:o,hideCaret:s,timeout:i,clearHighlights:a=!1}){a&&await this.removeAllHighlights();let l={fullPage:!1,type:"jpeg",quality:t,scale:n,caret:s?"hide":"initial",path:o,timeout:i??4e3};e&&(l.scale="css");let c;if(l.scale==="css"||l.path)c=await this.page.screenshot(l);else{let u=await this.cdpClient.send("Page.captureScreenshot",{format:"jpeg",quality:t,fromSurface:!0,optimizeForSpeed:!0});c=Buffer.from(u.data,"base64")}if(!e)return c;if(e){let u;"id"in e?u=(await this.resolveTarget(null,e)).locator:u=e;let d=await u.boundingBox();if(!d)throw new Error("Attempted to screenshot an element that is not visible on the page");let{x:m,y:p,width:h,height:g}=d;if(!h||!g)throw new Error("Attempted to screenshot an element with zero width or height");if(m<0||p<0)throw new Error("Attempted to screenshot an element with negative coordinates");m=Math.floor(m),p=Math.floor(p),h=Math.ceil(h),g=Math.ceil(g);try{c=await(await _g.fromBuffer(c)).crop({x:m,y:p,w:h,h:g}).getBuffer("image/jpeg")}catch(f){throw new Error(`Failed taking element screenshot at coordinates (${m}, ${p}) with size (${h}, ${g}): ${f}`)}}return c}async getViewport(){return this.viewport}async navigate({url:e,initialNavigation:t=!1,loadTimeoutMs:n=this.pageLoadTimeout}){Xl(e)&&(e=new URL(e,this.baseUrl).toString());let o=Date.now();this.logger.debug(`Navigating to ${e}`);try{t||await this.waitForDOMStability();try{await this.page.goto(e,{timeout:n,waitUntil:"domcontentloaded"})}catch(i){throw new R("ActionFailureError",i.message)}await this.loadFrameAndRecordUrl(this.page),this.logger.debug({url:e},`Navigation complete in ${Math.floor(Date.now()-o)}ms`)}catch(i){if(i instanceof Error&&i.message.includes("ERR_ABORTED")){this.logger.error({err:i},"Navigation error, possibly due to user cancellation");return}throw i}let s=this.url();if(Ql.has(s))throw new R("ActionFailureError",`${e} took too long to load \u{1F61E}. Please ensure the site and your internet are working.`,{},!0);if(t)try{await this.exposeRecordingBindings()}catch(i){i instanceof Error&&i.message.includes("already registered")||this.logger.error({err:i},"Failed to install Momentic libraries for action recording")}}async type(e,t={},n=!1){await this.directTypeHelper(e,t,n)}async directTypeHelper(e,t={},n=!1){let o=await this.getActivePageOrFrame();if(!await Ec(o,e,t,this.logger)){if(n){let s=Date.now(),i=!1;for(;Date.now()-s<this.smartWaitingTimeout;){let a=await o.evaluate(()=>document.activeElement&&document.activeElement.tagName.toLowerCase());if(a&&a!=="body"){i=!0;break}await X(250)}i||this.logger.warn("No active element found to type into, attempting anyways")}t.clearContent&&(process.platform==="darwin"?await this.page.keyboard.press("Meta+A"):await this.page.keyboard.press("Control+A"),await this.page.keyboard.press("Backspace")),t.pressKeysSequentially?await this.page.keyboard.type(e,{delay:100}):(await this.page.waitForTimeout(25),await this.page.keyboard.insertText(e)),t.pressEnter&&await this.page.keyboard.press("Enter")}}async scrollIntoView(e){await e.scrollIntoViewIfNeeded({timeout:4e3})}async highlight(e,t){try{let n=await this.resolveTarget(null,e,{skipFetchTree:!0});return await this.highlightTarget(n.locator,t),!0}catch(n){return this.logger.debug({err:n,target:e},"Failed to highlight target"),!1}}async removeAllHighlights(){await(await this.getActivePageOrFrame()).evaluate(()=>{let e=window,t=e.removeHighlightTimers||[];for(;t.length;){let n=t.pop();clearTimeout(n)}Object.values(e.removeHighlightFunctions??{}).forEach(n=>{n()})},{timeout:1e3})}async highlightTarget(e,t){try{return await this.removeAllHighlights(),await e.evaluate(n=>{let o=window;o.momenticIsEligible=c=>{let d=window.getComputedStyle(c,null).getPropertyValue("display");if(d==="none"||d==="contents")return!1;let m=c.getBoundingClientRect();return!(!m.height||!m.width)},o.removeHighlightTimers=o.removeHighlightTimers||[],o.removeHighlightFunctions=o.removeHighlightFunctions||{};let s=0;for(;!o.momenticIsEligible(n)&&s<3;){if(!n.parentElement)throw new Error("No eligible non-empty parent found for highlighting");n=n.parentElement,s++}let i=n.style.getPropertyValue("outline"),a=n.style.getPropertyPriority("outline");n.style.setProperty("outline","5px dashed rgb(255, 0, 153)","important");let l=`momentic${Math.floor(Math.random()*1e7)}`;o[l]=()=>{n.style.removeProperty("outline"),n.style.setProperty("outline",i,a)},o.removeHighlightTimers.push(setTimeout(()=>{o[l](),o.removeHighlightFunctions?.[l]&&delete o.removeHighlightFunctions[l]},5e3)),o.removeHighlightFunctions[l]=o[l]},t?.color,{timeout:1e3}),!0}catch(n){return this.logger.debug({err:n},"Failed to add node highlight, a page navigation likely occurred. This is non-fatal for tests."),!1}}recordUrlVisited(e){try{this.originsVisited.add(new URL(e).origin)}catch(t){this.logger.warn({err:t},"Failed to record origin visited")}}async wrapPageLoad(e){return await Promise.resolve(this.pageLoadPromise),await e()}async loadAuthState(e){await this.wrapPageLoad(async()=>{await this.waitForDOMStability(),await this.loadAuthStateHelper(e)})}async loadAuthStateHelper(e){let t=[];for(let o of e.cookies){let s=await this.setCookie(o);t=t.concat(s)}this.logger.info({cookiesSet:t},"Loaded cookies"),await this.cdpClient.send("DOMStorage.enable");let n=0;for(let o of e.origins??[])for(let s of o.localStorage)try{await this.cdpClient.send("DOMStorage.setDOMStorageItem",{storageId:{securityOrigin:new URL(o.origin).origin,isLocalStorage:!0},key:s.name,value:s.value}),n++}catch(i){this.logger.warn({err:i,origin:o},"Failed to set local storage entry");break}this.logger.debug({storageState:e},`Loaded ${e.cookies.length} cookies and ${n} local storage entries`),await this.refresh()}async saveAuthState(){return this.context.storageState()}async getOpenPageUrls(){return(await Us(this.context,this.logger)).map(t=>t.url)}saveA11yDetailsToCache(e,t){t.id=e.id,t.content=e.content,t.name=e.name,t.role=e.role,t.numChildren=e.children.length,t.serializedForm=e.getSerializedFormWithContext(),t.nodeOnlySerializedForm=e.getNodeOnlySerializedForm()}async saveNodeDetailsToCache(e,t,n,o,s){if(t&&this.saveA11yDetailsToCache(t,n),!(n.generatedSelectors&&n.generatedSelectors.length>1)){if(o)n.dataMomenticId=o;else{this.logger.debug("No data-momentic-id found for target, skipping HTML attribute generation");return}try{let i=await this.fetchHtmlAttributes(e,o);Object.assign(n,i)}catch(i){this.logger.warn({err:i},"Failed to fetch HTML attributes for target")}if(Rs.includes(n?.role??""))try{await this.saveElementVisualAttributes(n,s)}catch(i){this.logger.debug({err:i},"Failed to get element screenshot while saving node details")}}}async saveElementVisualAttributes(e,t){if(!t)return;await t.scrollIntoViewIfNeeded({timeout:4e3});let n=await t.boundingBox();if(!n||!n.width||!n.height){e.boundingBox=void 0,e.screenshotUrl=void 0;return}let{x:o=0,y:s=0,width:i=0,height:a=0}=n;if(e.boundingBox&&Math.abs(e.boundingBox.width-i)<1&&Math.abs(e.boundingBox.height-a)<1&&Math.abs((e.boundingBox.x??0)-o)<1&&Math.abs((e.boundingBox.y??0)-s)<1)return;this.logger.debug({oldBox:e.boundingBox,newBox:n},"Updating element screenshot");let l=await this.screenshot({target:t,scale:"css",timeout:4e3});e.boundingBox=n,e.screenshotUrl=await this.storage.uploadScreenshot(l)}async resolveTargetUsingCssSelectors(e,t){if(!t.generatedSelectors||t.generatedSelectors.length<2||!t.serializedHtml)throw new Error("Insufficient data to resolve target using CSS selectors");let n;try{n=await e.evaluate(l=>window.evaluateCssSelectors(l),{selectors:t.generatedSelectors,lDistThresholdLax:.5,lDistThresholdStrict:.1,serializedNodeWithContext:t.serializedHtml})}catch(l){throw new Error(`Failed to evaluate CSS selectors in browser: ${l}`)}if(n.result)this.logger.debug(n,"CSS selector evaluation returned an element");else throw new Error("CSS selector evaluation returned no eligible elements");let o=n.result,s=parseInt(o.dataMomenticId),i=this.dataMomenticIdToNodeMap.get(s);if(t.nodeOnlySerializedForm&&i){let l=Ms(i,t);if(l<4){let c=`Rejecting best CSS selector candidate due to low similarity score (${l})`;throw new Error(c)}}let a=e.locator(o.workingSelectors[0]);return t.generatedSelectors=void 0,await this.saveNodeDetailsToCache(e,i,t,s,a),t.generatedSelectors=Array.from(new Set([...o.workingSelectors??[],...t.generatedSelectors??[]])),{a11yNode:i,displayString:o.serializedElement,locator:a,decisions:[{type:"CSS_SELECTOR",matched:!0,reason:`${o.workingSelectors.length} CSS selectors matched the following element: ${o.serializedElement}`,selectors:o.workingSelectors.slice(0,5)}]}}async resolveTarget(e,t,n={}){let{skipFetchTree:o=!1,targetName:s}=n;this.logger.debug({target:t,skipFetchTree:o},"Resolve target called");let i=await this.getActivePageOrFrame();if(await fn(i,this.logger),t.id>0&&!In(t)){let m=this.a11yIdToNodeMap.get(t.id);if(!m)throw new R("InternalWebAgentError",`Resolving target failed because id ${t.id} does not exist on the page. This generally indicates an incorrect element was targeted.`);let p=await this.getLocatorFromA11yNode(m);return await this.saveNodeDetailsToCache(i,m,t,m.dataMomenticId,p),{locator:p,a11yNode:m,displayString:m.getNodeOnlySerializedForm(),decisions:[]}}let a=Date.now(),l,c=0,u=this.smartWaitingTimeout,d;for(;!l||l-a<u;){c++;try{l=Date.now(),d=await this.resolveTargetHelper({root:i,target:t,cssSelectorOnly:!0,skipFetchTreeWait:!0,skipFetchTree:o}),this.logger.debug(`Resolution succeeded through CSS selectors only (attempt ${c})`);break}catch(m){this.logger.debug({err:m,decisions:m instanceof mt?m.decisions:[]},`Could not resolve target through CSS selectors only (x${c})`),await X(500)}}return d||(this.logger.debug("Waiting for page stability and retrying all target matching methods"),d=await this.resolveTargetHelper({root:i,target:t,cssSelectorOnly:!1,skipFetchTreeWait:!1,skipFetchTree:o}),this.logger.debug({decisions:d.decisions},"Target resolution succeeded after waiting")),e?.details?.push({type:"TARGETING",name:s,elementLocationDecisions:d.decisions,pageState:d.pageState,targetSource:t.targetSource,targetUpdateTime:t.targetUpdateTime}),d}async resolveTargetHelper({root:e,target:t,cssSelectorOnly:n,skipFetchTree:o,skipFetchTreeWait:s}){let i=[];if(t.id<0&&t.selector){let m=e.locator(t.selector),p;try{p=await hn(m)}catch(h){throw new mt(`'${t.selector}' failed to resolve: ${h}`,[{type:"USER_SELECTOR",matched:!1}])}return i.push({type:"USER_SELECTOR",matched:!0,reason:`The user-provided CSS selector ${t.selector} matched an element on the page.`}),{locator:m,a11yNode:void 0,pageState:void 0,displayString:p,decisions:i}}let a;o||(a=(await this.getBrowserState({skipWait:s})).serialize(),this.logger.debug({skipFetchTreeWait:s,tree:a},"Got a11y tree before attempting target resolution"));let l=this.a11yIdToNodeMap.get(t.id),c=l?.getNodeOnlySerializedForm();if(l&&t.serializedForm&&c===t.serializedForm){let m=await this.getLocatorFromA11yNode(l);return await this.saveNodeDetailsToCache(e,l,t,l.dataMomenticId,m),i.push({type:"A11Y_ID",matched:!0,reason:`An element with the same Chrome-internal accessibility node ID matched the saved content exactly: ${c}.`}),{locator:m,a11yNode:l,displayString:c,decisions:i,pageState:a}}if(t.generatedSelectors){let m,p;try{m=await this.resolveTargetUsingCssSelectors(e,t)}catch(h){p=h}if(m)return{...m,pageState:a,decisions:[...i,...m.decisions]};n||(i.push({type:"CSS_SELECTOR",matched:!1,reason:p?.message,selectors:kg(t.generatedSelectors)}),t.generatedSelectors=void 0)}if(n)throw new mt("Could not resolve target with CSS selector only",i);if(t.serializedForm&&t.serializedForm.trim().length<10){let m="Refusing to attempt accessibility node comparison since the saved node is too short.";i.push({type:"A11Y_DISTANCE",matched:!1,reason:m,savedElement:t.serializedForm})}else if(t.serializedForm){let m=1/0,p,h;for(let f of this.a11yIdToNodeMap.values()){let y=f.getSerializedFormWithContext(),w=Mg(t.serializedForm,y);w<m?(m=w,p=f,h=void 0):w===m&&(h=f)}let g=Math.ceil(.1*t.serializedForm.length);if(p&&m<g&&m<25)if(h){let f=Lg`
|
|
1765
|
+
`}:{dataMomenticId:n,closestDistance:s,closestNodeSerialized:o}};import{mkdirSync as fg,rmSync as Td,statSync as gg}from"fs";import yg from"nodejs-file-downloader";import{tmpdir as Sg}from"os";import wg from"p-timeout";import zn,{basename as vd,dirname as bg}from"path";var jr="file://",Ed=zn.join(Sg(),"momentic","downloads"),$i=1e4,Cg=50*1024*1024;async function xd({uri:r,logger:e,orgId:t}){if(r.startsWith(jr)){let f=zn.join(Ed,t,r.slice(jr.length));return{filePath:f,momenticUri:r,cleanup:()=>{Td(bg(f),{recursive:!0,force:!0})}}}let n=new URL(r);n.search&&(n.search="");let o=vd(n.href),s=Wi(o),i=zn.extname(s);if(ec.includes(i))throw new Error(`Downloading files with extension ${i} is not allowed.`);let a=zi(t),l=new yg({url:r,fileName:s,directory:a,maxAttempts:2,headers:{"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36"},timeout:$i}),{downloadStatus:c,filePath:u}=await wg(l.download(),{milliseconds:$i,message:`Download timed out after ${$i}ms`});if(c!=="COMPLETE")throw new Error(`Download ended in non-success status: ${c}`);if(!u)throw new Error("File path of successfully downloaded file was empty");let m=gg(u).size;if(m>Cg)throw new Error("File size exceeds the maximum limit of 50MB");e.info({fileSizeInBytes:m,filePath:u,fileName:s},"Downloaded file to disk");let p;return{filePath:u,momenticUri:Bi(vd(a),s),cleanup:()=>{clearTimeout(p),p=setTimeout(()=>Td(a,{recursive:!0,force:!0}),10*60*1e3)}}}function Bi(r,e){return`${jr}${r}/${e}`}function zi(r){let e=Math.random().toString(36).substring(4),t=zn.join(Ed,r,e);return fg(t,{recursive:!0}),t}function Wi(r){let e=zn.extname(r),t=zn.basename(r,e);return r=(t.length>100?t.slice(t.length-100):t)+e,r=r.trim().replaceAll(" ","_"),r}async function Ad({locator:r,logger:e}){let[t,n]=await r.evaluate(s=>[s.tagName.toLowerCase(),s.getAttribute("class")??""],{timeout:1e3});if(t!=="input"||!n.toLowerCase().includes("chakra"))return;let o=await r.boundingBox({timeout:2e3});if(o===null){e.warn({elementDisplayString:await Wr(r)},"Attempting to click on element with no bounding box");return}if(!(o.width!==1||o.height!==1))try{await Hr(r.page(),e);let s=await r.evaluate(a=>{let l=window;if(!l.CssSelectorGenerator)return{type:"error",error:"[MOMENTIC] Missing CSS selector libraries"};let c=a.parentElement;if(!c)return{type:"error",error:"Input click target has no parent for redirection"};let u=l.CssSelectorGenerator.getCssSelector(c,{}),d=a.getBoundingClientRect(),m=c.getBoundingClientRect(),p={x:Math.min(Math.max(1,d.left-m.left),m.width-1),y:Math.min(Math.max(1,d.top-m.top),m.height-1)};return{type:"result",selector:u,relativePoint:p,serializedForm:c.outerHTML.slice(0,500)}},{timeout:1e3});if(s.type==="error")throw new Error(s.error);let i=r.page().locator(s.selector);return await i.waitFor({state:"attached",timeout:2e3}),e.info(s,`Redirected click to parent element with selector: ${s.selector}`),{locator:i,relativePoint:s.relativePoint}}catch(s){e.error({err:s},"Failed finding parent label for Chakra element");return}}var Id=["date","datetime-local","month","time","week"],Rd={date:/^\d{4}-\d{2}-\d{2}$/,"datetime-local":/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}$/,month:/^\d{4}-\d{2}$/,time:/^\d{2}:\d{2}$/,week:/^\d{4}-W\d{2}$/};async function Pd(r,e,t,n){let o=(await r.evaluate(()=>document.activeElement?.getAttribute("type"))??"").toLowerCase();return Rd[o]&&(Rd[o].test(e)&&n.warn(`Detected datetime input (${e}) in normalized format - this may fail to fill correctly as it is not how the user would input the value`),t.pressKeysSequentially=!0,t.clearContent=!1,n.debug("Transforming datetime input to use sequential key presses")),!1}async function Od(r,e,t,n,o){try{await Tg(r,e,t,n)}catch(s){o.error({err:s,tabIndex:e},"Error handling new console log")}}async function Tg(r,e,t,n){let o=n.text();o.length>$r&&(o=o.slice(0,$r)+"...(TRUNCATED)");let s=[];for(let i of n.args())try{let a=await i.jsonValue(),l=JSON.stringify(a);l.length>$r?s.push(l.slice(0,$r)+"...(TRUNCATED)"):(typeof a!="object"||Object.keys(a).length>0)&&s.push(a)}catch{}Hi(r,t,e,{url:r.url(),location:n.location(),type:n.type(),text:n.text(),args:s})}function Hi(r,e,t,n){let o=Date.now(),s=e.logsPerPage;if(s.length<=t||s[t]===void 0){s[t]=[];for(let i=0;i<t;i++)s[i]===void 0&&(s[i]=[])}s[t].length>_i&&(s[t]=s[t].slice(Math.floor(_i/2)),s[t]?.push({url:r.url(),timestamp:o,type:"warning",text:"[MOMENTIC] Truncated console logs due to buffer overflow",tabIndex:t})),s[t].push({...n,tabIndex:t,timestamp:o})}async function bt(r,e,t){let n=Date.now(),o=await r(),s=Date.now();return t[e]=s-n,o}function Ld(){return async r=>{let{fragment:e,code:t,context:n}=r,{env:o,results:s,inputs:i}=n||{},a=Object.getPrototypeOf(async function(){}).constructor;return{result:await Promise.resolve(new a("env","results","inputs",e?`return ${t}`:t)(o,s,i))}}}var Gg=$d(Ug(),"momentic","chromium"),Wn=process.env.TWO_CAPTCHA_KEY,ns=Wg($g);ns.use(Hg({provider:{id:"2captcha",token:Wn},visualFeedback:!0}));async function ji(r,e){let t,n;for(let o=0;o<4;o++)try{return t=r.pages(),(await Promise.all(t.map(async s=>({title:await s.title(),url:s.url()})))).filter(s=>dn(s.url,e))}catch(s){n=s,await K(500)}throw new Error(`Failed to get tab titles after all retries: ${n?.message}`)}var Mt=class r{static USER_AGENT=Bg["Desktop Chrome"].userAgent;contextInitialized=!1;browser;context;page;systemDevicePixelRatio;userControlledBrowserSettings;pageLoadPromise=null;lastTabChangeEventTimeout=void 0;a11yIdToNodeMap=new Map;dataMomenticIdToNodeMap=new Map;mostRecentA11yTree;domGraph=void 0;cdpClient;debugData={logsPerPage:[]};enricher;storage;logger;localMode;activeFrame;activeFrameCache;transformer;baseUrl;originsVisited=new Set;viewport;onTabsChange=void 0;constructor({storage:e,enricher:t,browser:n,context:o,page:s,baseUrl:i,logger:a,localMode:l,cdpClient:c,userBrowserSettings:u,viewport:d,onTabsChange:m,systemDevicePixelRatio:p}){tc(u),this.storage=e,this.enricher=t,this.browser=n,this.context=o,this.cdpClient=c,this.page=s,this.baseUrl=i,this.logger=a,this.userControlledBrowserSettings=u,this.localMode=!!l,this.viewport=d||Rt,this.onTabsChange=m,this.systemDevicePixelRatio=p}async initializeContext(){if(this.contextInitialized)return;this.userControlledBrowserSettings.extraHeaders&&await this.context.setExtraHTTPHeaders(this.userControlledBrowserSettings.extraHeaders),await this.context.grantPermissions(["clipboard-read","clipboard-write","microphone","camera"]);let e=[this.context.addInitScript({content:Fr.cssGeneratorLibJs}),this.context.addInitScript({content:Fr.htmlUtilsLibJs}),this.context.addInitScript({content:"window._MOMENTIC_BROWSER = true;"})];this.localMode&&e.push(this.context.addInitScript({content:bd}));let t=n=>this.handleNewPageEvent(n);this.context.on("page",t),await this.handleNewPageEventHelper(this.page),this.context.on("close",()=>{this.logger.debug("Chrome browser context was closed"),this.context.off("page",t)}),await Promise.all(e),this.contextInitialized=!0}static async init({baseUrl:e,logger:t,storage:n,enricher:o,userBrowserSettings:s,browserArgs:i,contextArgs:a,onClose:l,waitForLoad:c=!0,localMode:u,localAppUrl:d,extensionPath:m,skipPageSetup:p,timeout:f,browserbaseConnectUrl:h,onTabsChange:g}){process.env.PW_TEST_SCREENSHOT_NO_FONTS_READY="1";let y={headless:!0,handleSIGTERM:!1,chromiumSandbox:!1,...i??{}},S={viewport:Rt,userAgent:s.userAgent??r.USER_AGENT,geolocation:{latitude:37.7749,longitude:-122.4194},locale:"en-US",timezoneId:"America/Los_Angeles",...a??{}},b=null,C,v;if(u)C=await ns.launchPersistentContext(Gg,{...y,...S,ignoreDefaultArgs:["--enable-automation","--enable-strict-mixed-content-checking"],ignoreHTTPSErrors:!0,bypassCSP:!0,args:["--allow-insecure-localhost","--disable-site-isolation-for-policy","--disable-site-isolation-trials",`--unsafely-treat-insecure-origin-as-secure=${d}`,`--load-extension=${m}`,"--test-type=browser","--use-fake-device-for-media-stream","--use-fake-ui-for-media-stream"],baseURL:e}),v=C.pages()[0],l&&v.on("close",()=>{l()});else if(h){b=await ns.connectOverCDP(h);let O=b.contexts()[0];if(!O)throw new Error("Failed to get browserbase default context");let M=O.pages()[0];if(!M)throw new Error("Failed to get browserbase default page");C=O,v=M}else{b=await ns.launch({...y,args:["--disable-dev-shm-usage","--no-first-run","--renderer-process-limit=4","--disable-site-isolation-for-policy","--disable-site-isolation-trials","--autoplay-policy=user-gesture-required","--disable-add-to-shelf","--disable-desktop-notifications","--use-fake-device-for-media-stream","--use-fake-ui-for-media-stream"]});let O={...S,baseURL:e};C=await b.newContext(O),t.debug({contextArgs:O},"Browser initialization context args"),v=await C.newPage()}let E=await r.initCDPSession(C,v,t,f),P=new r({browser:b,context:C,page:v,baseUrl:e,logger:t,storage:n,enricher:o,localMode:u,userBrowserSettings:s,cdpClient:E,viewport:S.viewport||Rt,onTabsChange:g,systemDevicePixelRatio:S.deviceScaleFactor});await P.initializeContext();let A=async()=>{try{await P.navigate({url:e,initialNavigation:!p,loadTimeoutMs:f})}catch(O){if(t.error({err:O},"Failed to initialize Chrome browser"),c)throw O}};return c?await A():A(),P}async handleAvailableTabsChangeHelper(){try{let e=await ji(this.context,this.logger),t=this.page.url();this.onTabsChange?.(e,t)}catch(e){this.logger.error({err:e},"Error sending available tabs to frontend")}}async handleAvailableTabsChange(){try{clearTimeout(this.lastTabChangeEventTimeout),this.lastTabChangeEventTimeout=setTimeout(()=>this.handleAvailableTabsChangeHelper(),1500)}catch(e){this.logger.warn({err:e},"Error handling available tabs change")}}async handlePageErrorEvent(e){}handlePageClosedEvent(e){if(!this.browser||!this.browser.isConnected())return;let t=async()=>{try{if(this.page!==e){this.logger.info({url:e.url()},"Detected background page was closed"),this.handleAvailableTabsChange();return}this.logger.info({url:e.url()},"Detected active page was closed, switching to another tab");let n=this.context.pages();for(let o=n.length-1;o>=0;o--){let s=n[o];if(!(!s||s.isClosed()||!dn(s.url()))){this.logger.info(`Automatically switching to tab ${o} after close: ${s.url()}`),await this.switchToPageByIndex(s,o);break}}}catch(n){this.logger.warn({err:n},"Error in page close event handler")}};this.pageLoadPromise=t()}async handleNewPageEvent(e){let t=e.url();if(!(!t.trim()||t==="about:blank"))try{this.logger.debug({url:t},"Detected new page event, registering handlers and waiting for load to complete"),await this.handleNewPageEventHelper(e)}catch(n){this.logger.warn({err:n},"Error handling new page open, continuing....")}}async handleNewPageEventHelper(e){e.on("close",o=>this.handlePageClosedEvent(o)),e.on("pageerror",async o=>this.handlePageErrorEvent(o)),e.on("framenavigated",async o=>{o===e.mainFrame()&&await this.handleFrameNavigationEvent(o)});let t=this.context.pages().indexOf(e);e.on("console",o=>{Od(e,t,this.debugData,o,this.logger)});let n=this.pageLoadPromise;this.pageLoadPromise=(async()=>{try{await Promise.resolve(n),await this.loadFrameAndRecordUrl(e),this.handleAvailableTabsChange()}catch(o){this.logger.error({err:o},"Failed to wait for new page to load")}finally{this.pageLoadPromise=null}})()}async handleFrameNavigationEvent(e){let t=e.url();if(!t||t==="about:blank")return;let n=this.pageLoadPromise;this.pageLoadPromise=(async()=>{try{await Promise.resolve(n),await this.loadFrameAndRecordUrl(e),this.handleAvailableTabsChange()}catch(o){this.logger.error({err:o},"Failed to wait for frame navigation to finish")}finally{this.pageLoadPromise=null}})()}async getLocatorFromCdpFrame(e,t){let n=this.page;for(let a of t)n=n.frameLocator(`iframe[src=${JSON.stringify(a)}]`);let o=this.getAttributeFromStringArray(e.attributes??[],"src");if(!o)throw new Error(`Got iframe without src attribute: ${JSON.stringify(e)}`);let s=n.locator(`iframe[src=${JSON.stringify(o)}]`),i=await(await s.evaluateHandle(a=>a,{timeout:1e3})).asElement().contentFrame();if(!i)throw new Error(`Got null frame from locator: ${s}`);return await this.loadFrameAndRecordUrl(i),i}async getMatchingFrame(e){if(e.type!=="url")throw new Error("Only url frame identifiers are supported now");let t=e.url,o=[{node:(await this.cdpClient.send("DOM.getDocument",{pierce:!0,depth:-1})).root,srcChain:[]}],s=[];for(;o.length>0;){let i=o.pop(),a=i.node,l=i.srcChain;if(a.nodeName.toLowerCase()==="iframe"){let c=this.getAttributeFromStringArray(a.attributes??[],"src");if(!c)continue;t.startsWith("/")&&t.endsWith("/")?new RegExp(t.slice(1,-1)).test(c)&&s.push({node:a,frame:await this.getLocatorFromCdpFrame(a,l)}):t.trim()===c.trim()&&s.push({node:a,frame:await this.getLocatorFromCdpFrame(a,l)}),l=[...l,c]}for(let c of a.children??[])o.push({node:c,srcChain:l});a.contentDocument&&o.push({node:a.contentDocument,srcChain:l})}if(s.length===1)return s[0];throw s.length>1?new Error(`Found multiple frames with src matching '${t}'. Please use a more specific selector.`):new Error(`Failed to find frame with src matching: ${t}`)}async getActivePageOrFrameHelper(){if(!this.activeFrame)return this.page;let e,t="";if(this.activeFrame.type==="url")t=this.activeFrame.url,e=(await this.getMatchingFrame(this.activeFrame)).frame;else throw new Error(`Frame identifier type ${this.activeFrame.type} is not yet supported`);if(e)return e;throw new I("InternalWebAgentError",`Failed to find frame with src matching '${t}' on page`)}static async initCDPSession(e,t,n,o=8e3){let s=2,i=async()=>{try{let l=await e.newCDPSession(t);return l.on("Target.targetCrashed",c=>{n.error({payload:c},"CDP session crashed, Momentic will likely not function correctly")}),l.on("Inspector.targetCrashed",c=>{n.error({payload:c},"CDP inspector session crashed, Momentic will likely not function correctly")}),await l.send("Accessibility.enable"),await l.send("DOM.enable"),await l.send("Overlay.enable"),l}catch(l){if(s>0)return n.debug({err:l},"Failed to initialize CDP session, re-creating CDP client"),await K(500),s--,i();throw l}};return await ts(i(),{milliseconds:o,fallback:()=>{throw new Error(`Failed to initialize session within page load timeout (${t.url()})`)}})}ping(){if(this.closed)throw new Error("Page has been closed");if(this.browser&&!this.browser.isConnected())throw new Error("Browser is not connected")}setActiveFrame(e){e?(this.activeFrame=e,this.activeFrameCache=void 0):(this.activeFrame=void 0,this.activeFrameCache=void 0)}async reset(e){this.debugData.logsPerPage=[],this.a11yIdToNodeMap.clear(),this.dataMomenticIdToNodeMap.clear(),e.clearCookies&&await this.context.clearCookies();let t=this.context.pages();for(let s=0;s<t.length;s++){if(e.clearStorage){let i=t[s].url();try{this.originsVisited.delete(new URL(i).origin)}catch{}try{await t[s].evaluate(async()=>{window.localStorage.clear(),window.sessionStorage.clear(),await indexedDB.databases().then(a=>{a.forEach(l=>{l.name&&indexedDB.deleteDatabase(l.name)})})},{timeout:1e3})}catch(a){this.logger.debug({err:a},"Failed clearing site data, continuing...")}}s!==0&&!this.localMode&&(this.logger.debug(`Closing tab ${t[s].url()}`),await t[s].close())}if(this.page=this.context.pages()[0],this.page.isClosed()){this.logger.debug("Page is closed, exiting reset early");return}let n=await r.initCDPSession(this.context,this.page,this.logger,e.timeout),o=this.cdpClient;this.cdpClient=n;try{await o.detach()}catch{}if(e.clearStorage)for(let s of this.originsVisited)this.logger.debug({origin:s},"Clearing data using CDP"),await this.cdpClient.send("Storage.clearDataForOrigin",{origin:s,storageTypes:"all"}),this.originsVisited.delete(s);await this.navigate({url:e.url??this.baseUrl,initialNavigation:!0,loadTimeoutMs:e.timeout})}async toggleHints(e){let t=this.page;e.state==="on"?(await t.addStyleTag({content:Fr.vimiumCss}),await t.addScriptTag({content:Fr.vimiumJs}),await t.evaluate(Sd,{timeout:1e3})):await t.evaluate(wd,{timeout:1e3})}async showHints(){await this.toggleHints({state:"on"});let e=async()=>{try{await this.toggleHints({state:"off"})}catch(t){this.logger.debug({err:t},"Failed to remove vision hints")}};setTimeout(()=>{e()},3e3)}async cleanup(){if(!this.browser)return;let e=this.browser;this.browser=null;try{this.originsVisited.clear(),await this.page.close(),await this.context.close(),await e.close()}catch(t){throw new Error(`Error cleaning up browser: ${t}`)}finally{this.browser=null}}get closed(){return!this.browser||!this.browser.isConnected()}async html(){return(await this.getActivePageOrFrame()).content()}url(){return this.page.url()}async screenshotWithHints(e){let t=e.saveToDiskPath?.split("."),n=t?.slice(0,-1).join("."),o=t?.slice(-1)[0],s=Buffer.from("");await this.showHints();let i=await this.screenshot({...e,saveToDiskPath:e.saveToDiskPath?`${n}-after-hint.${o}`:void 0});return{before:s,after:i}}async screenshot(e){let{retries:t=1}=e;try{let n=await this.screenshotHelper({...e,retries:t});if(n.byteLength>5e6)this.logger.error("Page screenshot is greater than 5MB, which may cause performance issues with some AI models");else if(n.length===0)throw new Error("Got empty screenshot");return n}catch(n){if(t>0)return this.logger.debug({err:n},"Failed taking screenshot, retrying..."),await K(500),this.screenshot({...e,retries:t-1});throw n}}async screenshotHelper({target:e,quality:t,scale:n="device",saveToDiskPath:o,hideCaret:s,timeout:i,clearHighlights:a=!1}){a&&await this.removeAllHighlights();let l={fullPage:!1,type:"jpeg",quality:t,scale:n,caret:s?"hide":"initial",path:o,timeout:i??4e3};e&&(l.scale="css");let c;if(l.scale==="css"||l.path)c=await this.page.screenshot(l);else{let u=await this.cdpClient.send("Page.captureScreenshot",{format:"jpeg",quality:t,fromSurface:!0,optimizeForSpeed:!0});c=Buffer.from(u.data,"base64")}if(!e)return c;if(e){let u;"id"in e?u=(await this.resolveTarget(null,e)).locator:u=e;let d=await u.boundingBox();if(!d)throw new Error("Attempted to screenshot an element that is not visible on the page");let{x:m,y:p,width:f,height:h}=d;if(!f||!h)throw new Error("Attempted to screenshot an element with zero width or height");if(m<0||p<0)throw new Error("Attempted to screenshot an element with negative coordinates");m=Math.floor(m),p=Math.floor(p),f=Math.ceil(f),h=Math.ceil(h);try{c=await(await kg.fromBuffer(c)).crop({x:m,y:p,w:f,h}).getBuffer("image/jpeg")}catch(g){throw new Error(`Failed taking element screenshot at coordinates (${m}, ${p}) with size (${f}, ${h}): ${g}`)}}return c}async getViewport(){return this.viewport}async navigate({url:e,initialNavigation:t=!1,loadTimeoutMs:n=this.pageLoadTimeout}){nd(e)&&(e=new URL(e,this.baseUrl).toString());let o=Date.now();this.logger.debug(`Navigating to ${e}`);try{t||await this.waitForDOMStability();try{await this.page.goto(e,{timeout:n,waitUntil:"domcontentloaded"})}catch(i){throw new I("ActionFailureError",i.message)}await this.loadFrameAndRecordUrl(this.page),this.logger.debug({url:e},`Navigation complete in ${Math.floor(Date.now()-o)}ms`)}catch(i){if(i instanceof Error&&i.message.includes("ERR_ABORTED")){this.logger.error({err:i},"Navigation error, possibly due to user cancellation");return}throw i}let s=this.url();if(sd.has(s))throw new I("ActionFailureError",`${e} took too long to load \u{1F61E}. Please ensure the site and your internet are working.`,{},!0);if(t)try{await this.exposeRecordingBindings()}catch(i){i instanceof Error&&i.message.includes("already registered")||this.logger.error({err:i},"Failed to install Momentic libraries for action recording")}}async type(e,t={},n=!1){await this.directTypeHelper(e,t,n)}async directTypeHelper(e,t={},n=!1){let o=await this.getActivePageOrFrame();if(!await Pd(o,e,t,this.logger)){if(n){let s=Date.now(),i=!1;for(;Date.now()-s<this.smartWaitingTimeout;){let a=await o.evaluate(()=>document.activeElement&&document.activeElement.tagName.toLowerCase());if(a&&a!=="body"){i=!0;break}await K(250)}i||this.logger.warn("No active element found to type into, attempting anyways")}t.clearContent&&(process.platform==="darwin"?await this.page.keyboard.press("Meta+A"):await this.page.keyboard.press("Control+A"),await this.page.keyboard.press("Backspace")),t.pressKeysSequentially?await this.page.keyboard.type(e,{delay:100}):(await this.page.waitForTimeout(25),await this.page.keyboard.insertText(e)),t.pressEnter&&await this.page.keyboard.press("Enter")}}async scrollIntoView(e){await e.scrollIntoViewIfNeeded({timeout:4e3})}async highlight(e,t){try{let n=await this.resolveTarget(null,e,{skipFetchTree:!0});return await this.highlightTarget(n.locator,t),!0}catch(n){return this.logger.debug({err:n,target:e},"Failed to highlight target"),!1}}async removeAllHighlights(){await(await this.getActivePageOrFrame()).evaluate(()=>{let e=window,t=e.removeHighlightTimers||[];for(;t.length;){let n=t.pop();clearTimeout(n)}Object.values(e.removeHighlightFunctions??{}).forEach(n=>{n()})},{timeout:1e3})}async highlightTarget(e,t){try{return await this.removeAllHighlights(),await e.evaluate(n=>{let o=window;o.momenticIsEligible=c=>{let d=window.getComputedStyle(c,null).getPropertyValue("display");if(d==="none"||d==="contents")return!1;let m=c.getBoundingClientRect();return!(!m.height||!m.width)},o.removeHighlightTimers=o.removeHighlightTimers||[],o.removeHighlightFunctions=o.removeHighlightFunctions||{};let s=0;for(;!o.momenticIsEligible(n)&&s<3;){if(!n.parentElement)throw new Error("No eligible non-empty parent found for highlighting");n=n.parentElement,s++}let i=n.style.getPropertyValue("outline"),a=n.style.getPropertyPriority("outline");n.style.setProperty("outline","5px dashed rgb(255, 0, 153)","important");let l=`momentic${Math.floor(Math.random()*1e7)}`;o[l]=()=>{n.style.removeProperty("outline"),n.style.setProperty("outline",i,a)},o.removeHighlightTimers.push(setTimeout(()=>{o[l](),o.removeHighlightFunctions?.[l]&&delete o.removeHighlightFunctions[l]},5e3)),o.removeHighlightFunctions[l]=o[l]},t?.color,{timeout:1e3}),!0}catch(n){return this.logger.debug({err:n},"Failed to add node highlight, a page navigation likely occurred. This is non-fatal for tests."),!1}}recordUrlVisited(e){try{this.originsVisited.add(new URL(e).origin)}catch(t){this.logger.warn({err:t},"Failed to record origin visited")}}async wrapPageLoad(e){return await Promise.resolve(this.pageLoadPromise),await e()}async loadAuthState(e){await this.wrapPageLoad(async()=>{await this.waitForDOMStability(),await this.loadAuthStateHelper(e)})}async loadAuthStateHelper(e){let t=[];for(let o of e.cookies){let s=await this.setCookie(o);t=t.concat(s)}this.logger.info({cookiesSet:t},"Loaded cookies"),await this.cdpClient.send("DOMStorage.enable");let n=0;for(let o of e.origins??[])for(let s of o.localStorage)try{await this.cdpClient.send("DOMStorage.setDOMStorageItem",{storageId:{securityOrigin:new URL(o.origin).origin,isLocalStorage:!0},key:s.name,value:s.value}),n++}catch(i){this.logger.warn({err:i,origin:o},"Failed to set local storage entry");break}this.logger.debug({storageState:e},`Loaded ${e.cookies.length} cookies and ${n} local storage entries`),await this.refresh()}async saveAuthState(){return this.context.storageState()}async getOpenPageUrls(){return(await ji(this.context,this.logger)).map(t=>t.url)}saveA11yDetailsToCache(e,t){t.id=e.id,t.content=e.content,t.name=e.name,t.role=e.role,t.numChildren=e.children.length,t.serializedForm=e.getSerializedFormWithContext(),t.nodeOnlySerializedForm=e.getNodeOnlySerializedForm()}async saveNodeDetailsToCache(e,t,n,o,s){if(t&&this.saveA11yDetailsToCache(t,n),!(n.generatedSelectors&&n.generatedSelectors.length>1)){if(o)n.dataMomenticId=o;else{this.logger.debug("No data-momentic-id found for target, skipping HTML attribute generation");return}try{let i=await this.fetchHtmlAttributes(e,o);Object.assign(n,i)}catch(i){this.logger.warn({err:i},"Failed to fetch HTML attributes for target")}if(Ni.includes(n?.role??""))try{await this.saveElementVisualAttributes(n,s)}catch(i){this.logger.debug({err:i},"Failed to get element screenshot while saving node details")}}}async saveElementVisualAttributes(e,t){if(!t)return;await t.scrollIntoViewIfNeeded({timeout:4e3});let n=await t.boundingBox();if(!n||!n.width||!n.height){e.boundingBox=void 0,e.screenshotUrl=void 0;return}let{x:o=0,y:s=0,width:i=0,height:a=0}=n;if(e.boundingBox&&Math.abs(e.boundingBox.width-i)<1&&Math.abs(e.boundingBox.height-a)<1&&Math.abs((e.boundingBox.x??0)-o)<1&&Math.abs((e.boundingBox.y??0)-s)<1)return;this.logger.debug({oldBox:e.boundingBox,newBox:n},"Updating element screenshot");let l=await this.screenshot({target:t,scale:"css",timeout:4e3});e.boundingBox=n,e.screenshotUrl=await this.storage.uploadScreenshot(l)}async resolveTargetUsingCssSelectors(e,t){if(!t.generatedSelectors||t.generatedSelectors.length<2||!t.serializedHtml)throw new Error("Insufficient data to resolve target using CSS selectors");let n;try{n=await e.evaluate(l=>window.evaluateCssSelectors(l),{selectors:t.generatedSelectors,lDistThresholdLax:.5,lDistThresholdStrict:.1,serializedNodeWithContext:t.serializedHtml})}catch(l){throw new Error(`Failed to evaluate CSS selectors in browser: ${l}`)}if(n.result)this.logger.debug(n,"CSS selector evaluation returned an element");else throw new Error("CSS selector evaluation returned no eligible elements");let o=n.result,s=parseInt(o.dataMomenticId),i=this.dataMomenticIdToNodeMap.get(s);if(t.nodeOnlySerializedForm&&i){let l=Ui(i,t);if(l<4){let c=`Rejecting best CSS selector candidate due to low similarity score (${l})`;throw new Error(c)}}let a=e.locator(o.workingSelectors[0]);return t.generatedSelectors=void 0,await this.saveNodeDetailsToCache(e,i,t,s,a),t.generatedSelectors=Array.from(new Set([...o.workingSelectors??[],...t.generatedSelectors??[]])),{a11yNode:i,displayString:o.serializedElement,locator:a,decisions:[{type:"CSS_SELECTOR",matched:!0,reason:`${o.workingSelectors.length} CSS selectors matched the following element: ${o.serializedElement}`,selectors:o.workingSelectors.slice(0,5)}]}}async resolveTarget(e,t,n={}){let{skipFetchTree:o=!1,targetName:s}=n;this.logger.debug({target:t,skipFetchTree:o},"Resolve target called");let i=await this.getActivePageOrFrame();if(await Hr(i,this.logger),t.id>0&&!yo(t)){let m=this.a11yIdToNodeMap.get(t.id);if(!m)throw new I("InternalWebAgentError",`Resolving target failed because id ${t.id} does not exist on the page. This generally indicates an incorrect element was targeted.`);let p=await this.getLocatorFromA11yNode(m);return await this.saveNodeDetailsToCache(i,m,t,m.dataMomenticId,p),{locator:p,a11yNode:m,displayString:m.getNodeOnlySerializedForm(),decisions:[]}}let a=Date.now(),l,c=0,u=this.smartWaitingTimeout,d;for(;!l||l-a<u;){c++;try{l=Date.now(),d=await this.resolveTargetHelper({root:i,target:t,cssSelectorOnly:!0,skipFetchTreeWait:!0,skipFetchTree:o}),this.logger.debug(`Resolution succeeded through CSS selectors only (attempt ${c})`);break}catch(m){this.logger.debug({err:m,decisions:m instanceof Pt?m.decisions:[]},`Could not resolve target through CSS selectors only (x${c})`),await K(500)}}return d||(this.logger.debug("Waiting for page stability and retrying all target matching methods"),d=await this.resolveTargetHelper({root:i,target:t,cssSelectorOnly:!1,skipFetchTreeWait:!1,skipFetchTree:o}),this.logger.debug({decisions:d.decisions},"Target resolution succeeded after waiting")),e?.details?.push({type:"TARGETING",name:s,elementLocationDecisions:d.decisions,pageState:d.pageState,targetSource:t.targetSource,targetUpdateTime:t.targetUpdateTime}),d}async resolveTargetHelper({root:e,target:t,cssSelectorOnly:n,skipFetchTree:o,skipFetchTreeWait:s}){let i=[];if(t.id<0&&t.selector){let m=e.locator(t.selector),p;try{p=await Wr(m)}catch(f){throw new Pt(`'${t.selector}' failed to resolve: ${f}`,[{type:"USER_SELECTOR",matched:!1}])}return i.push({type:"USER_SELECTOR",matched:!0,reason:`The user-provided CSS selector ${t.selector} matched an element on the page.`}),{locator:m,a11yNode:void 0,pageState:void 0,displayString:p,decisions:i}}let a;o||(a=(await this.getBrowserState({skipWait:s})).serialize(),this.logger.debug({skipFetchTreeWait:s,tree:a},"Got a11y tree before attempting target resolution"));let l=this.a11yIdToNodeMap.get(t.id),c=l?.getNodeOnlySerializedForm();if(l&&t.serializedForm&&c===t.serializedForm){let m=await this.getLocatorFromA11yNode(l);return await this.saveNodeDetailsToCache(e,l,t,l.dataMomenticId,m),i.push({type:"A11Y_ID",matched:!0,reason:`An element with the same Chrome-internal accessibility node ID matched the saved content exactly: ${c}.`}),{locator:m,a11yNode:l,displayString:c,decisions:i,pageState:a}}if(t.generatedSelectors){let m,p;try{m=await this.resolveTargetUsingCssSelectors(e,t)}catch(f){p=f}if(m)return{...m,pageState:a,decisions:[...i,...m.decisions]};n||(i.push({type:"CSS_SELECTOR",matched:!1,reason:p?.message,selectors:Fg(t.generatedSelectors)}),t.generatedSelectors=void 0)}if(n)throw new Pt("Could not resolve target with CSS selector only",i);if(t.serializedForm&&t.serializedForm.trim().length<10){let m="Refusing to attempt accessibility node comparison since the saved node is too short.";i.push({type:"A11Y_DISTANCE",matched:!1,reason:m,savedElement:t.serializedForm})}else if(t.serializedForm){let m=1/0,p,f;for(let g of this.a11yIdToNodeMap.values()){let y=g.getSerializedFormWithContext(),S=Ng(t.serializedForm,y);S<m?(m=S,p=g,f=void 0):S===m&&(f=g)}let h=Math.ceil(.1*t.serializedForm.length);if(p&&m<h&&m<25)if(f){let g=Mg`
|
|
1768
1766
|
Multiple accessibility nodes have the same string distance - refusing to pick between them:
|
|
1769
1767
|
Candidate 1:
|
|
1770
1768
|
${p.getSerializedFormWithContext()}
|
|
1771
1769
|
=====================
|
|
1772
1770
|
Candidate 2:
|
|
1773
|
-
${
|
|
1771
|
+
${f.getSerializedFormWithContext()}`;i.push({type:"A11Y_DISTANCE",matched:!1,reason:g,distance:m,closestElement:p.getNodeOnlySerializedForm(),savedElement:t.serializedForm})}else{let g=await this.getLocatorFromA11yNode(p);return await this.saveNodeDetailsToCache(e,p,t,p.dataMomenticId,g),i.push({type:"A11Y_DISTANCE",matched:!0,reason:`Found an accessibility node on the page within ${h} distance of the saved element.`,distance:m,closestElement:p.getSerializedFormWithContext()}),{locator:g,pageState:a,a11yNode:p,displayString:p.getNodeOnlySerializedForm(),decisions:i}}else i.push({type:"A11Y_DISTANCE",matched:!1,reason:`Closest accessibility node is still too far away (${m} > ${h}) to be considered a match.`,distance:m,closestElement:p?.getSerializedFormWithContext(),savedElement:t.serializedForm})}if(t.nodeOnlySerializedHtml&&t.nodeOnlySerializedHtml.trim().length<10){let m="Refusing to attempt HTML comparison since the saved element is too short.";i.push({type:"HTML_DISTANCE",matched:!1,reason:m})}else if(t.nodeOnlySerializedHtml){let m=await e.content();m.length>5e5&&(m=m.slice(5e5)+"...");try{let p=await e.evaluate(Cd,{nodeOnlySerializedHtml:t.nodeOnlySerializedHtml}),f=Math.floor(.1*t.nodeOnlySerializedHtml.length);if(p.closestDistance&&p.closestDistance>=f){let h=`Closest HTML candidate still has too far distance (${p.closestDistance}) from threshold (${f})`;i.push({type:"HTML_DISTANCE",matched:!1,reason:h,distance:p.closestDistance,closestElement:p.closestNodeSerialized})}else{if(p.error)throw new Error(p.error);if(p.dataMomenticId){let h=parseInt(p.dataMomenticId),g=this.dataMomenticIdToNodeMap.get(h),y;g?y=await this.getLocatorFromA11yNode(g):y=e.locator(`[${it}="${h}"]`);let S=p.closestNodeSerialized??await Wr(y);return await this.saveNodeDetailsToCache(e,g,t,h,y),i.push({type:"HTML_DISTANCE",matched:!0,reason:`Found an element on the page within ${f} string comparison distance of the saved element.`,distance:p.closestDistance,closestElement:S,savedElement:t.nodeOnlySerializedHtml}),this.logger.debug({result:p,originalTarget:t,displayString:S},"Resolved cached target to new node with pure html levenshtein distance"),{locator:y,a11yNode:g,displayString:S,decisions:i,pageState:m}}else throw new Error(`Got invalid HTML evaluation result: ${JSON.stringify(p)}`)}}catch(p){this.logger.debug({err:p},"Failed to find closest HTML node using levenshtein distance"),i.push({type:"HTML_DISTANCE",matched:!1,reason:`Error finding closest HTML node by string distance: ${p}`})}}let u=t.screenshotUrl,d=t.role??"";if(u&&Ni.includes(d))try{let m=await this.resolveTargetWithScreenshot({screenshotUrl:u,oldTarget:t});return{...m,decisions:[...i,...m.decisions],pageState:a}}catch(m){i.push({type:"TEMPLATE_MATCHING",matched:!1,reason:`Error finding closest element using saved screenshot: ${m}`,elementImageUrl:u}),this.logger.warn({err:m},"Did not find any close element using saved screenshot")}throw this.logger.debug({target:t,decisions:i},"Failed to find any relevant node"),new Pt(`Could not find any relevant node given cached target: ${JSON.stringify(t)}`,i)}async resolveTargetWithScreenshot({screenshotUrl:e,oldTarget:t}){let n;if(!this.enricher)throw new Error("Enricher not available for screenshot resolution");let o=await this.screenshot({scale:"css"}),i=await(await fetch(e)).arrayBuffer(),a=jg(),l=await this.enricher.runTemplateMatching({searchImageBase64String:Buffer.from(i).toString("base64"),pageImageBase64String:o.toString("base64"),id:a});this.logger.debug({id:a,templateMatch:l},"Template matching got successful result");let{target:c,locator:u}=await this.getTargetFromPositionPercentages({percentX:l.x,percentY:l.y}),d=c.boundingBox?.width,m=c.boundingBox?.height;if(!d||!m)throw n="Rejecting target from screenshot due to no bounding box",new Error(n);let p=t.boundingBox?.width??0,f=t.boundingBox?.height??0;if(Math.abs(d-p)>50)throw n=`Rejecting target from screenshot due to width difference (${d-p})`,new Error(n);if(Math.abs(m-f)>50)throw n=`Rejecting target from screenshot due to height difference (${m-f})`,new Error(n);return{locator:u,a11yNode:this.a11yIdToNodeMap.get(c.id),displayString:c.nodeOnlySerializedHtml??"",decisions:[{type:"TEMPLATE_MATCHING",matched:!0,reason:"Found element using screenshot",elementImageUrl:e}]}}async resolveTargetWithXY(e,t=!1){if(this.logger.debug({target:e,skipFetchTree:t},"Resolve target through x / y positioning called"),!t){let i=(await this.getBrowserState({})).serialize();this.logger.debug({tree:i},"Got a11y tree for x / y resolution")}let n=await this.getActivePageOrFrame(),{target:o}=await this.getTargetFromPositionPercentages(e);if((o.generatedSelectors??[]).length>0)return{locator:n.locator(o.generatedSelectors[0]),a11yNode:this.a11yIdToNodeMap.get(o.id),displayString:o.nodeOnlySerializedHtml??o.nodeOnlySerializedForm??"Unknown element",decisions:[]};let s=this.a11yIdToNodeMap.get(o.id);if(s&&s.dataMomenticId)return{locator:n.locator(`[${it}="${s.dataMomenticId}"]`),a11yNode:s,displayString:s.getNodeOnlySerializedForm(),decisions:[]};throw new Error("Could not resolve target with x / y through either raw HTML or the accessibility tree")}async saveDownloadToDisk(e,t){this.logger.info("Download detected, saving file to disk");let n=await e,o=await n.path(),s=Wi(n.suggestedFilename()),i=t();await n.saveAs($d(i,s)),Dd(o,{force:!0}),setTimeout(()=>{Dd(i,{recursive:!0,force:!0})},5*60*1e3);let a=Bi(Fd(i),s);return this.logger.debug({uri:a,downloadFolder:i},"Saved download to isolated folder"),a}async typeIntoTarget(e,t,n={}){await this.highlightTarget(t);let o=1,s=await t.getAttribute("type",{timeout:1e3})??"",i=Id.some(a=>a===s.toLowerCase());for(;o>0;)try{await t.click({timeout:4e3,force:n.force,noWaitAfter:!0,position:i?{x:1,y:1}:void 0});break}catch(a){if(o--,o===0)throw new I("ActionFailureError",a.message,{cause:a});this.logger.warn({err:a},"Failed clicking on element for type action, retrying...")}return this.directTypeHelper(e,n)}async click(e,t,n={}){let o,s=await Ad({locator:e,logger:this.logger});s&&(e=s.locator,o=s.relativePoint),await this.highlightTarget(e);let i=this.url(),a=await this.getOpenPageUrls(),l;n.waitForDownload&&(l=(async()=>{try{return await this.page.waitForEvent("download",{timeout:1e4})}catch(d){throw d instanceof zg.TimeoutError?new I("ActionFailureError",`Download did not complete in ${1e4}ms`):d}})());let c=1,u=Date.now();for(;c>0;)try{if(n.doubleClick)await e.dblclick({button:n.rightClick?"right":"left",timeout:4e3,position:o,force:n.force,noWaitAfter:!0});else{let d=null;try{d=await e.getAttribute("target",{timeout:1e3})}catch(m){this.logger.warn({err:m},"Failed to get target attribute of element to be clicked, continuing...")}if(await e.click({button:n.rightClick?"right":"left",timeout:4e3,position:o,force:n.force,noWaitAfter:!0}),d==="_blank"){this.logger.debug("Waiting for new page promise due to _blank target");let m=Date.now(),p=this.pageLoadTimeout;for(;!this.pageLoadPromise&&Date.now()-m<p;)await K(250)}}this.logger.debug({duration:Date.now()-u},"Click completed on element");break}catch(d){if(c--,c===0)throw new I("ActionFailureError",d.message,{cause:d});this.logger.warn({err:d},"Failed clicking on element, retrying..."),await K(250)}if(n.waitForUrl&&await this.waitForUrl(i,n.waitForUrl,a),l){if(!t.createIsolatedFolder)throw new I("InternalWebAgentError","Cannot wait for download without a callback to create an isolated folder");return this.logger.info("Waiting for download to start and complete"),{downloadedFile:await ts(this.saveDownloadToDisk(l,t.createIsolatedFolder),{milliseconds:1e4,fallback:()=>{throw new I("ActionFailureError",`Download timed out after ${1e4}ms`)}})}}}async waitForUrl(e,t,n,o){let s=o??this.pageLoadTimeout,i=4;n||(n=await this.getOpenPageUrls());let a;for(let l=0;l<i;l++){if(a=await this.getOpenPageUrls(),a.length!==n.length)for(let c=a.length-1;c>=0;c--){let u=a[c];if(u!==e&&dn(u,this.logger)){await this.switchToPage(u,c);break}}try{await(await this.getActivePageOrFrame()).waitForURL(t,{timeout:Math.max(s/i,500),waitUntil:"domcontentloaded"});break}catch{if(l===i-1)throw new Error(`The browser did not navigate to '${t}' in the allocated timeout of ${s}ms. Current tabs:
|
|
1774
1772
|
${a.join(`
|
|
1775
|
-
`)}`);continue}}try{await this.loadFrameAndRecordUrl(this.page)}catch(l){this.logger.debug({err:l},"Failed waiting for page load after URL change, continuing...")}}async dragAndDrop(e,t,n={}){let o={timeout:8e3,force:n.force};await e.hover(o),await this.page.mouse.down(),await t.hover(o),await X(n.hoverSeconds?Math.min(n.hoverSeconds*1e3,8e3):500),await this.page.mouse.up()}async mouseDrag(e,t,n,o,s={}){let i=Object.assign({timeout:4e3},s);o&&await o.hover(i);let a=await(await this.getActivePageOrFrame()).evaluate(uc);a||(this.logger.debug("Could not get current mouse position before mouse drag action, defaulting to 0,0"),a={left:0,top:0}),await this.page.mouse.down(),await this.page.mouse.move(e+a.left,t+a.top,{steps:n}),await X(250),await this.page.mouse.up()}async hover(e,t){await this.highlightTarget(e),await e.hover({timeout:4e3,force:t})}async focus(e){await this.highlightTarget(e),await e.focus({timeout:4e3})}async blur(e){await this.highlightTarget(e),await e.blur({timeout:4e3})}async selectOption(e,t,n=!1){await this.highlightTarget(e);let o={timeout:4e3,force:n},s=2;for(;s>0;)try{await e.selectOption(t,o),this.logger.debug(`Selected '${t}' from dropdown`);break}catch(i){if(s--,s===0)throw i;this.logger.warn({err:i},"Failed selecting option, retrying...")}}async press(e){await this.page.keyboard.press(e)}async refresh(e){let t=e?.loadTimeoutMs??this.pageLoadTimeout,n=async()=>{await this.page.reload({waitUntil:"domcontentloaded",timeout:t}),await this.loadFrameAndRecordUrl(this.page)};await this.wrapPageLoad(n)}async getBrowserStateHelper({skipWait:e=!1,filterByViewport:t=!1,logger:n=this.logger}){let o={};await ot(()=>Promise.resolve(this.pageLoadPromise),"pageLoad",o);let s=await this.getActivePageOrFrameHelper(),i=await this.getViewportOffsetDetails(s),a;if(this.activeFrame){let d=this.activeFrame;a=(await ot(()=>this.getMatchingFrame(d),"frameFetch",o)).node.frameId,n.debug({iframeId:a},"Resolved iframe id")}let l=await ot(()=>this.getRawA11yTree({root:s,skipWait:e,iframeId:a,logger:n}),"a11yFetch",o),c=await ot(()=>this.getDOMTree(i.devicePixelRatio,a),"domFetch",o),u=await ot(()=>ac({a11yGraph:l,domGraph:c,logger:n,cdpClient:this.cdpClient,filterByViewport:t,viewportDetails:i}),"a11yProcess",o);if(!u||!u.root)throw new Error("Accessibility tree appears empty");return this.a11yIdToNodeMap=u.a11yIdNodeMap,this.dataMomenticIdToNodeMap=u.dataMomenticIdMap,this.domGraph=c,this.logger.debug(o,"Fetched browser state"),u}async getBrowserState(e){let{logger:t=this.logger,maxAttempts:n=2}=e,o=0,s;for(;o<n;){o++;try{return await bo(this.getBrowserStateHelper(e),{milliseconds:this.pageLoadTimeout})}catch(i){s=i instanceof Error?i.message:`${i}`,o<n&&t.debug({err:i,url:this.url()},"Error getting a11y tree, retrying...")}}throw new R("ActionFailureError",`Getting page content failed after ${n} attempts. Are you sure this page is working? Error: ${s}`)}getA11yIdFromDataMomenticId(e){return this.dataMomenticIdToNodeMap.get(e)?.id}async getViewportOffsetDetails(e){let[t,n,o,s,i]=await e.evaluate(()=>[window.scrollY,window.scrollX,window.screen.width,window.screen.height,window.devicePixelRatio]);return{upperBound:t,lowerBound:t+s,leftBound:n,rightBound:n+o,width:o,height:s,devicePixelRatio:this.systemDevicePixelRatio??i}}async getDOMTree(e,t){let n,o=0;for(;!n&&o<3;)try{if(await this.cdpClient.send("DOMSnapshot.enable"),n=await this.cdpClient.send("DOMSnapshot.captureSnapshot",{computedStyles:go}),!n||!n.documents.length)throw new Error("Got empty DOM tree")}catch(s){await X(500),this.logger.debug({err:s},"Error fetching DOM tree"),o++}if(!n||!n.documents.length)throw new R("InternalWebAgentError","Error fetching DOM tree");return dc({snapshot:n,devicePixelRatio:e,pageFrameId:t})}async waitForDOMStability(e){let{logger:t=this.logger}=e??{};try{let{root:s}=await this.cdpClient.send("DOM.getDocument",{depth:-1,pierce:!0})}catch(s){t.debug({err:s},"Failed to request root node while getting a11y tree")}let n={value:Date.now()},o=()=>{n.value=Date.now()};this.cdpClient.addListener("Accessibility.nodesUpdated",o),this.cdpClient.addListener("DOM.characterDataModified",o),this.cdpClient.addListener("DOM.attributeModified",o),this.cdpClient.addListener("DOM.childNodeCountUpdated",o),this.cdpClient.addListener("DOM.documentUpdated",o),this.cdpClient.addListener("Page.frameDetached",o),this.cdpClient.addListener("Page.frameStartedLoading",o),this.cdpClient.addListener("Page.frameRequestedNavigation",o);try{await this.waitForDOMStabilityHelper(n,t)}finally{this.cdpClient.removeListener("Accessibility.nodesUpdated",o),this.cdpClient.removeListener("DOM.characterDataModified",o),this.cdpClient.removeListener("DOM.attributeModified",o),this.cdpClient.removeListener("DOM.childNodeCountUpdated",o),this.cdpClient.removeListener("DOM.documentUpdated",o),this.cdpClient.removeListener("Page.frameDetached",o),this.cdpClient.removeListener("Page.frameStartedLoading",o),this.cdpClient.removeListener("Page.frameRequestedNavigation",o)}}async waitForDOMStabilityHelper(e,t=this.logger){let n=!1,o=Date.now(),s=this.smartWaitingTimeout,i;for(;Date.now()-o<s;){if(await X(500),i)try{let{data:l}=await this.cdpClient.send("Page.captureScreenshot",{optimizeForSpeed:!0,quality:25,format:"jpeg"});if(l!==i){i=l;continue}}catch{}else try{let{data:l}=await this.cdpClient.send("Page.captureScreenshot",{optimizeForSpeed:!0,quality:25,format:"jpeg"});i=l}catch{}if(!(Date.now()-e.value<750)){n=!0;break}}let a={duration:Date.now()-o,a11yStableReceived:n};n?t.debug(a,"A11y wait phase completed"):t.warn(a,"A11y wait phase completed due to timeout, continuing...")}async getRawA11yTree({root:e,skipWait:t=!1,iframeId:n=void 0,logger:o=this.logger}){let s={};t||await this.waitForDOMStability({logger:o}),await ot(async()=>e.evaluate("window.addIdsToElement(document.body, 1)"),"addIdsToElement",s);let i;if(n)i=(await ot(()=>this.cdpClient.send("Accessibility.getRootAXNode",{frameId:n}),"getRootAXNodeWithIframe",s)).node.backendDOMNodeId;else{let{node:l}=await ot(()=>this.cdpClient.send("Accessibility.getRootAXNode"),"getRootAXNode",s);i=l.backendDOMNodeId}let{nodes:a}=await ot(()=>this.cdpClient.send("Accessibility.queryAXTree",{backendNodeId:i}),"queryAXTree",s);if(!a||a.length<=1)throw new R("ActionFailureError","The page has no content. Are you sure it is working properly?");return Object.values(s).some(l=>typeof l=="number"&&l>500)&&o.warn({logTimings:s,numNodes:a.length},"Getting raw a11y tree took a long time"),{root:a[0],allNodes:a}}async clickUsingVisualCoordinates(e,t){let n=await this.getActivePageOrFrame(),{percentX:o,percentY:s}=e,{width:i,height:a}=await this.getViewportOffsetDetails(n),l=Math.ceil(i*o),c=Math.ceil(a*s),u=this.url(),d=await this.getOpenPageUrls();this.logger.debug({pixelDeltaX:l,pixelDeltaY:c,width:i,height:a},"Executing mouse click with visual coordinates"),await this.wrapPageLoad(async()=>this.page.mouse.click(l,c,{button:t.rightClick?"right":"left",clickCount:t.doubleClick?2:1})),t.waitForUrl&&await this.waitForUrl(u,t.waitForUrl,d)}async dragAndDropUsingVisualCoordinates(e,t,n){let o=await this.getActivePageOrFrame(),{percentX:s,percentY:i}=e,{percentX:a,percentY:l}=t,{width:c,height:u}=await this.getViewportOffsetDetails(o),d=Math.ceil(c*s),m=Math.ceil(u*i),p=Math.ceil(c*a),h=Math.ceil(u*l);await this.page.mouse.move(d,m),await this.page.mouse.down(),await this.page.mouse.move(p,h),await X(n.hoverSeconds?Math.min(n.hoverSeconds*1e3,8e3):500),await this.page.mouse.up()}async hoverUsingVisualCoordinates(e){let t=await this.getActivePageOrFrame(),{percentX:n,percentY:o}=e,{width:s,height:i}=await this.getViewportOffsetDetails(t),a=Math.ceil(s*n),l=Math.ceil(i*o);await this.page.mouse.move(a,l)}getAttributeFromStringArray(e,t){let n=e.findIndex(o=>o===t);if(!(n===-1||!e[n+1]))return e[n+1]}async getIDAttributeUsingCDP(e){await this.cdpClient.send("DOM.getDocument",{depth:0});let t=await this.cdpClient.send("DOM.requestNode",{objectId:e}),o=(await this.cdpClient.send("DOM.getAttributes",{nodeId:t.nodeId})).attributes,s=this.getAttributeFromStringArray(o,Ye);if(!s)throw new Error(`Could not find attribute ${Ye} for object ${e}`);return s}async getLocatorFromA11yNode(e){if(!e.backendNodeID)throw new Error(`Node with a11y id ${e.id} has no backend node ID`);return this.getLocatorFromBackendID(e.backendNodeID)}async getLocatorFromBackendID(e){let t=await this.cdpClient.send("DOM.resolveNode",{backendNodeId:e});if(!t||!t.object.objectId)throw new Error(`Could not resolve backend node ${e}`);let n;try{n=await this.getIDAttributeUsingCDP(t.object.objectId)}catch(o){throw this.logger.debug({err:o,object:JSON.stringify(t.object)},"Failed to get ID attribute"),o}return(await this.getActivePageOrFrame()).locator(`[${Ye}="${n}"]`)}async clickUsingCDP(e,t={}){let n=0,o,s=async l=>{let c=await this.getLocatorFromBackendID(l);t.doubleClick?await c.dblclick({timeout:4e3}):await c.click({timeout:4e3,button:t.rightClick?"right":"left",force:t.force,noWaitAfter:!0})};for(;n<2;)try{return await s(e.backendNodeID),e}catch(l){this.logger.error({err:l},"Failed clicking on node"),o=l,n++,await X(500)}let i=e.parent?.children??[];for(let l of i){if(l.id===e.id)continue;let c=!1,u=Ms(l,e);if(e.name&&l.name===e.name?c=!0:u>=5&&(this.logger.debug({similarityScore:u},"Sibling qualified for click redirection through comparison score"),c=!0),!!c)try{return await s(l.backendNodeID),l}catch(d){this.logger.debug({err:d,candidate:l.getLogForm()},"Failed clicking on sibling during click redirection")}}let a=e.parent;for(n=0;n<ec;){if(!a||["rootwebarea","main"].includes(a.role.toLowerCase()))throw new R("ActionFailureError",o.message,{cause:o});if(!a.backendNodeID){a=a.parent;continue}try{return await s(a.id),a}catch(c){this.logger.debug({err:c,candidate:a.getLogForm()},"Failed clicking on parent during click redirection"),n++,a=a.parent}}throw new R("ActionFailureError",`Max click attempts exhausted on element ${e.getLogForm()}: ${o.message}`,{cause:o})}async getElementLocation(e){let t=await this.cdpClient.send("DOMSnapshot.captureSnapshot",{computedStyles:[],includeDOMRects:!0,includePaintOrder:!0}),n=await this.page.evaluate(()=>window.devicePixelRatio);process.platform==="darwin"&&n===1&&(n=2);let o=t.documents[0],s=o.layout,i=o.nodes,a=i.nodeName||[],l=i.backendNodeId||[],c=s.nodeIndex,u=s.bounds,d=-1;for(let w=0;w<a.length;w++)if(l[w]===e){d=c.indexOf(w);break}if(d===-1)throw new Error(`Could not find any backend node with ID ${e}`);let[m=0,p=0,h=0,g=0]=u[d];m/=n,p/=n,h/=n,g/=n;let f=m+h/2,y=p+g/2;return{centerX:f,centerY:y}}async scroll(e,t,n,o){let s=t==="left"?-1:1,i=o==="up"?-1:1;if(this.activeFrame)await(await this.getActivePageOrFrame()).evaluate(([l,c,u,d])=>window.scrollTo(window.scrollX+(l??window.innerWidth)*u,window.scrollY+(c??window.innerHeight)*d),[e,n,s,i]);else{let a=this.page.viewportSize()||ct;await this.page.mouse.wheel((e??a.width)*s,(n??a.height)*i)}}async scrollUp(e){return this.scroll(0,null,e??null,"up")}async scrollDown(e){await this.scroll(0,null,e??null,"down")}async scrollLeft(e){await this.scroll(e??null,"left",0,null)}async scrollRight(e){await this.scroll(e??null,"right",0,null)}async goForward(){await this.wrapPageLoad(async()=>await this.page.goForward({waitUntil:"domcontentloaded",timeout:this.pageLoadTimeout}))}async goBack(){await this.wrapPageLoad(async()=>this.page.goBack({waitUntil:"domcontentloaded",timeout:this.pageLoadTimeout}))}async changeActivePage(e,t){this.recordUrlVisited(e.url()),this.page=e;let n=await r.initCDPSession(this.context,this.page,this.logger,t??this.pageLoadTimeout),o=this.cdpClient;this.cdpClient=n;try{await o.detach()}catch{}}async createNewTab(e,t){let n=await this.context.newPage();await this.changeActivePage(n,t?.loadTimeoutMs),await this.navigate({url:e,initialNavigation:!0,...t})}async switchToPageByIndex(e,t,n){let o=e.url();if(!Jt(o,this.logger)){this.logger.error({tabUrl:o},"Refusing to switch to tab with invalid URL");return}this.logger.debug(`Switching to tab ${t} with url ${o}`),await this.changeActivePage(e,n?.loadTimeoutMs),await this.loadFrameAndRecordUrl(e)}async switchToPage(e,t,n){await this.wrapPageLoad(async()=>this.switchToPageHelper(e,t,n))}async switchToPageHelper(e,t,n){let o=this.context.pages(),s=await Us(this.context,this.logger);if(t){await this.switchToPageByIndex(o[t],t,n);let i=s[t].url;this.onTabsChange?.(s,i);return}for(let i=0;i<o.length;i++){let a=o[i];if(a.url().includes(e)){await this.switchToPageByIndex(a,i,n);let l=s[i].url;this.onTabsChange?.(s,l);return}}throw new Error(`Could not find page with url containing ${e}`)}async setCookie(e){let t;return typeof e=="string"?t=ta(e):t=[e],await this.context.addCookies(t),t}async setLocalStorage(e,t){await(await this.getActivePageOrFrame()).evaluate(([o,s])=>{o&&localStorage.setItem(o,s||"")},[e,t])}async solveCloudflareTurnstile(){let t=(await this.getActivePageOrFrame()).locator(".cf-turnstile").locator("iframe").getAttribute("data-sitekey"),n=await fetch("https://2captcha.com/in.php",{method:"POST",body:JSON.stringify({key:Rr,method:"turnstile",sitekey:t,pageurl:this.url(),json:1})});if(!n.ok){let i=`Captcha solver API returned error response: ${n.statusText}`;throw this.logger.error({text:await n.text()},i),new Error(i)}let{request:o}=await n.json(),s=Date.now();for(;Date.now()-s<6e4;){await X(2500);let i=await fetch(`https://2captcha.com/res.php?key=${Rr}&action=get&id=${o}&json=1`,{method:"GET"});if(!i.ok){let l=`Captcha solution API returned error response: ${i.statusText}`;throw this.logger.error({text:await i.text()},l),new Error(l)}if((await i.json()).status===1)break}}async solveCaptcha(){await this.getBrowserState({});let e;for(let a of this.a11yIdToNodeMap.values())if(a.role==="image"&&a.name.toLowerCase().includes("captcha")){if(!a.backendNodeID)continue;e=await this.getLocatorFromBackendID(a.backendNodeID);break}if(!e){let a=await(await this.getActivePageOrFrame()).solveRecaptchas();if(!a.captchas||!a.captchas.length)throw new Error("No captchas found on the page");return}let t=await e.screenshot({type:"jpeg",animations:"allow",caret:"hide",quality:100,timeout:4e3}),n=await fetch("https://api.2captcha.com/createTask",{method:"POST",body:JSON.stringify({clientKey:Rr,task:{type:"ImageToTextTask",body:t.toString("base64"),case:!0},languagePool:"en"})});if(!n.ok){let a=`Captcha solver API returned error response: ${n.statusText}`;throw this.logger.error({text:await n.text()},a),new Error(a)}let{taskId:o}=await n.json(),s=Date.now(),i="";for(;Date.now()-s<6e4;){await X(2500);let a=await fetch("https://api.2captcha.com/getTaskResult",{method:"POST",body:JSON.stringify({clientKey:Rr,taskId:o})});if(!a.ok){let c=`Captcha solution API returned error response: ${a.statusText}`;throw this.logger.error({text:await a.text()},c),new Error(c)}let l=await a.json();if(l.errorId){let c=`Captcha solution API returned error ID ${l.errorId}`;throw this.logger.error(c),new Error(c)}if(l.status==="ready"){i=l.solution.text;break}}if(!i)throw new Error("Captcha solution timed out");return i}getActiveFrame(){return this.activeFrame}async captureTargetFromClick(){let e=new AbortController;await this.startTreeRefreshCronForRecording(e.signal);let t;try{if(t=await(await this.getActivePageOrFrame()).evaluate(async()=>{let n=window;if(!n.resolveRecordingTarget){console.error("[MOMENTIC] Missing Momentic recording library functions");return}let o=null;n.targetCaptureClickListener=async i=>(console.debug("[MOMENTIC] Target capture listener fired"),i.preventDefault(),i.stopImmediatePropagation(),o=i.target,!1),document.addEventListener("mousedown",n.targetCaptureClickListener,{capture:!0,once:!0});let s=Date.now();for(;!o&&Date.now()-s<1e4;)await new Promise(i=>setTimeout(i,250));if(!o)throw new Error("Timed out waiting for user to click on an element");return n.resolveRecordingTarget(o)}),t?.error)throw new Error(t.error);if(t?.target)t.warnings.length&&this.logger.warn({result:t},"Got warnings while capturing target from click");else throw new Error("No target captured from click")}catch(n){throw this.logger.error({err:n},"Error recording target click"),new Error(`Error recording click: ${n.message}`)}finally{e.abort()}if(!t)throw new Error("Got no target from recorded click - please make sure you clicked on an interactive element");return this.getTargetFromRecordedClick(t.target).target}areDomNodeBoundingBoxesSimilar(e,t,n){if(!t.bounds)return this.logger.debug({candidate:t},"Filtering out click candidate since it has no bounding box"),!1;let o=e.bounds,s=o.x??0,i=o.width??0,a=o.height??0,l=s+i,c=o.y??0,u=c+(o.height??0),d=t.bounds,m=d.width??0,p=d.height??0,h=d.x??0,g=h+(d.width??0),f=d.y??0,y=f+(d.height??0);return h<l&&g>s&&f<u&&y>c?Math.abs(i-m)<200&&Math.abs(a-p)<200?!0:(Sr({logger:this.logger,logKey:n,maxCount:5,intervalMs:3e3},{candidate:t,originalNode:e},"Filtering out click candidate since it has a significantly different area"),!1):(Sr({logger:this.logger,logKey:n,maxCount:5,intervalMs:3e3},{candidate:t},"Filtering out click candidate since it does not intersect with the original node"),!1)}getDomCandidatesInA11yTree(e,t){let n=Object.values(t.backendIdToNode),o,s=Og();for(let c of n)if(c.attributes?.[Ye]===e){o=c;break}if(!o)return[];let i=[],a=t.backendIdToNode[o.parentBackendNodeId??-1];for(;a&&(a?.momenticIgnored||!this.areDomNodeBoundingBoxesSimilar(o,a,s));)a=t.backendIdToNode[a.parentBackendNodeId??-1];a&&i.push(a);let l=[o];for(;l.length;){let c=l.shift();for(let u of c.children??[]){let d=t.backendIdToNode[u];d&&!d.momenticIgnored&&this.areDomNodeBoundingBoxesSimilar(o,d,s)?i.push(d):d&&l.push(d)}}return i}getTargetFromRecordedClick(e){this.logger.debug(e,"Got HTML target attributes from click recording");let{htmlAttributes:t,dataMomenticId:n}=e,s=this.dataMomenticIdToNodeMap.get(n),i={id:s?.id??-1,dataMomenticId:n,targetSource:"CLICK_TO_FIND",targetUpdateTime:new Date().toUTCString(),...t};return s?this.saveA11yDetailsToCache(s,i):this.logger.warn({htmlAttributes:t},"Could not find corresponding accessibility node for click. Continuing with HTML attributes only"),{target:i,a11yNode:s}}async exposeRecordingBindings(){let e=({frame:t},n)=>{if(!this.transformer)return;let{type:o,target:s,error:i,warnings:a,selectedValue:l}=n,c=t.url();if(this.logger.debug({url:c,...n},`${o} event captured on element`),i){this.logger.error({error:i,warnings:a},"Error while capturing passive element interaction");return}else if(s)a.length&&this.logger.warn({warnings:a},`Warnings while capturing passive element interaction of type ${o}`);else{this.logger.error({event:n},"No target found in passive element interaction event");return}let{dataMomenticId:u,htmlAttributes:d}=s,m=this.dataMomenticIdToNodeMap,p=this.mostRecentA11yTree,h=m.get(u),g={id:h?.id??-1,dataMomenticId:u,targetSource:"RECORDING",targetUpdateTime:new Date().toUTCString(),...d};h?this.saveA11yDetailsToCache(h,g):this.logger.debug({url:c,htmlAttributes:d},"Could not find corresponding accessibility node for click, continuing with HTML attributes only"),(async()=>{if(!this.transformer){this.logger.warn("No natural language translation since transformer is not initialized anymore");return}this.logger.debug({target:s,url:c},`Generating description for ${o.toLowerCase()}ed target`);let f=p?.serialize();h&&f&&f.length>5e3&&(f=lc(h.id,f),this.logger.debug({serializedTree:f},"Trimmed a11y tree for description transformation"));try{await this.transformer.recordElementAction({type:o,target:g,browserState:f,url:c,selectedValue:l})}catch(y){this.logger.error({err:y},`Failed to record ${o} action`)}})()};await this.context.exposeBinding("isRecordingActive",()=>!!this.transformer),await this.context.exposeBinding("captureElementEvent",({frame:t},n)=>{try{e({frame:t},n)}catch(o){this.logger.error({err:o},"Failed to capture element interaction")}},{handle:!1}),await this.context.exposeBinding("captureKeystroke",async(t,n)=>{this.transformer&&this.transformer.recordKeystroke(n)})}async fetchA11yTreeForRecording(){let e=await this.getBrowserState({skipWait:!0,maxAttempts:1});if(this.mostRecentA11yTree=e,Math.random()<.1){let n=this.mostRecentA11yTree.serialize();this.logger.debug({tree:n.length>4e5?"REDACTED_DUE_TO_SIZE":n},"Refreshed a11y tree during recording")}await(await this.getActivePageOrFrame()).evaluate(n=>{let o=window;o.momenticIdsInA11yTree=new Set(n)},Array.from(this.dataMomenticIdToNodeMap.keys()))}async startTreeRefreshCronForRecording(e){if(await this.fetchA11yTreeForRecording(),e.aborted)return;let t,n=!1,o=0,s=0,i=async()=>{if(!(Date.now()-s<=1e3)&&!n){n=!0;try{await this.fetchA11yTreeForRecording(),o=0}catch(a){if(s=Date.now(),o++,o>=8||a.message.includes("crashed")){clearInterval(t),this.logger.error({err:a},"Fatal errors while refreshing a11y tree during recording, exiting...");return}}finally{n=!1}}};t=setInterval(()=>{!this.transformer||e.aborted||i()},tc),e.addEventListener("abort",()=>{clearInterval(t),t=void 0})}async startRecording(e,t){this.logger.debug("Starting passive recording mode in Chrome browser"),await this.startTreeRefreshCronForRecording(e),this.transformer=t,e.addEventListener("abort",async()=>{this.transformer=void 0})}async getSelectOptions(e){return await e.evaluate(n=>Array.from(n.querySelectorAll("option")).map(s=>s.value),{timeout:1e3})}getActivePage(){return this.page}async getActivePageOrFrame(){if(!this.activeFrame)return this.page;if(this.activeFrameCache)if(JSON.stringify(this.activeFrame)!==this.activeFrameCache.frameIdentifierStringified)this.activeFrameCache=void 0;else if("isDetached"in this.activeFrameCache.frame&&this.activeFrameCache.frame.isDetached())this.activeFrameCache=void 0;else if("isClosed"in this.activeFrameCache.frame&&this.activeFrameCache.frame.isClosed())this.activeFrameCache=void 0;else return this.activeFrameCache.frame;let e=Date.now(),t,n;for(;Date.now()-e<this.smartWaitingTimeout;)try{t=await this.getActivePageOrFrameHelper();break}catch(o){n=o,await X(500)}if(t)return this.activeFrameCache={frame:t,frameIdentifierStringified:JSON.stringify(this.activeFrame),cacheTime:Date.now()},t;throw n}async loadFrameAndRecordUrl(e){let t=this.pageLoadTimeout;await e.waitForLoadState("domcontentloaded",{timeout:t});try{await e.waitForLoadState("load",{timeout:t})}catch(n){this.logger.warn({err:n},"Timeout elapsed waiting for current frame to load, continuing...")}this.recordUrlVisited(e.url())}async getCondensedHtml(){return this.wrapPageLoad(async()=>this.getCondensedHtmlHelper())}async getCondensedHtmlHelper(){await this.waitForDOMStability();let e=await this.getActivePageOrFrame();await fn(e,this.logger);let{result:t,error:n}=await e.evaluate(()=>window.getCondensedHtmlTree(),{timeout:1e3});if(n)throw new Error(`Failed to process page HTML: ${n}`);if(!t)throw new R("InternalWebAgentError","Got empty HTML tree - are you sure the page is fully loaded?");return Dg.html(t,{indent_size:1,indent_with_tabs:!1,preserve_newlines:!1,wrap_line_length:100})}async registerDialogHandler(e){let t=async n=>e==="ACCEPT"?n.accept():n.dismiss();this.page.once("dialog",t)}async evaluateFunctionInPage(e,t){return this.page.evaluate(t,e)}async evaluateCodeInPage({code:e,fragment:t,context:n,timeoutMs:o=2e3}){let s=xc(),i={code:e,fragment:t,context:n},{result:a}=await bo(this.page.evaluate(s,i),{milliseconds:o,fallback:()=>{throw new R("ActionFailureError",`Code evaluation in browser exceeded the allowed timeout of ${o/1e3} seconds`)}});return a}async getDomNodeFromPositionPercentages(e,{percentX:t,percentY:n}){if(t<0||t>1||n<0||n>1)throw new R("InternalWebAgentError","Invalid percent passed to percentage location");let{width:o,height:s,upperBound:i,leftBound:a,devicePixelRatio:l}=await this.getViewportOffsetDetails(e),c=Math.round(i),u=Math.round(a),d=Math.ceil(o*t),m=Math.ceil(s*n);await this.cdpClient.send("DOM.getDocument",{depth:0});let p;try{p=await this.cdpClient.send("DOM.getNodeForLocation",{x:d+u,y:m+c})}catch(h){throw this.logger.error({err:h,pixelDeltaX:d,pixelDeltaY:m,leftBoundRounded:u,upperBoundRounded:c,devicePixelRatio:l},"Failed to get DOM node from position percents"),new Error("No element was found at the given location")}return p}async highlightFromPositionPercentages(e){let t=await this.getActivePageOrFrame(),n;try{n=await this.getDomNodeFromPositionPercentages(t,e)}catch{}return n?(await this.cdpClient.send("Overlay.highlightNode",{highlightConfig:cc,backendNodeId:n.backendNodeId}),async()=>{try{await this.cdpClient.send("Overlay.hideHighlight",{backendNodeId:n?.backendNodeId})}catch{}}):async()=>{}}async clearAllCdpHighlights(){try{await this.cdpClient.send("Overlay.hideHighlight")}catch{}}async getTargetFromPositionPercentages(e){let t=await this.getActivePageOrFrame(),n=await this.getDomNodeFromPositionPercentages(t,e),o=this.domGraph?.backendIdToNode[n.backendNodeId],s=o?.attributes[Ye],i=parseInt(s??"");if(!o||!s||isNaN(i))throw new Error("No HTML node was found at the given location");let a=t.locator(`[${Ye}="${s}"]`);for(let d of this.a11yIdToNodeMap.values()){if(d.backendNodeID!==n.backendNodeId)continue;let m={id:d.id,targetSource:"XY_PERCENT",targetUpdateTime:new Date().toUTCString()};return await this.saveNodeDetailsToCache(t,d,m,parseInt(s),a),{target:m,locator:a}}let l=this.getDomCandidatesInA11yTree(`${s}`,this.domGraph);for(let d of l){let m=parseInt(d.attributes?.[Ye]??"");if(isNaN(m))continue;let p=t.locator(`[${Ye}="${m}"]`),h=this.dataMomenticIdToNodeMap.get(m),g=h?.id;if(!g)continue;let f={id:g,targetSource:"XY_PERCENT",targetUpdateTime:new Date().toUTCString()};return await this.saveNodeDetailsToCache(t,h,f,parseInt(s),p),this.logger.debug({target:f},"Redirected click on non-accessible element to nearest a11y node"),{target:f,locator:p}}let c=await this.fetchHtmlAttributes(t,i);return{target:{id:-1,dataMomenticId:i,targetSource:"XY_PERCENT",targetUpdateTime:new Date().toUTCString(),...c},locator:a}}async fetchHtmlAttributes(e,t){let n=await e.evaluate(o=>{let s=window;return s.generateHtmlCacheAttributes?s.generateHtmlCacheAttributes(o):{warnings:[],error:"generateHtmlCacheAttributes is not defined"}},t);if("error"in n)throw new Error(n.error);if(n.attributes)n.warnings.length&&this.logger.warn(n,"Got warnings while generating HTML attributes for target");else return this.logger.warn(n,"Got no generated HTML attributes for target"),{};return this.logger.debug(n.attributes,"Generated HTML attributes for target"),n.attributes}async moveMouseFromPositionPercentages(e,t){let n=await this.getActivePageOrFrame(),o;try{o=await this.getViewportOffsetDetails(n)}catch{return}let{width:s,height:i}=o,a=Math.ceil(s*e),l=Math.ceil(i*t);await this.page.mouse.move(a,l,{steps:3})}async clickMouseFromPositionPercentages(e,t){let n=await this.getActivePageOrFrame(),o;try{o=await this.getViewportOffsetDetails(n)}catch{return}let{width:s,height:i}=o,a=Math.ceil(s*e),l=Math.ceil(i*t);await this.page.mouse.click(a,l,{button:"left"})}async scrollFromPositionPercentages(e,t){let n=await this.getActivePageOrFrame(),o;try{o=await this.getViewportOffsetDetails(n)}catch{return}let{width:s,height:i}=o,a=Math.ceil(s*e),l=Math.ceil(i*t);return await this.page.mouse.wheel(a,l),{deltaX:a,deltaY:l}}canSolveCaptchas(){return!!Rr}async getFrameSrcUrls(){let e=this.page.url(),t=this.page.frames(),n=[];for(let s of t)if(!s.isDetached())try{let a=await(await s.frameElement()).evaluate(l=>"src"in l?l.getAttribute("src"):null);a&&a!=="about:blank"&&a!==e&&n.push(a)}catch(i){let a=i.message;["detached","browser has been closed"].some(l=>a.includes(l))||this.logger.debug({err:i},"Error fetching frame src url, continuing...")}return Array.from(new Set(n))}async setFileChooserHandler(e){setTimeout(()=>{try{e.cleanup()}catch(t){this.logger.debug({err:t,filePath:e.filePath},"Failed cleaning up file after upload")}},3e4),await this.setFileChooserHandlerHelper(e)}logToUserConsole(e,t,n,...o){let s=this.context.pages().indexOf(e);s=s===-1?0:s,Fs(e,this.debugData,s,{type:t,text:`[MOMENTIC] ${n}`,args:o})}async setFileChooserHandlerHelper({filePath:e}){if(!Pc(e)){let n=`File chooser triggered after the source file ${e} has been cleaned up, ignoring...`;this.logger.error(n),this.logToUserConsole(this.page,"error",n);return}this.page.once("filechooser",async n=>{this.logger.debug({filePath:e},"File chooser triggered");try{if(!Pc(e))throw new Error(`File chooser triggered after the source file ${e} has been cleaned up, ignoring...`);await n.setFiles(e,{timeout:8e3})}catch(o){this.logger.error({err:o},"Error handling file chooser"),this.logToUserConsole(this.page,"error",o.message)}});let t=Ng(e).toString("base64");await(await this.getActivePageOrFrame()).evaluate(({fileName:n,base64Data:o})=>{let s=window;s.MomenticFile=class{async getFile(){let i=atob(o),a=new Array(i.length);for(let u=0;u<i.length;u++)a[u]=i.charCodeAt(u);let l=new Uint8Array(a),c=new Blob([l]);return new File([c],n)}},s.showOpenFilePicker=async()=>[new s.MomenticFile]},{fileName:Lc(e),base64Data:t})}getSerializedFormFromA11yId(e){return this.a11yIdToNodeMap.get(e)?.getNodeOnlySerializedForm()}get smartWaitingTimeout(){return this.userControlledBrowserSettings.smartWaitingTimeoutMs??3e3}get pageLoadTimeout(){return this.userControlledBrowserSettings.pageLoadTimeoutMs??8e3}retrieveAndClearConsoleLogs(){let e=this.debugData.logsPerPage;return this.debugData.logsPerPage=[],e}};var Gg=({socket:r,metadata:e,logger:t,storage:n})=>async({baseUrl:o,environmentName:s})=>{let{testId:i,sessionId:a,orgId:l}=e;t.info({testId:i,sessionId:a,baseUrl:o},"Reset event received");let c=s?await n.fetchEnvironment(l,s,t):void 0,u=null,d=_.getSession(a);if(!d){r.emit("error",{message:"No session to reset"});return}let{controller:m,context:p}=d;await m.browser.reset({clearCookies:!0,clearStorage:!0,url:o});let h=m.browser.baseUrl;p.reset({baseUrl:h,currentUrl:m.browser.url(),variablesFromEnvironment:c?.variables??{},envName:s}),u=await m.browser.getViewport();let g=st.USER_AGENT;t.info(`Session reset for test ${i} at ${h}`),r.emit("session",{url:h,userAgent:g,viewport:u,sessionId:a})},_c={event:"reset",createHandler:Gg};var Vg=({metadata:r})=>{let{sessionId:e}=r;return async({url:t})=>{let n=_.getSession(e);if(!n)throw new Error("No active session found");await n.controller.browser.switchToPage(t)}},Dc={event:"switchTab",createHandler:Vg};var qg=({metadata:r})=>{let{sessionId:e}=r;return({indices:t},n)=>{let o=_.getSession(e);if(!o)return;let s=o.resultsManager.getContextCopyAtIndices(t)??o.context.toRedactedDisplayCopy();ts(s),n(s)}},kc={event:"getTestContext",createHandler:qg};import{PostHog as Kg}from"posthog-node";var Yg=new Kg("phc_WRWd8LYIv6rolgDsyCdrPpxtZhsu6qXAkEwPicl44bI",{host:"https://app.posthog.com"}),Ir=class r extends Hn{static async init(e){let t={},n,o=0,s=3;for(;o<s;)try{t=await Yg.getAllFlags(e);break}catch(i){n=i,o++,await new Promise(a=>setTimeout(a,500*o))}if(o===s)throw n;return new r(t)}};var Fc=process.env.GCP_TEMPLATE_MATCHING_FUNCTION_ENDPOINT,To=class{constructor(e){this.logger=e}async runTemplateMatching({searchImageBase64String:e,pageImageBase64String:t,id:n,timeoutMs:o=3e3}){if(!Fc)throw new Error("GCP_TEMPLATE_MATCHING_FUNCTION_ENDPOINT environment variable not set");let s={search_image:e,page_image:t,request_id:n},i=new AbortController,a=setTimeout(()=>{i.abort()},o),c=await fetch(Fc,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s),signal:i.signal});if(clearTimeout(a),c.status===422){let u=(await c.json()).error;throw new zn(u)}if(!c.ok)throw new Error(`Template matching server returned error code: ${c.status}`);try{let u=await c.json();return _n.parse(u)}catch(u){throw new Error(`Error parsing template matching response: ${u}`)}}};var Xg={type:"a11y",version:"1.0.0",useHistory:"diff",useGoalSplitter:!0},Sn=Xg;import Sh from"dedent";import wh from"diff-lines";import{cloneDeep as bh}from"lodash-es";import{z as Pr}from"zod";var Uc=Pr.object({doubleClick:Pr.boolean().optional(),rightClick:Pr.boolean().optional(),force:Pr.boolean().optional(),waitForDownload:Pr.boolean().optional(),waitForUrl:Pr.string().optional()});import{randomUUID as ft}from"crypto";var Jg=["Shift","CapsLock","Dead","Meta","AudioVolumeUp","AudioVolumeDown"],Eo=class{recordedSteps=new Map;onStepRecord;signal;generator;testId;orgId;storage;indices;logger;constructor({signal:e,onStepRecord:t,generator:n,initialIndices:o,storage:s,testId:i,orgId:a,logger:l}){this.signal=e,this.storage=s,this.logger=l,this.testId=i,this.orgId=a,this.onStepRecord=(c,u,d)=>{this.recordedSteps.set(JSON.stringify(u),{step:c,url:d}),t(c,u)},this.generator=n,this.indices=o}reserveIndexForCommand(e,t){let n=Array.from(this.indices);return this.recordedSteps.set(JSON.stringify(n),{step:{id:ft(),type:"PRESET_ACTION",command:It(e)},url:t}),this.indices[this.indices.length-1]++,n}async recordElementAction(e){if(this.signal.aborted){this.logger.debug("Transformer was already cleaned up, ignoring click...");return}let{type:t,target:n,browserState:o,url:s}=e,{indices:i}=e,a,l,c=n.nodeOnlySerializedHtml?.trim()??n.nodeOnlySerializedForm??"Unknown element - please provide a description manually";switch(t){case"CLICK":a="CLICK";let p=It(a);l={id:ft(),type:"PRESET_ACTION",command:{...p,target:{type:"description",elementDescriptor:c},cache:{target:n}}};break;case"SELECT":a="SELECT_OPTION";let h=It(a);l={id:ft(),type:"PRESET_ACTION",command:{...h,type:"SELECT_OPTION",target:{type:"description",elementDescriptor:c},cache:{target:n},option:e.selectedValue??"Unknown option"}};break;default:throw new Error(`Unknown action type: ${t}`)}if(i||(i=Array.from(this.indices),this.indices[this.indices.length-1]++),this.onStepRecord(l,i,s),n.id<=0){this.logger.debug("Skipping reverse mapping for non-accessible element");return}else if(!o){this.logger.debug("Skipping reverse mapping since the browser a11y state is not available");return}let u;try{u=(await this.generator.getReverseMappedDescription({goal:`${n.id}`,browserState:o},{disableCache:!1,orgId:this.orgId})).phrase}catch(p){this.logger.error({err:p},"Error generating reverse mapping description"),u=c}let d=this.recordedSteps.get(JSON.stringify(i))?.step,m=d?.command;m&&"target"in m&&m.target?(m.target={type:"description",elementDescriptor:u},this.onStepRecord({...d,command:m},i,s)):this.logger.warn("Could not find existing command to update after description mapping")}recordKeystroke(e){let{key:t,url:n,dataMomenticId:o}=e;if(Jg.includes(t)||this.signal.aborted)return;let s="normal";t.length>1&&(s="special");let i;if(s==="normal"){let p=It("TYPE");i={id:ft(),type:"PRESET_ACTION",command:{...p,target:void 0,value:t,clearContent:!1}}}else{let p=It("PRESS");i={id:ft(),type:"PRESET_ACTION",command:{...p,value:t}}}let a,l=Array.from(this.indices);l[this.indices.length-1]--;let c=this.recordedSteps.get(JSON.stringify(l)),u=c?.step,d=u?.command,m=c?.url;if(n===m){if(d?.type===i.command.type){let p=d.value,h=i.command.value;i={id:ft(),type:"PRESET_ACTION",command:{...d,value:i.command.type==="PRESS"?`${p}+${h}`:`${p}${h}`}},a=l}else if(d?.type==="CLICK"&&i.command.type==="TYPE")(!o||d.cache?.target.dataMomenticId===parseInt(o))&&(u.command={...i.command,target:d.target,cache:d.cache},i=c.step,a=l);else if(d?.type==="TYPE"&&i.command.type==="PRESS"&&i.command.value==="Backspace"){let p=d.value;i={id:ft(),type:"PRESET_ACTION",command:{...d,value:p.slice(0,p.length-1)}},a=l}}a||(a=Array.from(this.indices),this.indices[this.indices.length-1]++),this.onStepRecord(i,a,n)}recordScroll(e){if(this.signal.aborted)return;let{url:t}=e,n=()=>{let{deltaY:a}=e;if(!a)return;let l=Array.from(this.indices);l[this.indices.length-1]--;let c=this.recordedSteps.get(JSON.stringify(l))?.step.command,u;c?.type==="SCROLL_DOWN"&&c.deltaY?(a+=c.deltaY,u=l):c?.type==="SCROLL_UP"&&c.deltaY?(a-=c.deltaY,u=l):(u=Array.from(this.indices),this.indices[this.indices.length-1]++);let d=a>0?"SCROLL_DOWN":"SCROLL_UP",m=It(d);m.deltaY=Math.abs(a);let p={id:ft(),type:"PRESET_ACTION",command:m};this.onStepRecord(p,u,t)},o=()=>{let{deltaX:a}=e;if(!a)return;let l=Array.from(this.indices);l[this.indices.length-1]--;let c=this.recordedSteps.get(JSON.stringify(l))?.step.command,u;c?.type==="SCROLL_RIGHT"&&c.deltaX?(a+=c.deltaX,u=l):c?.type==="SCROLL_LEFT"&&c.deltaX?(a-=c.deltaX,u=l):(u=Array.from(this.indices),this.indices[this.indices.length-1]++);let d=a>0?"SCROLL_RIGHT":"SCROLL_LEFT",m=It(d);m.deltaX=Math.abs(a);let p={id:ft(),type:"PRESET_ACTION",command:m};this.onStepRecord(p,u,t)},s=Array.from(this.indices);s[this.indices.length-1]--;let i=this.recordedSteps.get(JSON.stringify(s));i?.step.command.type==="SCROLL_LEFT"||i?.step.command.type==="SCROLL_RIGHT"?(o(),e.deltaY>=20&&n()):(n(),e.deltaX>=20&&o())}};var $s=(r,e,t)=>{let[n,...o]=e.split("."),s=n;return o.length>=1?$s(r[s],o.join("."),t):r[s]=t,r};import ch from"p-timeout";var wn={"gpt-3.5-turbo-1106":16184,"ft:gpt-3.5-turbo-0125:momentic:locator-0508:9NvTpgSc":16184,"ft:gpt-3.5-turbo-1106:momentic:text-assertions:9CEFjgB4":16184,"ft:gpt-3.5-turbo-1106:momentic::8vgMsQca":16184,"gpt-4o-mini-2024-07-18":128e3,"gpt-4o-2024-05-13":128e3,"claude-3-opus-20240229":2e5,"claude-3-sonnet-20240229":2e5,"claude-3-5-sonnet-20240620":2e5,"claude-3-haiku-20240307":2e5};var vo=3.1;function Zg(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 xo(r){return Math.ceil(Bs(r)/vo)}function Bs(r){let e=0;if(typeof r=="string"){let t=r;t=t.replaceAll(`
|
|
1776
|
-
`,""),t=t.replaceAll(" ","");let n=
|
|
1773
|
+
`)}`);continue}}try{await this.loadFrameAndRecordUrl(this.page)}catch(l){this.logger.debug({err:l},"Failed waiting for page load after URL change, continuing...")}}async dragAndDrop(e,t,n={}){let o={timeout:8e3,force:n.force};await e.hover(o),await this.page.mouse.down(),await t.hover(o),await K(n.hoverSeconds?Math.min(n.hoverSeconds*1e3,8e3):500),await this.page.mouse.up()}async mouseDrag(e,t,n,o,s={}){let i=Object.assign({timeout:4e3},s);o&&await o.hover(i);let a=await(await this.getActivePageOrFrame()).evaluate(yd);a||(this.logger.debug("Could not get current mouse position before mouse drag action, defaulting to 0,0"),a={left:0,top:0}),await this.page.mouse.down(),await this.page.mouse.move(e+a.left,t+a.top,{steps:n}),await K(250),await this.page.mouse.up()}async hover(e,t){await this.highlightTarget(e),await e.hover({timeout:4e3,force:t})}async focus(e){await this.highlightTarget(e),await e.focus({timeout:4e3})}async blur(e){await this.highlightTarget(e),await e.blur({timeout:4e3})}async selectOption(e,t,n=!1){await this.highlightTarget(e);let o={timeout:4e3,force:n},s=2;for(;s>0;)try{await e.selectOption(t,o),this.logger.debug(`Selected '${t}' from dropdown`);break}catch(i){if(s--,s===0)throw i;this.logger.warn({err:i},"Failed selecting option, retrying...")}}async press(e){await this.page.keyboard.press(e)}async refresh(e){let t=e?.loadTimeoutMs??this.pageLoadTimeout,n=async()=>{await this.page.reload({waitUntil:"domcontentloaded",timeout:t}),await this.loadFrameAndRecordUrl(this.page)};await this.wrapPageLoad(n)}async getBrowserStateHelper({skipWait:e=!1,filterByViewport:t=!1,logger:n=this.logger}){let o={};await bt(()=>Promise.resolve(this.pageLoadPromise),"pageLoad",o);let s=await this.getActivePageOrFrameHelper(),i=await this.getViewportOffsetDetails(s),a;if(this.activeFrame){let d=this.activeFrame;a=(await bt(()=>this.getMatchingFrame(d),"frameFetch",o)).node.frameId,n.debug({iframeId:a},"Resolved iframe id")}let l=await bt(()=>this.getRawA11yTree({root:s,skipWait:e,iframeId:a,logger:n}),"a11yFetch",o),c=await bt(()=>this.getDOMTree(i.devicePixelRatio,a),"domFetch",o),u=await bt(()=>pd({a11yGraph:l,domGraph:c,logger:n,cdpClient:this.cdpClient,filterByViewport:t,viewportDetails:i}),"a11yProcess",o);if(!u||!u.root)throw new Error("Accessibility tree appears empty");return this.a11yIdToNodeMap=u.a11yIdNodeMap,this.dataMomenticIdToNodeMap=u.dataMomenticIdMap,this.domGraph=c,this.logger.debug(o,"Fetched browser state"),u}async getBrowserState(e){let{logger:t=this.logger,maxAttempts:n=2}=e,o=0,s;for(;o<n;){o++;try{return await ts(this.getBrowserStateHelper(e),{milliseconds:this.pageLoadTimeout})}catch(i){s=i instanceof Error?i.message:`${i}`,o<n&&t.debug({err:i,url:this.url()},"Error getting a11y tree, retrying...")}}throw new I("ActionFailureError",`Getting page content failed after ${n} attempts. Are you sure this page is working? Error: ${s}`)}getA11yIdFromDataMomenticId(e){return this.dataMomenticIdToNodeMap.get(e)?.id}async getViewportOffsetDetails(e){let[t,n,o,s,i]=await e.evaluate(()=>[window.scrollY,window.scrollX,window.screen.width,window.screen.height,window.devicePixelRatio]);return{upperBound:t,lowerBound:t+s,leftBound:n,rightBound:n+o,width:o,height:s,devicePixelRatio:this.systemDevicePixelRatio??i}}async getDOMTree(e,t){let n,o=0;for(;!n&&o<3;)try{if(await this.cdpClient.send("DOMSnapshot.enable"),n=await this.cdpClient.send("DOMSnapshot.captureSnapshot",{computedStyles:Yo}),!n||!n.documents.length)throw new Error("Got empty DOM tree")}catch(s){await K(500),this.logger.debug({err:s},"Error fetching DOM tree"),o++}if(!n||!n.documents.length)throw new I("InternalWebAgentError","Error fetching DOM tree");return gd({snapshot:n,devicePixelRatio:e,pageFrameId:t})}async waitForDOMStability(e){let{logger:t=this.logger}=e??{};try{let{root:s}=await this.cdpClient.send("DOM.getDocument",{depth:-1,pierce:!0})}catch(s){t.debug({err:s},"Failed to request root node while getting a11y tree")}let n={value:Date.now()},o=()=>{n.value=Date.now()};this.cdpClient.addListener("Accessibility.nodesUpdated",o),this.cdpClient.addListener("DOM.characterDataModified",o),this.cdpClient.addListener("DOM.attributeModified",o),this.cdpClient.addListener("DOM.childNodeCountUpdated",o),this.cdpClient.addListener("DOM.documentUpdated",o),this.cdpClient.addListener("Page.frameDetached",o),this.cdpClient.addListener("Page.frameStartedLoading",o),this.cdpClient.addListener("Page.frameRequestedNavigation",o);try{await this.waitForDOMStabilityHelper(n,t)}finally{this.cdpClient.removeListener("Accessibility.nodesUpdated",o),this.cdpClient.removeListener("DOM.characterDataModified",o),this.cdpClient.removeListener("DOM.attributeModified",o),this.cdpClient.removeListener("DOM.childNodeCountUpdated",o),this.cdpClient.removeListener("DOM.documentUpdated",o),this.cdpClient.removeListener("Page.frameDetached",o),this.cdpClient.removeListener("Page.frameStartedLoading",o),this.cdpClient.removeListener("Page.frameRequestedNavigation",o)}}async waitForDOMStabilityHelper(e,t=this.logger){let n=!1,o=Date.now(),s=this.smartWaitingTimeout,i;for(;Date.now()-o<s;){if(await K(500),i)try{let{data:l}=await this.cdpClient.send("Page.captureScreenshot",{optimizeForSpeed:!0,quality:25,format:"jpeg"});if(l!==i){i=l;continue}}catch{}else try{let{data:l}=await this.cdpClient.send("Page.captureScreenshot",{optimizeForSpeed:!0,quality:25,format:"jpeg"});i=l}catch{}if(!(Date.now()-e.value<750)){n=!0;break}}let a={duration:Date.now()-o,a11yStableReceived:n};n?t.debug(a,"A11y wait phase completed"):t.warn(a,"A11y wait phase completed due to timeout, continuing...")}async getRawA11yTree({root:e,skipWait:t=!1,iframeId:n=void 0,logger:o=this.logger}){let s={};t||await this.waitForDOMStability({logger:o}),await bt(async()=>e.evaluate("window.addIdsToElement(document.body, 1)"),"addIdsToElement",s);let i;if(n)i=(await bt(()=>this.cdpClient.send("Accessibility.getRootAXNode",{frameId:n}),"getRootAXNodeWithIframe",s)).node.backendDOMNodeId;else{let{node:l}=await bt(()=>this.cdpClient.send("Accessibility.getRootAXNode"),"getRootAXNode",s);i=l.backendDOMNodeId}let{nodes:a}=await bt(()=>this.cdpClient.send("Accessibility.queryAXTree",{backendNodeId:i}),"queryAXTree",s);if(!a||a.length<=1)throw new I("ActionFailureError","The page has no content. Are you sure it is working properly?");return Object.values(s).some(l=>typeof l=="number"&&l>500)&&o.warn({logTimings:s,numNodes:a.length},"Getting raw a11y tree took a long time"),{root:a[0],allNodes:a}}async clickUsingVisualCoordinates(e,t){let n=await this.getActivePageOrFrame(),{percentX:o,percentY:s}=e,{width:i,height:a}=await this.getViewportOffsetDetails(n),l=Math.ceil(i*o),c=Math.ceil(a*s),u=this.url(),d=await this.getOpenPageUrls();this.logger.debug({pixelDeltaX:l,pixelDeltaY:c,width:i,height:a},"Executing mouse click with visual coordinates"),await this.wrapPageLoad(async()=>this.page.mouse.click(l,c,{button:t.rightClick?"right":"left",clickCount:t.doubleClick?2:1})),t.waitForUrl&&await this.waitForUrl(u,t.waitForUrl,d)}async dragAndDropUsingVisualCoordinates(e,t,n){let o=await this.getActivePageOrFrame(),{percentX:s,percentY:i}=e,{percentX:a,percentY:l}=t,{width:c,height:u}=await this.getViewportOffsetDetails(o),d=Math.ceil(c*s),m=Math.ceil(u*i),p=Math.ceil(c*a),f=Math.ceil(u*l);await this.page.mouse.move(d,m),await this.page.mouse.down(),await this.page.mouse.move(p,f),await K(n.hoverSeconds?Math.min(n.hoverSeconds*1e3,8e3):500),await this.page.mouse.up()}async hoverUsingVisualCoordinates(e){let t=await this.getActivePageOrFrame(),{percentX:n,percentY:o}=e,{width:s,height:i}=await this.getViewportOffsetDetails(t),a=Math.ceil(s*n),l=Math.ceil(i*o);await this.page.mouse.move(a,l)}getAttributeFromStringArray(e,t){let n=e.findIndex(o=>o===t);if(!(n===-1||!e[n+1]))return e[n+1]}async getIDAttributeUsingCDP(e){await this.cdpClient.send("DOM.getDocument",{depth:0});let t=await this.cdpClient.send("DOM.requestNode",{objectId:e}),o=(await this.cdpClient.send("DOM.getAttributes",{nodeId:t.nodeId})).attributes,s=this.getAttributeFromStringArray(o,it);if(!s)throw new Error(`Could not find attribute ${it} for object ${e}`);return s}async getLocatorFromA11yNode(e){if(!e.backendNodeID)throw new Error(`Node with a11y id ${e.id} has no backend node ID`);return this.getLocatorFromBackendID(e.backendNodeID)}async getLocatorFromBackendID(e){let t=await this.cdpClient.send("DOM.resolveNode",{backendNodeId:e});if(!t||!t.object.objectId)throw new Error(`Could not resolve backend node ${e}`);let n;try{n=await this.getIDAttributeUsingCDP(t.object.objectId)}catch(o){throw this.logger.debug({err:o,object:JSON.stringify(t.object)},"Failed to get ID attribute"),o}return(await this.getActivePageOrFrame()).locator(`[${it}="${n}"]`)}async clickUsingCDP(e,t={}){let n=0,o,s=async l=>{let c=await this.getLocatorFromBackendID(l);t.doubleClick?await c.dblclick({timeout:4e3}):await c.click({timeout:4e3,button:t.rightClick?"right":"left",force:t.force,noWaitAfter:!0})};for(;n<2;)try{return await s(e.backendNodeID),e}catch(l){this.logger.error({err:l},"Failed clicking on node"),o=l,n++,await K(500)}let i=e.parent?.children??[];for(let l of i){if(l.id===e.id)continue;let c=!1,u=Ui(l,e);if(e.name&&l.name===e.name?c=!0:u>=5&&(this.logger.debug({similarityScore:u},"Sibling qualified for click redirection through comparison score"),c=!0),!!c)try{return await s(l.backendNodeID),l}catch(d){this.logger.debug({err:d,candidate:l.getLogForm()},"Failed clicking on sibling during click redirection")}}let a=e.parent;for(n=0;n<id;){if(!a||["rootwebarea","main"].includes(a.role.toLowerCase()))throw new I("ActionFailureError",o.message,{cause:o});if(!a.backendNodeID){a=a.parent;continue}try{return await s(a.id),a}catch(c){this.logger.debug({err:c,candidate:a.getLogForm()},"Failed clicking on parent during click redirection"),n++,a=a.parent}}throw new I("ActionFailureError",`Max click attempts exhausted on element ${e.getLogForm()}: ${o.message}`,{cause:o})}async getElementLocation(e){let t=await this.cdpClient.send("DOMSnapshot.captureSnapshot",{computedStyles:[],includeDOMRects:!0,includePaintOrder:!0}),n=await this.page.evaluate(()=>window.devicePixelRatio);process.platform==="darwin"&&n===1&&(n=2);let o=t.documents[0],s=o.layout,i=o.nodes,a=i.nodeName||[],l=i.backendNodeId||[],c=s.nodeIndex,u=s.bounds,d=-1;for(let S=0;S<a.length;S++)if(l[S]===e){d=c.indexOf(S);break}if(d===-1)throw new Error(`Could not find any backend node with ID ${e}`);let[m=0,p=0,f=0,h=0]=u[d];m/=n,p/=n,f/=n,h/=n;let g=m+f/2,y=p+h/2;return{centerX:g,centerY:y}}async scroll(e,t,n,o){let s=t==="left"?-1:1,i=o==="up"?-1:1;if(this.activeFrame)await(await this.getActivePageOrFrame()).evaluate(([l,c,u,d])=>window.scrollTo(window.scrollX+(l??window.innerWidth)*u,window.scrollY+(c??window.innerHeight)*d),[e,n,s,i]);else{let a=this.page.viewportSize()||Rt;await this.page.mouse.wheel((e??a.width)*s,(n??a.height)*i)}}async scrollUp(e){return this.scroll(0,null,e??null,"up")}async scrollDown(e){await this.scroll(0,null,e??null,"down")}async scrollLeft(e){await this.scroll(e??null,"left",0,null)}async scrollRight(e){await this.scroll(e??null,"right",0,null)}async goForward(){await this.wrapPageLoad(async()=>await this.page.goForward({waitUntil:"domcontentloaded",timeout:this.pageLoadTimeout}))}async goBack(){await this.wrapPageLoad(async()=>this.page.goBack({waitUntil:"domcontentloaded",timeout:this.pageLoadTimeout}))}async changeActivePage(e,t){this.recordUrlVisited(e.url()),this.page=e;let n=await r.initCDPSession(this.context,this.page,this.logger,t??this.pageLoadTimeout),o=this.cdpClient;this.cdpClient=n;try{await o.detach()}catch{}}async createNewTab(e,t){let n=await this.context.newPage();await this.changeActivePage(n,t?.loadTimeoutMs),await this.navigate({url:e,initialNavigation:!0,...t})}async switchToPageByIndex(e,t,n){let o=e.url();if(!dn(o,this.logger)){this.logger.error({tabUrl:o},"Refusing to switch to tab with invalid URL");return}this.logger.debug(`Switching to tab ${t} with url ${o}`),await this.changeActivePage(e,n?.loadTimeoutMs),await this.loadFrameAndRecordUrl(e)}async switchToPage(e,t,n){await this.wrapPageLoad(async()=>this.switchToPageHelper(e,t,n))}async switchToPageHelper(e,t,n){let o=this.context.pages(),s=await ji(this.context,this.logger);if(t){await this.switchToPageByIndex(o[t],t,n);let i=s[t].url;this.onTabsChange?.(s,i);return}for(let i=0;i<o.length;i++){let a=o[i];if(a.url().includes(e)){await this.switchToPageByIndex(a,i,n);let l=s[i].url;this.onTabsChange?.(s,l);return}}throw new Error(`Could not find page with url containing ${e}`)}async setCookie(e){let t;return typeof e=="string"?t=vl(e):t=[e],await this.context.addCookies(t),t}async setLocalStorage(e,t){await(await this.getActivePageOrFrame()).evaluate(([o,s])=>{o&&localStorage.setItem(o,s||"")},[e,t])}async solveCloudflareTurnstile(){let t=(await this.getActivePageOrFrame()).locator(".cf-turnstile").locator("iframe").getAttribute("data-sitekey"),n=await fetch("https://2captcha.com/in.php",{method:"POST",body:JSON.stringify({key:Wn,method:"turnstile",sitekey:t,pageurl:this.url(),json:1})});if(!n.ok){let i=`Captcha solver API returned error response: ${n.statusText}`;throw this.logger.error({text:await n.text()},i),new Error(i)}let{request:o}=await n.json(),s=Date.now();for(;Date.now()-s<6e4;){await K(2500);let i=await fetch(`https://2captcha.com/res.php?key=${Wn}&action=get&id=${o}&json=1`,{method:"GET"});if(!i.ok){let l=`Captcha solution API returned error response: ${i.statusText}`;throw this.logger.error({text:await i.text()},l),new Error(l)}if((await i.json()).status===1)break}}async solveCaptcha(){await this.getBrowserState({});let e;for(let a of this.a11yIdToNodeMap.values())if(a.role==="image"&&a.name.toLowerCase().includes("captcha")){if(!a.backendNodeID)continue;e=await this.getLocatorFromBackendID(a.backendNodeID);break}if(!e){let a=await(await this.getActivePageOrFrame()).solveRecaptchas();if(!a.captchas||!a.captchas.length)throw new Error("No captchas found on the page");return}let t=await e.screenshot({type:"jpeg",animations:"allow",caret:"hide",quality:100,timeout:4e3}),n=await fetch("https://api.2captcha.com/createTask",{method:"POST",body:JSON.stringify({clientKey:Wn,task:{type:"ImageToTextTask",body:t.toString("base64"),case:!0},languagePool:"en"})});if(!n.ok){let a=`Captcha solver API returned error response: ${n.statusText}`;throw this.logger.error({text:await n.text()},a),new Error(a)}let{taskId:o}=await n.json(),s=Date.now(),i="";for(;Date.now()-s<6e4;){await K(2500);let a=await fetch("https://api.2captcha.com/getTaskResult",{method:"POST",body:JSON.stringify({clientKey:Wn,taskId:o})});if(!a.ok){let c=`Captcha solution API returned error response: ${a.statusText}`;throw this.logger.error({text:await a.text()},c),new Error(c)}let l=await a.json();if(l.errorId){let c=`Captcha solution API returned error ID ${l.errorId}`;throw this.logger.error(c),new Error(c)}if(l.status==="ready"){i=l.solution.text;break}}if(!i)throw new Error("Captcha solution timed out");return i}getActiveFrame(){return this.activeFrame}async captureTargetFromClick(){let e=new AbortController;await this.startTreeRefreshCronForRecording(e.signal);let t;try{if(t=await(await this.getActivePageOrFrame()).evaluate(async()=>{let n=window;if(!n.resolveRecordingTarget){console.error("[MOMENTIC] Missing Momentic recording library functions");return}let o=null;n.targetCaptureClickListener=async i=>(console.debug("[MOMENTIC] Target capture listener fired"),i.preventDefault(),i.stopImmediatePropagation(),o=i.target,!1),document.addEventListener("mousedown",n.targetCaptureClickListener,{capture:!0,once:!0});let s=Date.now();for(;!o&&Date.now()-s<1e4;)await new Promise(i=>setTimeout(i,250));if(!o)throw new Error("Timed out waiting for user to click on an element");return n.resolveRecordingTarget(o)}),t?.error)throw new Error(t.error);if(t?.target)t.warnings.length&&this.logger.warn({result:t},"Got warnings while capturing target from click");else throw new Error("No target captured from click")}catch(n){throw this.logger.error({err:n},"Error recording target click"),new Error(`Error recording click: ${n.message}`)}finally{e.abort()}if(!t)throw new Error("Got no target from recorded click - please make sure you clicked on an interactive element");return this.getTargetFromRecordedClick(t.target).target}areDomNodeBoundingBoxesSimilar(e,t,n){if(!t.bounds)return this.logger.debug({candidate:t},"Filtering out click candidate since it has no bounding box"),!1;let o=e.bounds,s=o.x??0,i=o.width??0,a=o.height??0,l=s+i,c=o.y??0,u=c+(o.height??0),d=t.bounds,m=d.width??0,p=d.height??0,f=d.x??0,h=f+(d.width??0),g=d.y??0,y=g+(d.height??0);return f<l&&h>s&&g<u&&y>c?Math.abs(i-m)<200&&Math.abs(a-p)<200?!0:(Nn({logger:this.logger,logKey:n,maxCount:5,intervalMs:3e3},{candidate:t,originalNode:e},"Filtering out click candidate since it has a significantly different area"),!1):(Nn({logger:this.logger,logKey:n,maxCount:5,intervalMs:3e3},{candidate:t},"Filtering out click candidate since it does not intersect with the original node"),!1)}getDomCandidatesInA11yTree(e,t){let n=Object.values(t.backendIdToNode),o,s=Lg();for(let c of n)if(c.attributes?.[it]===e){o=c;break}if(!o)return[];let i=[],a=t.backendIdToNode[o.parentBackendNodeId??-1];for(;a&&(a?.momenticIgnored||!this.areDomNodeBoundingBoxesSimilar(o,a,s));)a=t.backendIdToNode[a.parentBackendNodeId??-1];a&&i.push(a);let l=[o];for(;l.length;){let c=l.shift();for(let u of c.children??[]){let d=t.backendIdToNode[u];d&&!d.momenticIgnored&&this.areDomNodeBoundingBoxesSimilar(o,d,s)?i.push(d):d&&l.push(d)}}return i}getTargetFromRecordedClick(e){this.logger.debug(e,"Got HTML target attributes from click recording");let{htmlAttributes:t,dataMomenticId:n}=e,s=this.dataMomenticIdToNodeMap.get(n),i={id:s?.id??-1,dataMomenticId:n,targetSource:"CLICK_TO_FIND",targetUpdateTime:new Date().toUTCString(),...t};return s?this.saveA11yDetailsToCache(s,i):this.logger.warn({htmlAttributes:t},"Could not find corresponding accessibility node for click. Continuing with HTML attributes only"),{target:i,a11yNode:s}}async exposeRecordingBindings(){let e=({frame:t},n)=>{if(!this.transformer)return;let{type:o,target:s,error:i,warnings:a,selectedValue:l}=n,c=t.url();if(this.logger.debug({url:c,...n},`${o} event captured on element`),i){this.logger.error({error:i,warnings:a},"Error while capturing passive element interaction");return}else if(s)a.length&&this.logger.warn({warnings:a},`Warnings while capturing passive element interaction of type ${o}`);else{this.logger.error({event:n},"No target found in passive element interaction event");return}let{dataMomenticId:u,htmlAttributes:d}=s,m=this.dataMomenticIdToNodeMap,p=this.mostRecentA11yTree,f=m.get(u),h={id:f?.id??-1,dataMomenticId:u,targetSource:"RECORDING",targetUpdateTime:new Date().toUTCString(),...d};f?this.saveA11yDetailsToCache(f,h):this.logger.debug({url:c,htmlAttributes:d},"Could not find corresponding accessibility node for click, continuing with HTML attributes only"),(async()=>{if(!this.transformer){this.logger.warn("No natural language translation since transformer is not initialized anymore");return}this.logger.debug({target:s,url:c},`Generating description for ${o.toLowerCase()}ed target`);let g=p?.serialize();f&&g&&g.length>5e3&&(g=hd(f.id,g),this.logger.debug({serializedTree:g},"Trimmed a11y tree for description transformation"));try{await this.transformer.recordElementAction({type:o,target:h,browserState:g,url:c,selectedValue:l})}catch(y){this.logger.error({err:y},`Failed to record ${o} action`)}})()};await this.context.exposeBinding("isRecordingActive",()=>!!this.transformer),await this.context.exposeBinding("captureElementEvent",({frame:t},n)=>{try{e({frame:t},n)}catch(o){this.logger.error({err:o},"Failed to capture element interaction")}},{handle:!1}),await this.context.exposeBinding("captureKeystroke",async(t,n)=>{this.transformer&&this.transformer.recordKeystroke(n)})}async fetchA11yTreeForRecording(){let e=await this.getBrowserState({skipWait:!0,maxAttempts:1});if(this.mostRecentA11yTree=e,Math.random()<.1){let n=this.mostRecentA11yTree.serialize();this.logger.debug({tree:n.length>4e5?"REDACTED_DUE_TO_SIZE":n},"Refreshed a11y tree during recording")}await(await this.getActivePageOrFrame()).evaluate(n=>{let o=window;o.momenticIdsInA11yTree=new Set(n)},Array.from(this.dataMomenticIdToNodeMap.keys()))}async startTreeRefreshCronForRecording(e){if(await this.fetchA11yTreeForRecording(),e.aborted)return;let t,n=!1,o=0,s=0,i=async()=>{if(!(Date.now()-s<=1e3)&&!n){n=!0;try{await this.fetchA11yTreeForRecording(),o=0}catch(a){if(s=Date.now(),o++,o>=8||a.message.includes("crashed")){clearInterval(t),this.logger.error({err:a},"Fatal errors while refreshing a11y tree during recording, exiting...");return}}finally{n=!1}}};t=setInterval(()=>{!this.transformer||e.aborted||i()},ad),e.addEventListener("abort",()=>{clearInterval(t),t=void 0})}async startRecording(e,t){this.logger.debug("Starting passive recording mode in Chrome browser"),await this.startTreeRefreshCronForRecording(e),this.transformer=t,e.addEventListener("abort",async()=>{this.transformer=void 0})}async getSelectOptions(e){return await e.evaluate(n=>Array.from(n.querySelectorAll("option")).map(s=>s.value),{timeout:1e3})}getActivePage(){return this.page}async getActivePageOrFrame(){if(!this.activeFrame)return this.page;if(this.activeFrameCache)if(JSON.stringify(this.activeFrame)!==this.activeFrameCache.frameIdentifierStringified)this.activeFrameCache=void 0;else if("isDetached"in this.activeFrameCache.frame&&this.activeFrameCache.frame.isDetached())this.activeFrameCache=void 0;else if("isClosed"in this.activeFrameCache.frame&&this.activeFrameCache.frame.isClosed())this.activeFrameCache=void 0;else return this.activeFrameCache.frame;let e=Date.now(),t,n;for(;Date.now()-e<this.smartWaitingTimeout;)try{t=await this.getActivePageOrFrameHelper();break}catch(o){n=o,await K(500)}if(t)return this.activeFrameCache={frame:t,frameIdentifierStringified:JSON.stringify(this.activeFrame),cacheTime:Date.now()},t;throw n}async loadFrameAndRecordUrl(e){let t=this.pageLoadTimeout;await e.waitForLoadState("domcontentloaded",{timeout:t});try{await e.waitForLoadState("load",{timeout:t})}catch(n){this.logger.warn({err:n},"Timeout elapsed waiting for current frame to load, continuing...")}this.recordUrlVisited(e.url())}async getCondensedHtml(){return this.wrapPageLoad(async()=>this.getCondensedHtmlHelper())}async getCondensedHtmlHelper(){await this.waitForDOMStability();let e=await this.getActivePageOrFrame();await Hr(e,this.logger);let{result:t,error:n}=await e.evaluate(()=>window.getCondensedHtmlTree(),{timeout:1e3});if(n)throw new Error(`Failed to process page HTML: ${n}`);if(!t)throw new I("InternalWebAgentError","Got empty HTML tree - are you sure the page is fully loaded?");return Dg.html(t,{indent_size:1,indent_with_tabs:!1,preserve_newlines:!1,wrap_line_length:100})}async registerDialogHandler(e){let t=async n=>e==="ACCEPT"?n.accept():n.dismiss();this.page.once("dialog",t)}async evaluateFunctionInPage(e,t){return this.page.evaluate(t,e)}async evaluateCodeInPage({code:e,fragment:t,context:n,timeoutMs:o=2e3}){let s=Ld(),i={code:e,fragment:t,context:n},{result:a}=await ts(this.page.evaluate(s,i),{milliseconds:o,fallback:()=>{throw new I("ActionFailureError",`Code evaluation in browser exceeded the allowed timeout of ${o/1e3} seconds`)}});return a}async getDomNodeFromPositionPercentages(e,{percentX:t,percentY:n}){if(t<0||t>1||n<0||n>1)throw new I("InternalWebAgentError","Invalid percent passed to percentage location");let{width:o,height:s,upperBound:i,leftBound:a,devicePixelRatio:l}=await this.getViewportOffsetDetails(e),c=Math.round(i),u=Math.round(a),d=Math.ceil(o*t),m=Math.ceil(s*n);await this.cdpClient.send("DOM.getDocument",{depth:0});let p;try{p=await this.cdpClient.send("DOM.getNodeForLocation",{x:d+u,y:m+c})}catch(f){throw this.logger.error({err:f,pixelDeltaX:d,pixelDeltaY:m,leftBoundRounded:u,upperBoundRounded:c,devicePixelRatio:l},"Failed to get DOM node from position percents"),new Error("No element was found at the given location")}return p}async highlightFromPositionPercentages(e){let t=await this.getActivePageOrFrame(),n;try{n=await this.getDomNodeFromPositionPercentages(t,e)}catch{}return n?(await this.cdpClient.send("Overlay.highlightNode",{highlightConfig:fd,backendNodeId:n.backendNodeId}),async()=>{try{await this.cdpClient.send("Overlay.hideHighlight",{backendNodeId:n?.backendNodeId})}catch{}}):async()=>{}}async clearAllCdpHighlights(){try{await this.cdpClient.send("Overlay.hideHighlight")}catch{}}async getTargetFromPositionPercentages(e){let t=await this.getActivePageOrFrame(),n=await this.getDomNodeFromPositionPercentages(t,e),o=this.domGraph?.backendIdToNode[n.backendNodeId],s=o?.attributes[it],i=parseInt(s??"");if(!o||!s||isNaN(i))throw new Error("No HTML node was found at the given location");let a=t.locator(`[${it}="${s}"]`);for(let d of this.a11yIdToNodeMap.values()){if(d.backendNodeID!==n.backendNodeId)continue;let m={id:d.id,targetSource:"XY_PERCENT",targetUpdateTime:new Date().toUTCString()};return await this.saveNodeDetailsToCache(t,d,m,parseInt(s),a),{target:m,locator:a}}let l=this.getDomCandidatesInA11yTree(`${s}`,this.domGraph);for(let d of l){let m=parseInt(d.attributes?.[it]??"");if(isNaN(m))continue;let p=t.locator(`[${it}="${m}"]`),f=this.dataMomenticIdToNodeMap.get(m),h=f?.id;if(!h)continue;let g={id:h,targetSource:"XY_PERCENT",targetUpdateTime:new Date().toUTCString()};return await this.saveNodeDetailsToCache(t,f,g,parseInt(s),p),this.logger.debug({target:g},"Redirected click on non-accessible element to nearest a11y node"),{target:g,locator:p}}let c=await this.fetchHtmlAttributes(t,i);return{target:{id:-1,dataMomenticId:i,targetSource:"XY_PERCENT",targetUpdateTime:new Date().toUTCString(),...c},locator:a}}async fetchHtmlAttributes(e,t){let n=await e.evaluate(o=>{let s=window;return s.generateHtmlCacheAttributes?s.generateHtmlCacheAttributes(o):{warnings:[],error:"generateHtmlCacheAttributes is not defined"}},t);if("error"in n)throw new Error(n.error);if(n.attributes)n.warnings.length&&this.logger.warn(n,"Got warnings while generating HTML attributes for target");else return this.logger.warn(n,"Got no generated HTML attributes for target"),{};return this.logger.debug(n.attributes,"Generated HTML attributes for target"),n.attributes}async moveMouseFromPositionPercentages(e,t){let n=await this.getActivePageOrFrame(),o;try{o=await this.getViewportOffsetDetails(n)}catch{return}let{width:s,height:i}=o,a=Math.ceil(s*e),l=Math.ceil(i*t);await this.page.mouse.move(a,l,{steps:3})}async clickMouseFromPositionPercentages(e,t){let n=await this.getActivePageOrFrame(),o;try{o=await this.getViewportOffsetDetails(n)}catch{return}let{width:s,height:i}=o,a=Math.ceil(s*e),l=Math.ceil(i*t);await this.page.mouse.click(a,l,{button:"left"})}async scrollFromPositionPercentages(e,t){let n=await this.getActivePageOrFrame(),o;try{o=await this.getViewportOffsetDetails(n)}catch{return}let{width:s,height:i}=o,a=Math.ceil(s*e),l=Math.ceil(i*t);return await this.page.mouse.wheel(a,l),{deltaX:a,deltaY:l}}canSolveCaptchas(){return!!Wn}async getFrameSrcUrls(){let e=this.page.url(),t=this.page.frames(),n=[];for(let s of t)if(!s.isDetached())try{let a=await(await s.frameElement()).evaluate(l=>"src"in l?l.getAttribute("src"):null);a&&a!=="about:blank"&&a!==e&&n.push(a)}catch(i){let a=i.message;["detached","browser has been closed"].some(l=>a.includes(l))||this.logger.debug({err:i},"Error fetching frame src url, continuing...")}return Array.from(new Set(n))}async setFileChooserHandler(e){setTimeout(()=>{try{e.cleanup()}catch(t){this.logger.debug({err:t,filePath:e.filePath},"Failed cleaning up file after upload")}},3e4),await this.setFileChooserHandlerHelper(e)}logToUserConsole(e,t,n,...o){let s=this.context.pages().indexOf(e);s=s===-1?0:s,Hi(e,this.debugData,s,{type:t,text:`[MOMENTIC] ${n}`,args:o})}async setFileChooserHandlerHelper({filePath:e}){if(!kd(e)){let n=`File chooser triggered after the source file ${e} has been cleaned up, ignoring...`;this.logger.error(n),this.logToUserConsole(this.page,"error",n);return}this.page.once("filechooser",async n=>{this.logger.debug({filePath:e},"File chooser triggered");try{if(!kd(e))throw new Error(`File chooser triggered after the source file ${e} has been cleaned up, ignoring...`);await n.setFiles(e,{timeout:8e3})}catch(o){this.logger.error({err:o},"Error handling file chooser"),this.logToUserConsole(this.page,"error",o.message)}});let t=_g(e).toString("base64");await(await this.getActivePageOrFrame()).evaluate(({fileName:n,base64Data:o})=>{let s=window;s.MomenticFile=class{async getFile(){let i=atob(o),a=new Array(i.length);for(let u=0;u<i.length;u++)a[u]=i.charCodeAt(u);let l=new Uint8Array(a),c=new Blob([l]);return new File([c],n)}},s.showOpenFilePicker=async()=>[new s.MomenticFile]},{fileName:Fd(e),base64Data:t})}getSerializedFormFromA11yId(e){return this.a11yIdToNodeMap.get(e)?.getNodeOnlySerializedForm()}get smartWaitingTimeout(){return this.userControlledBrowserSettings.smartWaitingTimeoutMs??3e3}get pageLoadTimeout(){return this.userControlledBrowserSettings.pageLoadTimeoutMs??8e3}retrieveAndClearConsoleLogs(){let e=this.debugData.logsPerPage;return this.debugData.logsPerPage=[],e}};var Vg=({socket:r,metadata:e,logger:t,storage:n})=>async({baseUrl:o,environmentName:s})=>{let{testId:i,sessionId:a,orgId:l}=e;t.info({testId:i,sessionId:a,baseUrl:o},"Reset event received");let c=s?await n.fetchEnvironment(l,s,t):void 0,u=null,d=_.getSession(a);if(!d){r.emit("error",{message:"No session to reset"});return}let{controller:m,context:p}=d;await m.browser.reset({clearCookies:!0,clearStorage:!0,url:o});let f=m.browser.baseUrl;p.reset({baseUrl:f,currentUrl:m.browser.url(),variablesFromEnvironment:c?.variables??{},envName:s}),u=await m.browser.getViewport();let h=Mt.USER_AGENT;t.info(`Session reset for test ${i} at ${f}`),r.emit("session",{url:f,userAgent:h,viewport:u,sessionId:a})},Bd={event:"reset",createHandler:Vg};var qg=({metadata:r})=>{let{sessionId:e}=r;return async({url:t})=>{let n=_.getSession(e);if(!n)throw new Error("No active session found");await n.controller.browser.switchToPage(t)}},zd={event:"switchTab",createHandler:qg};var Kg=({metadata:r})=>{let{sessionId:e}=r;return({indices:t},n)=>{let o=_.getSession(e);if(!o)return;let s=o.resultsManager.getContextCopyAtIndices(t)??o.context.toRedactedDisplayCopy();mi(s),n(s)}},Wd={event:"getTestContext",createHandler:Kg};import{PostHog as Yg}from"posthog-node";var Xg=new Yg("phc_WRWd8LYIv6rolgDsyCdrPpxtZhsu6qXAkEwPicl44bI",{host:"https://app.posthog.com"}),Hn=class r extends Lo{static async init(e){let t={},n,o=0,s=3;for(;o<s;)try{t=await Xg.getAllFlags(e);break}catch(i){n=i,o++,await new Promise(a=>setTimeout(a,500*o))}if(o===s)throw n;return new r(t)}};var Hd=process.env.GCP_TEMPLATE_MATCHING_FUNCTION_ENDPOINT,rs=class{constructor(e){this.logger=e}async runTemplateMatching({searchImageBase64String:e,pageImageBase64String:t,id:n,timeoutMs:o=3e3}){if(!Hd)throw new Error("GCP_TEMPLATE_MATCHING_FUNCTION_ENDPOINT environment variable not set");let s={search_image:e,page_image:t,request_id:n},i=new AbortController,a=setTimeout(()=>{i.abort()},o),c=await fetch(Hd,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s),signal:i.signal});if(clearTimeout(a),c.status===422){let u=(await c.json()).error;throw new Oo(u)}if(!c.ok)throw new Error(`Template matching server returned error code: ${c.status}`);try{let u=await c.json();return vo.parse(u)}catch(u){throw new Error(`Error parsing template matching response: ${u}`)}}};var Jg={type:"a11y",version:"1.0.0",useHistory:"diff",useGoalSplitter:!0},os=Jg;import Sy from"dedent";import wy from"diff-lines";import{cloneDeep as by}from"lodash-es";import{z as jn}from"zod";var jd=jn.object({doubleClick:jn.boolean().optional(),rightClick:jn.boolean().optional(),force:jn.boolean().optional(),waitForDownload:jn.boolean().optional(),waitForUrl:jn.string().optional()});import{randomUUID as Nt}from"crypto";var Zg=["Shift","CapsLock","Dead","Meta","AudioVolumeUp","AudioVolumeDown"],ss=class{recordedSteps=new Map;onStepRecord;signal;generator;testId;orgId;storage;indices;logger;constructor({signal:e,onStepRecord:t,generator:n,initialIndices:o,storage:s,testId:i,orgId:a,logger:l}){this.signal=e,this.storage=s,this.logger=l,this.testId=i,this.orgId=a,this.onStepRecord=(c,u,d)=>{this.recordedSteps.set(JSON.stringify(u),{step:c,url:d}),t(c,u)},this.generator=n,this.indices=o}reserveIndexForCommand(e,t){let n=Array.from(this.indices);return this.recordedSteps.set(JSON.stringify(n),{step:{id:Nt(),type:"PRESET_ACTION",command:Bt(e)},url:t}),this.indices[this.indices.length-1]++,n}async recordElementAction(e){if(this.signal.aborted){this.logger.debug("Transformer was already cleaned up, ignoring click...");return}let{type:t,target:n,browserState:o,url:s}=e,{indices:i}=e,a,l,c=n.nodeOnlySerializedHtml?.trim()??n.nodeOnlySerializedForm??"Unknown element - please provide a description manually";switch(t){case"CLICK":a="CLICK";let p=Bt(a);l={id:Nt(),type:"PRESET_ACTION",command:{...p,target:{type:"description",elementDescriptor:c},cache:{target:n}}};break;case"SELECT":a="SELECT_OPTION";let f=Bt(a);l={id:Nt(),type:"PRESET_ACTION",command:{...f,type:"SELECT_OPTION",target:{type:"description",elementDescriptor:c},cache:{target:n},option:e.selectedValue??"Unknown option"}};break;default:throw new Error(`Unknown action type: ${t}`)}if(i||(i=Array.from(this.indices),this.indices[this.indices.length-1]++),this.onStepRecord(l,i,s),n.id<=0){this.logger.debug("Skipping reverse mapping for non-accessible element");return}else if(!o){this.logger.debug("Skipping reverse mapping since the browser a11y state is not available");return}let u;try{u=(await this.generator.getReverseMappedDescription({goal:`${n.id}`,browserState:o},{disableCache:!1,orgId:this.orgId})).phrase}catch(p){this.logger.error({err:p},"Error generating reverse mapping description"),u=c}let d=this.recordedSteps.get(JSON.stringify(i))?.step,m=d?.command;m&&"target"in m&&m.target?(m.target={type:"description",elementDescriptor:u},this.onStepRecord({...d,command:m},i,s)):this.logger.warn("Could not find existing command to update after description mapping")}recordKeystroke(e){let{key:t,url:n,dataMomenticId:o}=e;if(Zg.includes(t)||this.signal.aborted)return;let s="normal";t.length>1&&(s="special");let i;if(s==="normal"){let p=Bt("TYPE");i={id:Nt(),type:"PRESET_ACTION",command:{...p,target:void 0,value:t,clearContent:!1}}}else{let p=Bt("PRESS");i={id:Nt(),type:"PRESET_ACTION",command:{...p,value:t}}}let a,l=Array.from(this.indices);l[this.indices.length-1]--;let c=this.recordedSteps.get(JSON.stringify(l)),u=c?.step,d=u?.command,m=c?.url;if(n===m){if(d?.type===i.command.type){let p=d.value,f=i.command.value;i={id:Nt(),type:"PRESET_ACTION",command:{...d,value:i.command.type==="PRESS"?`${p}+${f}`:`${p}${f}`}},a=l}else if(d?.type==="CLICK"&&i.command.type==="TYPE")(!o||d.cache?.target.dataMomenticId===parseInt(o))&&(u.command={...i.command,target:d.target,cache:d.cache},i=c.step,a=l);else if(d?.type==="TYPE"&&i.command.type==="PRESS"&&i.command.value==="Backspace"){let p=d.value;i={id:Nt(),type:"PRESET_ACTION",command:{...d,value:p.slice(0,p.length-1)}},a=l}}a||(a=Array.from(this.indices),this.indices[this.indices.length-1]++),this.onStepRecord(i,a,n)}recordScroll(e){if(this.signal.aborted)return;let{url:t}=e,n=()=>{let{deltaY:a}=e;if(!a)return;let l=Array.from(this.indices);l[this.indices.length-1]--;let c=this.recordedSteps.get(JSON.stringify(l))?.step.command,u;c?.type==="SCROLL_DOWN"&&c.deltaY?(a+=c.deltaY,u=l):c?.type==="SCROLL_UP"&&c.deltaY?(a-=c.deltaY,u=l):(u=Array.from(this.indices),this.indices[this.indices.length-1]++);let d=a>0?"SCROLL_DOWN":"SCROLL_UP",m=Bt(d);m.deltaY=Math.abs(a);let p={id:Nt(),type:"PRESET_ACTION",command:m};this.onStepRecord(p,u,t)},o=()=>{let{deltaX:a}=e;if(!a)return;let l=Array.from(this.indices);l[this.indices.length-1]--;let c=this.recordedSteps.get(JSON.stringify(l))?.step.command,u;c?.type==="SCROLL_RIGHT"&&c.deltaX?(a+=c.deltaX,u=l):c?.type==="SCROLL_LEFT"&&c.deltaX?(a-=c.deltaX,u=l):(u=Array.from(this.indices),this.indices[this.indices.length-1]++);let d=a>0?"SCROLL_RIGHT":"SCROLL_LEFT",m=Bt(d);m.deltaX=Math.abs(a);let p={id:Nt(),type:"PRESET_ACTION",command:m};this.onStepRecord(p,u,t)},s=Array.from(this.indices);s[this.indices.length-1]--;let i=this.recordedSteps.get(JSON.stringify(s));i?.step.command.type==="SCROLL_LEFT"||i?.step.command.type==="SCROLL_RIGHT"?(o(),e.deltaY>=20&&n()):(n(),e.deltaX>=20&&o())}};var Gi=(r,e,t)=>{let[n,...o]=e.split("."),s=n;return o.length>=1?Gi(r[s],o.join("."),t):r[s]=t,r};import cy from"p-timeout";var is=3.1783027;function Qg(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 as(r){return Math.ceil(Vi(r)/is)}function Vi(r){let e=0;if(typeof r=="string"){let t=r;t=t.replaceAll(`
|
|
1774
|
+
`,""),t=t.replaceAll(" ","");let n=Qg(t);return t.length-n+is*n}if(typeof r>"u")return 0;if(typeof r=="number")return String(r).length;if(Array.isArray(r))return r.forEach(t=>{e+=Vi(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*is:e+=85*is:e+=Vi(t[n])}),e}throw new Error(`Unsupported type passed to token length calculator '${typeof r}': ${r}`)}var ey=500,ty=3e3,ny=8e3,Gd=4e3,Vd=/<(\w+) id="(\d+)".*?>/g,ry=/(<\/(\w+?)>)|(<(\w+?).*?\/>)/g,qd=["h1","h2","section","footer","nav","aside","form","label","dialog"],oy=[...qd,"span","div","h3"],sy=["table","select","form","ul","ol","menu","pre","code","dialog"],iy=["table","form","dialog","nav","section","ul","select"];function ls({serializedTree:r,tokenLimit:e,logger:t}){let n=as(r);if(n<=e)return;let o=[],s=r.split(`
|
|
1777
1775
|
`),i=0,a=[],l=0,c=[],u=[],d=!1;for(;i<s.length;){d&&(o.push({ids:c,content:a.join(`
|
|
1778
|
-
`),tokenLength:l}),a=[],l=0,c=u.length?[u[u.length-1].id]:[],d=!1);let
|
|
1779
|
-
`),tokenLength:l});let m=n/o.length,p=Math.min(o.length,Math.ceil(e*1.5/m));return{chunks:o,numRecs:p}}async function yt(r,e,t={}){let n=await r.getBrowserState(t),o=n.serialize();return e.debug({tree:o.length>4e5?"REDACTED_DUE_TO_LENGTH":o,activeFrame:r.getActiveFrame()},"Got a11y tree"),{serializedTree:o,tree:n}}async function Ro({codePath:r,screenshotBuff:e,callback:t,storage:n,logger:o}){if(e)try{let s=await n.uploadScreenshot(e);o.debug({screenshotUrl:s,codePath:r},"Saved screenshot for debugging"),t?.(s)}catch(s){o.error({err:s,codePath:r},"Failed to save screenshot for debugging")}}async function Nt({frameUrl:r,action:e,browser:t,logger:n}){if(!r)return e();let o=t.getActiveFrame();try{return n.debug({frameUrl:r},"Setting parent iframe target"),t.setActiveFrame({type:"url",url:r}),await e()}finally{t.setActiveFrame(o)}}async function zs(r,e){if(!r.description)throw new R("ActionFailureError","Cannot locate element with empty description");return Nt({action:()=>dh(r,e),frameUrl:r.iframeUrl,browser:e.browser,logger:e.logger})}async function dh(r,e){let{disableCache:t,testContext:n,filterByViewport:o}=r,{ctx:s,orgId:i,logger:a,browser:l,localCodeEvalTools:c,flagStore:u,generator:d,storage:m}=e,p=r.description;n&&(p=await Ge({s:p,context:n,logger:e.logger,localTools:c}));let{serializedTree:h,tree:g}=await yt(l,a,{filterByViewport:o}),f,y=Date.now(),w;for(;!f&&Date.now()-y<3e3;)try{f=await l.screenshot({scale:"css",clearHighlights:!0,retries:0})}catch(A){w=A}if(!f)throw new R("InternalWebAgentError",`Failed to take screenshot of page to locate element: ${w?.message}`);let b=h,C=!1,v=.2*wn["gpt-4o-2024-05-13"],E=Ao({serializedTree:h,tokenLimit:v,logger:a});if(E&&u.isBooleanFlagEnabled("locator_rag")){try{u.isBooleanFlagEnabled("rag_keyword_optimization")&&(p=(await d.getExtractedKeywords({goal:p,completionType:"locator"},{disableCache:t,orgId:i})).keywords.join(", "),a.debug({description:p},"Extracted keywords for locator RAG"))}catch(J){a.warn({err:J},"Failed to extract keywords for locator, continuing with original description...")}let H=(await d.getRecommendedChunks({...E,description:p,tokenLimit:v})).ids;H.length===0?a.debug("RAG returned no important information"):(b=g.pruneUsingRelevantIds(new Set(H)).serialize(),a.debug({tree:n},"Pruned a11y tree with RAG"),C=!0)}let I=f.toString("base64");ch(Ro({codePath:"locator",screenshotBuff:f,storage:m,logger:a}),{milliseconds:5e3,fallback:()=>{}});let x=await d.getElementLocation({browserState:b,goal:p,screenshot:I,feedback:void 0},{disableCache:t,orgId:i});a.debug({usedRag:C,result:x},"Got locator result");let P=x.id>0;if(s?.details?.push({type:"AI_LOCATION",matched:P,pageState:b,ragUsed:C,thoughts:x.thoughts}),!P)throw new R("ActionFailureError",`Could not find any relevant element: ${x.thoughts}`);let D={id:x.id,inputDescription:p,targetSource:"AI",targetUpdateTime:new Date().toUTCString()},W=await l.resolveTarget(null,D);if(W.a11yNode?.properties?.hidden&&W.a11yNode?.properties?.hidden!=="false")throw new R("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: ${W.displayString}`);return{thoughts:x.thoughts,target:D,resolution:W}}import uh from"p-timeout";async function Hs({command:r,fixtures:e,opts:t={}}){if(!r.assertion.trim())throw new R("ActionFailureError","Assertion command is missing the assertion content");let{browser:n,logger:o}=e,{isExecutionCancelled:s}=t,i=r.timeout?r.timeout*1e3:n.smartWaitingTimeout,a=gh(i),l=0,c=Date.now(),u,d,m,p=()=>{if(s?.())throw new Ke(`AI assertion cancelled by user.${m?` Last error: ${m.message}`:""}`)},h;for(;!h||h-c<i;){p(),o.info(`Waiting ${a}ms before ${h?"retrying":"trying"} AI assertion`),await X(a,s);try{let g=await mh(n,o,e.storage);if(h=Date.now(),d&&d.serializedTree===g.serializedTree&&d.screenshotBuff.equals(g.screenshotBuff)){o.debug("A11y tree and page screenshot did not change, skipping assertion attempt");continue}d=g,u=await Nt({action:()=>ph(r,g,e),frameUrl:r.iframeUrl,logger:o,browser:n});break}catch(g){m=g instanceof Error?g:new Error(`${g}`),o.info({err:g},`AI_WAIT assert attempt ${l} failed, retrying...`)}finally{l++}}if(!u){let g=`AI assertion still failing after ${i}ms.`;throw m&&(g+=` Latest result: ${m.message}`),new R("AssertionFailureError",g)}return u}async function mh(r,e,t){let n=await yt(r,e),o=await r.screenshot({clearHighlights:!0,scale:"css",retries:2});return uh(Ro({codePath:"assertion",screenshotBuff:o,logger:e,storage:t}),{milliseconds:5e3,fallback:()=>{}}),{...n,screenshotBuff:o}}async function ph(r,e,t){let{browser:n,logger:o,generator:s,orgId:i,flagStore:a}=t,l={type:"ASSERTION"},{serializedTree:c}=e,u=e.screenshotBuff,{tree:d}=e,m=n.url(),p=.2*wn["gpt-4o-2024-05-13"],h=Ao({serializedTree:c,tokenLimit:p,logger:o});if(h){let y=r.assertion;try{a.isBooleanFlagEnabled("rag_keyword_optimization")&&(y=(await s.getExtractedKeywords({goal:r.assertion,completionType:"assertion"},{disableCache:!!r.disableCache,orgId:i})).keywords.join(", "),o.debug({description:y},"Extracted keywords for assertion RAG"))}catch(C){o.warn({err:C},"Failed to extract keywords for assertion, continuing with original description...")}let b=(await s.getRecommendedChunks({...h,description:y,tokenLimit:p})).ids;b.length===0?o.debug("RAG returned no important information for assertion"):(c=d.pruneUsingRelevantIds(new Set(b)).serialize(),o.debug({browserState:c},"Pruned a11y tree with RAG"),l.ragUsed=!0)}l.pageState=c;let g={goal:r.assertion,url:m,browserState:c,screenshot:u.toString("base64")},f=await s.getAssertionResult(g,{disableCache:!!r.disableCache,orgId:i});if(f.relevantElements&&(await Promise.all(Array.from(new Set(f.relevantElements)).slice(0,3).map(y=>n.highlight({id:y}))),l.relevantElementsSerialized=f.relevantElements.map(y=>n.getSerializedFormFromA11yId(y)).filter(y=>!!y)),o.debug({usedRag:l.ragUsed,result:f},"Got assertion result"),!f.result)throw new R("AssertionFailureError",f.thoughts);return{succeedImmediately:!1,thoughts:f.thoughts,urlAfterCommand:m,beforeScreenshotOverride:u}}function gh(r){let e;return r>10*60*1e3?e=Math.floor(r/6):r>60*1e3?e=Math.floor(r/5):r>10*1e3?e=Math.floor(r/4):e=500,e}function Hc(r){return{createIsolatedFolder:()=>Ds(r)}}async function Wc({assertion:r,element:e,callbacks:t}){switch(await t.highlightTarget(e),r.type){case"ELEMENT_CONTENT":{let n=await e.textContent()??"";if(!Ws(n,r.value,r.operation,!!r.negated)){let o=r.negated?Vt[r.operation]:qt[r.operation];throw new R("AssertionFailureError",`The content ${o} '${r.value}': ${n}`)}break}case"ELEMENT_ATTRIBUTE":{let n;try{n=await e.getAttribute(r.attr,{timeout:3e3})??""}catch{throw new R("AssertionFailureError",`The element does not have an attribute named ${r.attr}`)}if(!Ws(n,r.value,r.operation,!!r.negated)){let o=r.negated?Vt[r.operation]:qt[r.operation];throw new R("AssertionFailureError",`The attribute ${r.attr} ${o} '${r.value}': ${n}`)}break}case"ELEMENT_EXISTENCE":{let n;switch(r.condition){case"VISIBLE":{n=await e.isVisible({timeout:Bt*1e3});break}case"EDITABLE":{n=await e.isEditable({timeout:Bt*1e3});break}case"EXISTS":{n=!0;break}case"ENABLED":{n=await e.isEnabled({timeout:Bt*1e3});break}default:return(s=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(r.condition)}if(n=r.negated?!n:n,!n){let o=r.negated?ds[r.condition]:us[r.condition];throw new R("AssertionFailureError",`The element ${o}`)}break}}}async function jc({timeout:r=Bt,...e}){let t=Date.now(),n=r*1e3,o;for(;Date.now()-t<n;)try{await hh(e);return}catch(s){o=s,await X(1e3)}throw o}async function hh({assertion:r,page:e}){switch(r.type){case"CONTENT":{let t=await e.content();if(!Ws(t,r.value??"","CONTAINS",!!r.negated)){let n=r.negated?Vt.CONTAINS:qt.CONTAINS;throw new R("AssertionFailureError",`The page ${n} '${r.value}'`)}break}}}function Ws(r,e,t,n){let o;switch(t){case"CONTAINS":{o=r.includes(e);break}case"EQUALS":{o=r===e;break}case"STARTS_WITH":{o=r.startsWith(e);break}default:return(i=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(t)}return n?!o:o}import{Jimp as fh}from"jimp";async function bn(r,e){let t=await r.screenshot(e),n=await fh.fromBuffer(t);return{buffer:t,width:Math.ceil(n.width??0),height:Math.ceil(n.height??0)}}import{Jimp as Gc}from"jimp";import js from"jpeg-js";import yh from"pixelmatch";async function Vc({ctx:r,command:e,disableCache:t,browser:n,targetingWrapper:o,logger:s}){if(e.target&&!at(e.target))throw new Error("Visual Diff with x/y is not supported yet");if(!e.screenshot)throw new R("ActionFailureError","Cannot execute visual diff without saved screenshot");await yt(n,s,{skipWait:!1});let i={clearHighlights:!0,scale:"css",hideCaret:!0},a;if(!e.target)a=await bn(n,i);else{let x=await o({ctx:r,target:e.target,cache:e.cache?.target??e.target?.a11yData,action:async P=>{},options:{disableCache:!!t,useSelector:!!e.useSelector,iframeUrl:e.iframeUrl}});if(!x.cache)throw new R("ActionFailureError",`Could not find target given description: ${e.target.elementDescriptor}`);a=await bn(n,{target:x.cache,...i}),e.cache={target:x.cache}}let l;if(e.screenshot.data.startsWith("https://")){let x=await fetch(e.screenshot.data);l=Buffer.from(await x.arrayBuffer())}else l=Buffer.from(e.screenshot.data,"base64");if(Math.abs(a.height-e.screenshot.height)>10||Math.abs(a.width-e.screenshot.width)>10){let x=`${a.width}x${a.height}`,P=`${e.screenshot.width}x${e.screenshot.height}`;return{fail:!0,thoughts:`Current screenshot (${x}) does not match saved screenshot dimensions (${P}) - did you change the size of the target or the viewport?`,beforeScreenshotOverride:l,afterScreenshotOverride:a.buffer,succeedImmediately:!1,urlAfterCommand:n.url()}}let c=await Gc.fromBuffer(a.buffer),u={width:a.width,height:a.height},d=await Gc.fromBuffer(l),m={width:e.screenshot.width,height:e.screenshot.height},p,h=u.width*u.height,g=m.width*m.height,f=Math.abs(u.height-m.height),y=Math.abs(u.width-m.width);if(h>g){let x=c.cover({w:m.width,h:m.height});a.buffer=await x.getBuffer("image/jpeg"),p="current",a.width=m.width,a.height=m.height}else g>h&&(l=await d.cover({w:u.width,h:u.height}).getBuffer("image/jpeg"),p="saved");let w={data:Buffer.alloc(a.width*a.height*4),width:a.width,height:a.height},b=e.threshold??.1,v=yh(js.decode(l).data,js.decode(a.buffer).data,w.data,a.width,a.height,{threshold:b,diffColorAlt:[0,255,0]})/(a.width*a.height)*100,E=v>b*100,I=`Visual diff of ${v.toFixed(2)}% detected, which is ${E?"over":"under"} the threshold of ${b*100}%.`;return p&&(I+=` The ${p} screenshot was cropped since it was taller by ${f} pixels and wider by ${y} pixels.`),{fail:E,thoughts:I,beforeScreenshotOverride:a.buffer,afterScreenshotOverride:js.encode(w,75).data,succeedImmediately:!1,urlAfterCommand:n.url()}}async function qc({command:r,browser:e,logger:t}){let n=r.timeout??30,o=null,s=new AbortController,i=Object.fromEntries(Object.entries(r.headers||{}).filter(([h,g])=>h&&g)),a=new URLSearchParams;Object.entries(r.params||{}).filter(([h,g])=>h&&g).forEach(([h,g])=>{a.append(h,g)});let l;if(uo(r.url)&&(l=r.url),mo(r.url,e.baseUrl)&&(l=new URL(r.url,e.baseUrl).toString()),!l)throw new R("ActionFailureError",`Invalid URL: ${r.url}`);let c=async()=>{try{o=await fetch(`${l}?${a.toString()}`,{headers:i,method:r.method,body:r.body,signal:s.signal})}catch(h){t.error({err:h},"Failed to make HTTP request")}},u=async()=>{await new Promise(h=>setTimeout(h,n*1e3)),s.abort()};await Promise.race([u(),c()]);let d=o;if(!d)throw new R("ActionFailureError",`Fetch request timed out after ${n} seconds`);if(!d.ok)throw new R("ActionFailureError",`Fetch request failed with status ${d.status}`);let m={};d.headers.forEach((h,g)=>{m[g]=h});let p={status:d.status,headers:m};return d.headers.get("content-type")?.includes("json")?p.json=await d.json():d.headers.get("content-type")?.includes("text")&&(p.text=await d.text()),{succeedImmediately:!1,urlAfterCommand:e.url(),data:p}}var Ch=1e4,Or=class{flagStore;orgId;storage;localCodeEvalTools;browser;pendingInstructions;generator;commandHistory;config;closed=!1;logger;recordAbortController=null;constructor({browser:e,config:t,generator:n,logger:o,flagStore:s,storage:i,orgId:a,localCodeEvalTools:l}){this.orgId=a,this.browser=e,this.storage=i,this.localCodeEvalTools=l,this.generator=n,this.config=t,this.logger=o,this.flagStore=s,this.pendingInstructions=[],this.commandHistory=[]}get history(){return this.commandHistory.filter(e=>e.state==="DONE")}get lastExecutedCommand(){let e=this.history;return e.length===0?null:e[e.length-1]}setOpen(){this.closed=!1}isClosed(){return this.closed}setLogger(e){this.logger=e}resetHistory(){this.commandHistory=[],this.pendingInstructions=[]}async resetState(e){this.resetHistory(),this.closed=!0,await this.browser.reset(e)}getSerializedHistory(e,t){let n;return this.config.useHistory==="diff"?n=this.getDiffHistory(e,t):n=this.getListHistory(),n}async splitUserGoal(e,t,n){if(e==="AI_ACTION"&&t.match(/[,!;.]|(?:and)|(?:then)/)&&this.config.useGoalSplitter){let o=await this.generator.getGranularGoals({goal:t,url:this.browser.url()},{disableCache:n,orgId:this.orgId});this.pendingInstructions=o.reverse()}else this.pendingInstructions=[t]}async promptToCommand(e,t,n){try{return await this.promptToCommandHelper(e,t,n)}catch(o){throw o instanceof R?o:new R("InternalWebAgentError",`Error generating command: ${o instanceof Error?o.message:o}`,{cause:o})}}async promptToCommandHelper(e,t,n){if(this.pendingInstructions.length===0){if(!t.trim())throw new Error("Cannot generate commands for empty goal");await this.splitUserGoal(e,t,n)}let o=this.pendingInstructions[this.pendingInstructions.length-1];this.logger.debug({goal:o},"Starting prompt translation");let s=this.browser.url(),{serializedTree:i}=await yt(this.browser,this.logger,{}),a=this.commandHistory.length;this.commandHistory.push({state:"PENDING",browserStateBeforeCommand:i,urlBeforeCommand:s,type:e});let l=this.getSerializedHistory(s,i),c=(await this.browser.screenshot({scale:"css",clearHighlights:!0})).toString("base64"),u={url:s,numPrevious:a,browserState:i,history:l,goal:o,lastCommand:this.lastExecutedCommand,screenshot:c},d=await this.generator.getProposedCommand(u,{disableCache:n,orgId:this.orgId});if(this.logger.info({type:d.type,thoughts:d.thoughts},"Got proposed command"),d.type==="SUCCESS"){let m=this.pendingInstructions.pop();if(this.logger.debug({finishedInstruction:m,remainingInstructions:this.pendingInstructions},"Removing pending instruction due to SUCCESS"),this.pendingInstructions.length!==0)return this.commandHistory=[],this.promptToCommand(e,"",n)}else d.type==="FAILURE"&&(this.logger.debug({remainingInstructions:this.pendingInstructions},"Removing pending instructions due to FAILURE"),this.pendingInstructions=[]);return{context:u,command:d}}async getBrowserState(e){return yt(this.browser,this.logger,e)}async locateElement(e){return zs(e,this.getControllerFixtures())}async locateElementWithSelector(e,t){return Nt({action:async()=>{let n={id:-1,selector:e,targetSource:"USER_CSS_SELECTOR",targetUpdateTime:new Date().toUTCString()},o=await this.browser.resolveTarget(null,n);return{thoughts:"Located element with selector",target:n,resolution:o}},frameUrl:t,browser:this.browser,logger:this.logger})}getDiffHistory(e,t){let n=this.history.filter(s=>s.type==="AI_ACTION");if(n.length===0)return"<NONE/>";let o=[`
|
|
1780
|
-
You have already executed the following commands successfully (most recent listed first)`,"-".repeat(10)];return n.reverse().forEach((s,i)=>{if(o.push(`COMMAND ${n.length-i}${i===0?" (command just executed)":""}: ${s.serializedCommand}`),i===0)if(
|
|
1776
|
+
`),tokenLength:l}),a=[],l=0,c=u.length?[u[u.length-1].id]:[],d=!1);let f=s[i],h=f.length;h>Gd&&(f=f.slice(0,Gd),t.warn({lineNumber:i,currentLine:f},`Truncated line with ${h} characters during tree chunking`));let g=as(f);a.push(f),l+=g;let S=Array.from(f.matchAll(Vd)).map(R=>R&&R.length>=3?{tagName:R[1],id:R[2]}:void 0).filter(R=>!!R),C=Array.from(f.matchAll(ry)).map(R=>R&&(R[2]||R[4])).filter(R=>!!R);C.reverse();for(let R of S)c.push(R.id),u.push(R);for(let R of C){let H=u[u.length-1];H&&H.tagName===R&&u.pop()}let v=u.some(R=>sy.includes(R.tagName)),E=s[i+1]??"",P=as(E),O=Array.from(E.matchAll(Vd)).map(R=>R&&R.length>2?R[1]:void 0).filter(R=>!!R),M=O.some(R=>qd.includes(R)),Z=O.some(R=>oy.includes(R));l+P>=ny&&(d=!0),l>=ey&&(M&&!v||C.some(R=>iy.includes(R)))&&(d=!0),l>=ty&&Z&&!v&&(d=!0),i++}a.length&&o.push({ids:c,content:a.join(`
|
|
1777
|
+
`),tokenLength:l});let m=n/o.length,p=Math.min(o.length,Math.ceil(e*1.5/m));return{chunks:o,numRecs:p}}async function _t(r,e,t={}){let n=await r.getBrowserState(t),o=n.serialize();return e.debug({tree:o.length>4e5?"REDACTED_DUE_TO_LENGTH":o,activeFrame:r.getActiveFrame()},"Got a11y tree"),{serializedTree:o,tree:n}}async function cs({codePath:r,screenshotBuff:e,callback:t,storage:n,logger:o}){if(e)try{let s=await n.uploadScreenshot(e);o.debug({screenshotUrl:s,codePath:r},"Saved screenshot for debugging"),t?.(s)}catch(s){o.error({err:s,codePath:r},"Failed to save screenshot for debugging")}}async function Ht({frameUrl:r,action:e,browser:t,logger:n}){if(!r)return e();let o=t.getActiveFrame();try{return n.debug({frameUrl:r},"Setting parent iframe target"),t.setActiveFrame({type:"url",url:r}),await e()}finally{t.setActiveFrame(o)}}async function qi(r,e){if(!r.description)throw new I("ActionFailureError","Cannot locate element with empty description");return Ht({action:()=>dy(r,e),frameUrl:r.iframeUrl,browser:e.browser,logger:e.logger})}async function dy(r,e){let{disableCache:t,testContext:n,filterByViewport:o}=r,{ctx:s,orgId:i,logger:a,browser:l,localCodeEvalTools:c,flagStore:u,generator:d,storage:m}=e,p=r.description;n&&(p=await Ze({s:p,context:n,logger:e.logger,localTools:c}));let{serializedTree:f,tree:h}=await _t(l,a,{filterByViewport:o}),g,y=Date.now(),S;for(;!g&&Date.now()-y<3e3;)try{g=await l.screenshot({scale:"css",clearHighlights:!0,retries:0})}catch(R){S=R}if(!g)throw new I("InternalWebAgentError",`Failed to take screenshot of page to locate element: ${S?.message}`);let b=f,C=!1,v=25e3,E=ls({serializedTree:f,tokenLimit:v,logger:a});if(E&&u.isBooleanFlagEnabled("locator_rag")){try{u.isBooleanFlagEnabled("rag_keyword_optimization")&&(p=(await d.getExtractedKeywords({goal:p,completionType:"locator"},{disableCache:t,orgId:i})).keywords.join(", "),a.debug({description:p},"Extracted keywords for locator RAG"))}catch(Y){a.warn({err:Y},"Failed to extract keywords for locator, continuing with original description...")}let H=(await d.getRecommendedChunks({...E,description:p,tokenLimit:v})).ids;H.length===0?a.debug("RAG returned no important information"):(b=h.pruneUsingRelevantIds(new Set(H)).serialize(),a.debug({tree:n},"Pruned a11y tree with RAG"),C=!0)}let P=g.toString("base64");cy(cs({codePath:"locator",screenshotBuff:g,storage:m,logger:a}),{milliseconds:5e3,fallback:()=>{}});let A=await d.getElementLocation({browserState:b,goal:p,screenshot:P,feedback:void 0},{disableCache:t,orgId:i});a.debug({usedRag:C,result:A},"Got locator result");let O=A.id>0;if(s?.details?.push({type:"AI_LOCATION",matched:O,pageState:b,ragUsed:C,thoughts:A.thoughts}),!O)throw new I("ActionFailureError",`Could not find any relevant element: ${A.thoughts}`);let M={id:A.id,inputDescription:p,targetSource:"AI",targetUpdateTime:new Date().toUTCString()},Z=await l.resolveTarget(null,M);if(Z.a11yNode?.properties?.hidden&&Z.a11yNode?.properties?.hidden!=="false")throw new I("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: ${Z.displayString}`);return{thoughts:A.thoughts,target:M,resolution:Z}}import uy from"p-timeout";async function Ki({command:r,fixtures:e,opts:t={}}){if(!r.assertion.trim())throw new I("ActionFailureError","Assertion command is missing the assertion content");let{browser:n,logger:o}=e,{isExecutionCancelled:s}=t,i=r.timeout?r.timeout*1e3:n.smartWaitingTimeout,a=hy(i),l=0,c=Date.now(),u,d,m,p=()=>{if(s?.())throw new st(`AI assertion cancelled by user.${m?` Last error: ${m.message}`:""}`)},f;for(;!f||f-c<i;){p(),o.info(`Waiting ${a}ms before ${f?"retrying":"trying"} AI assertion`),await K(a,s);try{let h=await my(n,o,e.storage);if(f=Date.now(),d&&d.serializedTree===h.serializedTree&&d.screenshotBuff.equals(h.screenshotBuff)){o.debug("A11y tree and page screenshot did not change, skipping assertion attempt");continue}d=h,u=await Ht({action:()=>py(r,h,e),frameUrl:r.iframeUrl,logger:o,browser:n});break}catch(h){m=h instanceof Error?h:new Error(`${h}`),o.info({err:h},`AI_WAIT assert attempt ${l} failed, retrying...`)}finally{l++}}if(!u){let h=`AI assertion still failing after ${i}ms.`;throw m&&(h+=` Latest result: ${m.message}`),new I("AssertionFailureError",h)}return u}async function my(r,e,t){let n=await _t(r,e),o=await r.screenshot({clearHighlights:!0,scale:"css",retries:2});return uy(cs({codePath:"assertion",screenshotBuff:o,logger:e,storage:t}),{milliseconds:5e3,fallback:()=>{}}),{...n,screenshotBuff:o}}async function py(r,e,t){let{browser:n,logger:o,generator:s,orgId:i,flagStore:a}=t,l={type:"ASSERTION"},{serializedTree:c}=e,u=e.screenshotBuff,{tree:d}=e,m=n.url(),p=25e3,f=ls({serializedTree:c,tokenLimit:p,logger:o});if(f){let y=r.assertion;try{a.isBooleanFlagEnabled("rag_keyword_optimization")&&(y=(await s.getExtractedKeywords({goal:r.assertion,completionType:"assertion"},{disableCache:!!r.disableCache,orgId:i})).keywords.join(", "),o.debug({description:y},"Extracted keywords for assertion RAG"))}catch(C){o.warn({err:C},"Failed to extract keywords for assertion, continuing with original description...")}let b=(await s.getRecommendedChunks({...f,description:y,tokenLimit:p})).ids;b.length===0?o.debug("RAG returned no important information for assertion"):(c=d.pruneUsingRelevantIds(new Set(b)).serialize(),o.debug({browserState:c},"Pruned a11y tree with RAG"),l.ragUsed=!0)}l.pageState=c;let h={goal:r.assertion,url:m,browserState:c,screenshot:u.toString("base64")},g=await s.getAssertionResult(h,{disableCache:!!r.disableCache,orgId:i});if(g.relevantElements&&(await Promise.all(Array.from(new Set(g.relevantElements)).slice(0,3).map(y=>n.highlight({id:y}))),l.relevantElementsSerialized=g.relevantElements.map(y=>n.getSerializedFormFromA11yId(y)).filter(y=>!!y)),o.debug({usedRag:l.ragUsed,result:g},"Got assertion result"),!g.result)throw new I("AssertionFailureError",g.thoughts);return{succeedImmediately:!1,thoughts:g.thoughts,urlAfterCommand:m,beforeScreenshotOverride:u}}function hy(r){let e;return r>10*60*1e3?e=Math.floor(r/6):r>60*1e3?e=Math.floor(r/5):r>10*1e3?e=Math.floor(r/4):e=500,e}function Kd(r){return{createIsolatedFolder:()=>zi(r)}}async function Yd({assertion:r,element:e,callbacks:t}){switch(await t.highlightTarget(e),r.type){case"ELEMENT_CONTENT":{let n=await e.textContent()??"";if(!Yi(n,r.value,r.operation,!!r.negated)){let o=r.negated?on[r.operation]:sn[r.operation];throw new I("AssertionFailureError",`The content ${o} '${r.value}': ${n}`)}break}case"ELEMENT_ATTRIBUTE":{let n;try{n=await e.getAttribute(r.attr,{timeout:3e3})??""}catch{throw new I("AssertionFailureError",`The element does not have an attribute named ${r.attr}`)}if(!Yi(n,r.value,r.operation,!!r.negated)){let o=r.negated?on[r.operation]:sn[r.operation];throw new I("AssertionFailureError",`The attribute ${r.attr} ${o} '${r.value}': ${n}`)}break}case"ELEMENT_EXISTENCE":{let n;switch(r.condition){case"VISIBLE":{n=await e.isVisible({timeout:Zt*1e3});break}case"EDITABLE":{n=await e.isEditable({timeout:Zt*1e3});break}case"EXISTS":{n=!0;break}case"ENABLED":{n=await e.isEnabled({timeout:Zt*1e3});break}default:return(s=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(r.condition)}if(n=r.negated?!n:n,!n){let o=r.negated?vi[r.condition]:Ei[r.condition];throw new I("AssertionFailureError",`The element ${o}`)}break}}}async function Xd({timeout:r=Zt,...e}){let t=Date.now(),n=r*1e3,o;for(;Date.now()-t<n;)try{await fy(e);return}catch(s){o=s,await K(1e3)}throw o}async function fy({assertion:r,page:e}){switch(r.type){case"CONTENT":{let t=await e.content();if(!Yi(t,r.value??"","CONTAINS",!!r.negated)){let n=r.negated?on.CONTAINS:sn.CONTAINS;throw new I("AssertionFailureError",`The page ${n} '${r.value}'`)}break}}}function Yi(r,e,t,n){let o;switch(t){case"CONTAINS":{o=r.includes(e);break}case"EQUALS":{o=r===e;break}case"STARTS_WITH":{o=r.startsWith(e);break}default:return(i=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(t)}return n?!o:o}import{Jimp as gy}from"jimp";async function Gr(r,e){let t=await r.screenshot(e),n=await gy.fromBuffer(t);return{buffer:t,width:Math.ceil(n.width??0),height:Math.ceil(n.height??0)}}import{Jimp as Jd}from"jimp";import Xi from"jpeg-js";import yy from"pixelmatch";async function Zd({ctx:r,command:e,disableCache:t,browser:n,targetingWrapper:o,logger:s}){if(e.target&&!xt(e.target))throw new Error("Visual Diff with x/y is not supported yet");if(!e.screenshot)throw new I("ActionFailureError","Cannot execute visual diff without saved screenshot");await _t(n,s,{skipWait:!1});let i={clearHighlights:!0,scale:"css",hideCaret:!0},a;if(!e.target)a=await Gr(n,i);else{let A=await o({ctx:r,target:e.target,cache:e.cache?.target??e.target?.a11yData,action:async O=>{},options:{disableCache:!!t,useSelector:!!e.useSelector,iframeUrl:e.iframeUrl}});if(!A.cache)throw new I("ActionFailureError",`Could not find target given description: ${e.target.elementDescriptor}`);a=await Gr(n,{target:A.cache,...i}),e.cache={target:A.cache}}let l;if(e.screenshot.data.startsWith("https://")){let A=await fetch(e.screenshot.data);l=Buffer.from(await A.arrayBuffer())}else l=Buffer.from(e.screenshot.data,"base64");if(Math.abs(a.height-e.screenshot.height)>10||Math.abs(a.width-e.screenshot.width)>10){let A=`${a.width}x${a.height}`,O=`${e.screenshot.width}x${e.screenshot.height}`;return{fail:!0,thoughts:`Current screenshot (${A}) does not match saved screenshot dimensions (${O}) - did you change the size of the target or the viewport?`,beforeScreenshotOverride:l,afterScreenshotOverride:a.buffer,succeedImmediately:!1,urlAfterCommand:n.url()}}let c=await Jd.fromBuffer(a.buffer),u={width:a.width,height:a.height},d=await Jd.fromBuffer(l),m={width:e.screenshot.width,height:e.screenshot.height},p,f=u.width*u.height,h=m.width*m.height,g=Math.abs(u.height-m.height),y=Math.abs(u.width-m.width);if(f>h){let A=c.cover({w:m.width,h:m.height});a.buffer=await A.getBuffer("image/jpeg"),p="current",a.width=m.width,a.height=m.height}else h>f&&(l=await d.cover({w:u.width,h:u.height}).getBuffer("image/jpeg"),p="saved");let S={data:Buffer.alloc(a.width*a.height*4),width:a.width,height:a.height},b=e.threshold??.1,v=yy(Xi.decode(l).data,Xi.decode(a.buffer).data,S.data,a.width,a.height,{threshold:b,diffColorAlt:[0,255,0]})/(a.width*a.height)*100,E=v>b*100,P=`Visual diff of ${v.toFixed(2)}% detected, which is ${E?"over":"under"} the threshold of ${b*100}%.`;return p&&(P+=` The ${p} screenshot was cropped since it was taller by ${g} pixels and wider by ${y} pixels.`),{fail:E,thoughts:P,beforeScreenshotOverride:a.buffer,afterScreenshotOverride:Xi.encode(S,75).data,succeedImmediately:!1,urlAfterCommand:n.url()}}async function Qd({command:r,browser:e,logger:t}){let n=r.timeout??30,o=null,s=new AbortController,i=Object.fromEntries(Object.entries(r.headers||{}).filter(([f,h])=>f&&h)),a=new URLSearchParams;Object.entries(r.params||{}).filter(([f,h])=>f&&h).forEach(([f,h])=>{a.append(f,h)});let l;if(Vo(r.url)&&(l=r.url),qo(r.url,e.baseUrl)&&(l=new URL(r.url,e.baseUrl).toString()),!l)throw new I("ActionFailureError",`Invalid URL: ${r.url}`);let c=async()=>{try{o=await fetch(`${l}?${a.toString()}`,{headers:i,method:r.method,body:r.body,signal:s.signal})}catch(f){t.error({err:f},"Failed to make HTTP request")}},u=async()=>{await new Promise(f=>setTimeout(f,n*1e3)),s.abort()};await Promise.race([u(),c()]);let d=o;if(!d)throw new I("ActionFailureError",`Fetch request timed out after ${n} seconds`);if(!d.ok)throw new I("ActionFailureError",`Fetch request failed with status ${d.status}`);let m={};d.headers.forEach((f,h)=>{m[h]=f});let p={status:d.status,headers:m};return d.headers.get("content-type")?.includes("json")?p.json=await d.json():d.headers.get("content-type")?.includes("text")&&(p.text=await d.text()),{succeedImmediately:!1,urlAfterCommand:e.url(),data:p}}var Cy=1e4,Gn=class{flagStore;orgId;storage;localCodeEvalTools;browser;pendingInstructions;generator;commandHistory;config;closed=!1;logger;recordAbortController=null;constructor({browser:e,config:t,generator:n,logger:o,flagStore:s,storage:i,orgId:a,localCodeEvalTools:l}){this.orgId=a,this.browser=e,this.storage=i,this.localCodeEvalTools=l,this.generator=n,this.config=t,this.logger=o,this.flagStore=s,this.pendingInstructions=[],this.commandHistory=[]}get history(){return this.commandHistory.filter(e=>e.state==="DONE")}get lastExecutedCommand(){let e=this.history;return e.length===0?null:e[e.length-1]}setOpen(){this.closed=!1}isClosed(){return this.closed}setLogger(e){this.logger=e}resetHistory(){this.commandHistory=[],this.pendingInstructions=[]}async resetState(e){this.resetHistory(),this.closed=!0,await this.browser.reset(e)}getSerializedHistory(e,t){let n;return this.config.useHistory==="diff"?n=this.getDiffHistory(e,t):n=this.getListHistory(),n}async splitUserGoal(e,t,n){if(e==="AI_ACTION"&&t.match(/[,!;.]|(?:and)|(?:then)/)&&this.config.useGoalSplitter){let o=await this.generator.getGranularGoals({goal:t,url:this.browser.url()},{disableCache:n,orgId:this.orgId});this.pendingInstructions=o.reverse()}else this.pendingInstructions=[t]}async promptToCommand(e,t,n){try{return await this.promptToCommandHelper(e,t,n)}catch(o){throw o instanceof I?o:new I("InternalWebAgentError",`Error generating command: ${o instanceof Error?o.message:o}`,{cause:o})}}async promptToCommandHelper(e,t,n){if(this.pendingInstructions.length===0){if(!t.trim())throw new Error("Cannot generate commands for empty goal");await this.splitUserGoal(e,t,n)}let o=this.pendingInstructions[this.pendingInstructions.length-1];this.logger.debug({goal:o},"Starting prompt translation");let s=this.browser.url(),{serializedTree:i}=await _t(this.browser,this.logger,{}),a=this.commandHistory.length;this.commandHistory.push({state:"PENDING",browserStateBeforeCommand:i,urlBeforeCommand:s,type:e});let l=this.getSerializedHistory(s,i),c=(await this.browser.screenshot({scale:"css",clearHighlights:!0})).toString("base64"),u={url:s,numPrevious:a,browserState:i,history:l,goal:o,lastCommand:this.lastExecutedCommand,screenshot:c},d=await this.generator.getProposedCommand(u,{disableCache:n,orgId:this.orgId});if(this.logger.info({type:d.type,thoughts:d.thoughts},"Got proposed command"),d.type==="SUCCESS"){let m=this.pendingInstructions.pop();if(this.logger.debug({finishedInstruction:m,remainingInstructions:this.pendingInstructions},"Removing pending instruction due to SUCCESS"),this.pendingInstructions.length!==0)return this.commandHistory=[],this.promptToCommand(e,"",n)}else d.type==="FAILURE"&&(this.logger.debug({remainingInstructions:this.pendingInstructions},"Removing pending instructions due to FAILURE"),this.pendingInstructions=[]);return{context:u,command:d}}async getBrowserState(e){return _t(this.browser,this.logger,e)}async locateElement(e){return qi(e,this.getControllerFixtures())}async locateElementWithSelector(e,t){return Ht({action:async()=>{let n={id:-1,selector:e,targetSource:"USER_CSS_SELECTOR",targetUpdateTime:new Date().toUTCString()},o=await this.browser.resolveTarget(null,n);return{thoughts:"Located element with selector",target:n,resolution:o}},frameUrl:t,browser:this.browser,logger:this.logger})}getDiffHistory(e,t){let n=this.history.filter(s=>s.type==="AI_ACTION");if(n.length===0)return"<NONE/>";let o=[`
|
|
1778
|
+
You have already executed the following commands successfully (most recent listed first)`,"-".repeat(10)];return n.reverse().forEach((s,i)=>{if(o.push(`COMMAND ${n.length-i}${i===0?" (command just executed)":""}: ${s.serializedCommand}`),i===0)if(Ur(s.urlBeforeCommand,e))o.push(` URL CHANGE: '${s.urlBeforeCommand}' -> '${e}'`);else{let a=wy(s.browserStateBeforeCommand,t,{n_surrounding:1});a?a.length<Cy?(o.push("PAGE CONTENT CHANGE:"),a.split(`
|
|
1781
1779
|
`).forEach(l=>o.push(` ${l}`))):o.push("PAGE CONTENT CHANGE: <TOO_LONG_TO_DISPLAY/>"):o.push("PAGE CONTENT CHANGE: <NONE/>")}o.push("-".repeat(10))}),o.push(`STARTING URL: ${this.browser.baseUrl}`),o.join(`
|
|
1782
|
-
`)}getListHistory(){return
|
|
1780
|
+
`)}getListHistory(){return Sy`Here are the commands that you have successfully executed:
|
|
1783
1781
|
${this.commandHistory.filter(e=>e.type==="AI_ACTION").map(e=>`- ${e.serializedCommand}`).join(`
|
|
1784
|
-
`)}`}getControllerFixtures(e){return{ctx:e??null,browser:this.browser,generator:this.generator,logger:this.logger,orgId:this.orgId,flagStore:this.flagStore,storage:this.storage,localCodeEvalTools:this.localCodeEvalTools}}async executeCommand(e,t,n,o=!1){let s=this.commandHistory[this.commandHistory.length-1];if(!o&&(!s||s.state!=="PENDING"))throw new R("InternalWebAgentError","Executing command but there is no pending entry in the history");if(this.closed)throw new Error("Attempting to execute command on a closed controller");let i=Date.now(),a=await this.executePresetStep(null,e,t,n),l=Date.now()-i;return this.logger.debug({result:a,duration:l},"Got execution result"),a.succeedImmediately&&!o&&(this.pendingInstructions.pop(),this.pendingInstructions.length>0&&(a.succeedImmediately=!1)),a.elementInteracted&&"target"in e&&e.target&&e.target.type==="description"&&!e.target.elementDescriptor&&(e.target.elementDescriptor=a.elementInteracted.trim()),o||(s.generatedStep=e,s.serializedCommand=Lt(e),s.state="DONE"),a}async wrapMultiElementTargetingCommand(e,t,n,o,s,i,a=1){let l=await Promise.all(n.map((c,u)=>this.wrapElementTargetingCommand({ctx:e,target:c,cache:o[u],action:async d=>d,options:{...i,targetName:t[u]}})));try{return{result:await s(...l.map(u=>u.result)),caches:l.map(u=>u.cache),elementInteractedDisplayStrings:l.map(u=>u.elementInteractedDisplayString)}}catch(c){if(a>0)return this.logger.debug({err:c},"Failed to execute action with multiple cached targets, retrying with AI"),this.wrapMultiElementTargetingCommand(e,t,n,n.map(()=>{}),s,i,a-1);throw new R("ActionFailureError",c.message,{cause:c})}}async wrapElementTargetingCommand(e){return Nt({action:()=>this.wrapElementTargetingCommandHelper(e),frameUrl:e.options.iframeUrl,browser:this.browser,logger:this.logger})}async wrapElementTargetingCommandHelper({ctx:e,target:t,cache:n,action:o,options:s}){let{disableCache:i,useSelector:a,targetName:l="target",targetHealingInProgress:c}=s,u=s.retriesWithAI??1,d=!1;if((!n||i)&&!$o(t))throw new R("ActionFailureError","Cannot target element with no cached data or element descriptor");if(a){if(t.type!=="description")throw new R("ActionFailureError","Cannot use selector along with non-description target");let p={id:-1,selector:t.elementDescriptor,targetSource:"USER_CSS_SELECTOR",targetUpdateTime:new Date().toUTCString()},h=await this.browser.resolveTarget(e,p,{targetName:l});return{result:await o(h.locator),cache:p,elementInteractedDisplayString:h.displayString}}i&&(this.logger.debug("Cache explicitly disabled for this step"),d=!0,n=void 0),n?.inputDescription&&t.elementDescriptor!==n.inputDescription&&(this.logger.debug({old:n.inputDescription,new:t.elementDescriptor},"Target cache was generated with a different description, clearing it automatically"),d=!0,n=void 0);let m=!!n&&In(n);if(!n){this.logger.debug({targetHealingInProgress:c},"Prompting AI for an updated element location"),d&&await X(this.browser.smartWaitingTimeout);let p=await zs({description:t.elementDescriptor,disableCache:i,iframeUrl:s.iframeUrl},this.getControllerFixtures(e));u--;let h=await o(p.resolution.locator);return c&&(p.target={...p.target,targetSource:"AI_HEALED",targetUpdateTime:new Date().toUTCString()}),{result:h,cache:p.target,thoughts:p.thoughts,elementInteractedDisplayString:p.resolution.displayString}}try{let p=await this.browser.resolveTarget(e,n,{targetName:l}),h=await o(p.locator);return m?this.logger.debug({cache:n},"Successfully used cached target to perform action"):this.logger.debug({cache:n},"Successfully generated and used new target data"),{result:h,cache:n,thoughts:void 0,elementInteractedDisplayString:p.displayString}}catch(p){if(p instanceof R)throw p;if(u>0&&t)return this.logger.debug({err:p,cache:n},"Failed to execute action with cached target, retrying with AI"),this.wrapElementTargetingCommand({ctx:e,target:t,cache:void 0,action:o,options:{...s,retriesWithAI:u,targetHealingInProgress:!0}});throw new R("ActionFailureError",p.message,{cause:p})}}async screenshotWithDimensions(e){return bn(this.browser,e)}async executePresetStep(e,t,n,o,s){let i;try{i=await this.resolveCommandTemplateStrings(t,n)}catch(a){throw new R("ActionFailureError",a.message,{cause:a})}try{let a=await this.browser.getOpenPageUrls(),l=this.browser.url(),c=await this.executePresetActionHelper(e,t,n,o,s),u=!0;(t.type==="NAVIGATE"||t.type==="NEW_TAB"||t.type==="TAB"||t.type==="REFRESH")&&(u=!1);let d=await this.browser.getOpenPageUrls(),m=this.browser.url();if(u&&d.length!==a.length)for(let p=d.length-1;p>=0;p--){let h=d[p];if(Jt(h,this.logger)&&h!==l&&h!==m){await this.browser.switchToPage(h,p);break}}return c}catch(a){throw this.logger.error({err:a},"Error thrown in action controller"),a}finally{this.restoreCommandTemplateReplacements(t,i)}}restoreCommandTemplateReplacements(e,t={}){for(let[n,o]of Object.entries(t))$s(e,n,o)}async resolveCommandTemplateStrings(e,t,n="",o={}){let s=["type","a11yData","thoughts","cache"];for(let i in e){if(s.includes(i))continue;let a=e[i],l=n?`${n}.${i}`:i;if(typeof a=="string"&&a.includes("{{")){let c=await Ge({s:a,context:t,logger:this.logger,localTools:this.localCodeEvalTools});if(a===c)continue;o[l]=a,e[i]=c}else typeof a=="object"&&a!==null&&!Array.isArray(a)&&await this.resolveCommandTemplateStrings(a,t,l,o)}return o}async executePresetActionHelper(e,t,n,o,s){if(o=o||"disableCache"in t&&!!t.disableCache,s?.())throw new Ke("Execution cancelled by user");switch(t.type){case"SUCCESS":let i=t.condition;return i?.assertion.trim()?Hs({command:i,fixtures:this.getControllerFixtures(e)}):{succeedImmediately:!1,urlAfterCommand:this.browser.url()};case"AI_WAIT":case"AI_ASSERTION":{if(!t.assertion.trim())throw new R("ActionFailureError","Missing assertion");if(t.timeout&&t.timeout>1800)throw new R("AssertionFailureError",`AI assertion timeout of ${t.timeout} exceeds the maximum allowed value of 30 minutes.`);return Hs({command:{...t,type:"AI_ASSERTION"},fixtures:this.getControllerFixtures(e),opts:{isExecutionCancelled:s}})}case"AI_EXTRACT":{if(!t.goal.trim())throw new R("ActionFailureError","Cannot perform AI extraction without goal");let g=await this.browser.getCondensedHtml(),f=await this.generator.getTextExtraction({goal:t.goal,browserState:g,returnSchema:t.schema},{disableCache:o,orgId:this.orgId});if(f.result==="NOT_FOUND")throw new R("ActionFailureError","No relevant data found for extraction goal on this page");return{data:f.result,succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"NAVIGATE":if(!uo(t.url)&&!mo(t.url,this.browser.baseUrl))throw new R("ActionFailureError",`Invalid URL provided to navigate command: ${t.url}`);await this.browser.navigate({url:t.url,loadTimeoutMs:t.loadTimeout?t.loadTimeout*1e3:void 0});break;case"DIALOG":this.browser.registerDialogHandler(t.action);break;case"CAPTCHA":if(!this.browser.canSolveCaptchas())break;let a=await this.browser.solveCaptcha();a&&(await this.wrapElementTargetingCommand({ctx:e,target:{type:"description",elementDescriptor:"the captcha image solution input"},cache:void 0,action:g=>this.browser.click(g,{}),options:{disableCache:o,useSelector:!!t.useSelector,iframeUrl:t.iframeUrl}}),await this.browser.type(a,{clearContent:!0,pressKeysSequentially:!1,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":if(t.target&&!at(t.target))throw new Error("Scroll with x/y is not supported yet");let l,c;if(t.target&&t.target.elementDescriptor.trim()){let{cache:g,thoughts:f,elementInteractedDisplayString:y}=await this.wrapElementTargetingCommand({ctx:e,target:t.target,cache:t.cache?.target,action:w=>this.browser.hover(w,!1),options:{disableCache:o,useSelector:!!t.useSelector,iframeUrl:t.iframeUrl}});l=y,g&&(t.cache={target:g}),c=f}switch(t.type){case"SCROLL_UP":await this.browser.scrollUp(t.deltaY);break;case"SCROLL_DOWN":await this.browser.scrollDown(t.deltaY);break;case"SCROLL_LEFT":await this.browser.scrollLeft(t.deltaX);break;case"SCROLL_RIGHT":await this.browser.scrollRight(t.deltaX);break}return{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:l,thoughts:c};case"WAIT_FOR_URL":if(t.timeout&&t.timeout>1800)throw new R("UserConfigurationError",`WAIT_FOR_URL timeout of ${t.timeout} exceeds the maximum allowed value of 30 minutes.`);await this.browser.waitForUrl(this.browser.url(),t.url,void 0,t.timeout?t.timeout*1e3:void 0);break;case"WAIT":if(t.delay>1800)throw new R("UserConfigurationError",`User requested to wait for ${t.delay} seconds, which exceeds the maximum allowed time of 30 minutes`);let u=t.delay*1e3;await X(u,s);break;case"REFRESH":await this.browser.refresh({loadTimeoutMs:t.loadTimeout?t.loadTimeout*1e3:void 0});break;case"CLICK":{let g=Uc.parse(t);if($t(t.target)){await this.browser.clickUsingVisualCoordinates(t.target.percentXYLocation,g);break}let f=this.browser.url(),y={disableCache:o,useSelector:!!t.useSelector,iframeUrl:t.iframeUrl},{elementInteractedDisplayString:w,cache:b,thoughts:C,result:v}=await this.wrapElementTargetingCommand({ctx:e,target:t.target,cache:t.cache?.target,action:I=>this.browser.click(I,Hc(this.orgId),g),options:y});b&&(t.cache={target:b});let E={urlAfterCommand:this.browser.url(),succeedImmediately:!1,elementInteracted:w,thoughts:C,data:v};return un(f,E.urlAfterCommand)&&(E.succeedImmediately=!0,E.succeedImmediatelyReason="URL changed"),E}case"DRAG":{if($t(t.fromTarget)&&$t(t.toTarget)){await this.browser.dragAndDropUsingVisualCoordinates(t.fromTarget.percentXYLocation,t.toTarget.percentXYLocation,{force:t.force,hoverSeconds:t.hoverSeconds});break}if($t(t.fromTarget)||$t(t.toTarget))throw new Error("Drag and drop targets must be both coordinates or both descriptions");let{caches:g,elementInteractedDisplayStrings:f}=await this.wrapMultiElementTargetingCommand(e,["from target","to target"],[t.fromTarget,t.toTarget],[t.cache?.fromTarget,t.cache?.toTarget],(y,w)=>this.browser.dragAndDrop(y,w,{force:t.force,hoverSeconds:t.hoverSeconds}),{useSelector:!!t.useSelector,disableCache:o});return g&&g.every(y=>y)&&(t.cache={fromTarget:g[0],toTarget:g[1]}),{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:f[0]}}case"MOUSE_DRAG":{if(t.target&&!at(t.target))throw new Error("Scroll with x/y is not supported yet");let g,f,y;if(t.target?.elementDescriptor){let{cache:C,thoughts:v,elementInteractedDisplayString:E,result:I}=await this.wrapElementTargetingCommand({ctx:e,target:t.target,cache:t.cache?.target,action:async x=>x,options:{useSelector:!!t.useSelector,iframeUrl:t.iframeUrl,disableCache:o}});g=I,f=E,y=v,C&&(t.cache={target:C})}let w=parseInt(t.deltaX),b=parseInt(t.deltaY);if(isNaN(w)||isNaN(b))throw new R("ActionFailureError",`Invalid pixel values passed to mouse drag command: (${t.deltaX}, ${t.deltaY})`);return await this.browser.mouseDrag(w,b,t.steps,g,{force:t.force}),{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:f,thoughts:y}}case"SELECT_OPTION":{if(!at(t.target))throw new Error("Select with x/y is not supported yet");let g=t.target.elementDescriptor,{cache:f,thoughts:y,elementInteractedDisplayString:w}=await this.wrapElementTargetingCommand({ctx:e,target:{type:"description",elementDescriptor:Zr(t,g)},cache:t.cache?.target,action:b=>this.browser.selectOption(b,t.option,t.force),options:{disableCache:o,useSelector:!!t.useSelector,iframeUrl:t.iframeUrl}});return f&&(t.cache={target:f}),{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:w,thoughts:y}}case"TAB":await this.browser.switchToPage(t.url,void 0,{loadTimeoutMs:t.loadTimeout?t.loadTimeout*1e3:void 0});break;case"NEW_TAB":await this.browser.createNewTab(t.url,{loadTimeoutMs:t.loadTimeout?t.loadTimeout*1e3:void 0});break;case"COOKIE":if(!t.value)break;let d=await this.browser.setCookie(t.value);this.logger.debug({results:d},"Set cookies");break;case"LOCAL_STORAGE":if(!t.value||!t.key)break;await this.browser.setLocalStorage(t.key,t.value);break;case"JAVASCRIPT":{let g;try{t.environment==="BROWSER"?g=await this.browser.evaluateCodeInPage({code:t.code,fragment:t.fragment??!1,context:n.toObjectCopy(),timeoutMs:t.timeout?t.timeout*1e3:void 0}):g=await xr({code:t.code,fragment:!!t.fragment,context:n,timeoutMs:t.timeout?t.timeout*1e3:void 0,logger:this.logger,localTools:this.localCodeEvalTools})}catch(f){throw new R("ActionFailureError",f instanceof Error?f.message:`${f}`,{cause:f})}try{JSON.stringify(g)}catch(f){throw new R("ActionFailureError",`Return value is not serializable: ${f instanceof Error?f.message:`${f}`}`,{cause:f})}return{urlAfterCommand:this.browser.url(),succeedImmediately:!1,data:g}}case"TYPE":{let g=this.browser.url(),f,y,w=bh(t.target);if(w){w.elementDescriptor=Zr(t,w.elementDescriptor);let{elementInteractedDisplayString:C,cache:v,thoughts:E}=await this.wrapElementTargetingCommand({ctx:e,target:w,cache:t.cache?.target,action:I=>this.browser.typeIntoTarget(t.value,I,{force:t.force,clearContent:t.clearContent,pressKeysSequentially:t.pressKeysSequentially,pressEnter:t.pressEnter}),options:{disableCache:o,useSelector:!!t.useSelector,iframeUrl:t.iframeUrl}});y=E,f=C,v&&(t.cache={target:v})}else await this.browser.type(t.value,{force:t.force,clearContent:t.clearContent,pressKeysSequentially:t.pressKeysSequentially,pressEnter:t.pressEnter},!0);let b={urlAfterCommand:this.browser.url(),succeedImmediately:!1,elementInteracted:f,thoughts:y};return un(g,b.urlAfterCommand)&&(b.succeedImmediately=!0,b.succeedImmediatelyReason="URL changed"),b}case"HOVER":{if($t(t.target)){await this.browser.hoverUsingVisualCoordinates(t.target.percentXYLocation);break}let{cache:g,thoughts:f,elementInteractedDisplayString:y}=await this.wrapElementTargetingCommand({ctx:e,target:t.target,cache:t.cache?.target,action:w=>this.browser.hover(w,!!t.force),options:{disableCache:o,useSelector:!!t.useSelector,iframeUrl:t.iframeUrl}});return g&&(t.cache={target:g}),{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:y,thoughts:f}}case"FOCUS":{if(!at(t.target))throw new Error("Focus with x/y is not supported yet");let{elementInteractedDisplayString:g,cache:f,thoughts:y}=await this.wrapElementTargetingCommand({ctx:e,target:t.target,cache:t.cache?.target,action:w=>this.browser.focus(w),options:{disableCache:o,useSelector:!!t.useSelector,iframeUrl:t.iframeUrl}});return f&&(t.cache={target:f}),{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:g,thoughts:y}}case"BLUR":{if(!at(t.target))throw new Error("Blur with x/y is not supported yet");let{cache:g,thoughts:f,elementInteractedDisplayString:y}=await this.wrapElementTargetingCommand({ctx:e,target:t.target,cache:t.cache?.target,action:w=>this.browser.blur(w),options:{disableCache:o,useSelector:!!t.useSelector,iframeUrl:t.iframeUrl}});return g&&(t.cache={target:g}),{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:y,thoughts:f}}case"PRESS":let m=this.browser.url();await this.browser.press(t.value);let p={urlAfterCommand:this.browser.url(),succeedImmediately:!1};return un(m,p.urlAfterCommand)&&(p.succeedImmediately=!0,p.succeedImmediatelyReason="URL changed"),p;case"REQUEST":return qc({command:t,browser:this.browser,logger:this.logger});case"VISUAL_DIFF":return Vc({ctx:e,command:t,disableCache:o,browser:this.browser,logger:this.logger,targetingWrapper:g=>this.wrapElementTargetingCommand(g)});case"FILE_UPLOAD":{let g=t.fileSource.url;if(!g.startsWith("http")&&!g.startsWith(yn))throw new R("UserConfigurationError","The source URI for the file upload step must be a valid URL or a previously downloaded file beginning with 'file://'");let f=await wc({uri:g,logger:this.logger,orgId:this.orgId});await this.browser.setFileChooserHandler(f);break}case"AUTH_SAVE":return{data:await this.browser.saveAuthState(),succeedImmediately:!1,urlAfterCommand:this.browser.url()};case"AUTH_LOAD":{let g=await xr({code:t.storageState,fragment:!1,context:n,logger:this.logger,localTools:this.localCodeEvalTools});if(typeof g!="object")throw new R("ActionFailureError",`Credentials must evaluate to an object (received ${typeof g} instead)`);let f;try{f=ra.parse(g)}catch(y){throw new R("ActionFailureError",`Credentials provided do not follow the required format: ${y}`)}await this.browser.loadAuthState(f);break}case"ELEMENT_CHECK":{if(t.target&&!at(t.target))throw new Error("Element assertion with x/y is not supported yet");let g=Date.now(),f=(t.timeout??Bt)*1e3,y=0,w;for(;y<2||Date.now()-g<f;){y++;try{let{cache:b,thoughts:C,elementInteractedDisplayString:v}=await this.wrapElementTargetingCommand({ctx:e,target:t.target,cache:t.cache?.target,action:async E=>{await Wc({assertion:t.assertion,element:E,callbacks:{highlightTarget:async I=>this.browser.highlightTarget(I)}})},options:{disableCache:o,useSelector:!!t.useSelector,iframeUrl:t.iframeUrl}});return b&&(t.cache={target:b}),{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:v,thoughts:C}}catch(b){if(w=b,t.assertion.type==="ELEMENT_EXISTENCE"&&t.assertion.negated)return{succeedImmediately:!1,urlAfterCommand:this.browser.url()}}}throw new R("AssertionFailureError",`Element check still failing after ${Math.floor((Date.now()-g)/1e3)} seconds: ${w?w.message:""}`)}case"PAGE_CHECK":{await Nt({frameUrl:t.iframeUrl,browser:this.browser,logger:this.logger,action:async()=>jc({assertion:t.assertion,page:await this.browser.getActivePageOrFrame(),logger:this.logger,timeout:t.timeout})});break}default:return(g=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(t)}return{succeedImmediately:!1,urlAfterCommand:this.browser.url()}}async getReverseMappedTarget(e,t,n){return(await this.generator.getReverseMappedDescription({browserState:e.browserState,goal:`${t}`},{disableCache:n,orgId:this.orgId})).phrase}async stopRecordMode(){this.recordAbortController?.abort(),await this.browser.clearAllCdpHighlights()}async startRecordMode(e){this.recordAbortController=new AbortController;let t=new Eo({signal:this.recordAbortController.signal,...e});return await this.browser.startRecording(this.recordAbortController.signal,t),t}async runSectionAutohealing(e){return this.generator.getAutohealingProposal(e,{disableCache:!0,orgId:this.orgId})}};var Th=4;async function Kc({socket:r,logger:e,storage:t,devicePixelRatio:n,generator:o,browserbase:s,authorization:i}){let a=r.id,l=r.handshake.query.testId,c=r.handshake.query.baseUrl,u=r.handshake.query.envName,d=r.handshake.query.viewport?JSON.parse(decodeURIComponent(r.handshake.query.viewport)):void 0,m=be.parse(JSON.parse(decodeURIComponent(r.handshake.query.testMetadata)));if(!l||!c)throw new Error("Socket connection request is missing testId or baseUrl");let p=await t.getOrgId(l);e=e.child({testId:l,baseUrl:c,orgId:p});let h=r.handshake.query.environmentVariables?JSON.parse(decodeURIComponent(r.handshake.query.environmentVariables)):{};if(await Promise.all((m.parameters??[]).map(async w=>{let b=await Ge({s:w.defaultValue,context:ie.dummyContext(u,h),logger:e,localTools:y});h[w.name]=b})),_.getSession(a))return e.info("Associating connection with existing session (likely reconnect)"),{sessionId:a,orgId:p,testId:l};let f=r.handshake.headers["x-forwarded-for"]?.split(",")[0];if(e.info({clientIp:f,event:"connect",args:r.handshake.query},"Websocket event (connect)"),f&&_.getCurrentConnectionsByIp(f)>=Th)throw e.error({clientIp:f,sessions:_.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 retry or contact Momentic support if you believe this is in error.");_.reserveCapacityByIp(f);let y;i?.type==="API_KEY"&&(y=new gt(i));try{await Eh({socket:r,baseUrl:c,envName:u,viewport:d,testMetadata:m,orgId:p,sessionId:a,logger:e,environmentVariables:h,clientIp:f,devicePixelRatio:n,storage:t,localCodeEvalTools:y,generator:o,browserbase:s})}catch(w){throw e.warn({err:w},"Error setting up socket session, possibly due to client closing the connection"),_.releaseCapacityByIp(f),w}return{sessionId:a,testId:l,orgId:p}}async function Eh({socket:r,baseUrl:e,viewport:t,envName:n,devicePixelRatio:o,testMetadata:s,orgId:i,sessionId:a,logger:l,storage:c,localCodeEvalTools:u,generator:d,environmentVariables:m,clientIp:p}){let h={};t&&(h.viewport=t),o&&(h.deviceScaleFactor=o);let g=Yr.parse(s?.advanced??{}),[f,y]=await Promise.all([st.init({baseUrl:e,userBrowserSettings:g,waitForLoad:!0,enricher:new To(l),timeout:g.pageLoadTimeoutMs,storage:c,logger:l,contextArgs:h,onTabsChange:(E,I)=>{r.emit("tabs",{tabs:E,activeTab:I})}}),Ir.init(i)]),w=new Or({browser:f,generator:d,config:Sn,logger:l,flagStore:y,orgId:i,storage:c,localCodeEvalTools:u}),b=El(r,a,l),C=async()=>{clearInterval(b.timer)},v=new ie({baseUrl:e,currentUrl:w.browser.url(),variablesFromEnvironment:m,envName:n});if(!r.connected)throw await f.cleanup(),new Error("Socket not connected anymore, not proceeding with session setup");r.emit("session",{url:e,userAgent:st.USER_AGENT,viewport:await w.browser.getViewport(),sessionId:a}),_.registerSession({controller:w,context:v,sessionId:a,cleanup:C,clientIp:p})}var Yc=[xl,zl,Hl,_c,vl,kc,Dc,jl,ql,Kl,Gl,Wl,Yl,Vl];var Xc=r=>{let{logger:e}=r,t=new vh(r.baseServer,{cors:{origin:"*",methods:["GET","POST"]},pingTimeout:3e4,pingInterval:6e4,maxHttpBufferSize:1e7});return t.on("connection",async n=>{let o=e.child({socketId:n.id}),s;try{o.info({event:"connection",transport:n.conn.transport.name},"Websocket connection established"),s=await Kc({...r,socket:n,logger:o}),o=o.child(s)}catch(i){o.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}Yc.forEach(i=>xh(i,{socket:n,metadata:s,...r,logger:o}))}),t},xh=(r,e)=>{let t=r.createHandler(e),n=(...o)=>{["cloudMouseMove","cloudScroll","cloudType"].includes(r.event)||e.logger.debug({...e.metadata,event:r.event,args:o},`Websocket event (${r.event})`);let s=i=>{e.logger.error({event:r.event,type:"websocket",args:o,err:i instanceof Error?i:new Error(`${i}`)},"Unhandled exception in socket handler"),e.socket.emit("error",{message:i instanceof Error?i.message:`${i}`})};try{let i=t.apply(void 0,o);i&&typeof i.catch=="function"&&i.catch(s)}catch(i){s(i)}};e.socket.on(r.event,n)};import{z as Ih}from"zod";import Ah from"fetch-retry";var Rh=Ah(global.fetch),ge=class{static API_VERSION="v1";baseURL;apiKey;constructor(e){this.baseURL=e.baseURL,this.apiKey=e.apiKey}async sendRequest(e,t){let n=await Rh(`${this.baseURL}${e}`,{retries:1,retryDelay:1e3,method:"POST",body:JSON.stringify(t),headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`}});if(!n.ok)throw new Error(`Request to ${e} failed with status ${n.status}: ${await n.text()}`);return n.json()}};var Qt=class extends ge{constructor(e){super(e)}async getRecommendedChunks(e){let t=await this.sendRequest(`/${ge.API_VERSION}/web-agent/recommend-chunks`,e);return Ki.parse(t)}async getScreenshotFromS3(e){let t=await this.sendRequest(`/${ge.API_VERSION}/s3/visual-diff-screenshot`,{url:e});return Ih.string().parse(t)}async getElementLocation(e,t){let n=await this.sendRequest(`/${ge.API_VERSION}/web-agent/locate-element`,{...e,disableCache:t.disableCache});return Sa.parse(n)}async getAssertionResult(e,t){let n={...e,disableCache:!!t.disableCache},o=await this.sendRequest(`/${ge.API_VERSION}/web-agent/assertion`,{...n,history:"",numPrevious:0,lastCommand:null});return ya.parse(o)}async getProposedCommand(e,t){let n=await this.sendRequest(`/${ge.API_VERSION}/web-agent/next-command`,{url:e.url,browserState:e.browserState,goal:e.goal,history:e.history,numPrevious:e.numPrevious,lastCommand:e.lastCommand,screenshot:e.screenshot,disableCache:t.disableCache});return fa.parse(n)}async getGranularGoals(e,t){let n=await this.sendRequest(`/${ge.API_VERSION}/web-agent/split-goal`,{url:e.url,goal:e.goal,disableCache:t.disableCache});return wa.parse(n)}async getReverseMappedDescription(e,t){let n=await this.sendRequest(`/${ge.API_VERSION}/web-agent/reverse-mapped-description`,{goal:e.goal,browserState:e.browserState,disableCache:t.disableCache});return ba.parse(n)}async getTextExtraction(e,t){let n={goal:e.goal,browserState:e.browserState,returnSchema:e.returnSchema,disableCache:t.disableCache},o=await this.sendRequest(`/${ge.API_VERSION}/web-agent/text-extraction`,n);return ss.parse(o)}async getTestResultClassification(e){let t=await this.sendRequest(`/${ge.API_VERSION}/web-agent/result-classification`,e);return rs.parse(t)}async getExtractedKeywords(e,t){let n=await this.sendRequest(`/${ge.API_VERSION}/web-agent/extract-keywords`,{goal:e,disableCache:t.disableCache});return Zi.parse(n)}async getAutohealingProposal(e,t){let n=await this.sendRequest(`/${ge.API_VERSION}/web-agent/autoheal-section`,e);return qi.parse(n)}};import{Router as Ph}from"express";function Ne(r){return function(...e){let t=e[e.length-1],n=r(...e);Promise.resolve(n).catch(t)}}var Jc=Ph();Jc.get("/",Ne((r,e)=>{let t=Tl();e.status(200).json(t)}));var Zc=Jc;import{Router as _h}from"express";import Qc,{multistream as Oh}from"pino";import Lh from"pino-pretty";var Gs=new Map,Mh=!0,Vs=class r{consoleLogger;ddClientToken;hostname;bindingAttributes;excludeAttributesInConsoleLogs;excludeTimestamps;disableConsoleLogs;site="https://http-intake.logs.us5.datadoghq.com/api/v2/logs";constructor({bindings:e,clientToken:t,hostname:n,excludeAttributesInConsoleLogs:o,excludeTimestamps:s,disableConsoleLogs:i}){this.ddClientToken=t,this.hostname=n,this.excludeAttributesInConsoleLogs=o,this.excludeTimestamps=s,this.disableConsoleLogs=i,this.bindingAttributes={...e,env:"production"};let a={base:o?{}:this.bindingAttributes,errorKey:"err",level:"debug",timestamp:!s};this.consoleLogger=Mh?Qc(a):Qc(a,Oh([{stream:Lh({colorize:!0})}]))}child(e){return new r({clientToken:this.ddClientToken,bindings:{...this.bindingAttributes,...e},hostname:this.hostname,excludeAttributesInConsoleLogs:this.excludeAttributesInConsoleLogs,disableConsoleLogs:this.disableConsoleLogs})}flush(e){this.disableConsoleLogs||this.consoleLogger.flush(e)}log(e,t,n,...o){if(t&&n===void 0&&(n=`${t}`,t={}),this.disableConsoleLogs||this.consoleLogger[e](e==="error"?t:{testId:t.testId,runId:t.runId},n,...o),typeof t=="object"&&t&&"err"in t&&t.err instanceof Error){let i={};for(let a of Object.getOwnPropertyNames(t.err))i[a]=t.err[a];i.name=t.err.name,t.err=i}let s=Object.assign({},this.bindingAttributes,t&&typeof t=="object"?t:{});o.length>0&&(s.args=o),(async()=>{try{let i=await fetch(this.site,{method:"POST",headers:{Accept:"application/json","Content-Type":"application/json","DD-API-KEY":this.ddClientToken},body:JSON.stringify([{ddsource:this.bindingAttributes.app,hostname:this.hostname??"vercel",service:"momentic",message:{message:n||"",...s,level:e}}])});if(!i.ok)throw new Error(`Failed to log to Datadog: ${i.statusText})}`)}catch(i){this.disableConsoleLogs||this.consoleLogger.warn({obj:t,msg:n,args:o,err:i},"Failed to log to Datadog")}})()}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}setMinLevel(e){this.consoleLogger.level=e}enableConsoleLogs(){this.disableConsoleLogs=!1}},Io=({app:r,clientToken:e,hostname:t,excludeAttributesInConsoleLogs:n,excludeTimestamps:o,disableConsoleLogs:s})=>{if(!process.env.DD_CLIENT_TOKEN&&!process.env.NEXT_PUBLIC_DD_CLIENT_TOKEN&&!e)throw new Error("Missing DD_CLIENT_TOKEN");return Gs.has(r)||Gs.set(r,new Vs({bindings:{app:r},hostname:t,clientToken:e||process.env.NEXT_PUBLIC_DD_CLIENT_TOKEN||process.env.DD_CLIENT_TOKEN,excludeAttributesInConsoleLogs:n,excludeTimestamps:o,disableConsoleLogs:s})),Gs.get(r)};import{hostname as Nh}from"os";var _e=Io({app:"desktop-server",clientToken:"pubcfd7516a5c0ba852b42675cd97bee027",hostname:Nh(),excludeAttributesInConsoleLogs:!0,excludeTimestamps:!0,disableConsoleLogs:!0});var Cn=_h();Cn.get("/",Ne(async(r,e)=>{let n=(await hl(_e)).filter(o=>o.enabled??!0);e.status(200).json(n)}));Cn.get("/metadata",Ne((r,e)=>{let t=gl();e.status(200).json(t)}));Cn.post("/",Ne(async(r,e)=>{let t;try{t=ma.parse(r.body)}catch(o){e.status(400).json({error:`Invalid request body: ${o}`});return}try{Qr(t.name)}catch(o){e.status(400).json({error:`Invalid module name: ${o}`});return}let n=await pl(t.name,t.description,t.enabled,t.steps);e.status(201).json(n)}));Cn.get("/:moduleId",Ne(async(r,e)=>{if(!r.params.moduleId){e.status(400).json({error:"Missing moduleId in url path."});return}let t=await fl(r.params.moduleId,_e);if(!t){e.status(404).json({error:"Module not found."});return}e.json(t)}));var ed=Cn;import{Router as Dh}from"express";import{existsSync as kh}from"fs";import{join as Oo}from"path";import{v4 as Fh}from"uuid";var Ks="https://api.momentic.ai",td=r=>{Ks=r},Tn=()=>Ks,Lr,qs,rd=async r=>{if(Lr)return Lr;let e=new ye({baseUrl:Ks,apiKey:r});try{return Lr=await e.getOrgId(),qs=r,Lr}catch(t){throw new Error(`Error checking API key against server: ${t}`)}},Po=()=>{if(!Lr)throw new Error("Your organization ID appears invalid. Please contact Momentic support.");return Lr},nd=()=>{if(!qs)throw new Error("Your API key appears invalid. Please contact Momentic support.");return qs};var er=Dh();er.get("/",Ne((r,e)=>{let t=an(pe,_e);e.status(200).json(t)}));er.post("/",Ne(async(r,e)=>{let t;try{t=ua.parse(r.body)}catch(a){e.status(400).json({error:`Invalid request body: ${a}`});return}try{Qr(t.name)}catch(a){e.status(400).json({error:a.message});return}let o={id:Fh(),name:t.name,baseUrl:t.baseUrl,schemaVersion:Oe,advanced:{disableAICaching:!1,viewport:t.viewport??ct},retries:0,steps:[]};t.environment&&(o.envs=[{name:t.environment,default:!0}]);let s=await wl(o,t.name),i={...o,testPath:s};e.status(201).json(i)}));er.get("/:testPath",Ne(async(r,e)=>{if(!r.params.testPath){e.status(400).json({error:"Missing testPath in url path."});return}let t=Oo(pe,r.params.testPath);if(!kh(t)){e.status(400).json({error:`Test not found at path: ${t}`});return}let n=await no(t,Mt,_e);e.status(200).json(n)}));er.patch("/:testPath/metadata",Ne(async(r,e)=>{if(!r.params.testPath){e.status(400).json({error:"Missing testPath in url path."});return}let t;try{t=da.parse(r.body)}catch(o){e.status(400).json({error:`Invalid request body: ${o}`});return}let n=Oo(pe,r.params.testPath);ro(t,n),e.status(201).json({message:"ok"})}));er.patch("/:testPath",Ne(async(r,e)=>{if(!r.params.testPath){e.status(400).json({error:"Missing testPath in url path."});return}let t;try{t=ca.parse(r.body)}catch(c){e.status(400).json({error:`Invalid request body: ${c}`});return}let n=Oo(pe,r.params.testPath),o;try{o=bl(n)}catch(c){e.status(400).json({error:`Existing test file on disk is invalid: ${c}`});return}let{stepsToSave:s,moduleUpdates:i,cachesToSave:a}=await tt({steps:t.steps,cacheCreationParams:{testId:o.id,orgId:Po()}});i.forEach(c=>ml({...c,schemaVersion:Oe})),ro({schemaVersion:Oe,steps:s},n),await new ye({apiKey:nd(),baseUrl:Tn()}).updateStepCaches({entries:a,testId:o.id}),e.status(201).json({message:"ok"})}));er.patch("/:testPath/environments",Ne(async(r,e)=>{if(!r.params.testPath){e.status(400).json({error:"Missing testPath in url path."});return}let t;try{t=pa.parse(r.body)}catch(o){e.status(400).json({error:`Invalid request body: ${o}`});return}let n=Oo(pe,r.params.testPath);ro({envs:t.defaultEnv?[{name:t.defaultEnv,default:!0}]:[]},n),e.status(201).json({message:"ok"})}));var od=er;async function sd(r){let{momenticServerUrl:e,apiKey:t,serverPort:n,appPort:o,staticDir:s,devicePixelRatio:i}=r;if(!Bh(pe)||!zh(pe).isDirectory()){let f=jh.isAbsolute(pe);throw new Error(`Root folder ${pe} does not exist${f?"":` in the current directory ("${process.cwd()}")`}. Please run \`npx momentic@latest init\` if you wish to setup Momentic here for the first time.`)}e&&td(e),_e.debug(r,"Initializing desktop server");let a=await rd(t);_e.debug({orgId:a},"Checking API key successful");let c=`http://localhost:${n}`;o&&(c=`http://localhost:${o}`);let u=Gh(s);await new Promise(f=>{u.listen(n,()=>{_e.info(`Server is running at http://localhost:${n}`),f()})});let m=new Qt({baseURL:Tn(),apiKey:t}),p={type:"API_KEY",baseUrl:Tn(),apiKey:t},h=new ye(p),g=new vr(h,Po());Xc({baseServer:u,generator:m,storage:g,logger:_e,devicePixelRatio:i,authorization:p}),await Wh(c)}function Gh(r){let e=Ys();e.use($h()),e.use(Uh.json({limit:"25mb"}));let t=Ys.Router();if(t.use("/tests",od),t.use("/modules",ed),t.use("/environments",Zc),e.use("/api",t),e.use((o,s,i)=>{o.path!=="/healthcheck"&&_e.debug({url:o.url,path:o.path,query:o.query,method:o.method,body:o.body,headers:o.rawHeaders,client:o.ip},"Received desktop-server request"),s.on("close",()=>{s.statusCode>=400&&_e.error({url:o.url,method:o.method,statusCode:s.statusCode},"Request completed in error")}),i()}),e.use((o,s,i,a)=>{o instanceof Error&&o.message.includes("BadRequestError: request aborted")||(_e.error({stack:o.stack,msg:o.message,url:s.url,method:s.method},"Unhandled exception leading to 500 on desktop-server"),i.status(500).send("Internal Server Error"),a(o))}),r){let o=Ys.static(r);e.use("/",o),e.use("*",o)}return Hh.createServer(e)}import{existsSync as Jf}from"fs";import Vd,{dirname as Zf,join as Qf}from"path";import{chdir as ey}from"process";import{fileURLToPath as ty}from"url";import En from"chalk";var _t=(...r)=>{le(En.blue(...r))};var Ie=(...r)=>{le(En.dim(...r))};var Pe=(...r)=>{le(En.green(...r))},le=(...r)=>{console.log(...r)},ce=(...r)=>{console.error(En.yellow(...r))},M=(...r)=>{console.error(En.red(...r))};import{hostname as Vh}from"os";var O=Io({app:"cli",clientToken:"pub7eb923f18fb3f1d42ac5eba8c5ea13a5",hostname:Vh(),excludeAttributesInConsoleLogs:!0,excludeTimestamps:!0,disableConsoleLogs:!0});import{execSync as qh}from"child_process";import{platform as Kh}from"os";function Xs(){return id()?(_t("Setting device pixel ratio to 2 automatically since a Mac OS Retina screen was detected."),_t("If you are using a low pixel-density monitor, you should manually set --pixel-ratio to 1 to avoid incorrect viewport calculations."),_t("Confirm your device's pixel-ratio at https://www.mydevice.io."),2):(_t("Setting device pixel ratio to 1."),_t("If you are using Momentic on a high-pixel density (HiDPI) monitor, relaunch with the --pixel-ratio option to avoid incorrect viewport calculations"),_t("Confirm your device's pixel-ratio at https://www.mydevice.io."),1)}function id(){return Kh()==="darwin"&&qh("system_profiler SPDisplaysDataType").toString().includes("Retina")}function Js(r){id()&&r===1&&(ce("If you are using Momentic on a Retina screen, relaunch with the --pixel-ratio option to avoid incorrect viewport calculations."),ce("Confirm your device's pixel-ratio at https://www.mydevice.io."))}import{createHash as md}from"crypto";import{existsSync as pd,readFileSync as ni,writeFileSync as gd}from"fs";import{join as hd}from"path";import{parse as uf}from"yaml";import{existsSync as ei,mkdirSync as ld,readdirSync as of,statSync as cd}from"fs";import{homedir as dd}from"os";import{join as St,resolve as sf}from"path";import{existsSync as Yh,statSync as Xh}from"fs";var Lo=!!process.env.CI||!process.stdout.isTTY;function Dt(r){try{return Yh(r)&&Xh(r).isDirectory()}catch(e){return M({err:e},`Error reading path ${r} during directory existence check`),!1}}import{registry as Zs}from"playwright-core/lib/server";function Jh(r){let e=[],t=[];for(let n of r){let o=Zs.findExecutable(n);!o||o.installType==="none"?e.push(n):t.push(o)}return t}async function Mo(){let r=Jh(["chromium"]);await Zs.installDeps(r,!1),await Zs.install(r,!1)}import{existsSync as Zh,mkdirSync as Qh,statSync as ef}from"fs";import{dirname as tf}from"path";import rf from"readline/promises";var Qs=!1,nf=(()=>{try{return ef("/.dockerenv"),!0}catch{return!1}})();async function Xe(r,e){if(Lo||Qs||nf)return!0;O.flush(),await new Promise(i=>setTimeout(i,500));let t=rf.createInterface({input:process.stdin,output:process.stdout}),n=r.split("."),o;if(n.length===1)o=r;else{let i=`${n.slice(0,n.length-1).join(". ").trim()}.`;e?ce(i):le(i),o=n[n.length-1].trim()}let s=await t.question(`${o} ('y' for yes / n for no / 'A' to accept all) `);return t.close(),s==="A"?(Qs=!0,setTimeout(()=>{Qs=!1},3e3),!0):s.toLowerCase()==="y"}async function vn(r){let e=tf(r);return Dt(e)?Zh(r)?Xe(`File '${ad(r)}' already exists. Overwrite existing content?`,!0):!0:await Xe(`Directory '${ad(e)}' doesn't exist. Create it now?`,!0)?(Qh(e,{recursive:!0}),!0):!1}function ad(r){return r.replace(/(\s+)/g,"\\$1")}var af=[Ot,Wn,yr],wt=df(),tr=St(wt,Ot),ri=St(wt,Wn),bt=St(wt,yr),ti=St(dd(),"momentic",ls),ud=[tr,ri,bt];async function Ct(r){let e=process.versions.node,t=parseInt(e.split(".")[0]);(isNaN(t)||t<20)&&(M(`Node.js version 20 or higher is required to run the Momentic CLI. Detected: ${process.versions.node}.`),process.exit(1));let n=await r.client.getOrgId();return r.installBrowsers&&await Mo(),await cf(r),n}async function lf(r){Dt(wt)||!r&&!await Xe(`The root '${Pt}' folder was not found in the current directory. You will need to invoke the Momentic CLI from this directory in the future. Proceed?`)&&(M("Setup cancelled."),process.exit(1)),Dt(ti)||(!r&&!await Xe("The Chrome cache folder was not found in your home directory. Proceed with creation?")&&(M("Setup cancelled."),process.exit(1)),ld(ti,{recursive:!0}));for(let e of ud)Dt(e)||(!r&&!await Xe(`'${e}' folder was not found in the current directory. Create it now?`)&&(M("Setup cancelled."),process.exit(1)),ld(e,{recursive:!0}))}function xn(r,e,t=new Set){for(let n of r){let o=sf(n),s=!1;try{s=ei(o)&&cd(o).isDirectory()}catch(i){O.error({err:i},`Error reading path ${o} during collect paths`)}if(o&&s){let i=of(o).map(a=>St(o,a));xn(i,e,t);continue}if(o.endsWith(".yaml")){try{if(!ei(o)||!cd(o).isFile()){O.error(`File not found or unreadable: ${o}`);continue}}catch(i){O.error({err:i},`Error reading file ${o} during collect paths`);continue}if(!e(o))continue;t.add(o)}}return t}async function cf({client:r,createFolders:e,skipPrompts:t,pullEnvs:n}){if(dd()||(M("Your home directory could not be found. Please ensure the HOME environment variable is set for POSIX systems, and the USERPROFILE environment variable is set for Windows systems."),process.exit(1)),e)await lf(t);else for(let o of[wt,ti,...ud])!Dt(o)&&!Lo&&(M(`The '${o}' folder is required to run the Momentic CLI but was not found in the current directory. Please run 'npx momentic@latest init' to create the required folders.`),M(`The current working directory is: ${process.cwd()}`),process.exit(1));n&&(!t&&!await Xe("Pull environments from Momentic Cloud? Environment definitions may be required to run tests locally.")&&(M("Setup cancelled."),process.exit(1)),await No({client:r,all:!0,skipPrompts:t}))}function df(){let r=n=>ei(St(n,Pt))&&af.some(o=>Dt(St(n,Pt,o))),e=process.cwd();for(;e!=="/"&&!r(e);)e=St(e,"..");let t;return r(e)?t=e:t=process.cwd(),t!==process.cwd()?ce(`Current working directory does not contain a ${Pt} folder, treating ${t} as the Momentic root folder instead`):O.info(`Identified ${t} as the Momentic root folder`),St(t,Pt)}async function No({envNames:r,client:e,all:t,skipPrompts:n}){let o=await e.getAllEnvironments();r&&!t&&(o=o.filter(a=>r?.includes(a.name))),pd(bt)||(M(`${bt} does not exist in the current directory. Please run 'npx momentic@latest init' first.`),process.exit(1));let s=[],i=[];for(let a of o){let l=hd(bt,`${a.name}.yaml`);if(!n&&!await vn(l))return;if(!pd(l))gd(l,fs(a)),s.push(l);else{let c=md("sha256").update(ni(l)).digest("hex"),u=fs(a),d=md("sha256").update(u).digest("hex");c!==d&&(gd(l,u),i.push(l))}}Pe("Pulled environments successfully!"),s.length&&(Pe("Created:"),s.forEach(a=>Pe(" ",a))),i.length&&(Pe("Updated:"),i.forEach(a=>Pe(" ",a)))}function mf(r){return r.endsWith(".yaml")?ni(r,"utf8").includes("momentic/environment")?!0:(ce(`Skipping YAML that is not a Momentic environment: ${r}`),!1):!1}async function fd({client:r,names:e,all:t,yes:n}){let o;t?o=[bt]:o=e.map(a=>hd(bt,`${a.toLowerCase()}.yaml`));let s=xn(o,mf);le(`Found ${s.size} environments to push:`),s.forEach(a=>le(" ",a));let i=[];for(let a of s){let l=uf(ni(a,"utf-8"));try{let c=ke.parse(l);i.push(c)}catch(c){M(`${a} failed to parse as a valid environment file.`),M(c),process.exit(1)}}!n&&!await Xe("Pushing environments can overwrite variables on cloud and instantly affect scheduled runs. Continue?",!0)||(await r.updateEnvironments(i),Pe("Pushed environments successfully!"))}import{Argument as An,Option as Ee}from"@commander-js/extra-typings";import{validateHeaderValue as pf}from"http";import{cpus as yd}from"os";import{parse as gf}from"yaml";import{z as B}from"zod";var _o=58888,Tt=new Ee("--api-key <key>","API key for authentication. If not supplied, attempts to read the MOMENTIC_API_KEY env var."),Et=new Ee("--server <server>","Momentic server to use. Leave unchanged unless using Momentic on-premise."),vt=new Ee("-y, --yes","Skip all confirmation prompts."),si=new Ee("-w, --wait","Wait for tests to finish running before exiting. Only applicable when running tests remotely").implies({remote:!0}),ii=new Ee("--wait-timeout <waitTimeout>","The maximum number of seconds to wait for tests to complete. Only applicable when the --wait option is specified."),ai=new Ee("--custom-headers <customHeaders...>","Specify custom headers in the form HEADER=VALUE to be sent with each request during the test. Multiple entries can be provided.");function li(r){if(r===void 0)return;let e={};for(let t of r){let n=t.indexOf("=");if(n===-1)throw new Error(`Header value pair does not contain '=': ${t}`);let o=t.slice(0,n),s=t.slice(n+1);pf(o,s),e[o]=s}return e}var ci=new Ee("--no-report","Skip reporting test results to Momentic Cloud when running with the --local flag.").implies({local:!0}),di=new Ee("--pixel-ratio <pixelRatio>","Device pixel ratio of your screen or monitor. Mac OS Retina displays and machines marketed as 'HiDPI' should set this to 2. Visit https://www.mydevice.io/ to find your device's pixel ratio."),Sd=new Ee("--port <port>",`Port to run the app on. Defaults to ${_o}.`),wd=new Ee("--input-csv <inputCsv>","Path to a CSV file on disk where each row represents a set of inputs that will be made available to all tests that are ran. Only applicable when running locally. The first line of the CSV must be the input names."),ui=new Ee("--env <env>","Name of the environment to use when running tests."),mi=new Ee("--url-override <urlOverride>","Fully qualified url (e.g. https://www.google.com) to start all tests from. Overrides any default starting url set from the test or environment."),pi=new Ee("-a, --all","Select all tests in your organization from Momentic Cloud. Cannot be used together with <tests> arguments."),gi=new Ee("-a, --all","Select all environments in your organization from Momentic Cloud. Cannot be used together with <paths> arguments."),bd=new An("<tests...>",`One or more test paths to pull from Momentic Cloud.
|
|
1782
|
+
`)}`}getControllerFixtures(e){return{ctx:e??null,browser:this.browser,generator:this.generator,logger:this.logger,orgId:this.orgId,flagStore:this.flagStore,storage:this.storage,localCodeEvalTools:this.localCodeEvalTools}}async executeCommand(e,t,n,o=!1){let s=this.commandHistory[this.commandHistory.length-1];if(!o&&(!s||s.state!=="PENDING"))throw new I("InternalWebAgentError","Executing command but there is no pending entry in the history");if(this.closed)throw new Error("Attempting to execute command on a closed controller");let i=Date.now(),a=await this.executePresetStep(null,e,t,n),l=Date.now()-i;return this.logger.debug({result:a,duration:l},"Got execution result"),a.succeedImmediately&&!o&&(this.pendingInstructions.pop(),this.pendingInstructions.length>0&&(a.succeedImmediately=!1)),a.elementInteracted&&"target"in e&&e.target&&e.target.type==="description"&&!e.target.elementDescriptor&&(e.target.elementDescriptor=a.elementInteracted.trim()),o||(s.generatedStep=e,s.serializedCommand=Wt(e),s.state="DONE"),a}async wrapMultiElementTargetingCommand(e,t,n,o,s,i,a=1){let l=await Promise.all(n.map((c,u)=>this.wrapElementTargetingCommand({ctx:e,target:c,cache:o[u],action:async d=>d,options:{...i,targetName:t[u]}})));try{return{result:await s(...l.map(u=>u.result)),caches:l.map(u=>u.cache),elementInteractedDisplayStrings:l.map(u=>u.elementInteractedDisplayString)}}catch(c){if(a>0)return this.logger.debug({err:c},"Failed to execute action with multiple cached targets, retrying with AI"),this.wrapMultiElementTargetingCommand(e,t,n,n.map(()=>{}),s,i,a-1);throw new I("ActionFailureError",c.message,{cause:c})}}async wrapElementTargetingCommand(e){return Ht({action:()=>this.wrapElementTargetingCommandHelper(e),frameUrl:e.options.iframeUrl,browser:this.browser,logger:this.logger})}async wrapElementTargetingCommandHelper({ctx:e,target:t,cache:n,action:o,options:s}){let{disableCache:i,useSelector:a,targetName:l="target",targetHealingInProgress:c}=s,u=s.retriesWithAI??1,d=!1;if((!n||i)&&!Xs(t))throw new I("ActionFailureError","Cannot target element with no cached data or element descriptor");if(a){if(t.type!=="description")throw new I("ActionFailureError","Cannot use selector along with non-description target");let p={id:-1,selector:t.elementDescriptor,targetSource:"USER_CSS_SELECTOR",targetUpdateTime:new Date().toUTCString()},f=await this.browser.resolveTarget(e,p,{targetName:l});return{result:await o(f.locator),cache:p,elementInteractedDisplayString:f.displayString}}i&&(this.logger.debug("Cache explicitly disabled for this step"),d=!0,n=void 0),n?.inputDescription&&t.elementDescriptor!==n.inputDescription&&(this.logger.debug({old:n.inputDescription,new:t.elementDescriptor},"Target cache was generated with a different description, clearing it automatically"),d=!0,n=void 0);let m=!!n&&yo(n);if(!n){this.logger.debug({targetHealingInProgress:c},"Prompting AI for an updated element location"),d&&await K(this.browser.smartWaitingTimeout);let p=await qi({description:t.elementDescriptor,disableCache:i,iframeUrl:s.iframeUrl},this.getControllerFixtures(e));u--;let f=await o(p.resolution.locator);return c&&(p.target={...p.target,targetSource:"AI_HEALED",targetUpdateTime:new Date().toUTCString()}),{result:f,cache:p.target,thoughts:p.thoughts,elementInteractedDisplayString:p.resolution.displayString}}try{let p=await this.browser.resolveTarget(e,n,{targetName:l}),f=await o(p.locator);return m?this.logger.debug({cache:n},"Successfully used cached target to perform action"):this.logger.debug({cache:n},"Successfully generated and used new target data"),{result:f,cache:n,thoughts:void 0,elementInteractedDisplayString:p.displayString}}catch(p){if(p instanceof I)throw p;if(u>0&&t)return this.logger.debug({err:p,cache:n},"Failed to execute action with cached target, retrying with AI"),this.wrapElementTargetingCommand({ctx:e,target:t,cache:void 0,action:o,options:{...s,retriesWithAI:u,targetHealingInProgress:!0}});throw new I("ActionFailureError",p.message,{cause:p})}}async screenshotWithDimensions(e){return Gr(this.browser,e)}async executePresetStep(e,t,n,o,s){let i;try{i=await this.resolveCommandTemplateStrings(t,n)}catch(a){throw new I("ActionFailureError",a.message,{cause:a})}try{let a=await this.browser.getOpenPageUrls(),l=this.browser.url(),c=await this.executePresetActionHelper(e,t,n,o,s),u=!0;(t.type==="NAVIGATE"||t.type==="NEW_TAB"||t.type==="TAB"||t.type==="REFRESH")&&(u=!1);let d=await this.browser.getOpenPageUrls(),m=this.browser.url();if(u&&d.length!==a.length)for(let p=d.length-1;p>=0;p--){let f=d[p];if(dn(f,this.logger)&&f!==l&&f!==m){await this.browser.switchToPage(f,p);break}}return c}catch(a){throw this.logger.error({err:a},"Error thrown in action controller"),a}finally{this.restoreCommandTemplateReplacements(t,i)}}restoreCommandTemplateReplacements(e,t={}){for(let[n,o]of Object.entries(t))Gi(e,n,o)}async resolveCommandTemplateStrings(e,t,n="",o={}){let s=["type","a11yData","thoughts","cache"];for(let i in e){if(s.includes(i))continue;let a=e[i],l=n?`${n}.${i}`:i;if(typeof a=="string"&&a.includes("{{")){let c=await Ze({s:a,context:t,logger:this.logger,localTools:this.localCodeEvalTools});if(a===c)continue;o[l]=a,e[i]=c}else typeof a=="object"&&a!==null&&!Array.isArray(a)&&await this.resolveCommandTemplateStrings(a,t,l,o)}return o}async executePresetActionHelper(e,t,n,o,s){if(o=o||"disableCache"in t&&!!t.disableCache,s?.())throw new st("Execution cancelled by user");switch(t.type){case"SUCCESS":let i=t.condition;return i?.assertion.trim()?Ki({command:i,fixtures:this.getControllerFixtures(e)}):{succeedImmediately:!1,urlAfterCommand:this.browser.url()};case"AI_WAIT":case"AI_ASSERTION":{if(!t.assertion.trim())throw new I("ActionFailureError","Missing assertion");if(t.timeout&&t.timeout>1800)throw new I("AssertionFailureError",`AI assertion timeout of ${t.timeout} exceeds the maximum allowed value of 30 minutes.`);return Ki({command:{...t,type:"AI_ASSERTION"},fixtures:this.getControllerFixtures(e),opts:{isExecutionCancelled:s}})}case"AI_EXTRACT":{if(!t.goal.trim())throw new I("ActionFailureError","Cannot perform AI extraction without goal");let h=await this.browser.getCondensedHtml(),g=await this.generator.getTextExtraction({goal:t.goal,browserState:h,returnSchema:t.schema},{disableCache:o,orgId:this.orgId});if(g.result==="NOT_FOUND")throw new I("ActionFailureError","No relevant data found for extraction goal on this page");return{data:g.result,succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"NAVIGATE":if(!Vo(t.url)&&!qo(t.url,this.browser.baseUrl))throw new I("ActionFailureError",`Invalid URL provided to navigate command: ${t.url}`);await this.browser.navigate({url:t.url,loadTimeoutMs:t.loadTimeout?t.loadTimeout*1e3:void 0});break;case"DIALOG":this.browser.registerDialogHandler(t.action);break;case"CAPTCHA":if(!this.browser.canSolveCaptchas())break;let a=await this.browser.solveCaptcha();a&&(await this.wrapElementTargetingCommand({ctx:e,target:{type:"description",elementDescriptor:"the captcha image solution input"},cache:void 0,action:h=>this.browser.click(h,{}),options:{disableCache:o,useSelector:!!t.useSelector,iframeUrl:t.iframeUrl}}),await this.browser.type(a,{clearContent:!0,pressKeysSequentially:!1,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":if(t.target&&!xt(t.target))throw new Error("Scroll with x/y is not supported yet");let l,c;if(t.target&&t.target.elementDescriptor.trim()){let{cache:h,thoughts:g,elementInteractedDisplayString:y}=await this.wrapElementTargetingCommand({ctx:e,target:t.target,cache:t.cache?.target,action:S=>this.browser.hover(S,!1),options:{disableCache:o,useSelector:!!t.useSelector,iframeUrl:t.iframeUrl}});l=y,h&&(t.cache={target:h}),c=g}switch(t.type){case"SCROLL_UP":await this.browser.scrollUp(t.deltaY);break;case"SCROLL_DOWN":await this.browser.scrollDown(t.deltaY);break;case"SCROLL_LEFT":await this.browser.scrollLeft(t.deltaX);break;case"SCROLL_RIGHT":await this.browser.scrollRight(t.deltaX);break}return{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:l,thoughts:c};case"WAIT_FOR_URL":if(t.timeout&&t.timeout>1800)throw new I("UserConfigurationError",`WAIT_FOR_URL timeout of ${t.timeout} exceeds the maximum allowed value of 30 minutes.`);await this.browser.waitForUrl(this.browser.url(),t.url,void 0,t.timeout?t.timeout*1e3:void 0);break;case"WAIT":if(t.delay>1800)throw new I("UserConfigurationError",`User requested to wait for ${t.delay} seconds, which exceeds the maximum allowed time of 30 minutes`);let u=t.delay*1e3;await K(u,s);break;case"REFRESH":await this.browser.refresh({loadTimeoutMs:t.loadTimeout?t.loadTimeout*1e3:void 0});break;case"CLICK":{let h=jd.parse(t);if(Jt(t.target)){await this.browser.clickUsingVisualCoordinates(t.target.percentXYLocation,h);break}let g=this.browser.url(),y={disableCache:o,useSelector:!!t.useSelector,iframeUrl:t.iframeUrl},{elementInteractedDisplayString:S,cache:b,thoughts:C,result:v}=await this.wrapElementTargetingCommand({ctx:e,target:t.target,cache:t.cache?.target,action:P=>this.browser.click(P,Kd(this.orgId),h),options:y});b&&(t.cache={target:b});let E={urlAfterCommand:this.browser.url(),succeedImmediately:!1,elementInteracted:S,thoughts:C,data:v};return Ur(g,E.urlAfterCommand)&&(E.succeedImmediately=!0,E.succeedImmediatelyReason="URL changed"),E}case"DRAG":{if(Jt(t.fromTarget)&&Jt(t.toTarget)){await this.browser.dragAndDropUsingVisualCoordinates(t.fromTarget.percentXYLocation,t.toTarget.percentXYLocation,{force:t.force,hoverSeconds:t.hoverSeconds});break}if(Jt(t.fromTarget)||Jt(t.toTarget))throw new Error("Drag and drop targets must be both coordinates or both descriptions");let{caches:h,elementInteractedDisplayStrings:g}=await this.wrapMultiElementTargetingCommand(e,["from target","to target"],[t.fromTarget,t.toTarget],[t.cache?.fromTarget,t.cache?.toTarget],(y,S)=>this.browser.dragAndDrop(y,S,{force:t.force,hoverSeconds:t.hoverSeconds}),{useSelector:!!t.useSelector,disableCache:o});return h&&h.every(y=>y)&&(t.cache={fromTarget:h[0],toTarget:h[1]}),{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:g[0]}}case"MOUSE_DRAG":{if(t.target&&!xt(t.target))throw new Error("Scroll with x/y is not supported yet");let h,g,y;if(t.target?.elementDescriptor){let{cache:C,thoughts:v,elementInteractedDisplayString:E,result:P}=await this.wrapElementTargetingCommand({ctx:e,target:t.target,cache:t.cache?.target,action:async A=>A,options:{useSelector:!!t.useSelector,iframeUrl:t.iframeUrl,disableCache:o}});h=P,g=E,y=v,C&&(t.cache={target:C})}let S=parseInt(t.deltaX),b=parseInt(t.deltaY);if(isNaN(S)||isNaN(b))throw new I("ActionFailureError",`Invalid pixel values passed to mouse drag command: (${t.deltaX}, ${t.deltaY})`);return await this.browser.mouseDrag(S,b,t.steps,h,{force:t.force}),{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:g,thoughts:y}}case"SELECT_OPTION":{if(!xt(t.target))throw new Error("Select with x/y is not supported yet");let h=t.target.elementDescriptor,{cache:g,thoughts:y,elementInteractedDisplayString:S}=await this.wrapElementTargetingCommand({ctx:e,target:{type:"description",elementDescriptor:Or(t,h)},cache:t.cache?.target,action:b=>this.browser.selectOption(b,t.option,t.force),options:{disableCache:o,useSelector:!!t.useSelector,iframeUrl:t.iframeUrl}});return g&&(t.cache={target:g}),{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:S,thoughts:y}}case"TAB":await this.browser.switchToPage(t.url,void 0,{loadTimeoutMs:t.loadTimeout?t.loadTimeout*1e3:void 0});break;case"NEW_TAB":await this.browser.createNewTab(t.url,{loadTimeoutMs:t.loadTimeout?t.loadTimeout*1e3:void 0});break;case"COOKIE":if(!t.value)break;let d=await this.browser.setCookie(t.value);this.logger.debug({results:d},"Set cookies");break;case"LOCAL_STORAGE":if(!t.value||!t.key)break;await this.browser.setLocalStorage(t.key,t.value);break;case"JAVASCRIPT":{let h;try{t.environment==="BROWSER"?h=await this.browser.evaluateCodeInPage({code:t.code,fragment:t.fragment??!1,context:n.toObjectCopy(),timeoutMs:t.timeout?t.timeout*1e3:void 0}):h=await Bn({code:t.code,fragment:!!t.fragment,context:n,timeoutMs:t.timeout?t.timeout*1e3:void 0,logger:this.logger,localTools:this.localCodeEvalTools})}catch(g){throw new I("ActionFailureError",g instanceof Error?g.message:`${g}`,{cause:g})}try{JSON.stringify(h)}catch(g){throw new I("ActionFailureError",`Return value is not serializable: ${g instanceof Error?g.message:`${g}`}`,{cause:g})}return{urlAfterCommand:this.browser.url(),succeedImmediately:!1,data:h}}case"TYPE":{let h=this.browser.url(),g,y,S=by(t.target);if(S){S.elementDescriptor=Or(t,S.elementDescriptor);let{elementInteractedDisplayString:C,cache:v,thoughts:E}=await this.wrapElementTargetingCommand({ctx:e,target:S,cache:t.cache?.target,action:P=>this.browser.typeIntoTarget(t.value,P,{force:t.force,clearContent:t.clearContent,pressKeysSequentially:t.pressKeysSequentially,pressEnter:t.pressEnter}),options:{disableCache:o,useSelector:!!t.useSelector,iframeUrl:t.iframeUrl}});y=E,g=C,v&&(t.cache={target:v})}else await this.browser.type(t.value,{force:t.force,clearContent:t.clearContent,pressKeysSequentially:t.pressKeysSequentially,pressEnter:t.pressEnter},!0);let b={urlAfterCommand:this.browser.url(),succeedImmediately:!1,elementInteracted:g,thoughts:y};return Ur(h,b.urlAfterCommand)&&(b.succeedImmediately=!0,b.succeedImmediatelyReason="URL changed"),b}case"HOVER":{if(Jt(t.target)){await this.browser.hoverUsingVisualCoordinates(t.target.percentXYLocation);break}let{cache:h,thoughts:g,elementInteractedDisplayString:y}=await this.wrapElementTargetingCommand({ctx:e,target:t.target,cache:t.cache?.target,action:S=>this.browser.hover(S,!!t.force),options:{disableCache:o,useSelector:!!t.useSelector,iframeUrl:t.iframeUrl}});return h&&(t.cache={target:h}),{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:y,thoughts:g}}case"FOCUS":{if(!xt(t.target))throw new Error("Focus with x/y is not supported yet");let{elementInteractedDisplayString:h,cache:g,thoughts:y}=await this.wrapElementTargetingCommand({ctx:e,target:t.target,cache:t.cache?.target,action:S=>this.browser.focus(S),options:{disableCache:o,useSelector:!!t.useSelector,iframeUrl:t.iframeUrl}});return g&&(t.cache={target:g}),{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:h,thoughts:y}}case"BLUR":{if(!xt(t.target))throw new Error("Blur with x/y is not supported yet");let{cache:h,thoughts:g,elementInteractedDisplayString:y}=await this.wrapElementTargetingCommand({ctx:e,target:t.target,cache:t.cache?.target,action:S=>this.browser.blur(S),options:{disableCache:o,useSelector:!!t.useSelector,iframeUrl:t.iframeUrl}});return h&&(t.cache={target:h}),{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:y,thoughts:g}}case"PRESS":let m=this.browser.url();await this.browser.press(t.value);let p={urlAfterCommand:this.browser.url(),succeedImmediately:!1};return Ur(m,p.urlAfterCommand)&&(p.succeedImmediately=!0,p.succeedImmediatelyReason="URL changed"),p;case"REQUEST":return Qd({command:t,browser:this.browser,logger:this.logger});case"VISUAL_DIFF":return Zd({ctx:e,command:t,disableCache:o,browser:this.browser,logger:this.logger,targetingWrapper:h=>this.wrapElementTargetingCommand(h)});case"FILE_UPLOAD":{let h=t.fileSource.url;if(!h.startsWith("http")&&!h.startsWith(jr))throw new I("UserConfigurationError","The source URI for the file upload step must be a valid URL or a previously downloaded file beginning with 'file://'");let g=await xd({uri:h,logger:this.logger,orgId:this.orgId});await this.browser.setFileChooserHandler(g);break}case"AUTH_SAVE":return{data:await this.browser.saveAuthState(),succeedImmediately:!1,urlAfterCommand:this.browser.url()};case"AUTH_LOAD":{let h=await Bn({code:t.storageState,fragment:!1,context:n,logger:this.logger,localTools:this.localCodeEvalTools});if(typeof h!="object")throw new I("ActionFailureError",`Credentials must evaluate to an object (received ${typeof h} instead)`);let g;try{g=El.parse(h)}catch(y){throw new I("ActionFailureError",`Credentials provided do not follow the required format: ${y}`)}await this.browser.loadAuthState(g);break}case"ELEMENT_CHECK":{if(t.target&&!xt(t.target))throw new Error("Element assertion with x/y is not supported yet");let h=Date.now(),g=(t.timeout??Zt)*1e3,y=0,S;for(;y<2||Date.now()-h<g;){y++;try{let{cache:b,thoughts:C,elementInteractedDisplayString:v}=await this.wrapElementTargetingCommand({ctx:e,target:t.target,cache:t.cache?.target,action:async E=>{await Yd({assertion:t.assertion,element:E,callbacks:{highlightTarget:async P=>this.browser.highlightTarget(P)}})},options:{disableCache:o,useSelector:!!t.useSelector,iframeUrl:t.iframeUrl}});return b&&(t.cache={target:b}),{succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:v,thoughts:C}}catch(b){if(S=b,t.assertion.type==="ELEMENT_EXISTENCE"&&t.assertion.negated)return{succeedImmediately:!1,urlAfterCommand:this.browser.url()}}}throw new I("AssertionFailureError",`Element check still failing after ${Math.floor((Date.now()-h)/1e3)} seconds: ${S?S.message:""}`)}case"PAGE_CHECK":{await Ht({frameUrl:t.iframeUrl,browser:this.browser,logger:this.logger,action:async()=>Xd({assertion:t.assertion,page:await this.browser.getActivePageOrFrame(),logger:this.logger,timeout:t.timeout})});break}default:return(h=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(t)}return{succeedImmediately:!1,urlAfterCommand:this.browser.url()}}async getReverseMappedTarget(e,t,n){return(await this.generator.getReverseMappedDescription({browserState:e.browserState,goal:`${t}`},{disableCache:n,orgId:this.orgId})).phrase}async stopRecordMode(){this.recordAbortController?.abort(),await this.browser.clearAllCdpHighlights()}async startRecordMode(e){this.recordAbortController=new AbortController;let t=new ss({signal:this.recordAbortController.signal,...e});return await this.browser.startRecording(this.recordAbortController.signal,t),t}async runSectionAutohealing(e){return this.generator.getAutohealingProposal(e,{disableCache:!0,orgId:this.orgId})}};var Ty=4;async function eu({socket:r,logger:e,storage:t,devicePixelRatio:n,generator:o,browserbase:s,authorization:i}){let a=r.id,l=r.handshake.query.testId,c=r.handshake.query.baseUrl,u=r.handshake.query.envName,d=r.handshake.query.viewport?JSON.parse(decodeURIComponent(r.handshake.query.viewport)):void 0,m=pe.parse(JSON.parse(decodeURIComponent(r.handshake.query.testMetadata)));if(!l||!c)throw new Error("Socket connection request is missing testId or baseUrl");let p=await t.getOrgId(l);e=e.child({testId:l,baseUrl:c,orgId:p});let f=r.handshake.query.environmentVariables?JSON.parse(decodeURIComponent(r.handshake.query.environmentVariables)):{};if(await Promise.all((m.parameters??[]).map(async S=>{let b=await Ze({s:S.defaultValue,context:le.dummyContext(u,f),logger:e,localTools:y});f[S.name]=b})),_.getSession(a))return e.info("Associating connection with existing session (likely reconnect)"),{sessionId:a,orgId:p,testId:l};let g=r.handshake.headers["x-forwarded-for"]?.split(",")[0];if(e.info({clientIp:g,event:"connect",args:r.handshake.query},"Websocket event (connect)"),g&&_.getCurrentConnectionsByIp(g)>=Ty)throw e.error({clientIp:g,sessions:_.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 retry or contact Momentic support if you believe this is in error.");_.reserveCapacityByIp(g);let y;i?.type==="API_KEY"&&(y=new Lt(i));try{await vy({socket:r,baseUrl:c,envName:u,viewport:d,testMetadata:m,orgId:p,sessionId:a,logger:e,environmentVariables:f,clientIp:g,devicePixelRatio:n,storage:t,localCodeEvalTools:y,generator:o,browserbase:s})}catch(S){throw e.warn({err:S},"Error setting up socket session, possibly due to client closing the connection"),_.releaseCapacityByIp(g),S}return{sessionId:a,testId:l,orgId:p}}async function vy({socket:r,baseUrl:e,viewport:t,envName:n,devicePixelRatio:o,testMetadata:s,orgId:i,sessionId:a,logger:l,storage:c,localCodeEvalTools:u,generator:d,environmentVariables:m,clientIp:p}){let f={};t&&(f.viewport=t),o&&(f.deviceScaleFactor=o);let h=Rr.parse(s?.advanced??{}),[g,y]=await Promise.all([Mt.init({baseUrl:e,userBrowserSettings:h,waitForLoad:!0,enricher:new rs(l),timeout:h.pageLoadTimeoutMs,storage:c,logger:l,contextArgs:f,onTabsChange:(E,P)=>{r.emit("tabs",{tabs:E,activeTab:P})}}),Hn.init(i)]),S=new Gn({browser:g,generator:d,config:os,logger:l,flagStore:y,orgId:i,storage:c,localCodeEvalTools:u}),b=Oc(r,a,l),C=async()=>{clearInterval(b.timer)},v=new le({baseUrl:e,currentUrl:S.browser.url(),variablesFromEnvironment:m,envName:n});if(!r.connected)throw await g.cleanup(),new Error("Socket not connected anymore, not proceeding with session setup");r.emit("session",{url:e,userAgent:Mt.USER_AGENT,viewport:await S.browser.getViewport(),sessionId:a}),_.registerSession({controller:S,context:v,sessionId:a,cleanup:C,clientIp:p})}var tu=[Mc,qc,Kc,Bd,Lc,Wd,zd,Xc,Qc,ed,Jc,Yc,td,Zc];var nu=r=>{let{logger:e}=r,t=new Ey(r.baseServer,{cors:{origin:"*",methods:["GET","POST"]},pingTimeout:3e4,pingInterval:6e4,maxHttpBufferSize:1e7});return t.on("connection",async n=>{let o=e.child({socketId:n.id}),s;try{o.info({event:"connection",transport:n.conn.transport.name},"Websocket connection established"),s=await eu({...r,socket:n,logger:o}),o=o.child(s)}catch(i){o.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}tu.forEach(i=>xy(i,{socket:n,metadata:s,...r,logger:o}))}),t},xy=(r,e)=>{let t=r.createHandler(e),n=(...o)=>{["cloudMouseMove","cloudScroll","cloudType"].includes(r.event)||e.logger.debug({...e.metadata,event:r.event,args:o},`Websocket event (${r.event})`);let s=i=>{e.logger.error({event:r.event,type:"websocket",args:o,err:i instanceof Error?i:new Error(`${i}`)},"Unhandled exception in socket handler"),e.socket.emit("error",{message:i instanceof Error?i.message:`${i}`})};try{let i=t.apply(void 0,o);i&&typeof i.catch=="function"&&i.catch(s)}catch(i){s(i)}};e.socket.on(r.event,n)};import{z as Iy}from"zod";import Ay from"fetch-retry";var Ry=Ay(global.fetch),he=class{static API_VERSION="v1";baseURL;apiKey;constructor(e){this.baseURL=e.baseURL,this.apiKey=e.apiKey}async sendRequest(e,t){let n=await Ry(`${this.baseURL}${e}`,{retries:1,retryDelay:1e3,method:"POST",body:JSON.stringify(t),headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`}});if(!n.ok)throw new Error(`Request to ${e} failed with status ${n.status}: ${await n.text()}`);return n.json()}};var Vn=class extends he{constructor(e){super(e)}async getRecommendedChunks(e){let t=await this.sendRequest(`/${he.API_VERSION}/web-agent/recommend-chunks`,e);return gl.parse(t)}async getScreenshotFromS3(e){let t=await this.sendRequest(`/${he.API_VERSION}/s3/visual-diff-screenshot`,{url:e});return Iy.string().parse(t)}async getElementLocation(e,t){let n=await this.sendRequest(`/${he.API_VERSION}/web-agent/locate-element`,{...e,disableCache:t.disableCache});return Ul.parse(n)}async getAssertionResult(e,t){let n={...e,disableCache:!!t.disableCache},o=await this.sendRequest(`/${he.API_VERSION}/web-agent/assertion`,{...n,history:"",numPrevious:0,lastCommand:null});return Fl.parse(o)}async getProposedCommand(e,t){let n=await this.sendRequest(`/${he.API_VERSION}/web-agent/next-command`,{url:e.url,browserState:e.browserState,goal:e.goal,history:e.history,numPrevious:e.numPrevious,lastCommand:e.lastCommand,screenshot:e.screenshot,disableCache:t.disableCache});return Dl.parse(n)}async getGranularGoals(e,t){let n=await this.sendRequest(`/${he.API_VERSION}/web-agent/split-goal`,{url:e.url,goal:e.goal,disableCache:t.disableCache});return $l.parse(n)}async getReverseMappedDescription(e,t){let n=await this.sendRequest(`/${he.API_VERSION}/web-agent/reverse-mapped-description`,{goal:e.goal,browserState:e.browserState,disableCache:t.disableCache});return Bl.parse(n)}async getTextExtraction(e,t){let n={goal:e.goal,browserState:e.browserState,returnSchema:e.returnSchema,disableCache:t.disableCache},o=await this.sendRequest(`/${he.API_VERSION}/web-agent/text-extraction`,n);return gi.parse(o)}async getTestResultClassification(e){let t=await this.sendRequest(`/${he.API_VERSION}/web-agent/result-classification`,e);return pi.parse(t)}async getExtractedKeywords(e,t){let n=await this.sendRequest(`/${he.API_VERSION}/web-agent/extract-keywords`,{goal:e,disableCache:t.disableCache});return bl.parse(n)}async getAutohealingProposal(e,t){let n=await this.sendRequest(`/${he.API_VERSION}/web-agent/autoheal-section`,e);return fl.parse(n)}};import{Router as Sw}from"express";import Ut from"fs";import hn from"path";import co from"yaml";import em from"fs";var vu=lp(fu(),1);var qr=r=>{if(typeof r!="string")throw new TypeError("invalid pattern");if(r.length>65536)throw new TypeError("pattern is too long")};var Dy={"[:alnum:]":["\\p{L}\\p{Nl}\\p{Nd}",!0],"[:alpha:]":["\\p{L}\\p{Nl}",!0],"[:ascii:]":["\\x00-\\x7f",!1],"[:blank:]":["\\p{Zs}\\t",!0],"[:cntrl:]":["\\p{Cc}",!0],"[:digit:]":["\\p{Nd}",!0],"[:graph:]":["\\p{Z}\\p{C}",!0,!0],"[:lower:]":["\\p{Ll}",!0],"[:print:]":["\\p{C}",!0],"[:punct:]":["\\p{P}",!0],"[:space:]":["\\p{Z}\\t\\r\\n\\v\\f",!0],"[:upper:]":["\\p{Lu}",!0],"[:word:]":["\\p{L}\\p{Nl}\\p{Nd}\\p{Pc}",!0],"[:xdigit:]":["A-Fa-f0-9",!1]},Kr=r=>r.replace(/[[\]\\-]/g,"\\$&"),Fy=r=>r.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),gu=r=>r.join(""),yu=(r,e)=>{let t=e;if(r.charAt(t)!=="[")throw new Error("not in a brace expression");let n=[],o=[],s=t+1,i=!1,a=!1,l=!1,c=!1,u=t,d="";e:for(;s<r.length;){let h=r.charAt(s);if((h==="!"||h==="^")&&s===t+1){c=!0,s++;continue}if(h==="]"&&i&&!l){u=s+1;break}if(i=!0,h==="\\"&&!l){l=!0,s++;continue}if(h==="["&&!l){for(let[g,[y,S,b]]of Object.entries(Dy))if(r.startsWith(g,s)){if(d)return["$.",!1,r.length-t,!0];s+=g.length,b?o.push(y):n.push(y),a=a||S;continue e}}if(l=!1,d){h>d?n.push(Kr(d)+"-"+Kr(h)):h===d&&n.push(Kr(h)),d="",s++;continue}if(r.startsWith("-]",s+1)){n.push(Kr(h+"-")),s+=2;continue}if(r.startsWith("-",s+1)){d=h,s+=2;continue}n.push(Kr(h)),s++}if(u<s)return["",!1,0,!1];if(!n.length&&!o.length)return["$.",!1,r.length-t,!0];if(o.length===0&&n.length===1&&/^\\?.$/.test(n[0])&&!c){let h=n[0].length===2?n[0].slice(-1):n[0];return[Fy(h),!1,u-t,!1]}let m="["+(c?"^":"")+gu(n)+"]",p="["+(c?"":"^")+gu(o)+"]";return[n.length&&o.length?"("+m+"|"+p+")":n.length?m:p,a,u-t,!0]};var at=(r,{windowsPathsNoEscape:e=!1}={})=>e?r.replace(/\[([^\/\\])\]/g,"$1"):r.replace(/((?!\\).|^)\[([^\/\\])\]/g,"$1$2").replace(/\\([^\/])/g,"$1");var Uy=new Set(["!","?","+","*","@"]),Su=r=>Uy.has(r),$y="(?!(?:^|/)\\.\\.?(?:$|/))",ds="(?!\\.)",By=new Set(["[","."]),zy=new Set(["..","."]),Wy=new Set("().*{}+?[]^$\\!"),Hy=r=>r.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),Qi="[^/]",wu=Qi+"*?",bu=Qi+"+?",qn=class r{type;#e;#t;#s=!1;#r=[];#i;#b;#c;#u=!1;#a;#l;#o=!1;constructor(e,t,n={}){this.type=e,e&&(this.#t=!0),this.#i=t,this.#e=this.#i?this.#i.#e:this,this.#a=this.#e===this?n:this.#e.#a,this.#c=this.#e===this?[]:this.#e.#c,e==="!"&&!this.#e.#u&&this.#c.push(this),this.#b=this.#i?this.#i.#r.length:0}get hasMagic(){if(this.#t!==void 0)return this.#t;for(let e of this.#r)if(typeof e!="string"&&(e.type||e.hasMagic))return this.#t=!0;return this.#t}toString(){return this.#l!==void 0?this.#l:this.type?this.#l=this.type+"("+this.#r.map(e=>String(e)).join("|")+")":this.#l=this.#r.map(e=>String(e)).join("")}#g(){if(this!==this.#e)throw new Error("should only call on root");if(this.#u)return this;this.toString(),this.#u=!0;let e;for(;e=this.#c.pop();){if(e.type!=="!")continue;let t=e,n=t.#i;for(;n;){for(let o=t.#b+1;!n.type&&o<n.#r.length;o++)for(let s of e.#r){if(typeof s=="string")throw new Error("string part in extglob AST??");s.copyIn(n.#r[o])}t=n,n=t.#i}}return this}push(...e){for(let t of e)if(t!==""){if(typeof t!="string"&&!(t instanceof r&&t.#i===this))throw new Error("invalid part: "+t);this.#r.push(t)}}toJSON(){let e=this.type===null?this.#r.slice().map(t=>typeof t=="string"?t:t.toJSON()):[this.type,...this.#r.map(t=>t.toJSON())];return this.isStart()&&!this.type&&e.unshift([]),this.isEnd()&&(this===this.#e||this.#e.#u&&this.#i?.type==="!")&&e.push({}),e}isStart(){if(this.#e===this)return!0;if(!this.#i?.isStart())return!1;if(this.#b===0)return!0;let e=this.#i;for(let t=0;t<this.#b;t++){let n=e.#r[t];if(!(n instanceof r&&n.type==="!"))return!1}return!0}isEnd(){if(this.#e===this||this.#i?.type==="!")return!0;if(!this.#i?.isEnd())return!1;if(!this.type)return this.#i?.isEnd();let e=this.#i?this.#i.#r.length:0;return this.#b===e-1}copyIn(e){typeof e=="string"?this.push(e):this.push(e.clone(this))}clone(e){let t=new r(this.type,e);for(let n of this.#r)t.copyIn(n);return t}static#y(e,t,n,o){let s=!1,i=!1,a=-1,l=!1;if(t.type===null){let p=n,f="";for(;p<e.length;){let h=e.charAt(p++);if(s||h==="\\"){s=!s,f+=h;continue}if(i){p===a+1?(h==="^"||h==="!")&&(l=!0):h==="]"&&!(p===a+2&&l)&&(i=!1),f+=h;continue}else if(h==="["){i=!0,a=p,l=!1,f+=h;continue}if(!o.noext&&Su(h)&&e.charAt(p)==="("){t.push(f),f="";let g=new r(h,t);p=r.#y(e,g,p,o),t.push(g);continue}f+=h}return t.push(f),p}let c=n+1,u=new r(null,t),d=[],m="";for(;c<e.length;){let p=e.charAt(c++);if(s||p==="\\"){s=!s,m+=p;continue}if(i){c===a+1?(p==="^"||p==="!")&&(l=!0):p==="]"&&!(c===a+2&&l)&&(i=!1),m+=p;continue}else if(p==="["){i=!0,a=c,l=!1,m+=p;continue}if(Su(p)&&e.charAt(c)==="("){u.push(m),m="";let f=new r(p,u);u.push(f),c=r.#y(e,f,c,o);continue}if(p==="|"){u.push(m),m="",d.push(u),u=new r(null,t);continue}if(p===")")return m===""&&t.#r.length===0&&(t.#o=!0),u.push(m),m="",t.push(...d,u),c;m+=p}return t.type=null,t.#t=void 0,t.#r=[e.substring(n-1)],c}static fromGlob(e,t={}){let n=new r(null,void 0,t);return r.#y(e,n,0,t),n}toMMPattern(){if(this!==this.#e)return this.#e.toMMPattern();let e=this.toString(),[t,n,o,s]=this.toRegExpSource();if(!(o||this.#t||this.#a.nocase&&!this.#a.nocaseMagicOnly&&e.toUpperCase()!==e.toLowerCase()))return n;let a=(this.#a.nocase?"i":"")+(s?"u":"");return Object.assign(new RegExp(`^${t}$`,a),{_src:t,_glob:e})}get options(){return this.#a}toRegExpSource(e){let t=e??!!this.#a.dot;if(this.#e===this&&this.#g(),!this.type){let l=this.isStart()&&this.isEnd(),c=this.#r.map(p=>{let[f,h,g,y]=typeof p=="string"?r.#m(p,this.#t,l):p.toRegExpSource(e);return this.#t=this.#t||g,this.#s=this.#s||y,f}).join(""),u="";if(this.isStart()&&typeof this.#r[0]=="string"&&!(this.#r.length===1&&zy.has(this.#r[0]))){let f=By,h=t&&f.has(c.charAt(0))||c.startsWith("\\.")&&f.has(c.charAt(2))||c.startsWith("\\.\\.")&&f.has(c.charAt(4)),g=!t&&!e&&f.has(c.charAt(0));u=h?$y:g?ds:""}let d="";return this.isEnd()&&this.#e.#u&&this.#i?.type==="!"&&(d="(?:$|\\/)"),[u+c+d,at(c),this.#t=!!this.#t,this.#s]}let n=this.type==="*"||this.type==="+",o=this.type==="!"?"(?:(?!(?:":"(?:",s=this.#p(t);if(this.isStart()&&this.isEnd()&&!s&&this.type!=="!"){let l=this.toString();return this.#r=[l],this.type=null,this.#t=void 0,[l,at(this.toString()),!1,!1]}let i=!n||e||t||!ds?"":this.#p(!0);i===s&&(i=""),i&&(s=`(?:${s})(?:${i})*?`);let a="";if(this.type==="!"&&this.#o)a=(this.isStart()&&!t?ds:"")+bu;else{let l=this.type==="!"?"))"+(this.isStart()&&!t&&!e?ds:"")+wu+")":this.type==="@"?")":this.type==="?"?")?":this.type==="+"&&i?")":this.type==="*"&&i?")?":`)${this.type}`;a=o+s+l}return[a,at(s),this.#t=!!this.#t,this.#s]}#p(e){return this.#r.map(t=>{if(typeof t=="string")throw new Error("string type in extglob ast??");let[n,o,s,i]=t.toRegExpSource(e);return this.#s=this.#s||i,n}).filter(t=>!(this.isStart()&&this.isEnd())||!!t).join("|")}static#m(e,t,n=!1){let o=!1,s="",i=!1;for(let a=0;a<e.length;a++){let l=e.charAt(a);if(o){o=!1,s+=(Wy.has(l)?"\\":"")+l;continue}if(l==="\\"){a===e.length-1?s+="\\\\":o=!0;continue}if(l==="["){let[c,u,d,m]=yu(e,a);if(d){s+=c,i=i||u,a+=d-1,t=t||m;continue}}if(l==="*"){n&&e==="*"?s+=bu:s+=wu,t=!0;continue}if(l==="?"){s+=Qi,t=!0;continue}s+=Hy(l)}return[s,at(e),!!t,i]}};var Kn=(r,{windowsPathsNoEscape:e=!1}={})=>e?r.replace(/[?*()[\]]/g,"[$&]"):r.replace(/[?*()[\]\\]/g,"\\$&");var Ne=(r,e,t={})=>(qr(e),!t.nocomment&&e.charAt(0)==="#"?!1:new $e(e,t).match(r)),jy=/^\*+([^+@!?\*\[\(]*)$/,Gy=r=>e=>!e.startsWith(".")&&e.endsWith(r),Vy=r=>e=>e.endsWith(r),qy=r=>(r=r.toLowerCase(),e=>!e.startsWith(".")&&e.toLowerCase().endsWith(r)),Ky=r=>(r=r.toLowerCase(),e=>e.toLowerCase().endsWith(r)),Yy=/^\*+\.\*+$/,Xy=r=>!r.startsWith(".")&&r.includes("."),Jy=r=>r!=="."&&r!==".."&&r.includes("."),Zy=/^\.\*+$/,Qy=r=>r!=="."&&r!==".."&&r.startsWith("."),eS=/^\*+$/,tS=r=>r.length!==0&&!r.startsWith("."),nS=r=>r.length!==0&&r!=="."&&r!=="..",rS=/^\?+([^+@!?\*\[\(]*)?$/,oS=([r,e=""])=>{let t=Eu([r]);return e?(e=e.toLowerCase(),n=>t(n)&&n.toLowerCase().endsWith(e)):t},sS=([r,e=""])=>{let t=xu([r]);return e?(e=e.toLowerCase(),n=>t(n)&&n.toLowerCase().endsWith(e)):t},iS=([r,e=""])=>{let t=xu([r]);return e?n=>t(n)&&n.endsWith(e):t},aS=([r,e=""])=>{let t=Eu([r]);return e?n=>t(n)&&n.endsWith(e):t},Eu=([r])=>{let e=r.length;return t=>t.length===e&&!t.startsWith(".")},xu=([r])=>{let e=r.length;return t=>t.length===e&&t!=="."&&t!==".."},Au=typeof process=="object"&&process?typeof process.env=="object"&&process.env&&process.env.__MINIMATCH_TESTING_PLATFORM__||process.platform:"posix",Cu={win32:{sep:"\\"},posix:{sep:"/"}},lS=Au==="win32"?Cu.win32.sep:Cu.posix.sep;Ne.sep=lS;var be=Symbol("globstar **");Ne.GLOBSTAR=be;var cS="[^/]",dS=cS+"*?",uS="(?:(?!(?:\\/|^)(?:\\.{1,2})($|\\/)).)*?",mS="(?:(?!(?:\\/|^)\\.).)*?",pS=(r,e={})=>t=>Ne(t,r,e);Ne.filter=pS;var Qe=(r,e={})=>Object.assign({},r,e),hS=r=>{if(!r||typeof r!="object"||!Object.keys(r).length)return Ne;let e=Ne;return Object.assign((n,o,s={})=>e(n,o,Qe(r,s)),{Minimatch:class extends e.Minimatch{constructor(o,s={}){super(o,Qe(r,s))}static defaults(o){return e.defaults(Qe(r,o)).Minimatch}},AST:class extends e.AST{constructor(o,s,i={}){super(o,s,Qe(r,i))}static fromGlob(o,s={}){return e.AST.fromGlob(o,Qe(r,s))}},unescape:(n,o={})=>e.unescape(n,Qe(r,o)),escape:(n,o={})=>e.escape(n,Qe(r,o)),filter:(n,o={})=>e.filter(n,Qe(r,o)),defaults:n=>e.defaults(Qe(r,n)),makeRe:(n,o={})=>e.makeRe(n,Qe(r,o)),braceExpand:(n,o={})=>e.braceExpand(n,Qe(r,o)),match:(n,o,s={})=>e.match(n,o,Qe(r,s)),sep:e.sep,GLOBSTAR:be})};Ne.defaults=hS;var Ru=(r,e={})=>(qr(r),e.nobrace||!/\{(?:(?!\{).)*\}/.test(r)?[r]:(0,vu.default)(r));Ne.braceExpand=Ru;var fS=(r,e={})=>new $e(r,e).makeRe();Ne.makeRe=fS;var gS=(r,e,t={})=>{let n=new $e(e,t);return r=r.filter(o=>n.match(o)),n.options.nonull&&!r.length&&r.push(e),r};Ne.match=gS;var Tu=/[?*]|[+@!]\(.*?\)|\[|\]/,yS=r=>r.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),$e=class{options;set;pattern;windowsPathsNoEscape;nonegate;negate;comment;empty;preserveMultipleSlashes;partial;globSet;globParts;nocase;isWindows;platform;windowsNoMagicRoot;regexp;constructor(e,t={}){qr(e),t=t||{},this.options=t,this.pattern=e,this.platform=t.platform||Au,this.isWindows=this.platform==="win32",this.windowsPathsNoEscape=!!t.windowsPathsNoEscape||t.allowWindowsEscape===!1,this.windowsPathsNoEscape&&(this.pattern=this.pattern.replace(/\\/g,"/")),this.preserveMultipleSlashes=!!t.preserveMultipleSlashes,this.regexp=null,this.negate=!1,this.nonegate=!!t.nonegate,this.comment=!1,this.empty=!1,this.partial=!!t.partial,this.nocase=!!this.options.nocase,this.windowsNoMagicRoot=t.windowsNoMagicRoot!==void 0?t.windowsNoMagicRoot:!!(this.isWindows&&this.nocase),this.globSet=[],this.globParts=[],this.set=[],this.make()}hasMagic(){if(this.options.magicalBraces&&this.set.length>1)return!0;for(let e of this.set)for(let t of e)if(typeof t!="string")return!0;return!1}debug(...e){}make(){let e=this.pattern,t=this.options;if(!t.nocomment&&e.charAt(0)==="#"){this.comment=!0;return}if(!e){this.empty=!0;return}this.parseNegate(),this.globSet=[...new Set(this.braceExpand())],t.debug&&(this.debug=(...s)=>console.error(...s)),this.debug(this.pattern,this.globSet);let n=this.globSet.map(s=>this.slashSplit(s));this.globParts=this.preprocess(n),this.debug(this.pattern,this.globParts);let o=this.globParts.map((s,i,a)=>{if(this.isWindows&&this.windowsNoMagicRoot){let l=s[0]===""&&s[1]===""&&(s[2]==="?"||!Tu.test(s[2]))&&!Tu.test(s[3]),c=/^[a-z]:/i.test(s[0]);if(l)return[...s.slice(0,4),...s.slice(4).map(u=>this.parse(u))];if(c)return[s[0],...s.slice(1).map(u=>this.parse(u))]}return s.map(l=>this.parse(l))});if(this.debug(this.pattern,o),this.set=o.filter(s=>s.indexOf(!1)===-1),this.isWindows)for(let s=0;s<this.set.length;s++){let i=this.set[s];i[0]===""&&i[1]===""&&this.globParts[s][2]==="?"&&typeof i[3]=="string"&&/^[a-z]:$/i.test(i[3])&&(i[2]="?")}this.debug(this.pattern,this.set)}preprocess(e){if(this.options.noglobstar)for(let n=0;n<e.length;n++)for(let o=0;o<e[n].length;o++)e[n][o]==="**"&&(e[n][o]="*");let{optimizationLevel:t=1}=this.options;return t>=2?(e=this.firstPhasePreProcess(e),e=this.secondPhasePreProcess(e)):t>=1?e=this.levelOneOptimize(e):e=this.adjascentGlobstarOptimize(e),e}adjascentGlobstarOptimize(e){return e.map(t=>{let n=-1;for(;(n=t.indexOf("**",n+1))!==-1;){let o=n;for(;t[o+1]==="**";)o++;o!==n&&t.splice(n,o-n)}return t})}levelOneOptimize(e){return e.map(t=>(t=t.reduce((n,o)=>{let s=n[n.length-1];return o==="**"&&s==="**"?n:o===".."&&s&&s!==".."&&s!=="."&&s!=="**"?(n.pop(),n):(n.push(o),n)},[]),t.length===0?[""]:t))}levelTwoFileOptimize(e){Array.isArray(e)||(e=this.slashSplit(e));let t=!1;do{if(t=!1,!this.preserveMultipleSlashes){for(let o=1;o<e.length-1;o++){let s=e[o];o===1&&s===""&&e[0]===""||(s==="."||s==="")&&(t=!0,e.splice(o,1),o--)}e[0]==="."&&e.length===2&&(e[1]==="."||e[1]==="")&&(t=!0,e.pop())}let n=0;for(;(n=e.indexOf("..",n+1))!==-1;){let o=e[n-1];o&&o!=="."&&o!==".."&&o!=="**"&&(t=!0,e.splice(n-1,2),n-=2)}}while(t);return e.length===0?[""]:e}firstPhasePreProcess(e){let t=!1;do{t=!1;for(let n of e){let o=-1;for(;(o=n.indexOf("**",o+1))!==-1;){let i=o;for(;n[i+1]==="**";)i++;i>o&&n.splice(o+1,i-o);let a=n[o+1],l=n[o+2],c=n[o+3];if(a!==".."||!l||l==="."||l===".."||!c||c==="."||c==="..")continue;t=!0,n.splice(o,1);let u=n.slice(0);u[o]="**",e.push(u),o--}if(!this.preserveMultipleSlashes){for(let i=1;i<n.length-1;i++){let a=n[i];i===1&&a===""&&n[0]===""||(a==="."||a==="")&&(t=!0,n.splice(i,1),i--)}n[0]==="."&&n.length===2&&(n[1]==="."||n[1]==="")&&(t=!0,n.pop())}let s=0;for(;(s=n.indexOf("..",s+1))!==-1;){let i=n[s-1];if(i&&i!=="."&&i!==".."&&i!=="**"){t=!0;let l=s===1&&n[s+1]==="**"?["."]:[];n.splice(s-1,2,...l),n.length===0&&n.push(""),s-=2}}}}while(t);return e}secondPhasePreProcess(e){for(let t=0;t<e.length-1;t++)for(let n=t+1;n<e.length;n++){let o=this.partsMatch(e[t],e[n],!this.preserveMultipleSlashes);if(o){e[t]=[],e[n]=o;break}}return e.filter(t=>t.length)}partsMatch(e,t,n=!1){let o=0,s=0,i=[],a="";for(;o<e.length&&s<t.length;)if(e[o]===t[s])i.push(a==="b"?t[s]:e[o]),o++,s++;else if(n&&e[o]==="**"&&t[s]===e[o+1])i.push(e[o]),o++;else if(n&&t[s]==="**"&&e[o]===t[s+1])i.push(t[s]),s++;else if(e[o]==="*"&&t[s]&&(this.options.dot||!t[s].startsWith("."))&&t[s]!=="**"){if(a==="b")return!1;a="a",i.push(e[o]),o++,s++}else if(t[s]==="*"&&e[o]&&(this.options.dot||!e[o].startsWith("."))&&e[o]!=="**"){if(a==="a")return!1;a="b",i.push(t[s]),o++,s++}else return!1;return e.length===t.length&&i}parseNegate(){if(this.nonegate)return;let e=this.pattern,t=!1,n=0;for(let o=0;o<e.length&&e.charAt(o)==="!";o++)t=!t,n++;n&&(this.pattern=e.slice(n)),this.negate=t}matchOne(e,t,n=!1){let o=this.options;if(this.isWindows){let h=typeof e[0]=="string"&&/^[a-z]:$/i.test(e[0]),g=!h&&e[0]===""&&e[1]===""&&e[2]==="?"&&/^[a-z]:$/i.test(e[3]),y=typeof t[0]=="string"&&/^[a-z]:$/i.test(t[0]),S=!y&&t[0]===""&&t[1]===""&&t[2]==="?"&&typeof t[3]=="string"&&/^[a-z]:$/i.test(t[3]),b=g?3:h?0:void 0,C=S?3:y?0:void 0;if(typeof b=="number"&&typeof C=="number"){let[v,E]=[e[b],t[C]];v.toLowerCase()===E.toLowerCase()&&(t[C]=v,C>b?t=t.slice(C):b>C&&(e=e.slice(b)))}}let{optimizationLevel:s=1}=this.options;s>=2&&(e=this.levelTwoFileOptimize(e)),this.debug("matchOne",this,{file:e,pattern:t}),this.debug("matchOne",e.length,t.length);for(var i=0,a=0,l=e.length,c=t.length;i<l&&a<c;i++,a++){this.debug("matchOne loop");var u=t[a],d=e[i];if(this.debug(t,u,d),u===!1)return!1;if(u===be){this.debug("GLOBSTAR",[t,u,d]);var m=i,p=a+1;if(p===c){for(this.debug("** at the end");i<l;i++)if(e[i]==="."||e[i]===".."||!o.dot&&e[i].charAt(0)===".")return!1;return!0}for(;m<l;){var f=e[m];if(this.debug(`
|
|
1783
|
+
globstar while`,e,m,t,p,f),this.matchOne(e.slice(m),t.slice(p),n))return this.debug("globstar found match!",m,l,f),!0;if(f==="."||f===".."||!o.dot&&f.charAt(0)==="."){this.debug("dot detected!",e,m,t,p);break}this.debug("globstar swallow a segment, and continue"),m++}return!!(n&&(this.debug(`
|
|
1784
|
+
>>> no match, partial?`,e,m,t,p),m===l))}let h;if(typeof u=="string"?(h=d===u,this.debug("string match",u,d,h)):(h=u.test(d),this.debug("pattern match",u,d,h)),!h)return!1}if(i===l&&a===c)return!0;if(i===l)return n;if(a===c)return i===l-1&&e[i]==="";throw new Error("wtf?")}braceExpand(){return Ru(this.pattern,this.options)}parse(e){qr(e);let t=this.options;if(e==="**")return be;if(e==="")return"";let n,o=null;(n=e.match(eS))?o=t.dot?nS:tS:(n=e.match(jy))?o=(t.nocase?t.dot?Ky:qy:t.dot?Vy:Gy)(n[1]):(n=e.match(rS))?o=(t.nocase?t.dot?sS:oS:t.dot?iS:aS)(n):(n=e.match(Yy))?o=t.dot?Jy:Xy:(n=e.match(Zy))&&(o=Qy);let s=qn.fromGlob(e,this.options).toMMPattern();return o&&typeof s=="object"&&Reflect.defineProperty(s,"test",{value:o}),s}makeRe(){if(this.regexp||this.regexp===!1)return this.regexp;let e=this.set;if(!e.length)return this.regexp=!1,this.regexp;let t=this.options,n=t.noglobstar?dS:t.dot?uS:mS,o=new Set(t.nocase?["i"]:[]),s=e.map(l=>{let c=l.map(u=>{if(u instanceof RegExp)for(let d of u.flags.split(""))o.add(d);return typeof u=="string"?yS(u):u===be?be:u._src});return c.forEach((u,d)=>{let m=c[d+1],p=c[d-1];u!==be||p===be||(p===void 0?m!==void 0&&m!==be?c[d+1]="(?:\\/|"+n+"\\/)?"+m:c[d]=n:m===void 0?c[d-1]=p+"(?:\\/|"+n+")?":m!==be&&(c[d-1]=p+"(?:\\/|\\/"+n+"\\/)"+m,c[d+1]=be))}),c.filter(u=>u!==be).join("/")}).join("|"),[i,a]=e.length>1?["(?:",")"]:["",""];s="^"+i+s+a+"$",this.negate&&(s="^(?!"+s+").+$");try{this.regexp=new RegExp(s,[...o].join(""))}catch{this.regexp=!1}return this.regexp}slashSplit(e){return this.preserveMultipleSlashes?e.split("/"):this.isWindows&&/^\/\/[^\/]+/.test(e)?["",...e.split(/\/+/)]:e.split(/\/+/)}match(e,t=this.partial){if(this.debug("match",e,this.pattern),this.comment)return!1;if(this.empty)return e==="";if(e==="/"&&t)return!0;let n=this.options;this.isWindows&&(e=e.split("\\").join("/"));let o=this.slashSplit(e);this.debug(this.pattern,"split",o);let s=this.set;this.debug(this.pattern,"set",s);let i=o[o.length-1];if(!i)for(let a=o.length-2;!i&&a>=0;a--)i=o[a];for(let a=0;a<s.length;a++){let l=s[a],c=o;if(n.matchBase&&l.length===1&&(c=[i]),this.matchOne(c,l,t))return n.flipNegate?!0:!this.negate}return n.flipNegate?!1:this.negate}static defaults(e){return Ne.defaults(e).Minimatch}};Ne.AST=qn;Ne.Minimatch=$e;Ne.escape=Kn;Ne.unescape=at;import{fileURLToPath as YS}from"node:url";var Yn=typeof performance=="object"&&performance&&typeof performance.now=="function"?performance:Date,Pu=new Set,ea=typeof process=="object"&&process?process:{},Ou=(r,e,t,n)=>{typeof ea.emitWarning=="function"?ea.emitWarning(r,e,t,n):console.error(`[${t}] ${e}: ${r}`)},us=globalThis.AbortController,Iu=globalThis.AbortSignal;if(typeof us>"u"){Iu=class{onabort;_onabort=[];reason;aborted=!1;addEventListener(n,o){this._onabort.push(o)}},us=class{constructor(){e()}signal=new Iu;abort(n){if(!this.signal.aborted){this.signal.reason=n,this.signal.aborted=!0;for(let o of this.signal._onabort)o(n);this.signal.onabort?.(n)}}};let r=ea.env?.LRU_CACHE_IGNORE_AC_WARNING!=="1",e=()=>{r&&(r=!1,Ou("AbortController is not defined. If using lru-cache in node 14, load an AbortController polyfill from the `node-abort-controller` package. A minimal polyfill is provided for use by LRUCache.fetch(), but it should not be relied upon in other contexts (eg, passing it to other APIs that use AbortController/AbortSignal might have undesirable effects). You may disable this with LRU_CACHE_IGNORE_AC_WARNING=1 in the env.","NO_ABORT_CONTROLLER","ENOTSUP",e))}}var SS=r=>!Pu.has(r),i$=Symbol("type"),jt=r=>r&&r===Math.floor(r)&&r>0&&isFinite(r),Lu=r=>jt(r)?r<=Math.pow(2,8)?Uint8Array:r<=Math.pow(2,16)?Uint16Array:r<=Math.pow(2,32)?Uint32Array:r<=Number.MAX_SAFE_INTEGER?Xn:null:null,Xn=class extends Array{constructor(e){super(e),this.fill(0)}},ta=class r{heap;length;static#e=!1;static create(e){let t=Lu(e);if(!t)return[];r.#e=!0;let n=new r(e,t);return r.#e=!1,n}constructor(e,t){if(!r.#e)throw new TypeError("instantiate Stack using Stack.create(n)");this.heap=new t(e),this.length=0}push(e){this.heap[this.length++]=e}pop(){return this.heap[--this.length]}},Yr=class r{#e;#t;#s;#r;#i;#b;ttl;ttlResolution;ttlAutopurge;updateAgeOnGet;updateAgeOnHas;allowStale;noDisposeOnSet;noUpdateTTL;maxEntrySize;sizeCalculation;noDeleteOnFetchRejection;noDeleteOnStaleGet;allowStaleOnFetchAbort;allowStaleOnFetchRejection;ignoreFetchAbort;#c;#u;#a;#l;#o;#g;#y;#p;#m;#v;#f;#E;#x;#w;#C;#T;#h;static unsafeExposeInternals(e){return{starts:e.#x,ttls:e.#w,sizes:e.#E,keyMap:e.#a,keyList:e.#l,valList:e.#o,next:e.#g,prev:e.#y,get head(){return e.#p},get tail(){return e.#m},free:e.#v,isBackgroundFetch:t=>e.#d(t),backgroundFetch:(t,n,o,s)=>e.#U(t,n,o,s),moveToTail:t=>e.#B(t),indexes:t=>e.#R(t),rindexes:t=>e.#I(t),isStale:t=>e.#S(t)}}get max(){return this.#e}get maxSize(){return this.#t}get calculatedSize(){return this.#u}get size(){return this.#c}get fetchMethod(){return this.#i}get memoMethod(){return this.#b}get dispose(){return this.#s}get disposeAfter(){return this.#r}constructor(e){let{max:t=0,ttl:n,ttlResolution:o=1,ttlAutopurge:s,updateAgeOnGet:i,updateAgeOnHas:a,allowStale:l,dispose:c,disposeAfter:u,noDisposeOnSet:d,noUpdateTTL:m,maxSize:p=0,maxEntrySize:f=0,sizeCalculation:h,fetchMethod:g,memoMethod:y,noDeleteOnFetchRejection:S,noDeleteOnStaleGet:b,allowStaleOnFetchRejection:C,allowStaleOnFetchAbort:v,ignoreFetchAbort:E}=e;if(t!==0&&!jt(t))throw new TypeError("max option must be a nonnegative integer");let P=t?Lu(t):Array;if(!P)throw new Error("invalid max value: "+t);if(this.#e=t,this.#t=p,this.maxEntrySize=f||this.#t,this.sizeCalculation=h,this.sizeCalculation){if(!this.#t&&!this.maxEntrySize)throw new TypeError("cannot set sizeCalculation without setting maxSize or maxEntrySize");if(typeof this.sizeCalculation!="function")throw new TypeError("sizeCalculation set to non-function")}if(y!==void 0&&typeof y!="function")throw new TypeError("memoMethod must be a function if defined");if(this.#b=y,g!==void 0&&typeof g!="function")throw new TypeError("fetchMethod must be a function if specified");if(this.#i=g,this.#T=!!g,this.#a=new Map,this.#l=new Array(t).fill(void 0),this.#o=new Array(t).fill(void 0),this.#g=new P(t),this.#y=new P(t),this.#p=0,this.#m=0,this.#v=ta.create(t),this.#c=0,this.#u=0,typeof c=="function"&&(this.#s=c),typeof u=="function"?(this.#r=u,this.#f=[]):(this.#r=void 0,this.#f=void 0),this.#C=!!this.#s,this.#h=!!this.#r,this.noDisposeOnSet=!!d,this.noUpdateTTL=!!m,this.noDeleteOnFetchRejection=!!S,this.allowStaleOnFetchRejection=!!C,this.allowStaleOnFetchAbort=!!v,this.ignoreFetchAbort=!!E,this.maxEntrySize!==0){if(this.#t!==0&&!jt(this.#t))throw new TypeError("maxSize must be a positive integer if specified");if(!jt(this.maxEntrySize))throw new TypeError("maxEntrySize must be a positive integer if specified");this.#O()}if(this.allowStale=!!l,this.noDeleteOnStaleGet=!!b,this.updateAgeOnGet=!!i,this.updateAgeOnHas=!!a,this.ttlResolution=jt(o)||o===0?o:1,this.ttlAutopurge=!!s,this.ttl=n||0,this.ttl){if(!jt(this.ttl))throw new TypeError("ttl must be a positive integer if specified");this.#P()}if(this.#e===0&&this.ttl===0&&this.#t===0)throw new TypeError("At least one of max, maxSize, or ttl is required");if(!this.ttlAutopurge&&!this.#e&&!this.#t){let A="LRU_CACHE_UNBOUNDED";SS(A)&&(Pu.add(A),Ou("TTL caching without ttlAutopurge, max, or maxSize can result in unbounded memory consumption.","UnboundedCacheWarning",A,r))}}getRemainingTTL(e){return this.#a.has(e)?1/0:0}#P(){let e=new Xn(this.#e),t=new Xn(this.#e);this.#w=e,this.#x=t,this.#M=(s,i,a=Yn.now())=>{if(t[s]=i!==0?a:0,e[s]=i,i!==0&&this.ttlAutopurge){let l=setTimeout(()=>{this.#S(s)&&this.#L(this.#l[s],"expire")},i+1);l.unref&&l.unref()}},this.#A=s=>{t[s]=e[s]!==0?Yn.now():0},this.#n=(s,i)=>{if(e[i]){let a=e[i],l=t[i];if(!a||!l)return;s.ttl=a,s.start=l,s.now=n||o();let c=s.now-l;s.remainingTTL=a-c}};let n=0,o=()=>{let s=Yn.now();if(this.ttlResolution>0){n=s;let i=setTimeout(()=>n=0,this.ttlResolution);i.unref&&i.unref()}return s};this.getRemainingTTL=s=>{let i=this.#a.get(s);if(i===void 0)return 0;let a=e[i],l=t[i];if(!a||!l)return 1/0;let c=(n||o())-l;return a-c},this.#S=s=>{let i=t[s],a=e[s];return!!a&&!!i&&(n||o())-i>a}}#A=()=>{};#n=()=>{};#M=()=>{};#S=()=>!1;#O(){let e=new Xn(this.#e);this.#u=0,this.#E=e,this.#N=t=>{this.#u-=e[t],e[t]=0},this.#k=(t,n,o,s)=>{if(this.#d(n))return 0;if(!jt(o))if(s){if(typeof s!="function")throw new TypeError("sizeCalculation must be a function");if(o=s(n,t),!jt(o))throw new TypeError("sizeCalculation return invalid (expect positive integer)")}else throw new TypeError("invalid size value (must be positive integer). When maxSize or maxEntrySize is used, sizeCalculation or size must be set.");return o},this.#_=(t,n,o)=>{if(e[t]=n,this.#t){let s=this.#t-e[t];for(;this.#u>s;)this.#F(!0)}this.#u+=e[t],o&&(o.entrySize=n,o.totalCalculatedSize=this.#u)}}#N=e=>{};#_=(e,t,n)=>{};#k=(e,t,n,o)=>{if(n||o)throw new TypeError("cannot set size without setting maxSize or maxEntrySize on cache");return 0};*#R({allowStale:e=this.allowStale}={}){if(this.#c)for(let t=this.#m;!(!this.#D(t)||((e||!this.#S(t))&&(yield t),t===this.#p));)t=this.#y[t]}*#I({allowStale:e=this.allowStale}={}){if(this.#c)for(let t=this.#p;!(!this.#D(t)||((e||!this.#S(t))&&(yield t),t===this.#m));)t=this.#g[t]}#D(e){return e!==void 0&&this.#a.get(this.#l[e])===e}*entries(){for(let e of this.#R())this.#o[e]!==void 0&&this.#l[e]!==void 0&&!this.#d(this.#o[e])&&(yield[this.#l[e],this.#o[e]])}*rentries(){for(let e of this.#I())this.#o[e]!==void 0&&this.#l[e]!==void 0&&!this.#d(this.#o[e])&&(yield[this.#l[e],this.#o[e]])}*keys(){for(let e of this.#R()){let t=this.#l[e];t!==void 0&&!this.#d(this.#o[e])&&(yield t)}}*rkeys(){for(let e of this.#I()){let t=this.#l[e];t!==void 0&&!this.#d(this.#o[e])&&(yield t)}}*values(){for(let e of this.#R())this.#o[e]!==void 0&&!this.#d(this.#o[e])&&(yield this.#o[e])}*rvalues(){for(let e of this.#I())this.#o[e]!==void 0&&!this.#d(this.#o[e])&&(yield this.#o[e])}[Symbol.iterator](){return this.entries()}[Symbol.toStringTag]="LRUCache";find(e,t={}){for(let n of this.#R()){let o=this.#o[n],s=this.#d(o)?o.__staleWhileFetching:o;if(s!==void 0&&e(s,this.#l[n],this))return this.get(this.#l[n],t)}}forEach(e,t=this){for(let n of this.#R()){let o=this.#o[n],s=this.#d(o)?o.__staleWhileFetching:o;s!==void 0&&e.call(t,s,this.#l[n],this)}}rforEach(e,t=this){for(let n of this.#I()){let o=this.#o[n],s=this.#d(o)?o.__staleWhileFetching:o;s!==void 0&&e.call(t,s,this.#l[n],this)}}purgeStale(){let e=!1;for(let t of this.#I({allowStale:!0}))this.#S(t)&&(this.#L(this.#l[t],"expire"),e=!0);return e}info(e){let t=this.#a.get(e);if(t===void 0)return;let n=this.#o[t],o=this.#d(n)?n.__staleWhileFetching:n;if(o===void 0)return;let s={value:o};if(this.#w&&this.#x){let i=this.#w[t],a=this.#x[t];if(i&&a){let l=i-(Yn.now()-a);s.ttl=l,s.start=Date.now()}}return this.#E&&(s.size=this.#E[t]),s}dump(){let e=[];for(let t of this.#R({allowStale:!0})){let n=this.#l[t],o=this.#o[t],s=this.#d(o)?o.__staleWhileFetching:o;if(s===void 0||n===void 0)continue;let i={value:s};if(this.#w&&this.#x){i.ttl=this.#w[t];let a=Yn.now()-this.#x[t];i.start=Math.floor(Date.now()-a)}this.#E&&(i.size=this.#E[t]),e.unshift([n,i])}return e}load(e){this.clear();for(let[t,n]of e){if(n.start){let o=Date.now()-n.start;n.start=Yn.now()-o}this.set(t,n.value,n)}}set(e,t,n={}){if(t===void 0)return this.delete(e),this;let{ttl:o=this.ttl,start:s,noDisposeOnSet:i=this.noDisposeOnSet,sizeCalculation:a=this.sizeCalculation,status:l}=n,{noUpdateTTL:c=this.noUpdateTTL}=n,u=this.#k(e,t,n.size||0,a);if(this.maxEntrySize&&u>this.maxEntrySize)return l&&(l.set="miss",l.maxEntrySizeExceeded=!0),this.#L(e,"set"),this;let d=this.#c===0?void 0:this.#a.get(e);if(d===void 0)d=this.#c===0?this.#m:this.#v.length!==0?this.#v.pop():this.#c===this.#e?this.#F(!1):this.#c,this.#l[d]=e,this.#o[d]=t,this.#a.set(e,d),this.#g[this.#m]=d,this.#y[d]=this.#m,this.#m=d,this.#c++,this.#_(d,u,l),l&&(l.set="add"),c=!1;else{this.#B(d);let m=this.#o[d];if(t!==m){if(this.#T&&this.#d(m)){m.__abortController.abort(new Error("replaced"));let{__staleWhileFetching:p}=m;p!==void 0&&!i&&(this.#C&&this.#s?.(p,e,"set"),this.#h&&this.#f?.push([p,e,"set"]))}else i||(this.#C&&this.#s?.(m,e,"set"),this.#h&&this.#f?.push([m,e,"set"]));if(this.#N(d),this.#_(d,u,l),this.#o[d]=t,l){l.set="replace";let p=m&&this.#d(m)?m.__staleWhileFetching:m;p!==void 0&&(l.oldValue=p)}}else l&&(l.set="update")}if(o!==0&&!this.#w&&this.#P(),this.#w&&(c||this.#M(d,o,s),l&&this.#n(l,d)),!i&&this.#h&&this.#f){let m=this.#f,p;for(;p=m?.shift();)this.#r?.(...p)}return this}pop(){try{for(;this.#c;){let e=this.#o[this.#p];if(this.#F(!0),this.#d(e)){if(e.__staleWhileFetching)return e.__staleWhileFetching}else if(e!==void 0)return e}}finally{if(this.#h&&this.#f){let e=this.#f,t;for(;t=e?.shift();)this.#r?.(...t)}}}#F(e){let t=this.#p,n=this.#l[t],o=this.#o[t];return this.#T&&this.#d(o)?o.__abortController.abort(new Error("evicted")):(this.#C||this.#h)&&(this.#C&&this.#s?.(o,n,"evict"),this.#h&&this.#f?.push([o,n,"evict"])),this.#N(t),e&&(this.#l[t]=void 0,this.#o[t]=void 0,this.#v.push(t)),this.#c===1?(this.#p=this.#m=0,this.#v.length=0):this.#p=this.#g[t],this.#a.delete(n),this.#c--,t}has(e,t={}){let{updateAgeOnHas:n=this.updateAgeOnHas,status:o}=t,s=this.#a.get(e);if(s!==void 0){let i=this.#o[s];if(this.#d(i)&&i.__staleWhileFetching===void 0)return!1;if(this.#S(s))o&&(o.has="stale",this.#n(o,s));else return n&&this.#A(s),o&&(o.has="hit",this.#n(o,s)),!0}else o&&(o.has="miss");return!1}peek(e,t={}){let{allowStale:n=this.allowStale}=t,o=this.#a.get(e);if(o===void 0||!n&&this.#S(o))return;let s=this.#o[o];return this.#d(s)?s.__staleWhileFetching:s}#U(e,t,n,o){let s=t===void 0?void 0:this.#o[t];if(this.#d(s))return s;let i=new us,{signal:a}=n;a?.addEventListener("abort",()=>i.abort(a.reason),{signal:i.signal});let l={signal:i.signal,options:n,context:o},c=(h,g=!1)=>{let{aborted:y}=i.signal,S=n.ignoreFetchAbort&&h!==void 0;if(n.status&&(y&&!g?(n.status.fetchAborted=!0,n.status.fetchError=i.signal.reason,S&&(n.status.fetchAbortIgnored=!0)):n.status.fetchResolved=!0),y&&!S&&!g)return d(i.signal.reason);let b=p;return this.#o[t]===p&&(h===void 0?b.__staleWhileFetching?this.#o[t]=b.__staleWhileFetching:this.#L(e,"fetch"):(n.status&&(n.status.fetchUpdated=!0),this.set(e,h,l.options))),h},u=h=>(n.status&&(n.status.fetchRejected=!0,n.status.fetchError=h),d(h)),d=h=>{let{aborted:g}=i.signal,y=g&&n.allowStaleOnFetchAbort,S=y||n.allowStaleOnFetchRejection,b=S||n.noDeleteOnFetchRejection,C=p;if(this.#o[t]===p&&(!b||C.__staleWhileFetching===void 0?this.#L(e,"fetch"):y||(this.#o[t]=C.__staleWhileFetching)),S)return n.status&&C.__staleWhileFetching!==void 0&&(n.status.returnedStale=!0),C.__staleWhileFetching;if(C.__returned===C)throw h},m=(h,g)=>{let y=this.#i?.(e,s,l);y&&y instanceof Promise&&y.then(S=>h(S===void 0?void 0:S),g),i.signal.addEventListener("abort",()=>{(!n.ignoreFetchAbort||n.allowStaleOnFetchAbort)&&(h(void 0),n.allowStaleOnFetchAbort&&(h=S=>c(S,!0)))})};n.status&&(n.status.fetchDispatched=!0);let p=new Promise(m).then(c,u),f=Object.assign(p,{__abortController:i,__staleWhileFetching:s,__returned:void 0});return t===void 0?(this.set(e,f,{...l.options,status:void 0}),t=this.#a.get(e)):this.#o[t]=f,f}#d(e){if(!this.#T)return!1;let t=e;return!!t&&t instanceof Promise&&t.hasOwnProperty("__staleWhileFetching")&&t.__abortController instanceof us}async fetch(e,t={}){let{allowStale:n=this.allowStale,updateAgeOnGet:o=this.updateAgeOnGet,noDeleteOnStaleGet:s=this.noDeleteOnStaleGet,ttl:i=this.ttl,noDisposeOnSet:a=this.noDisposeOnSet,size:l=0,sizeCalculation:c=this.sizeCalculation,noUpdateTTL:u=this.noUpdateTTL,noDeleteOnFetchRejection:d=this.noDeleteOnFetchRejection,allowStaleOnFetchRejection:m=this.allowStaleOnFetchRejection,ignoreFetchAbort:p=this.ignoreFetchAbort,allowStaleOnFetchAbort:f=this.allowStaleOnFetchAbort,context:h,forceRefresh:g=!1,status:y,signal:S}=t;if(!this.#T)return y&&(y.fetch="get"),this.get(e,{allowStale:n,updateAgeOnGet:o,noDeleteOnStaleGet:s,status:y});let b={allowStale:n,updateAgeOnGet:o,noDeleteOnStaleGet:s,ttl:i,noDisposeOnSet:a,size:l,sizeCalculation:c,noUpdateTTL:u,noDeleteOnFetchRejection:d,allowStaleOnFetchRejection:m,allowStaleOnFetchAbort:f,ignoreFetchAbort:p,status:y,signal:S},C=this.#a.get(e);if(C===void 0){y&&(y.fetch="miss");let v=this.#U(e,C,b,h);return v.__returned=v}else{let v=this.#o[C];if(this.#d(v)){let M=n&&v.__staleWhileFetching!==void 0;return y&&(y.fetch="inflight",M&&(y.returnedStale=!0)),M?v.__staleWhileFetching:v.__returned=v}let E=this.#S(C);if(!g&&!E)return y&&(y.fetch="hit"),this.#B(C),o&&this.#A(C),y&&this.#n(y,C),v;let P=this.#U(e,C,b,h),O=P.__staleWhileFetching!==void 0&&n;return y&&(y.fetch=E?"stale":"refresh",O&&E&&(y.returnedStale=!0)),O?P.__staleWhileFetching:P.__returned=P}}async forceFetch(e,t={}){let n=await this.fetch(e,t);if(n===void 0)throw new Error("fetch() returned undefined");return n}memo(e,t={}){let n=this.#b;if(!n)throw new Error("no memoMethod provided to constructor");let{context:o,forceRefresh:s,...i}=t,a=this.get(e,i);if(!s&&a!==void 0)return a;let l=n(e,a,{options:i,context:o});return this.set(e,l,i),l}get(e,t={}){let{allowStale:n=this.allowStale,updateAgeOnGet:o=this.updateAgeOnGet,noDeleteOnStaleGet:s=this.noDeleteOnStaleGet,status:i}=t,a=this.#a.get(e);if(a!==void 0){let l=this.#o[a],c=this.#d(l);return i&&this.#n(i,a),this.#S(a)?(i&&(i.get="stale"),c?(i&&n&&l.__staleWhileFetching!==void 0&&(i.returnedStale=!0),n?l.__staleWhileFetching:void 0):(s||this.#L(e,"expire"),i&&n&&(i.returnedStale=!0),n?l:void 0)):(i&&(i.get="hit"),c?l.__staleWhileFetching:(this.#B(a),o&&this.#A(a),l))}else i&&(i.get="miss")}#$(e,t){this.#y[t]=e,this.#g[e]=t}#B(e){e!==this.#m&&(e===this.#p?this.#p=this.#g[e]:this.#$(this.#y[e],this.#g[e]),this.#$(this.#m,e),this.#m=e)}delete(e){return this.#L(e,"delete")}#L(e,t){let n=!1;if(this.#c!==0){let o=this.#a.get(e);if(o!==void 0)if(n=!0,this.#c===1)this.#z(t);else{this.#N(o);let s=this.#o[o];if(this.#d(s)?s.__abortController.abort(new Error("deleted")):(this.#C||this.#h)&&(this.#C&&this.#s?.(s,e,t),this.#h&&this.#f?.push([s,e,t])),this.#a.delete(e),this.#l[o]=void 0,this.#o[o]=void 0,o===this.#m)this.#m=this.#y[o];else if(o===this.#p)this.#p=this.#g[o];else{let i=this.#y[o];this.#g[i]=this.#g[o];let a=this.#g[o];this.#y[a]=this.#y[o]}this.#c--,this.#v.push(o)}}if(this.#h&&this.#f?.length){let o=this.#f,s;for(;s=o?.shift();)this.#r?.(...s)}return n}clear(){return this.#z("delete")}#z(e){for(let t of this.#I({allowStale:!0})){let n=this.#o[t];if(this.#d(n))n.__abortController.abort(new Error("deleted"));else{let o=this.#l[t];this.#C&&this.#s?.(n,o,e),this.#h&&this.#f?.push([n,o,e])}}if(this.#a.clear(),this.#o.fill(void 0),this.#l.fill(void 0),this.#w&&this.#x&&(this.#w.fill(0),this.#x.fill(0)),this.#E&&this.#E.fill(0),this.#p=0,this.#m=0,this.#v.length=0,this.#u=0,this.#c=0,this.#h&&this.#f){let t=this.#f,n;for(;n=t?.shift();)this.#r?.(...n)}}};import{posix as PS,win32 as ua}from"node:path";import{fileURLToPath as OS}from"node:url";import{lstatSync as LS,readdir as MS,readdirSync as NS,readlinkSync as _S,realpathSync as kS}from"fs";import*as DS from"node:fs";import{lstat as US,readdir as $S,readlink as BS,realpath as zS}from"node:fs/promises";import{EventEmitter as la}from"node:events";import Du from"node:stream";import{StringDecoder as wS}from"node:string_decoder";var Mu=typeof process=="object"&&process?process:{stdout:null,stderr:null},bS=r=>!!r&&typeof r=="object"&&(r instanceof Vt||r instanceof Du||CS(r)||TS(r)),CS=r=>!!r&&typeof r=="object"&&r instanceof la&&typeof r.pipe=="function"&&r.pipe!==Du.Writable.prototype.pipe,TS=r=>!!r&&typeof r=="object"&&r instanceof la&&typeof r.write=="function"&&typeof r.end=="function",kt=Symbol("EOF"),Dt=Symbol("maybeEmitEnd"),Gt=Symbol("emittedEnd"),ms=Symbol("emittingEnd"),Xr=Symbol("emittedError"),ps=Symbol("closed"),Nu=Symbol("read"),hs=Symbol("flush"),_u=Symbol("flushChunk"),lt=Symbol("encoding"),Jn=Symbol("decoder"),fe=Symbol("flowing"),Jr=Symbol("paused"),Zn=Symbol("resume"),ge=Symbol("buffer"),_e=Symbol("pipes"),ye=Symbol("bufferLength"),na=Symbol("bufferPush"),fs=Symbol("bufferShift"),Ae=Symbol("objectMode"),re=Symbol("destroyed"),ra=Symbol("error"),oa=Symbol("emitData"),ku=Symbol("emitEnd"),sa=Symbol("emitEnd2"),Ct=Symbol("async"),ia=Symbol("abort"),gs=Symbol("aborted"),Zr=Symbol("signal"),mn=Symbol("dataListeners"),Be=Symbol("discarded"),Qr=r=>Promise.resolve().then(r),vS=r=>r(),ES=r=>r==="end"||r==="finish"||r==="prefinish",xS=r=>r instanceof ArrayBuffer||!!r&&typeof r=="object"&&r.constructor&&r.constructor.name==="ArrayBuffer"&&r.byteLength>=0,AS=r=>!Buffer.isBuffer(r)&&ArrayBuffer.isView(r),ys=class{src;dest;opts;ondrain;constructor(e,t,n){this.src=e,this.dest=t,this.opts=n,this.ondrain=()=>e[Zn](),this.dest.on("drain",this.ondrain)}unpipe(){this.dest.removeListener("drain",this.ondrain)}proxyErrors(e){}end(){this.unpipe(),this.opts.end&&this.dest.end()}},aa=class extends ys{unpipe(){this.src.removeListener("error",this.proxyErrors),super.unpipe()}constructor(e,t,n){super(e,t,n),this.proxyErrors=o=>t.emit("error",o),e.on("error",this.proxyErrors)}},RS=r=>!!r.objectMode,IS=r=>!r.objectMode&&!!r.encoding&&r.encoding!=="buffer",Vt=class extends la{[fe]=!1;[Jr]=!1;[_e]=[];[ge]=[];[Ae];[lt];[Ct];[Jn];[kt]=!1;[Gt]=!1;[ms]=!1;[ps]=!1;[Xr]=null;[ye]=0;[re]=!1;[Zr];[gs]=!1;[mn]=0;[Be]=!1;writable=!0;readable=!0;constructor(...e){let t=e[0]||{};if(super(),t.objectMode&&typeof t.encoding=="string")throw new TypeError("Encoding and objectMode may not be used together");RS(t)?(this[Ae]=!0,this[lt]=null):IS(t)?(this[lt]=t.encoding,this[Ae]=!1):(this[Ae]=!1,this[lt]=null),this[Ct]=!!t.async,this[Jn]=this[lt]?new wS(this[lt]):null,t&&t.debugExposeBuffer===!0&&Object.defineProperty(this,"buffer",{get:()=>this[ge]}),t&&t.debugExposePipes===!0&&Object.defineProperty(this,"pipes",{get:()=>this[_e]});let{signal:n}=t;n&&(this[Zr]=n,n.aborted?this[ia]():n.addEventListener("abort",()=>this[ia]()))}get bufferLength(){return this[ye]}get encoding(){return this[lt]}set encoding(e){throw new Error("Encoding must be set at instantiation time")}setEncoding(e){throw new Error("Encoding must be set at instantiation time")}get objectMode(){return this[Ae]}set objectMode(e){throw new Error("objectMode must be set at instantiation time")}get async(){return this[Ct]}set async(e){this[Ct]=this[Ct]||!!e}[ia](){this[gs]=!0,this.emit("abort",this[Zr]?.reason),this.destroy(this[Zr]?.reason)}get aborted(){return this[gs]}set aborted(e){}write(e,t,n){if(this[gs])return!1;if(this[kt])throw new Error("write after end");if(this[re])return this.emit("error",Object.assign(new Error("Cannot call write after a stream was destroyed"),{code:"ERR_STREAM_DESTROYED"})),!0;typeof t=="function"&&(n=t,t="utf8"),t||(t="utf8");let o=this[Ct]?Qr:vS;if(!this[Ae]&&!Buffer.isBuffer(e)){if(AS(e))e=Buffer.from(e.buffer,e.byteOffset,e.byteLength);else if(xS(e))e=Buffer.from(e);else if(typeof e!="string")throw new Error("Non-contiguous data written to non-objectMode stream")}return this[Ae]?(this[fe]&&this[ye]!==0&&this[hs](!0),this[fe]?this.emit("data",e):this[na](e),this[ye]!==0&&this.emit("readable"),n&&o(n),this[fe]):e.length?(typeof e=="string"&&!(t===this[lt]&&!this[Jn]?.lastNeed)&&(e=Buffer.from(e,t)),Buffer.isBuffer(e)&&this[lt]&&(e=this[Jn].write(e)),this[fe]&&this[ye]!==0&&this[hs](!0),this[fe]?this.emit("data",e):this[na](e),this[ye]!==0&&this.emit("readable"),n&&o(n),this[fe]):(this[ye]!==0&&this.emit("readable"),n&&o(n),this[fe])}read(e){if(this[re])return null;if(this[Be]=!1,this[ye]===0||e===0||e&&e>this[ye])return this[Dt](),null;this[Ae]&&(e=null),this[ge].length>1&&!this[Ae]&&(this[ge]=[this[lt]?this[ge].join(""):Buffer.concat(this[ge],this[ye])]);let t=this[Nu](e||null,this[ge][0]);return this[Dt](),t}[Nu](e,t){if(this[Ae])this[fs]();else{let n=t;e===n.length||e===null?this[fs]():typeof n=="string"?(this[ge][0]=n.slice(e),t=n.slice(0,e),this[ye]-=e):(this[ge][0]=n.subarray(e),t=n.subarray(0,e),this[ye]-=e)}return this.emit("data",t),!this[ge].length&&!this[kt]&&this.emit("drain"),t}end(e,t,n){return typeof e=="function"&&(n=e,e=void 0),typeof t=="function"&&(n=t,t="utf8"),e!==void 0&&this.write(e,t),n&&this.once("end",n),this[kt]=!0,this.writable=!1,(this[fe]||!this[Jr])&&this[Dt](),this}[Zn](){this[re]||(!this[mn]&&!this[_e].length&&(this[Be]=!0),this[Jr]=!1,this[fe]=!0,this.emit("resume"),this[ge].length?this[hs]():this[kt]?this[Dt]():this.emit("drain"))}resume(){return this[Zn]()}pause(){this[fe]=!1,this[Jr]=!0,this[Be]=!1}get destroyed(){return this[re]}get flowing(){return this[fe]}get paused(){return this[Jr]}[na](e){this[Ae]?this[ye]+=1:this[ye]+=e.length,this[ge].push(e)}[fs](){return this[Ae]?this[ye]-=1:this[ye]-=this[ge][0].length,this[ge].shift()}[hs](e=!1){do;while(this[_u](this[fs]())&&this[ge].length);!e&&!this[ge].length&&!this[kt]&&this.emit("drain")}[_u](e){return this.emit("data",e),this[fe]}pipe(e,t){if(this[re])return e;this[Be]=!1;let n=this[Gt];return t=t||{},e===Mu.stdout||e===Mu.stderr?t.end=!1:t.end=t.end!==!1,t.proxyErrors=!!t.proxyErrors,n?t.end&&e.end():(this[_e].push(t.proxyErrors?new aa(this,e,t):new ys(this,e,t)),this[Ct]?Qr(()=>this[Zn]()):this[Zn]()),e}unpipe(e){let t=this[_e].find(n=>n.dest===e);t&&(this[_e].length===1?(this[fe]&&this[mn]===0&&(this[fe]=!1),this[_e]=[]):this[_e].splice(this[_e].indexOf(t),1),t.unpipe())}addListener(e,t){return this.on(e,t)}on(e,t){let n=super.on(e,t);if(e==="data")this[Be]=!1,this[mn]++,!this[_e].length&&!this[fe]&&this[Zn]();else if(e==="readable"&&this[ye]!==0)super.emit("readable");else if(ES(e)&&this[Gt])super.emit(e),this.removeAllListeners(e);else if(e==="error"&&this[Xr]){let o=t;this[Ct]?Qr(()=>o.call(this,this[Xr])):o.call(this,this[Xr])}return n}removeListener(e,t){return this.off(e,t)}off(e,t){let n=super.off(e,t);return e==="data"&&(this[mn]=this.listeners("data").length,this[mn]===0&&!this[Be]&&!this[_e].length&&(this[fe]=!1)),n}removeAllListeners(e){let t=super.removeAllListeners(e);return(e==="data"||e===void 0)&&(this[mn]=0,!this[Be]&&!this[_e].length&&(this[fe]=!1)),t}get emittedEnd(){return this[Gt]}[Dt](){!this[ms]&&!this[Gt]&&!this[re]&&this[ge].length===0&&this[kt]&&(this[ms]=!0,this.emit("end"),this.emit("prefinish"),this.emit("finish"),this[ps]&&this.emit("close"),this[ms]=!1)}emit(e,...t){let n=t[0];if(e!=="error"&&e!=="close"&&e!==re&&this[re])return!1;if(e==="data")return!this[Ae]&&!n?!1:this[Ct]?(Qr(()=>this[oa](n)),!0):this[oa](n);if(e==="end")return this[ku]();if(e==="close"){if(this[ps]=!0,!this[Gt]&&!this[re])return!1;let s=super.emit("close");return this.removeAllListeners("close"),s}else if(e==="error"){this[Xr]=n,super.emit(ra,n);let s=!this[Zr]||this.listeners("error").length?super.emit("error",n):!1;return this[Dt](),s}else if(e==="resume"){let s=super.emit("resume");return this[Dt](),s}else if(e==="finish"||e==="prefinish"){let s=super.emit(e);return this.removeAllListeners(e),s}let o=super.emit(e,...t);return this[Dt](),o}[oa](e){for(let n of this[_e])n.dest.write(e)===!1&&this.pause();let t=this[Be]?!1:super.emit("data",e);return this[Dt](),t}[ku](){return this[Gt]?!1:(this[Gt]=!0,this.readable=!1,this[Ct]?(Qr(()=>this[sa]()),!0):this[sa]())}[sa](){if(this[Jn]){let t=this[Jn].end();if(t){for(let n of this[_e])n.dest.write(t);this[Be]||super.emit("data",t)}}for(let t of this[_e])t.end();let e=super.emit("end");return this.removeAllListeners("end"),e}async collect(){let e=Object.assign([],{dataLength:0});this[Ae]||(e.dataLength=0);let t=this.promise();return this.on("data",n=>{e.push(n),this[Ae]||(e.dataLength+=n.length)}),await t,e}async concat(){if(this[Ae])throw new Error("cannot concat in objectMode");let e=await this.collect();return this[lt]?e.join(""):Buffer.concat(e,e.dataLength)}async promise(){return new Promise((e,t)=>{this.on(re,()=>t(new Error("stream destroyed"))),this.on("error",n=>t(n)),this.on("end",()=>e())})}[Symbol.asyncIterator](){this[Be]=!1;let e=!1,t=async()=>(this.pause(),e=!0,{value:void 0,done:!0});return{next:()=>{if(e)return t();let o=this.read();if(o!==null)return Promise.resolve({done:!1,value:o});if(this[kt])return t();let s,i,a=d=>{this.off("data",l),this.off("end",c),this.off(re,u),t(),i(d)},l=d=>{this.off("error",a),this.off("end",c),this.off(re,u),this.pause(),s({value:d,done:!!this[kt]})},c=()=>{this.off("error",a),this.off("data",l),this.off(re,u),t(),s({done:!0,value:void 0})},u=()=>a(new Error("stream destroyed"));return new Promise((d,m)=>{i=m,s=d,this.once(re,u),this.once("error",a),this.once("end",c),this.once("data",l)})},throw:t,return:t,[Symbol.asyncIterator](){return this}}}[Symbol.iterator](){this[Be]=!1;let e=!1,t=()=>(this.pause(),this.off(ra,t),this.off(re,t),this.off("end",t),e=!0,{done:!0,value:void 0}),n=()=>{if(e)return t();let o=this.read();return o===null?t():{done:!1,value:o}};return this.once("end",t),this.once(ra,t),this.once(re,t),{next:n,throw:t,return:t,[Symbol.iterator](){return this}}}destroy(e){if(this[re])return e?this.emit("error",e):this.emit(re),this;this[re]=!0,this[Be]=!0,this[ge].length=0,this[ye]=0;let t=this;return typeof t.close=="function"&&!this[ps]&&t.close(),e?this.emit("error",e):this.emit(re),this}static get isStream(){return bS}};var FS=kS.native,to={lstatSync:LS,readdir:MS,readdirSync:NS,readlinkSync:_S,realpathSync:FS,promises:{lstat:US,readdir:$S,readlink:BS,realpath:zS}},zu=r=>!r||r===to||r===DS?to:{...to,...r,promises:{...to.promises,...r.promises||{}}},Wu=/^\\\\\?\\([a-z]:)\\?$/i,WS=r=>r.replace(/\//g,"\\").replace(Wu,"$1\\"),HS=/[\\\/]/,tt=0,Hu=1,ju=2,Tt=4,Gu=6,Vu=8,pn=10,qu=12,et=15,eo=~et,ca=16,Fu=32,no=64,ct=128,Ss=256,bs=512,Uu=no|ct|bs,jS=1023,da=r=>r.isFile()?Vu:r.isDirectory()?Tt:r.isSymbolicLink()?pn:r.isCharacterDevice()?ju:r.isBlockDevice()?Gu:r.isSocket()?qu:r.isFIFO()?Hu:tt,$u=new Map,ro=r=>{let e=$u.get(r);if(e)return e;let t=r.normalize("NFKD");return $u.set(r,t),t},Bu=new Map,ws=r=>{let e=Bu.get(r);if(e)return e;let t=ro(r.toLowerCase());return Bu.set(r,t),t},Cs=class extends Yr{constructor(){super({max:256})}},ma=class extends Yr{constructor(e=16*1024){super({maxSize:e,sizeCalculation:t=>t.length+1})}},Ku=Symbol("PathScurry setAsCwd"),Re=class{name;root;roots;parent;nocase;isCWD=!1;#e;#t;get dev(){return this.#t}#s;get mode(){return this.#s}#r;get nlink(){return this.#r}#i;get uid(){return this.#i}#b;get gid(){return this.#b}#c;get rdev(){return this.#c}#u;get blksize(){return this.#u}#a;get ino(){return this.#a}#l;get size(){return this.#l}#o;get blocks(){return this.#o}#g;get atimeMs(){return this.#g}#y;get mtimeMs(){return this.#y}#p;get ctimeMs(){return this.#p}#m;get birthtimeMs(){return this.#m}#v;get atime(){return this.#v}#f;get mtime(){return this.#f}#E;get ctime(){return this.#E}#x;get birthtime(){return this.#x}#w;#C;#T;#h;#P;#A;#n;#M;#S;#O;get parentPath(){return(this.parent||this).fullpath()}get path(){return this.parentPath}constructor(e,t=tt,n,o,s,i,a){this.name=e,this.#w=s?ws(e):ro(e),this.#n=t&jS,this.nocase=s,this.roots=o,this.root=n||this,this.#M=i,this.#T=a.fullpath,this.#P=a.relative,this.#A=a.relativePosix,this.parent=a.parent,this.parent?this.#e=this.parent.#e:this.#e=zu(a.fs)}depth(){return this.#C!==void 0?this.#C:this.parent?this.#C=this.parent.depth()+1:this.#C=0}childrenCache(){return this.#M}resolve(e){if(!e)return this;let t=this.getRootString(e),o=e.substring(t.length).split(this.splitSep);return t?this.getRoot(t).#N(o):this.#N(o)}#N(e){let t=this;for(let n of e)t=t.child(n);return t}children(){let e=this.#M.get(this);if(e)return e;let t=Object.assign([],{provisional:0});return this.#M.set(this,t),this.#n&=~ca,t}child(e,t){if(e===""||e===".")return this;if(e==="..")return this.parent||this;let n=this.children(),o=this.nocase?ws(e):ro(e);for(let l of n)if(l.#w===o)return l;let s=this.parent?this.sep:"",i=this.#T?this.#T+s+e:void 0,a=this.newChild(e,tt,{...t,parent:this,fullpath:i});return this.canReaddir()||(a.#n|=ct),n.push(a),a}relative(){if(this.isCWD)return"";if(this.#P!==void 0)return this.#P;let e=this.name,t=this.parent;if(!t)return this.#P=this.name;let n=t.relative();return n+(!n||!t.parent?"":this.sep)+e}relativePosix(){if(this.sep==="/")return this.relative();if(this.isCWD)return"";if(this.#A!==void 0)return this.#A;let e=this.name,t=this.parent;if(!t)return this.#A=this.fullpathPosix();let n=t.relativePosix();return n+(!n||!t.parent?"":"/")+e}fullpath(){if(this.#T!==void 0)return this.#T;let e=this.name,t=this.parent;if(!t)return this.#T=this.name;let o=t.fullpath()+(t.parent?this.sep:"")+e;return this.#T=o}fullpathPosix(){if(this.#h!==void 0)return this.#h;if(this.sep==="/")return this.#h=this.fullpath();if(!this.parent){let o=this.fullpath().replace(/\\/g,"/");return/^[a-z]:\//i.test(o)?this.#h=`//?/${o}`:this.#h=o}let e=this.parent,t=e.fullpathPosix(),n=t+(!t||!e.parent?"":"/")+this.name;return this.#h=n}isUnknown(){return(this.#n&et)===tt}isType(e){return this[`is${e}`]()}getType(){return this.isUnknown()?"Unknown":this.isDirectory()?"Directory":this.isFile()?"File":this.isSymbolicLink()?"SymbolicLink":this.isFIFO()?"FIFO":this.isCharacterDevice()?"CharacterDevice":this.isBlockDevice()?"BlockDevice":this.isSocket()?"Socket":"Unknown"}isFile(){return(this.#n&et)===Vu}isDirectory(){return(this.#n&et)===Tt}isCharacterDevice(){return(this.#n&et)===ju}isBlockDevice(){return(this.#n&et)===Gu}isFIFO(){return(this.#n&et)===Hu}isSocket(){return(this.#n&et)===qu}isSymbolicLink(){return(this.#n&pn)===pn}lstatCached(){return this.#n&Fu?this:void 0}readlinkCached(){return this.#S}realpathCached(){return this.#O}readdirCached(){let e=this.children();return e.slice(0,e.provisional)}canReadlink(){if(this.#S)return!0;if(!this.parent)return!1;let e=this.#n&et;return!(e!==tt&&e!==pn||this.#n&Ss||this.#n&ct)}calledReaddir(){return!!(this.#n&ca)}isENOENT(){return!!(this.#n&ct)}isNamed(e){return this.nocase?this.#w===ws(e):this.#w===ro(e)}async readlink(){let e=this.#S;if(e)return e;if(this.canReadlink()&&this.parent)try{let t=await this.#e.promises.readlink(this.fullpath()),n=(await this.parent.realpath())?.resolve(t);if(n)return this.#S=n}catch(t){this.#d(t.code);return}}readlinkSync(){let e=this.#S;if(e)return e;if(this.canReadlink()&&this.parent)try{let t=this.#e.readlinkSync(this.fullpath()),n=this.parent.realpathSync()?.resolve(t);if(n)return this.#S=n}catch(t){this.#d(t.code);return}}#_(e){this.#n|=ca;for(let t=e.provisional;t<e.length;t++){let n=e[t];n&&n.#k()}}#k(){this.#n&ct||(this.#n=(this.#n|ct)&eo,this.#R())}#R(){let e=this.children();e.provisional=0;for(let t of e)t.#k()}#I(){this.#n|=bs,this.#D()}#D(){if(this.#n&no)return;let e=this.#n;(e&et)===Tt&&(e&=eo),this.#n=e|no,this.#R()}#F(e=""){e==="ENOTDIR"||e==="EPERM"?this.#D():e==="ENOENT"?this.#k():this.children().provisional=0}#U(e=""){e==="ENOTDIR"?this.parent.#D():e==="ENOENT"&&this.#k()}#d(e=""){let t=this.#n;t|=Ss,e==="ENOENT"&&(t|=ct),(e==="EINVAL"||e==="UNKNOWN")&&(t&=eo),this.#n=t,e==="ENOTDIR"&&this.parent&&this.parent.#D()}#$(e,t){return this.#L(e,t)||this.#B(e,t)}#B(e,t){let n=da(e),o=this.newChild(e.name,n,{parent:this}),s=o.#n&et;return s!==Tt&&s!==pn&&s!==tt&&(o.#n|=no),t.unshift(o),t.provisional++,o}#L(e,t){for(let n=t.provisional;n<t.length;n++){let o=t[n];if((this.nocase?ws(e.name):ro(e.name))===o.#w)return this.#z(e,o,n,t)}}#z(e,t,n,o){let s=t.name;return t.#n=t.#n&eo|da(e),s!==e.name&&(t.name=e.name),n!==o.provisional&&(n===o.length-1?o.pop():o.splice(n,1),o.unshift(t)),o.provisional++,t}async lstat(){if(!(this.#n&ct))try{return this.#G(await this.#e.promises.lstat(this.fullpath())),this}catch(e){this.#U(e.code)}}lstatSync(){if(!(this.#n&ct))try{return this.#G(this.#e.lstatSync(this.fullpath())),this}catch(e){this.#U(e.code)}}#G(e){let{atime:t,atimeMs:n,birthtime:o,birthtimeMs:s,blksize:i,blocks:a,ctime:l,ctimeMs:c,dev:u,gid:d,ino:m,mode:p,mtime:f,mtimeMs:h,nlink:g,rdev:y,size:S,uid:b}=e;this.#v=t,this.#g=n,this.#x=o,this.#m=s,this.#u=i,this.#o=a,this.#E=l,this.#p=c,this.#t=u,this.#b=d,this.#a=m,this.#s=p,this.#f=f,this.#y=h,this.#r=g,this.#c=y,this.#l=S,this.#i=b;let C=da(e);this.#n=this.#n&eo|C|Fu,C!==tt&&C!==Tt&&C!==pn&&(this.#n|=no)}#H=[];#j=!1;#V(e){this.#j=!1;let t=this.#H.slice();this.#H.length=0,t.forEach(n=>n(null,e))}readdirCB(e,t=!1){if(!this.canReaddir()){t?e(null,[]):queueMicrotask(()=>e(null,[]));return}let n=this.children();if(this.calledReaddir()){let s=n.slice(0,n.provisional);t?e(null,s):queueMicrotask(()=>e(null,s));return}if(this.#H.push(e),this.#j)return;this.#j=!0;let o=this.fullpath();this.#e.readdir(o,{withFileTypes:!0},(s,i)=>{if(s)this.#F(s.code),n.provisional=0;else{for(let a of i)this.#$(a,n);this.#_(n)}this.#V(n.slice(0,n.provisional))})}#W;async readdir(){if(!this.canReaddir())return[];let e=this.children();if(this.calledReaddir())return e.slice(0,e.provisional);let t=this.fullpath();if(this.#W)await this.#W;else{let n=()=>{};this.#W=new Promise(o=>n=o);try{for(let o of await this.#e.promises.readdir(t,{withFileTypes:!0}))this.#$(o,e);this.#_(e)}catch(o){this.#F(o.code),e.provisional=0}this.#W=void 0,n()}return e.slice(0,e.provisional)}readdirSync(){if(!this.canReaddir())return[];let e=this.children();if(this.calledReaddir())return e.slice(0,e.provisional);let t=this.fullpath();try{for(let n of this.#e.readdirSync(t,{withFileTypes:!0}))this.#$(n,e);this.#_(e)}catch(n){this.#F(n.code),e.provisional=0}return e.slice(0,e.provisional)}canReaddir(){if(this.#n&Uu)return!1;let e=et&this.#n;return e===tt||e===Tt||e===pn}shouldWalk(e,t){return(this.#n&Tt)===Tt&&!(this.#n&Uu)&&!e.has(this)&&(!t||t(this))}async realpath(){if(this.#O)return this.#O;if(!((bs|Ss|ct)&this.#n))try{let e=await this.#e.promises.realpath(this.fullpath());return this.#O=this.resolve(e)}catch{this.#I()}}realpathSync(){if(this.#O)return this.#O;if(!((bs|Ss|ct)&this.#n))try{let e=this.#e.realpathSync(this.fullpath());return this.#O=this.resolve(e)}catch{this.#I()}}[Ku](e){if(e===this)return;e.isCWD=!1,this.isCWD=!0;let t=new Set([]),n=[],o=this;for(;o&&o.parent;)t.add(o),o.#P=n.join(this.sep),o.#A=n.join("/"),o=o.parent,n.push("..");for(o=e;o&&o.parent&&!t.has(o);)o.#P=void 0,o.#A=void 0,o=o.parent}},Ts=class r extends Re{sep="\\";splitSep=HS;constructor(e,t=tt,n,o,s,i,a){super(e,t,n,o,s,i,a)}newChild(e,t=tt,n={}){return new r(e,t,this.root,this.roots,this.nocase,this.childrenCache(),n)}getRootString(e){return ua.parse(e).root}getRoot(e){if(e=WS(e.toUpperCase()),e===this.root.name)return this.root;for(let[t,n]of Object.entries(this.roots))if(this.sameRoot(e,t))return this.roots[e]=n;return this.roots[e]=new Qn(e,this).root}sameRoot(e,t=this.root.name){return e=e.toUpperCase().replace(/\//g,"\\").replace(Wu,"$1\\"),e===t}},vs=class r extends Re{splitSep="/";sep="/";constructor(e,t=tt,n,o,s,i,a){super(e,t,n,o,s,i,a)}getRootString(e){return e.startsWith("/")?"/":""}getRoot(e){return this.root}newChild(e,t=tt,n={}){return new r(e,t,this.root,this.roots,this.nocase,this.childrenCache(),n)}},Es=class{root;rootPath;roots;cwd;#e;#t;#s;nocase;#r;constructor(e=process.cwd(),t,n,{nocase:o,childrenCacheSize:s=16*1024,fs:i=to}={}){this.#r=zu(i),(e instanceof URL||e.startsWith("file://"))&&(e=OS(e));let a=t.resolve(e);this.roots=Object.create(null),this.rootPath=this.parseRootPath(a),this.#e=new Cs,this.#t=new Cs,this.#s=new ma(s);let l=a.substring(this.rootPath.length).split(n);if(l.length===1&&!l[0]&&l.pop(),o===void 0)throw new TypeError("must provide nocase setting to PathScurryBase ctor");this.nocase=o,this.root=this.newRoot(this.#r),this.roots[this.rootPath]=this.root;let c=this.root,u=l.length-1,d=t.sep,m=this.rootPath,p=!1;for(let f of l){let h=u--;c=c.child(f,{relative:new Array(h).fill("..").join(d),relativePosix:new Array(h).fill("..").join("/"),fullpath:m+=(p?"":d)+f}),p=!0}this.cwd=c}depth(e=this.cwd){return typeof e=="string"&&(e=this.cwd.resolve(e)),e.depth()}childrenCache(){return this.#s}resolve(...e){let t="";for(let s=e.length-1;s>=0;s--){let i=e[s];if(!(!i||i===".")&&(t=t?`${i}/${t}`:i,this.isAbsolute(i)))break}let n=this.#e.get(t);if(n!==void 0)return n;let o=this.cwd.resolve(t).fullpath();return this.#e.set(t,o),o}resolvePosix(...e){let t="";for(let s=e.length-1;s>=0;s--){let i=e[s];if(!(!i||i===".")&&(t=t?`${i}/${t}`:i,this.isAbsolute(i)))break}let n=this.#t.get(t);if(n!==void 0)return n;let o=this.cwd.resolve(t).fullpathPosix();return this.#t.set(t,o),o}relative(e=this.cwd){return typeof e=="string"&&(e=this.cwd.resolve(e)),e.relative()}relativePosix(e=this.cwd){return typeof e=="string"&&(e=this.cwd.resolve(e)),e.relativePosix()}basename(e=this.cwd){return typeof e=="string"&&(e=this.cwd.resolve(e)),e.name}dirname(e=this.cwd){return typeof e=="string"&&(e=this.cwd.resolve(e)),(e.parent||e).fullpath()}async readdir(e=this.cwd,t={withFileTypes:!0}){typeof e=="string"?e=this.cwd.resolve(e):e instanceof Re||(t=e,e=this.cwd);let{withFileTypes:n}=t;if(e.canReaddir()){let o=await e.readdir();return n?o:o.map(s=>s.name)}else return[]}readdirSync(e=this.cwd,t={withFileTypes:!0}){typeof e=="string"?e=this.cwd.resolve(e):e instanceof Re||(t=e,e=this.cwd);let{withFileTypes:n=!0}=t;return e.canReaddir()?n?e.readdirSync():e.readdirSync().map(o=>o.name):[]}async lstat(e=this.cwd){return typeof e=="string"&&(e=this.cwd.resolve(e)),e.lstat()}lstatSync(e=this.cwd){return typeof e=="string"&&(e=this.cwd.resolve(e)),e.lstatSync()}async readlink(e=this.cwd,{withFileTypes:t}={withFileTypes:!1}){typeof e=="string"?e=this.cwd.resolve(e):e instanceof Re||(t=e.withFileTypes,e=this.cwd);let n=await e.readlink();return t?n:n?.fullpath()}readlinkSync(e=this.cwd,{withFileTypes:t}={withFileTypes:!1}){typeof e=="string"?e=this.cwd.resolve(e):e instanceof Re||(t=e.withFileTypes,e=this.cwd);let n=e.readlinkSync();return t?n:n?.fullpath()}async realpath(e=this.cwd,{withFileTypes:t}={withFileTypes:!1}){typeof e=="string"?e=this.cwd.resolve(e):e instanceof Re||(t=e.withFileTypes,e=this.cwd);let n=await e.realpath();return t?n:n?.fullpath()}realpathSync(e=this.cwd,{withFileTypes:t}={withFileTypes:!1}){typeof e=="string"?e=this.cwd.resolve(e):e instanceof Re||(t=e.withFileTypes,e=this.cwd);let n=e.realpathSync();return t?n:n?.fullpath()}async walk(e=this.cwd,t={}){typeof e=="string"?e=this.cwd.resolve(e):e instanceof Re||(t=e,e=this.cwd);let{withFileTypes:n=!0,follow:o=!1,filter:s,walkFilter:i}=t,a=[];(!s||s(e))&&a.push(n?e:e.fullpath());let l=new Set,c=(d,m)=>{l.add(d),d.readdirCB((p,f)=>{if(p)return m(p);let h=f.length;if(!h)return m();let g=()=>{--h===0&&m()};for(let y of f)(!s||s(y))&&a.push(n?y:y.fullpath()),o&&y.isSymbolicLink()?y.realpath().then(S=>S?.isUnknown()?S.lstat():S).then(S=>S?.shouldWalk(l,i)?c(S,g):g()):y.shouldWalk(l,i)?c(y,g):g()},!0)},u=e;return new Promise((d,m)=>{c(u,p=>{if(p)return m(p);d(a)})})}walkSync(e=this.cwd,t={}){typeof e=="string"?e=this.cwd.resolve(e):e instanceof Re||(t=e,e=this.cwd);let{withFileTypes:n=!0,follow:o=!1,filter:s,walkFilter:i}=t,a=[];(!s||s(e))&&a.push(n?e:e.fullpath());let l=new Set([e]);for(let c of l){let u=c.readdirSync();for(let d of u){(!s||s(d))&&a.push(n?d:d.fullpath());let m=d;if(d.isSymbolicLink()){if(!(o&&(m=d.realpathSync())))continue;m.isUnknown()&&m.lstatSync()}m.shouldWalk(l,i)&&l.add(m)}}return a}[Symbol.asyncIterator](){return this.iterate()}iterate(e=this.cwd,t={}){return typeof e=="string"?e=this.cwd.resolve(e):e instanceof Re||(t=e,e=this.cwd),this.stream(e,t)[Symbol.asyncIterator]()}[Symbol.iterator](){return this.iterateSync()}*iterateSync(e=this.cwd,t={}){typeof e=="string"?e=this.cwd.resolve(e):e instanceof Re||(t=e,e=this.cwd);let{withFileTypes:n=!0,follow:o=!1,filter:s,walkFilter:i}=t;(!s||s(e))&&(yield n?e:e.fullpath());let a=new Set([e]);for(let l of a){let c=l.readdirSync();for(let u of c){(!s||s(u))&&(yield n?u:u.fullpath());let d=u;if(u.isSymbolicLink()){if(!(o&&(d=u.realpathSync())))continue;d.isUnknown()&&d.lstatSync()}d.shouldWalk(a,i)&&a.add(d)}}}stream(e=this.cwd,t={}){typeof e=="string"?e=this.cwd.resolve(e):e instanceof Re||(t=e,e=this.cwd);let{withFileTypes:n=!0,follow:o=!1,filter:s,walkFilter:i}=t,a=new Vt({objectMode:!0});(!s||s(e))&&a.write(n?e:e.fullpath());let l=new Set,c=[e],u=0,d=()=>{let m=!1;for(;!m;){let p=c.shift();if(!p){u===0&&a.end();return}u++,l.add(p);let f=(g,y,S=!1)=>{if(g)return a.emit("error",g);if(o&&!S){let b=[];for(let C of y)C.isSymbolicLink()&&b.push(C.realpath().then(v=>v?.isUnknown()?v.lstat():v));if(b.length){Promise.all(b).then(()=>f(null,y,!0));return}}for(let b of y)b&&(!s||s(b))&&(a.write(n?b:b.fullpath())||(m=!0));u--;for(let b of y){let C=b.realpathCached()||b;C.shouldWalk(l,i)&&c.push(C)}m&&!a.flowing?a.once("drain",d):h||d()},h=!0;p.readdirCB(f,!0),h=!1}};return d(),a}streamSync(e=this.cwd,t={}){typeof e=="string"?e=this.cwd.resolve(e):e instanceof Re||(t=e,e=this.cwd);let{withFileTypes:n=!0,follow:o=!1,filter:s,walkFilter:i}=t,a=new Vt({objectMode:!0}),l=new Set;(!s||s(e))&&a.write(n?e:e.fullpath());let c=[e],u=0,d=()=>{let m=!1;for(;!m;){let p=c.shift();if(!p){u===0&&a.end();return}u++,l.add(p);let f=p.readdirSync();for(let h of f)(!s||s(h))&&(a.write(n?h:h.fullpath())||(m=!0));u--;for(let h of f){let g=h;if(h.isSymbolicLink()){if(!(o&&(g=h.realpathSync())))continue;g.isUnknown()&&g.lstatSync()}g.shouldWalk(l,i)&&c.push(g)}}m&&!a.flowing&&a.once("drain",d)};return d(),a}chdir(e=this.cwd){let t=this.cwd;this.cwd=typeof e=="string"?this.cwd.resolve(e):e,this.cwd[Ku](t)}},Qn=class extends Es{sep="\\";constructor(e=process.cwd(),t={}){let{nocase:n=!0}=t;super(e,ua,"\\",{...t,nocase:n}),this.nocase=n;for(let o=this.cwd;o;o=o.parent)o.nocase=this.nocase}parseRootPath(e){return ua.parse(e).root.toUpperCase()}newRoot(e){return new Ts(this.rootPath,Tt,void 0,this.roots,this.nocase,this.childrenCache(),{fs:e})}isAbsolute(e){return e.startsWith("/")||e.startsWith("\\")||/^[a-z]:(\/|\\)/i.test(e)}},er=class extends Es{sep="/";constructor(e=process.cwd(),t={}){let{nocase:n=!1}=t;super(e,PS,"/",{...t,nocase:n}),this.nocase=n}parseRootPath(e){return"/"}newRoot(e){return new vs(this.rootPath,Tt,void 0,this.roots,this.nocase,this.childrenCache(),{fs:e})}isAbsolute(e){return e.startsWith("/")}},oo=class extends er{constructor(e=process.cwd(),t={}){let{nocase:n=!0}=t;super(e,{...t,nocase:n})}},S$=process.platform==="win32"?Ts:vs,Yu=process.platform==="win32"?Qn:process.platform==="darwin"?oo:er;var GS=r=>r.length>=1,VS=r=>r.length>=1,tr=class r{#e;#t;#s;length;#r;#i;#b;#c;#u;#a;#l=!0;constructor(e,t,n,o){if(!GS(e))throw new TypeError("empty pattern list");if(!VS(t))throw new TypeError("empty glob list");if(t.length!==e.length)throw new TypeError("mismatched pattern list and glob list lengths");if(this.length=e.length,n<0||n>=this.length)throw new TypeError("index out of range");if(this.#e=e,this.#t=t,this.#s=n,this.#r=o,this.#s===0){if(this.isUNC()){let[s,i,a,l,...c]=this.#e,[u,d,m,p,...f]=this.#t;c[0]===""&&(c.shift(),f.shift());let h=[s,i,a,l,""].join("/"),g=[u,d,m,p,""].join("/");this.#e=[h,...c],this.#t=[g,...f],this.length=this.#e.length}else if(this.isDrive()||this.isAbsolute()){let[s,...i]=this.#e,[a,...l]=this.#t;i[0]===""&&(i.shift(),l.shift());let c=s+"/",u=a+"/";this.#e=[c,...i],this.#t=[u,...l],this.length=this.#e.length}}}pattern(){return this.#e[this.#s]}isString(){return typeof this.#e[this.#s]=="string"}isGlobstar(){return this.#e[this.#s]===be}isRegExp(){return this.#e[this.#s]instanceof RegExp}globString(){return this.#b=this.#b||(this.#s===0?this.isAbsolute()?this.#t[0]+this.#t.slice(1).join("/"):this.#t.join("/"):this.#t.slice(this.#s).join("/"))}hasMore(){return this.length>this.#s+1}rest(){return this.#i!==void 0?this.#i:this.hasMore()?(this.#i=new r(this.#e,this.#t,this.#s+1,this.#r),this.#i.#a=this.#a,this.#i.#u=this.#u,this.#i.#c=this.#c,this.#i):this.#i=null}isUNC(){let e=this.#e;return this.#u!==void 0?this.#u:this.#u=this.#r==="win32"&&this.#s===0&&e[0]===""&&e[1]===""&&typeof e[2]=="string"&&!!e[2]&&typeof e[3]=="string"&&!!e[3]}isDrive(){let e=this.#e;return this.#c!==void 0?this.#c:this.#c=this.#r==="win32"&&this.#s===0&&this.length>1&&typeof e[0]=="string"&&/^[a-z]:$/i.test(e[0])}isAbsolute(){let e=this.#e;return this.#a!==void 0?this.#a:this.#a=e[0]===""&&e.length>1||this.isDrive()||this.isUNC()}root(){let e=this.#e[0];return typeof e=="string"&&this.isAbsolute()&&this.#s===0?e:""}checkFollowGlobstar(){return!(this.#s===0||!this.isGlobstar()||!this.#l)}markFollowGlobstar(){return this.#s===0||!this.isGlobstar()||!this.#l?!1:(this.#l=!1,!0)}};var qS=typeof process=="object"&&process&&typeof process.platform=="string"?process.platform:"linux",nr=class{relative;relativeChildren;absolute;absoluteChildren;platform;mmopts;constructor(e,{nobrace:t,nocase:n,noext:o,noglobstar:s,platform:i=qS}){this.relative=[],this.absolute=[],this.relativeChildren=[],this.absoluteChildren=[],this.platform=i,this.mmopts={dot:!0,nobrace:t,nocase:n,noext:o,noglobstar:s,optimizationLevel:2,platform:i,nocomment:!0,nonegate:!0};for(let a of e)this.add(a)}add(e){let t=new $e(e,this.mmopts);for(let n=0;n<t.set.length;n++){let o=t.set[n],s=t.globParts[n];if(!o||!s)throw new Error("invalid pattern object");for(;o[0]==="."&&s[0]===".";)o.shift(),s.shift();let i=new tr(o,s,0,this.platform),a=new $e(i.globString(),this.mmopts),l=s[s.length-1]==="**",c=i.isAbsolute();c?this.absolute.push(a):this.relative.push(a),l&&(c?this.absoluteChildren.push(a):this.relativeChildren.push(a))}}ignored(e){let t=e.fullpath(),n=`${t}/`,o=e.relative()||".",s=`${o}/`;for(let i of this.relative)if(i.match(o)||i.match(s))return!0;for(let i of this.absolute)if(i.match(t)||i.match(n))return!0;return!1}childrenIgnored(e){let t=e.fullpath()+"/",n=(e.relative()||".")+"/";for(let o of this.relativeChildren)if(o.match(n))return!0;for(let o of this.absoluteChildren)if(o.match(t))return!0;return!1}};var pa=class r{store;constructor(e=new Map){this.store=e}copy(){return new r(new Map(this.store))}hasWalked(e,t){return this.store.get(e.fullpath())?.has(t.globString())}storeWalked(e,t){let n=e.fullpath(),o=this.store.get(n);o?o.add(t.globString()):this.store.set(n,new Set([t.globString()]))}},ha=class{store=new Map;add(e,t,n){let o=(t?2:0)|(n?1:0),s=this.store.get(e);this.store.set(e,s===void 0?o:o&s)}entries(){return[...this.store.entries()].map(([e,t])=>[e,!!(t&2),!!(t&1)])}},fa=class{store=new Map;add(e,t){if(!e.canReaddir())return;let n=this.store.get(e);n?n.find(o=>o.globString()===t.globString())||n.push(t):this.store.set(e,[t])}get(e){let t=this.store.get(e);if(!t)throw new Error("attempting to walk unknown path");return t}entries(){return this.keys().map(e=>[e,this.store.get(e)])}keys(){return[...this.store.keys()].filter(e=>e.canReaddir())}},so=class r{hasWalkedCache;matches=new ha;subwalks=new fa;patterns;follow;dot;opts;constructor(e,t){this.opts=e,this.follow=!!e.follow,this.dot=!!e.dot,this.hasWalkedCache=t?t.copy():new pa}processPatterns(e,t){this.patterns=t;let n=t.map(o=>[e,o]);for(let[o,s]of n){this.hasWalkedCache.storeWalked(o,s);let i=s.root(),a=s.isAbsolute()&&this.opts.absolute!==!1;if(i){o=o.resolve(i==="/"&&this.opts.root!==void 0?this.opts.root:i);let d=s.rest();if(d)s=d;else{this.matches.add(o,!0,!1);continue}}if(o.isENOENT())continue;let l,c,u=!1;for(;typeof(l=s.pattern())=="string"&&(c=s.rest());)o=o.resolve(l),s=c,u=!0;if(l=s.pattern(),c=s.rest(),u){if(this.hasWalkedCache.hasWalked(o,s))continue;this.hasWalkedCache.storeWalked(o,s)}if(typeof l=="string"){let d=l===".."||l===""||l===".";this.matches.add(o.resolve(l),a,d);continue}else if(l===be){(!o.isSymbolicLink()||this.follow||s.checkFollowGlobstar())&&this.subwalks.add(o,s);let d=c?.pattern(),m=c?.rest();if(!c||(d===""||d===".")&&!m)this.matches.add(o,a,d===""||d===".");else if(d===".."){let p=o.parent||o;m?this.hasWalkedCache.hasWalked(p,m)||this.subwalks.add(p,m):this.matches.add(p,a,!0)}}else l instanceof RegExp&&this.subwalks.add(o,s)}return this}subwalkTargets(){return this.subwalks.keys()}child(){return new r(this.opts,this.hasWalkedCache)}filterEntries(e,t){let n=this.subwalks.get(e),o=this.child();for(let s of t)for(let i of n){let a=i.isAbsolute(),l=i.pattern(),c=i.rest();l===be?o.testGlobstar(s,i,c,a):l instanceof RegExp?o.testRegExp(s,l,c,a):o.testString(s,l,c,a)}return o}testGlobstar(e,t,n,o){if((this.dot||!e.name.startsWith("."))&&(t.hasMore()||this.matches.add(e,o,!1),e.canReaddir()&&(this.follow||!e.isSymbolicLink()?this.subwalks.add(e,t):e.isSymbolicLink()&&(n&&t.checkFollowGlobstar()?this.subwalks.add(e,n):t.markFollowGlobstar()&&this.subwalks.add(e,t)))),n){let s=n.pattern();if(typeof s=="string"&&s!==".."&&s!==""&&s!==".")this.testString(e,s,n.rest(),o);else if(s===".."){let i=e.parent||e;this.subwalks.add(i,n)}else s instanceof RegExp&&this.testRegExp(e,s,n.rest(),o)}}testRegExp(e,t,n,o){t.test(e.name)&&(n?this.subwalks.add(e,n):this.matches.add(e,o,!1))}testString(e,t,n,o){e.isNamed(t)&&(n?this.subwalks.add(e,n):this.matches.add(e,o,!1))}};var KS=(r,e)=>typeof r=="string"?new nr([r],e):Array.isArray(r)?new nr(r,e):r,xs=class{path;patterns;opts;seen=new Set;paused=!1;aborted=!1;#e=[];#t;#s;signal;maxDepth;includeChildMatches;constructor(e,t,n){if(this.patterns=e,this.path=t,this.opts=n,this.#s=!n.posix&&n.platform==="win32"?"\\":"/",this.includeChildMatches=n.includeChildMatches!==!1,(n.ignore||!this.includeChildMatches)&&(this.#t=KS(n.ignore??[],n),!this.includeChildMatches&&typeof this.#t.add!="function")){let o="cannot ignore child matches, ignore lacks add() method.";throw new Error(o)}this.maxDepth=n.maxDepth||1/0,n.signal&&(this.signal=n.signal,this.signal.addEventListener("abort",()=>{this.#e.length=0}))}#r(e){return this.seen.has(e)||!!this.#t?.ignored?.(e)}#i(e){return!!this.#t?.childrenIgnored?.(e)}pause(){this.paused=!0}resume(){if(this.signal?.aborted)return;this.paused=!1;let e;for(;!this.paused&&(e=this.#e.shift());)e()}onResume(e){this.signal?.aborted||(this.paused?this.#e.push(e):e())}async matchCheck(e,t){if(t&&this.opts.nodir)return;let n;if(this.opts.realpath){if(n=e.realpathCached()||await e.realpath(),!n)return;e=n}let s=e.isUnknown()||this.opts.stat?await e.lstat():e;if(this.opts.follow&&this.opts.nodir&&s?.isSymbolicLink()){let i=await s.realpath();i&&(i.isUnknown()||this.opts.stat)&&await i.lstat()}return this.matchCheckTest(s,t)}matchCheckTest(e,t){return e&&(this.maxDepth===1/0||e.depth()<=this.maxDepth)&&(!t||e.canReaddir())&&(!this.opts.nodir||!e.isDirectory())&&(!this.opts.nodir||!this.opts.follow||!e.isSymbolicLink()||!e.realpathCached()?.isDirectory())&&!this.#r(e)?e:void 0}matchCheckSync(e,t){if(t&&this.opts.nodir)return;let n;if(this.opts.realpath){if(n=e.realpathCached()||e.realpathSync(),!n)return;e=n}let s=e.isUnknown()||this.opts.stat?e.lstatSync():e;if(this.opts.follow&&this.opts.nodir&&s?.isSymbolicLink()){let i=s.realpathSync();i&&(i?.isUnknown()||this.opts.stat)&&i.lstatSync()}return this.matchCheckTest(s,t)}matchFinish(e,t){if(this.#r(e))return;if(!this.includeChildMatches&&this.#t?.add){let s=`${e.relativePosix()}/**`;this.#t.add(s)}let n=this.opts.absolute===void 0?t:this.opts.absolute;this.seen.add(e);let o=this.opts.mark&&e.isDirectory()?this.#s:"";if(this.opts.withFileTypes)this.matchEmit(e);else if(n){let s=this.opts.posix?e.fullpathPosix():e.fullpath();this.matchEmit(s+o)}else{let s=this.opts.posix?e.relativePosix():e.relative(),i=this.opts.dotRelative&&!s.startsWith(".."+this.#s)?"."+this.#s:"";this.matchEmit(s?i+s+o:"."+o)}}async match(e,t,n){let o=await this.matchCheck(e,n);o&&this.matchFinish(o,t)}matchSync(e,t,n){let o=this.matchCheckSync(e,n);o&&this.matchFinish(o,t)}walkCB(e,t,n){this.signal?.aborted&&n(),this.walkCB2(e,t,new so(this.opts),n)}walkCB2(e,t,n,o){if(this.#i(e))return o();if(this.signal?.aborted&&o(),this.paused){this.onResume(()=>this.walkCB2(e,t,n,o));return}n.processPatterns(e,t);let s=1,i=()=>{--s===0&&o()};for(let[a,l,c]of n.matches.entries())this.#r(a)||(s++,this.match(a,l,c).then(()=>i()));for(let a of n.subwalkTargets()){if(this.maxDepth!==1/0&&a.depth()>=this.maxDepth)continue;s++;let l=a.readdirCached();a.calledReaddir()?this.walkCB3(a,l,n,i):a.readdirCB((c,u)=>this.walkCB3(a,u,n,i),!0)}i()}walkCB3(e,t,n,o){n=n.filterEntries(e,t);let s=1,i=()=>{--s===0&&o()};for(let[a,l,c]of n.matches.entries())this.#r(a)||(s++,this.match(a,l,c).then(()=>i()));for(let[a,l]of n.subwalks.entries())s++,this.walkCB2(a,l,n.child(),i);i()}walkCBSync(e,t,n){this.signal?.aborted&&n(),this.walkCB2Sync(e,t,new so(this.opts),n)}walkCB2Sync(e,t,n,o){if(this.#i(e))return o();if(this.signal?.aborted&&o(),this.paused){this.onResume(()=>this.walkCB2Sync(e,t,n,o));return}n.processPatterns(e,t);let s=1,i=()=>{--s===0&&o()};for(let[a,l,c]of n.matches.entries())this.#r(a)||this.matchSync(a,l,c);for(let a of n.subwalkTargets()){if(this.maxDepth!==1/0&&a.depth()>=this.maxDepth)continue;s++;let l=a.readdirSync();this.walkCB3Sync(a,l,n,i)}i()}walkCB3Sync(e,t,n,o){n=n.filterEntries(e,t);let s=1,i=()=>{--s===0&&o()};for(let[a,l,c]of n.matches.entries())this.#r(a)||this.matchSync(a,l,c);for(let[a,l]of n.subwalks.entries())s++,this.walkCB2Sync(a,l,n.child(),i);i()}},io=class extends xs{matches=new Set;constructor(e,t,n){super(e,t,n)}matchEmit(e){this.matches.add(e)}async walk(){if(this.signal?.aborted)throw this.signal.reason;return this.path.isUnknown()&&await this.path.lstat(),await new Promise((e,t)=>{this.walkCB(this.path,this.patterns,()=>{this.signal?.aborted?t(this.signal.reason):e(this.matches)})}),this.matches}walkSync(){if(this.signal?.aborted)throw this.signal.reason;return this.path.isUnknown()&&this.path.lstatSync(),this.walkCBSync(this.path,this.patterns,()=>{if(this.signal?.aborted)throw this.signal.reason}),this.matches}},ao=class extends xs{results;constructor(e,t,n){super(e,t,n),this.results=new Vt({signal:this.signal,objectMode:!0}),this.results.on("drain",()=>this.resume()),this.results.on("resume",()=>this.resume())}matchEmit(e){this.results.write(e),this.results.flowing||this.pause()}stream(){let e=this.path;return e.isUnknown()?e.lstat().then(()=>{this.walkCB(e,this.patterns,()=>this.results.end())}):this.walkCB(e,this.patterns,()=>this.results.end()),this.results}streamSync(){return this.path.isUnknown()&&this.path.lstatSync(),this.walkCBSync(this.path,this.patterns,()=>this.results.end()),this.results}};var XS=typeof process=="object"&&process&&typeof process.platform=="string"?process.platform:"linux",dt=class{absolute;cwd;root;dot;dotRelative;follow;ignore;magicalBraces;mark;matchBase;maxDepth;nobrace;nocase;nodir;noext;noglobstar;pattern;platform;realpath;scurry;stat;signal;windowsPathsNoEscape;withFileTypes;includeChildMatches;opts;patterns;constructor(e,t){if(!t)throw new TypeError("glob options required");if(this.withFileTypes=!!t.withFileTypes,this.signal=t.signal,this.follow=!!t.follow,this.dot=!!t.dot,this.dotRelative=!!t.dotRelative,this.nodir=!!t.nodir,this.mark=!!t.mark,t.cwd?(t.cwd instanceof URL||t.cwd.startsWith("file://"))&&(t.cwd=YS(t.cwd)):this.cwd="",this.cwd=t.cwd||"",this.root=t.root,this.magicalBraces=!!t.magicalBraces,this.nobrace=!!t.nobrace,this.noext=!!t.noext,this.realpath=!!t.realpath,this.absolute=t.absolute,this.includeChildMatches=t.includeChildMatches!==!1,this.noglobstar=!!t.noglobstar,this.matchBase=!!t.matchBase,this.maxDepth=typeof t.maxDepth=="number"?t.maxDepth:1/0,this.stat=!!t.stat,this.ignore=t.ignore,this.withFileTypes&&this.absolute!==void 0)throw new Error("cannot set absolute and withFileTypes:true");if(typeof e=="string"&&(e=[e]),this.windowsPathsNoEscape=!!t.windowsPathsNoEscape||t.allowWindowsEscape===!1,this.windowsPathsNoEscape&&(e=e.map(l=>l.replace(/\\/g,"/"))),this.matchBase){if(t.noglobstar)throw new TypeError("base matching requires globstar");e=e.map(l=>l.includes("/")?l:`./**/${l}`)}if(this.pattern=e,this.platform=t.platform||XS,this.opts={...t,platform:this.platform},t.scurry){if(this.scurry=t.scurry,t.nocase!==void 0&&t.nocase!==t.scurry.nocase)throw new Error("nocase option contradicts provided scurry option")}else{let l=t.platform==="win32"?Qn:t.platform==="darwin"?oo:t.platform?er:Yu;this.scurry=new l(this.cwd,{nocase:t.nocase,fs:t.fs})}this.nocase=this.scurry.nocase;let n=this.platform==="darwin"||this.platform==="win32",o={...t,dot:this.dot,matchBase:this.matchBase,nobrace:this.nobrace,nocase:this.nocase,nocaseMagicOnly:n,nocomment:!0,noext:this.noext,nonegate:!0,optimizationLevel:2,platform:this.platform,windowsPathsNoEscape:this.windowsPathsNoEscape,debug:!!this.opts.debug},s=this.pattern.map(l=>new $e(l,o)),[i,a]=s.reduce((l,c)=>(l[0].push(...c.set),l[1].push(...c.globParts),l),[[],[]]);this.patterns=i.map((l,c)=>{let u=a[c];if(!u)throw new Error("invalid pattern object");return new tr(l,u,0,this.platform)})}async walk(){return[...await new io(this.patterns,this.scurry.cwd,{...this.opts,maxDepth:this.maxDepth!==1/0?this.maxDepth+this.scurry.cwd.depth():1/0,platform:this.platform,nocase:this.nocase,includeChildMatches:this.includeChildMatches}).walk()]}walkSync(){return[...new io(this.patterns,this.scurry.cwd,{...this.opts,maxDepth:this.maxDepth!==1/0?this.maxDepth+this.scurry.cwd.depth():1/0,platform:this.platform,nocase:this.nocase,includeChildMatches:this.includeChildMatches}).walkSync()]}stream(){return new ao(this.patterns,this.scurry.cwd,{...this.opts,maxDepth:this.maxDepth!==1/0?this.maxDepth+this.scurry.cwd.depth():1/0,platform:this.platform,nocase:this.nocase,includeChildMatches:this.includeChildMatches}).stream()}streamSync(){return new ao(this.patterns,this.scurry.cwd,{...this.opts,maxDepth:this.maxDepth!==1/0?this.maxDepth+this.scurry.cwd.depth():1/0,platform:this.platform,nocase:this.nocase,includeChildMatches:this.includeChildMatches}).streamSync()}iterateSync(){return this.streamSync()[Symbol.iterator]()}[Symbol.iterator](){return this.iterateSync()}iterate(){return this.stream()[Symbol.asyncIterator]()}[Symbol.asyncIterator](){return this.iterate()}};var ga=(r,e={})=>{Array.isArray(r)||(r=[r]);for(let t of r)if(new $e(t,e).hasMagic())return!0;return!1};function As(r,e={}){return new dt(r,e).streamSync()}function Zu(r,e={}){return new dt(r,e).stream()}function Rs(r,e={}){return new dt(r,e).walkSync()}async function Xu(r,e={}){return new dt(r,e).walk()}function Is(r,e={}){return new dt(r,e).iterateSync()}function Qu(r,e={}){return new dt(r,e).iterate()}var JS=As,ZS=Object.assign(Zu,{sync:As}),QS=Is,ew=Object.assign(Qu,{sync:Is}),tw=Object.assign(Rs,{stream:As,iterate:Is}),Ju=Object.assign(Xu,{glob:Xu,globSync:Rs,sync:tw,globStream:Zu,stream:ZS,globStreamSync:As,streamSync:JS,globIterate:Qu,iterate:ew,globIterateSync:Is,iterateSync:QS,Glob:dt,hasMagic:ga,escape:Kn,unescape:at});Ju.glob=Ju;import Ps from"path";import nw from"yaml";import{z as tm}from"zod";var ut=(t=>(t.TEST=`${bi}.yaml`,t.MODULE=`${Ci}.yaml`,t))(ut||{}),lo=[`**/*.${ut.TEST}`,`**/*.${ut.MODULE}`],rw=50,ow=tm.object({fileType:tm.nativeEnum(te)});function Ft(r,e){let t={tests:{},modules:{}},n=r.config.include??lo,o=Array.from(r.config.exclude??[]).concat(_l),s=Rs(n,{absolute:!1,cwd:r.rootDir,ignore:o,dotRelative:!1,maxDepth:rw,nodir:!0});for(let i of s)sw(r.rootDir,i,t,e);return t}function sw(r,e,t,n){let o=Ps.join(r,e),s;try{s=em.readFileSync(o,"utf-8")}catch(d){n.warn(`Could not read possible Momentic file at ${o}, skipping: ${d}`);return}let i;try{if(i=nw.parse(s),typeof i!="object"||i===null)throw new Error("The YAML document should parse as a map with key-value pairs")}catch(d){n.warn(`Could not parse possible Momentic file at ${o}, skipping: ${d}`);return}let a=ow.safeParse(i);if(a.error){n.warn(`Possible Momentic file at ${o} does not have a 'fileType', skipping: ${a.error}`);return}let l=a.data.fileType,c;try{c=em.statSync(o)}catch(d){n.warn(`Skipping path '${o}' because it could not be stat, skipping: ${d}`);return}let u={relativePath:e,fullFilePath:o,platformSep:Ps.sep,fullPathSegments:o.split(Ps.sep),fileName:Ps.basename(o),lastModified:c.mtime,createdAt:c.ctime};switch(l){case te.TEST:try{let d=pe.parse(i);t.tests[d.id]={type:te.TEST,name:d.name,id:d.id,...u};return}catch(d){n.warn(`Skipping file '${o}' because it is missing Momentic test metadata: ${d}`);return}case te.MODULE:try{let d=qe.parse(i);t.modules[d.moduleId]={type:te.MODULE,name:d.name,id:d.moduleId,...u};return}catch(d){n.warn(`Skipping file '${o}' because it is missing Momentic module metadata: ${d}`);return}default:n.warn(`Unsupported file type ${l}, skipping...`);return}}import Os from"fs";import{v4 as iw}from"uuid";import Ls from"yaml";function nm(r,e){let t=e.modules[r.moduleId]?.fullFilePath;if(!t)throw new Error(`Tried to update module ${r.moduleId} that could not be found on disk`);let n=Os.readFileSync(t,"utf-8"),o=Ls.parse(n),s={fileType:te.MODULE,...o,...r},i=Ls.stringify(s);Os.writeFileSync(t,i,"utf-8")}async function rm(r,e,t,n,o){o||(o=`${xe(r)}.module.yaml`);let s=iw(),{stepsToSave:i}=await yt({steps:n}),a={fileType:te.MODULE,schemaVersion:ke,moduleId:s,name:r,description:e,enabled:t,steps:i},l=Ls.stringify(a);return Os.writeFileSync(o,l,"utf-8"),{moduleId:s,name:r,description:e,enabled:t,steps:n}}function Ms(r,e){let t=Os.readFileSync(r,"utf-8"),n=Ls.parse(t);try{return Ti.parse(n)}catch(o){throw e.error({err:o,moduleFilePath:r,moduleContents:t},`${r} does not parse as a valid Momentic module`),o}}async function ya(r,e,t,n){let o=Ms(r.fullFilePath,t),{resolvedSteps:s}=await Ri({rawSteps:o.steps,metadata:{id:o.moduleId,schemaVersion:o.schemaVersion},resolvedModuleCache:n,logger:t,callbacks:{onFetchModule:async({id:a})=>{let l=e.modules[a]?.fullFilePath;if(l)return Ms(l,t)}}}),i={...o,steps:s};return n&&(n[r.id]=i),i}async function om(r,e){let t={};return await Promise.all(Object.values(r.modules).map(async n=>{await ya(n,r,e,t)})),Array.from(Object.values(t))}async function sm(r,e){let t=await Pc(r);if(Object.keys(t.modules).length)throw new Error("A brand new test should not contain any modules in it");let n=xe(e),o=`${n}.${ut.TEST}`;return Ut.writeFileSync(o,t.test,"utf-8"),n}function Ns(r,e){if(!Ut.existsSync(e))throw new Error(`Test not found at path: ${hn}`);let t=Ut.readFileSync(e,"utf-8"),o={...co.parse(t),...r},s=pe.parse(o),i={fileType:te.TEST,...s,steps:o.steps},a=co.stringify(i);Ut.writeFileSync(e,a,"utf-8")}function Sa(r,e,t=r){let n=r.split(hn.sep).pop()??"";if(Mr.includes(n))return e.warn(`Skipping directory '${r}' because it is likely an artifact folder.`),[];let o=Ut.readdirSync(r),s=[];return o.forEach(i=>{let a=hn.join(r,i),l;try{l=Ut.statSync(a)}catch(c){e.warn({err:c},`Skipping path '${a}' because it could not be read.`);return}if(l.isDirectory())s=s.concat(Sa(a,e,t));else if(i.endsWith(".yaml")){let c=Ut.readFileSync(a,"utf-8"),u=hn.relative(hn.resolve(t),hn.resolve(a));try{let d=co.parse(c),m=pe.parse(d);s.push({id:m.id,name:m.name,fullPathSegments:a.split(hn.sep),testPath:u,fileName:i,lastModified:l.mtime,createdAt:l.ctime})}catch{e.warn(`Skipping file '${a}' because it does not parse as a valid Momentic test.`)}}}),s}function im(r){let e;try{e=Ut.readFileSync(r,"utf8"),e=e.replace(/\r\n|\r/g,`
|
|
1785
|
+
`)}catch(n){throw new Error(`Could not read test file ${r}: ${n}`)}let t;try{t=co.parse(e)}catch(n){throw new Error(`Could not parse test file ${r} as YAML: ${n}`)}return pe.parse(t)}async function _s(r,e,t){let n=Ut.readFileSync(r,"utf-8"),o=co.parse(n);if(!o.steps||!Array.isArray(o.steps))throw new Error(`Test ${r} is missing steps`);let s;try{s=pe.parse(o)}catch(a){throw new Error(`Test ${r} is missing metadata or has invalid metadata: ${a}`)}let{resolvedTest:i}=await Ac({rawSteps:o.steps,metadata:s,logger:e,callbacks:{onFetchModule:async({id:a,logger:l})=>{let c=t.modules[a]?.fullFilePath;if(c)return Ms(c,l)}}});return i}import aw from"dotenv";import{readFileSync as lw}from"fs";import cw from"path";function am(r){return(r.config.environments??[]).map(e=>wa(e.name,r))}function wa(r,e){let t=(e.config.environments??[]).find(s=>s.name===r);if(!t)throw new Error(`Environment ${r} not found in local workspace configuration file`);let n={[ae]:t.baseUrl};return t.envVariables&&Object.assign(n,t.envVariables),t.envFile&&Object.assign(n,aw.parse(lw(cw.resolve(e.rootDir,t.envFile)))),{name:r,variables:n}}import{readFileSync as dw,readdirSync as uw,writeFileSync as mw}from"fs";import rr,{dirname as pw}from"path";import{cwd as hw}from"process";import lm from"yaml";import{z as nt}from"zod";var uo="momentic.config.yaml",fw=nt.object({name:nt.string().refine(r=>/^[a-zA-Z0-9-]+$/.test(r)).describe("name for this environment, must be unique per workspace and alphanumeric + dashes"),baseUrl:nt.string(),envFile:nt.string().optional().describe("path to a file on disk to read environment variables from. can be relative to workspace root or absolute."),envVariables:nt.record(nt.string(),nt.string()).optional()}),gw=nt.object({name:nt.string().describe("name for this workspace, e.g. app or team name"),include:nt.string().array().optional().describe("list of glob patterns that match momentic files (optional)"),exclude:nt.string().array().optional().describe("opposite of include, takes precedence over include"),environments:nt.array(fw).optional()});function cm(r){let e;try{e=dw(r,"utf-8")}catch(n){T.warn(`Could not read possible Momentic configuration file at ${r}: ${n}`);return}let t;try{if(t=lm.parse(e),typeof t!="object"||t===null)throw new Error("The top-level document should parse as a map with key-value pairs")}catch(n){T.warn(`Possible Momentic configuration file at ${r} does not parse as valid YAML: ${n}`);return}try{return gw.parse(t)}catch(n){T.warn(`Possible Momentic configuration file at ${r} does not adhere to the required schema: ${n}`);return}}function yw(){let r=[],e=hw(),t=rr.parse(e).root,n=15,o=0;for(;o<n&&e!==t;){o++;let s=rr.basename(e);if(Mr.includes(s))return T.warn(`Stopping search for Momentic workspaces since the current directory name (${s}) is likely a system artifact folder.`),r;for(let i of uw(e))if(i.endsWith(uo)){let a=rr.join(e,i),l=cm(a);l&&r.push({configFilePath:a,config:l,rootDir:pw(a)})}if(r.length)return r;e=rr.dirname(e)}return r}function mo(r){if(r){r=rr.resolve(r);let t=cm(r);return t||(T.error("No valid Momentic workspace file available, exiting..."),process.exit(1)),{config:t,configFilePath:r,rootDir:rr.dirname(r)}}let e=yw();return e.length>1?(T.error(`Multiple valid workspace files were found in the same directory. Please use the '-c / --config' flag to disambiguate:
|
|
1786
|
+
${e.map(t=>t.configFilePath)}`),process.exit(1)):e.length===0&&(T.error("No valid Momentic workspace file available, exiting..."),process.exit(1)),e[0]}function or(r,e){let t=lm.stringify(r);mw(e,t)}var Ca="https://api.momentic.ai",dm,um=r=>{Ca=r},po=()=>Ca,mm=r=>{dm=r},$t=()=>dm,sr,ba,pm=async r=>{if(sr)return sr;let e=new Ue({baseUrl:Ca,apiKey:r});try{return sr=await e.getOrgId(),ba=r,sr}catch(t){throw new Error(`Error checking API key against server: ${t}`)}},ks=()=>{if(!sr)throw new Error("Your organization ID appears invalid. Please contact Momentic support.");return sr},hm=()=>{if(!ba)throw new Error("Your API key appears invalid. Please contact Momentic support.");return ba};function ze(r){return function(...e){let t=e[e.length-1],n=r(...e);Promise.resolve(n).catch(t)}}var fm=Sw();fm.get("/",ze((r,e)=>{let t=am($t());e.status(200).json(t)}));var gm=fm;import{Router as vw}from"express";import ym,{multistream as ww}from"pino";import bw from"pino-pretty";var Ta=new Map,Cw=!0,va=class r{consoleLogger;ddClientToken;hostname;bindingAttributes;excludeAttributesInConsoleLogs;excludeTimestamps;disableConsoleLogs;site="https://http-intake.logs.us5.datadoghq.com/api/v2/logs";constructor({bindings:e,clientToken:t,hostname:n,excludeAttributesInConsoleLogs:o,excludeTimestamps:s,disableConsoleLogs:i}){this.ddClientToken=t,this.hostname=n,this.excludeAttributesInConsoleLogs=o,this.excludeTimestamps=s,this.disableConsoleLogs=i,this.bindingAttributes={...e,env:"production"};let a={base:o?{}:this.bindingAttributes,errorKey:"err",level:"debug",timestamp:!s};this.consoleLogger=Cw?ym(a):ym(a,ww([{stream:bw({colorize:!0})}]))}child(e){return new r({clientToken:this.ddClientToken,bindings:{...this.bindingAttributes,...e},hostname:this.hostname,excludeAttributesInConsoleLogs:this.excludeAttributesInConsoleLogs,disableConsoleLogs:this.disableConsoleLogs})}flush(e){this.disableConsoleLogs||this.consoleLogger.flush(e)}log(e,t,n,...o){if(t&&n===void 0&&(n=`${t}`,t={}),this.disableConsoleLogs||this.consoleLogger[e](e==="error"?t:{testId:t.testId,runId:t.runId},n,...o),typeof t=="object"&&t&&"err"in t&&t.err instanceof Error){let i={};for(let a of Object.getOwnPropertyNames(t.err))i[a]=t.err[a];i.name=t.err.name,t.err=i}let s=Object.assign({},this.bindingAttributes,t&&typeof t=="object"?t:{});o.length>0&&(s.args=o),(async()=>{try{let i=await fetch(this.site,{method:"POST",headers:{Accept:"application/json","Content-Type":"application/json","DD-API-KEY":this.ddClientToken},body:JSON.stringify([{ddsource:this.bindingAttributes.app,hostname:this.hostname??"vercel",service:"momentic",message:{message:n||"",...s,level:e}}])});if(!i.ok)throw new Error(`Failed to log to Datadog: ${i.statusText})}`)}catch(i){this.disableConsoleLogs||this.consoleLogger.warn({obj:t,msg:n,args:o,err:i},"Failed to log to Datadog")}})()}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}setMinLevel(e){this.consoleLogger.level=e}enableConsoleLogs(){this.disableConsoleLogs=!1}},Ds=({app:r,clientToken:e,hostname:t,excludeAttributesInConsoleLogs:n,excludeTimestamps:o,disableConsoleLogs:s})=>{if(!process.env.DD_CLIENT_TOKEN&&!process.env.NEXT_PUBLIC_DD_CLIENT_TOKEN&&!e)throw new Error("Missing DD_CLIENT_TOKEN");return Ta.has(r)||Ta.set(r,new va({bindings:{app:r},hostname:t,clientToken:e||process.env.NEXT_PUBLIC_DD_CLIENT_TOKEN||process.env.DD_CLIENT_TOKEN,excludeAttributesInConsoleLogs:n,excludeTimestamps:o,disableConsoleLogs:s})),Ta.get(r)};import{hostname as Tw}from"os";var rt=Ds({app:"desktop-server",clientToken:"pubcfd7516a5c0ba852b42675cd97bee027",hostname:Tw(),excludeAttributesInConsoleLogs:!0,excludeTimestamps:!0,disableConsoleLogs:!0});var Fs=vw();Fs.get("/",ze(async(r,e)=>{let t=Ft($t(),T),o=(await om(t,rt)).filter(s=>s.enabled??!0);e.status(200).json(o)}));Fs.post("/",ze(async(r,e)=>{let t;try{t=Ml.parse(r.body)}catch(o){e.status(400).json({error:`Invalid request body: ${o}`});return}try{Lr(t.name)}catch(o){e.status(400).json({error:`Invalid module name: ${o}`});return}let n=await rm(t.name,t.description,t.enabled,t.steps);e.status(201).json(n)}));Fs.get("/:moduleId",ze(async(r,e)=>{if(!r.params.moduleId){e.status(400).json({error:"Missing moduleId in url path."});return}let t=Ft($t(),T),n=t.modules[r.params.moduleId];if(!n){e.status(404).json({error:"Module not found."});return}try{let o=await ya(n,t,T);e.json(o)}catch(o){e.status(400).json({err:o})}}));var Sm=Fs;import{Router as Ew}from"express";import{existsSync as xw}from"fs";import{v4 as Aw}from"uuid";var fn=Ew();fn.get("/",ze((r,e)=>{let t=$t(),n=Ft(t,T),o=Array.from(Object.values(n.tests));e.status(200).json(o)}));fn.post("/",ze(async(r,e)=>{let t;try{t=Ll.parse(r.body)}catch(a){e.status(400).json({error:`Invalid request body: ${a}`});return}try{Lr(t.name)}catch(a){e.status(400).json({error:a.message});return}let o={id:Aw(),name:t.name,baseUrl:t.baseUrl,schemaVersion:ke,advanced:{disableAICaching:!1,viewport:t.viewport??Rt},retries:0,steps:[]};t.environment&&(o.envs=[{name:t.environment,default:!0}]);let s=await sm(o,t.name),i={...o,testPath:s};e.status(201).json(i)}));fn.get("/:testPath",ze(async(r,e)=>{let{testPath:t}=r.params;if(!t){e.status(400).json({error:"Missing testPath in url path."});return}if(!xw(t)){e.status(400).json({error:`No file found at path: ${t}`});return}let n=Ft($t(),T),o=await _s(t,rt,n);e.status(200).json(o)}));fn.patch("/:testPath/metadata",ze(async(r,e)=>{if(!r.params.testPath){e.status(400).json({error:"Missing testPath in url path."});return}let t;try{t=Ol.parse(r.body)}catch(n){e.status(400).json({error:`Invalid request body: ${n}`});return}Ns(t,r.params.testPath),e.status(201).json({message:"ok"})}));fn.patch("/:testPath",ze(async(r,e)=>{let{testPath:t}=r.params;if(!t){e.status(400).json({error:"Missing testPath in url path."});return}let n;try{n=Pl.parse(r.body)}catch(u){e.status(400).json({error:`Invalid request body: ${u}`});return}let o;try{o=im(t)}catch(u){e.status(400).json({error:`Existing test file on disk is invalid: ${u}`});return}let s=Ft($t(),T),{stepsToSave:i,moduleUpdates:a,cachesToSave:l}=await yt({steps:n.steps,cacheCreationParams:{testId:o.id,orgId:ks()}});a.forEach(u=>{nm({...u,schemaVersion:ke},s)}),Ns({schemaVersion:ke,steps:i},t),await new Ue({apiKey:hm(),baseUrl:po()}).updateStepCaches({entries:l,testId:o.id}),e.status(201).json({message:"ok"})}));fn.patch("/:testPath/environments",ze(async(r,e)=>{let{testPath:t}=r.params;if(!t){e.status(400).json({error:"Missing testPath in url path."});return}let n;try{n=Nl.parse(r.body)}catch(o){e.status(400).json({error:`Invalid request body: ${o}`});return}Ns({envs:n.defaultEnv?[{name:n.defaultEnv,default:!0}]:[]},t),e.status(201).json({message:"ok"})}));var wm=fn;async function bm(r){let{momenticServerUrl:e,apiKey:t,serverPort:n,appPort:o,staticDir:s,devicePixelRatio:i,workspace:a}=r;mm(a),e&&um(e),rt.debug(r,"Initializing desktop server");let l=await pm(t);rt.debug({orgId:l},"Checking API key successful");let u=`http://localhost:${n}`;o&&(u=`http://localhost:${o}`);let d=Lw(s);await new Promise(y=>{d.listen(n,()=>{rt.info(`Server is running at http://localhost:${n}`),y()})});let p=new Vn({baseURL:po(),apiKey:t}),f={type:"API_KEY",baseUrl:po(),apiKey:t},h=new Ue(f),g=new $n(h,ks());nu({baseServer:d,generator:p,storage:g,logger:rt,devicePixelRatio:i,authorization:f}),await Ow(u)}function Lw(r){let e=Ea();e.use(Iw()),e.use(Rw.json({limit:"25mb"}));let t=Ea.Router();if(t.use("/tests",wm),t.use("/modules",Sm),t.use("/environments",gm),e.use("/api",t),e.use((o,s,i)=>{o.path!=="/healthcheck"&&rt.debug({url:o.url,path:o.path,query:o.query,method:o.method,body:o.body,headers:o.rawHeaders,client:o.ip},"Received desktop-server request"),s.on("close",()=>{s.statusCode>=400&&rt.error({url:o.url,method:o.method,statusCode:s.statusCode},"Request completed in error")}),i()}),e.use((o,s,i,a)=>{o instanceof Error&&o.message.includes("BadRequestError: request aborted")||(rt.error({stack:o.stack,msg:o.message,url:s.url,method:s.method},"Unhandled exception leading to 500 on desktop-server"),i.status(500).send("Internal Server Error"),a(o))}),r){let o=Ea.static(r);e.use("/",o),e.use("*",o)}return Pw.createServer(e)}import ep from"fs";import Ys from"path";import{chdir as wb}from"process";import{fileURLToPath as bb}from"url";import{existsSync as Hw,mkdirSync as jw,statSync as Gw}from"fs";import{dirname as Vw}from"path";import xm from"readline/promises";import{execSync as Mw}from"child_process";import{platform as Nw}from"os";function xa(){return Cm()?(T.info("Setting device pixel ratio to 2 automatically since a Mac OS Retina screen was detected."),T.info("If you are using a low pixel-density monitor, you should manually set --pixel-ratio to 1 to avoid incorrect viewport calculations."),T.info("Confirm your device's pixel-ratio at https://www.mydevice.io."),2):(T.info("Setting device pixel ratio to 1."),T.info("If you are using Momentic on a high-pixel density (HiDPI) monitor, relaunch with the --pixel-ratio option to avoid incorrect viewport calculations"),T.info("Confirm your device's pixel-ratio at https://www.mydevice.io."),1)}function Cm(){return Nw()==="darwin"&&Mw("system_profiler SPDisplaysDataType").toString().includes("Retina")}function Aa(r){Cm()&&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 _w from"@actions/exec";import kw from"@actions/io";import Dw from"quote";import Fw from"string-argv";async function Tm(r,e=!0){let t=Fw(r),n=await kw.which(t[0],!0),o=t.slice(1),s=_w.exec(Dw(n),o,{delay:100});if(e)return s}import{existsSync as Uw,statSync as $w}from"fs";var vm=!!process.env.CI||!process.stdout.isTTY;function ho(r){try{return Uw(r)&&$w(r).isDirectory()}catch(e){return T.error({err:e},`Error reading path ${r} during directory existence check`),!1}}import Bw from"csv-parser";import{createReadStream as zw}from"fs";function Ra(r){return new Promise((e,t)=>{let n=[];zw(r).pipe(Bw()).on("data",o=>n.push(o)).on("end",()=>e(n)).on("error",o=>t(o))})}import{hostname as Ww}from"os";var z=Ds({app:"cli",clientToken:"pub7eb923f18fb3f1d42ac5eba8c5ea13a5",hostname:Ww(),excludeAttributesInConsoleLogs:!0,excludeTimestamps:!0,disableConsoleLogs:!0});var Ia=!1,qw=(()=>{try{return Gw("/.dockerenv"),!0}catch{return!1}})();async function vt(r,e){if(vm||Ia||qw)return!0;z.flush(),await new Promise(i=>setTimeout(i,500));let t=xm.createInterface({input:process.stdin,output:process.stdout}),n=r.split("."),o;if(n.length===1)o=r;else{let i=`${n.slice(0,n.length-1).join(".").trim()}.`;e?T.warn(i):T.log(i),o=n[n.length-1].trim()}let s=await t.question(`${o} ('y' for yes / n for no / 'A' to accept all) `);return t.close(),s==="A"?(Ia=!0,setTimeout(()=>{Ia=!1},3e3),!0):s.toLowerCase()==="y"}async function Pa(r){let e=Vw(r);return ho(e)?Hw(r)?vt(`File '${Em(r)}' already exists. Overwrite existing content?`,!0):!0:await vt(`Directory '${Em(e)}' doesn't exist. Create it now?`,!0)?(jw(e,{recursive:!0}),!0):!1}function Em(r){return r.replace(/(\s+)/g,"\\$1")}async function Am(r){let e=xm.createInterface({input:process.stdin,output:process.stdout}),t=await e.question(`${r} `);return e.close(),t.trim()}import{cloneDeep as Kw}from"lodash-es";async function Rm({client:r,skipPrompts:e,ws:t}){let n=await r.getAllEnvironments(),o=Kw(t.config);o.environments||(o.environments=[]);for(let s of n){let i=o.environments?.find(a=>a.name===s.name);if(i)!e&&!await vt(`Environment ${s.name} already exists in the workspace configuration file. Would you like to overwrite its variables?`)&&process.exit(1),i.baseUrl=s.variables[ae],delete s.variables[ae],i.envVariables=s.variables;else{let a=s.variables[ae];delete s.variables[ae],o.environments.push({name:s.name,baseUrl:a,envVariables:s.variables})}}or(o,t.configFilePath),T.success(`Pulled ${n.length} environments successfully! Please make sure to commit any changes to your workspace configuration file.`)}import{createHash as Im}from"crypto";import Pm from"fs";async function Lm({testsToFetch:r,client:e,all:t,yes:n}){let{tests:o,modules:s}=await e.getTestYAMLExport({paths:r,all:t}),i=0;for(let[l,c]of Object.entries(o)){let u=Om(l,te.TEST);!n&&!await Pa(u)||(i+=1,Pm.writeFileSync(u,c,"utf-8"),z.info({checksum:Im("md5").update(c).digest("hex")},`Wrote '${u}'`))}let a=0;for(let[l,c]of Object.entries(s)){let u=Om(l,te.MODULE);!n&&!await Pa(u)||(a+=1,Pm.writeFileSync(u,c,"utf-8"),z.info({checksum:Im("md5").update(c).digest("hex")},`Wrote '${u}'`))}i===0?T.success("Pulled 0 tests."):T.success(`Pulled ${i} test${i>1?"s":""}${a?` and ${a} module${a>1?"s":""}`:""}!`)}function Om(r,e){switch(e){case te.TEST:return`${xe(r)}.${ut.TEST}`;case te.MODULE:return`${xe(r)}.${ut.MODULE}`;default:throw new Error(`Unknown entity type ${e}`)}}async function Mm(r){let{ws:e,client:t,skipPrompts:n}=r;T.info("Welcome to the Momentic Cloud importer wizard! \u{1F636}\u200D\u{1F32B}\uFE0F"),T.info("Importing environments from Momentic Cloud."),T.info(`This command will overwrite all local environment configuration in ${e.configFilePath} with environments from Momentic Cloud.`),await vt("Are you sure you want to proceed?",!0)||(T.info("Aborting..."),process.exit(1)),await Rm({client:t,ws:e,skipPrompts:n}),T.success(`Successfully imported environments from Momentic Cloud. We recommend pulling secrets out of ${e.configFilePath} into .env files or dynamically set environment variables for security.`),T.info("Importing tests and modules from Momentic Cloud."),await Lm({testsToFetch:[],client:t,all:!0,yes:n}),T.success("Successfully imported tests and modules from Momentic Cloud. You can move them to the desired location in your workspace. We recommend committing these files to version control so you can share them with team members and run Momentic tests in CI.")}import We from"fs";import gn from"path";import Yw from"yaml";function Nm(){ho("momentic")||(T.error(`The migration command should be ran from the v0 root Momentic directory, which should contain a folder called 'momentic'. No folder named 'momentic' was found in the current working directory (${process.cwd()}).`),process.exit(1));let r={name:"default",include:lo,environments:[]};T.info("Migrating environments");let e=_m(["momentic/environments"],Xw);for(let n of e){let o=Yw.parse(We.readFileSync(n,"utf-8"));try{let s=zt.parse(o),i=s.variables[ae]??"";delete s.variables[ae],r.environments?.push({name:s.name,baseUrl:i,envVariables:s.variables})}catch(s){T.error(`${n} failed to parse as a valid environment file.`),T.error(s),process.exit(1)}}T.info("Migrating tests");let t=Sa("./momentic",T);for(let n of t){let o=gn.join(...n.fullPathSegments),s=gn.join(gn.dirname(o),`${n.fileName.slice(0,-5)}.test.yaml`);T.debug(`Moving test ${o} to ${s}`),We.renameSync(o,s)}if(ho("momentic/modules")){T.info("Migrating modules");for(let n of We.readdirSync("./momentic/modules")){if(!n.endsWith(".yaml"))continue;let o=gn.resolve(gn.join("./momentic/modules",n));if(!We.readFileSync(o,"utf-8").includes("schemaVersion")){T.warn(`Skipping file ${o} since it does not have valid Momentic module contents`);continue}let i=`${o.slice(0,-5)}.module.yaml`;T.debug(`Moving module ${o} to ${i}`),We.renameSync(o,i)}}T.debug("Writing new workspace configuration file"),or(r,"momentic.config.yaml"),We.rmSync("./momentic/environments",{recursive:!0,force:!0}),We.rmSync("./momentic/fixtures",{recursive:!0,force:!0}),T.success("Migration succeeded!"),T.info("Going forward:"),T.info(` - You can store test and module files anywhere under the workspace root (${process.cwd()})`),T.info(" - Environment details and other common options are tracked in the root momentic.config.yaml file")}function _m(r,e,t=new Set){for(let n of r){let o=gn.resolve(n),s=!1;try{s=We.existsSync(o)&&We.statSync(o).isDirectory()}catch(i){T.error({err:i},`Error reading path ${o} during collect paths`)}if(o&&s){let i=We.readdirSync(o).map(a=>gn.join(o,a));_m(i,e,t);continue}if(o.endsWith(".yaml")){try{if(!We.existsSync(o)||!We.statSync(o).isFile()){T.warn(`File not found or unreadable: ${o}`);continue}}catch(i){T.error({err:i},`Error reading file ${o} during collect paths`);continue}if(!e(o))continue;t.add(o)}}return t}function Xw(r){return r.endsWith(".yaml")?We.readFileSync(r,"utf8").includes("momentic/environment")?!0:(T.warn(`Skipping YAML that is not a Momentic environment: ${r}`),!1):!1}import{Argument as ir,Option as Ce}from"@commander-js/extra-typings";import{validateHeaderValue as Jw}from"http";import{cpus as km}from"os";import{parse as Zw}from"yaml";import{z as $}from"zod";var Us=58888,ar=new Ce("--api-key <key>","API key for authentication. If not supplied, attempts to read the MOMENTIC_API_KEY env var."),lr=new Ce("--server <server>","Momentic server to use. Leave unchanged unless using Momentic on-premise."),yn=new Ce("-y, --yes","Skip all confirmation prompts."),La=new Ce("-w, --wait","Wait for tests to finish running before exiting. Only applicable when running tests remotely").implies({remote:!0}),Ma=new Ce("--wait-timeout <waitTimeout>","The maximum number of seconds to wait for tests to complete. Only applicable when the --wait option is specified."),$s=new Ce("--custom-headers <customHeaders...>","Specify custom headers in the form HEADER=VALUE to be sent with each request during the test. Multiple entries can be provided.");function Bs(r){if(r===void 0)return;let e={};for(let t of r){let n=t.indexOf("=");if(n===-1)throw new Error(`Header value pair does not contain '=': ${t}`);let o=t.slice(0,n),s=t.slice(n+1);Jw(o,s),e[o]=s}return e}var Na=new Ce("--no-report","Skip reporting test results to Momentic Cloud when running with the --local flag.").implies({local:!0}),_a=new Ce("--pixel-ratio <pixelRatio>","Device pixel ratio of your screen or monitor. Mac OS Retina displays and machines marketed as 'HiDPI' should set this to 2. Visit https://www.mydevice.io/ to find your device's pixel ratio."),Dm=new Ce("--port <port>",`Port to run the app on. Defaults to ${Us}.`),ka=new Ce("--input-csv <inputCsv>","Path to a CSV file on disk where each row represents a set of inputs that will be made available to all tests that are ran. Only applicable when running locally. The first line of the CSV must be the input names."),zs=new Ce("--env <env>","Name of the environment to use when running tests."),Ws=new Ce("--url-override <urlOverride>","Fully qualified url (e.g. https://www.google.com) to start all tests from. Overrides any default starting url set from the test or environment."),uH=new Ce("-a, --all","Select all tests in your organization from Momentic Cloud. Cannot be used together with <tests> arguments."),mH=new Ce("-a, --all","Select all environments in your organization from Momentic Cloud. Cannot be used together with <paths> arguments."),pH=new ir("<tests...>",`One or more test paths to pull from Momentic Cloud.
|
|
1785
1787
|
|
|
1786
|
-
A test path is a lowercased version of your test name where spaces are replaced with dashes: 'npx momentic@latest pull hello-world'.`).argOptional(),
|
|
1788
|
+
A test path is a lowercased version of your test name where spaces are replaced with dashes: 'npx momentic@latest pull hello-world'.`).argOptional(),Fm=new ir("<tests...>",`One or more test paths to queue on Momentic Cloud.
|
|
1787
1789
|
|
|
1788
|
-
|
|
1790
|
+
A test path is a lowercased version of your test name where spaces are replaced with dashes: 'npx momentic@latest pull hello-world'.`),Um=new ir("<tests...>","One or more test file path or folders that exist on the local machine: 'npx momentic@latest run --local momentic/hello-world.yaml'.").argOptional(),$m=new ir("<suites...>",`One or more suite paths that exist on Momentic Cloud.
|
|
1789
1791
|
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
The suite path is a lowercased version of your suite name where spaces and special characters are replaced with dashes, such as 'production-tests'.`),Ed=new An("<paths...>","File paths pointing to one or more Momentic YAML files. Paths to directories are supported as well."),vd=new Ee("--shard-index <shardIndex>","The index of the shard to run tests for. Defaults to 1.").default(1).argParser(r=>parseInt(r,10)),xd=new Ee("--shard-count <shardCount>","The number of shards that tests are being run on. Defaults to 1.").default(1).argParser(r=>parseInt(r,10)),hi=new An("<envs...>","One or more environment names to push").argOptional(),oi=B.object({apiKey:B.preprocess(r=>r!==void 0?r:process.env.MOMENTIC_API_KEY,B.string()),server:B.string().default("https://api.momentic.ai"),local:B.boolean().optional(),remote:B.boolean().optional(),yes:B.preprocess(r=>process.env.CI?!0:r,B.boolean().optional()),pixelRatio:B.coerce.number().optional(),port:B.coerce.number().default(_o).optional(),wait:B.preprocess(r=>!!r,B.boolean()).optional(),waitTimeout:B.coerce.number().optional(),start:B.string().optional(),waitOn:B.string().optional(),waitOnTimeout:B.coerce.number().default(60).optional(),customHeaders:B.string().array().optional(),noReport:B.boolean().optional(),report:B.boolean().optional(),env:B.string().optional(),urlOverride:B.string().url().optional(),all:B.boolean().optional(),parallel:B.coerce.number().optional(),retries:B.coerce.number().optional(),shardIndex:B.coerce.number().optional(),shardCount:B.coerce.number().optional(),inputCsv:B.string().optional(),tests:B.array(B.string()).optional(),suites:B.array(B.string()).optional(),paths:B.array(B.string()).optional(),envs:B.array(B.string()).optional()}),xt=async r=>{let e={};process.stdin.isTTY||Object.assign(e,await yf());let t;try{let n=Object.assign(e,oi.partial().parse(r));t=oi.parse(n)}catch(n){M(`Error parsing command line arguments: ${n.message}`),process.exit(1)}try{Sf(t)}catch(n){M(`Invalid command line arguments: ${n.message}`),process.exit(1)}return t};function hf(r){try{return oi.partial().parse(r)}catch(e){M(`Config object does not match expected schema: ${e.message}`),process.exit(1)}}function ff(r){let e;try{if(e=gf(r),typeof e!="object"||e===null)throw new Error("The top-level document should parse as a map with key-value pairs")}catch(t){console.error(`Config file does not parse as valid YAML: ${t.message}`),process.exit(1)}return hf(e)}async function yf(){return new Promise(r=>{let e="";process.stdin.setEncoding("utf8"),process.stdin.on("data",t=>e+=t),process.stdin.on("end",()=>{try{if(!e)return r({});r(ff(e))}catch(t){console.error(`Failed to parse YAML from stdin: ${t.message}`),process.exit(1)}})})}var Sf=r=>{for(let[e,t]of Object.entries(r))switch(e){case"shardIndex":if(!r.shardCount)throw new Error("The --shard-count flag must be provided alongside --shard-index");if(r.shardCount&&r.shardIndex&&r.shardIndex>r.shardCount)throw new Error("Shard index cannot be greater than shard count");if(r.shardIndex!==void 0&&r.shardIndex<1)throw new Error("Shard index must be greater than 0");break;case"waitTimeout":case"pixelRatio":try{r[e]=B.number().int().optional().parse(t)}catch{throw new Error(`Invalid ${e} provided does not parse a number: ${t}`)}break;case"urlOverride":if(t===void 0)break;try{B.string().url().parse(t)}catch(n){throw new Error(`Invalid URL provided for ${e}`,{cause:n})}break;case"server":if(typeof t!="string")throw new Error(`Expected a string for ${e}`);if(!t.startsWith("http"))throw new Error("--server option must be a fully qualified URL beginning with http");break;case"parallel":if(t===void 0)break;if(typeof t!="number"||isNaN(t))throw new Error(`Expected a number for ${e}`);yd().length<t*2&&ce(`You requested to run ${t} tests in parallel on a machine with ${yd().length} cores. This may cause performance issues and test failures as Chrome requires at least 2 cores per browser instance.`);break;default:break}};import{createHash as Ad}from"crypto";import{writeFileSync as Rd}from"fs";import{join as Id}from"path";async function Od({testsToFetch:r,client:e,all:t,yes:n}){let{tests:o,modules:s}=await e.getTestYAMLExport({paths:r,all:t}),i=0;for(let[l,c]of Object.entries(o)){let u=Id(wt,Pd(l));!n&&!await vn(u)||(i+=1,Rd(u,c,"utf-8"),O.info({checksum:Ad("md5").update(c).digest("hex")},`Wrote '${u}'`))}let a=0;for(let[l,c]of Object.entries(s)){let u=Id(tr,Pd(l));!n&&!await vn(u)||(a+=1,Rd(u,c,"utf-8"),O.info({checksum:Ad("md5").update(c).digest("hex")},`Wrote '${u}'`))}i===0?Pe("Pulled 0 tests."):Pe(`Pulled ${i} test${i>1?"s":""}${a?` and ${a} module${a>1?"s":""}`:""}!`)}function Pd(r){return`${Te(r)}.yaml`}import{readFileSync as bf}from"fs";async function Ld(r){let e=xn(r.paths,Cf);le(`Found ${e.size} tests to push:`),e.forEach(s=>le(" ",s));let t=Array.from(e).map(s=>Cs(s,tr)),n=new Set(t.flatMap(s=>Object.keys(s.modules)));e.size===0&&n.size===0&&(M("Found no valid tests or modules to push."),process.exit(1));let o="Pushing tests overwrites tests on production and will instantly affect scheduled runs. Continue?";!r.yes&&!await Xe(o,!0)&&(M("Push cancelled."),process.exit(1)),await r.client.updateTestWithYAML(t),Pe("Pushed tests successfully!")}function Cf(r){return r.endsWith(".yaml")?bf(r,"utf8").includes("momentic/test")?!0:(O.warn(`Skipping YAML that is not a Momentic test: ${r}`),!1):(O.warn(`Skipping file that does not have YAML extension: ${r}`),!1)}import Dd from"log-update";import _d from"chalk";import{Console as Md}from"console";import{format as Rn}from"util";var fi=class extends Error{constructor(e,t,n){let o=Error.stackTraceLimit;n&&(Error.stackTraceLimit=Math.max(n,o||10)),super(e),Error.captureStackTrace&&Error.captureStackTrace(this,t),Error.stackTraceLimit=o}},Do=class r extends Md{_buffer=[];_groupDepth=0;Console=Md;constructor(){super({write:e=>(r.write(this._buffer,"log",e),!0)})}static write(e,t,n,o=2){let s=new fi(void 0,r.write).stack;if(!s)return e;let i=s.split(`
|
|
1792
|
+
The suite path is a lowercased version of your suite name where spaces and special characters are replaced with dashes, such as 'production-tests'.`),hH=new ir("<paths...>","File paths pointing to one or more Momentic YAML files. Paths to directories are supported as well."),Bm=new Ce("--shard-index <shardIndex>","The index of the shard to run tests for. Defaults to 1.").default(1).argParser(r=>parseInt(r,10)),fo=new Ce("-c, --config <configPath>","Absolute or relative path to a Momentic configuration file (*.momentic.config.yaml)"),zm=new Ce("--shard-count <shardCount>","The number of shards that tests are being run on. Defaults to 1.").default(1).argParser(r=>parseInt(r,10)),fH=new ir("<envs...>","One or more environment names to push").argOptional(),Oa=$.object({apiKey:$.preprocess(r=>r!==void 0?r:process.env.MOMENTIC_API_KEY,$.string()),server:$.string().default("https://api.momentic.ai"),config:$.string().optional(),yes:$.preprocess(r=>process.env.CI?!0:r,$.boolean().optional()),pixelRatio:$.coerce.number().optional(),port:$.coerce.number().default(Us).optional(),wait:$.preprocess(r=>!!r,$.boolean()).optional(),waitTimeout:$.coerce.number().optional(),start:$.string().optional(),waitOn:$.string().optional(),waitOnTimeout:$.coerce.number().default(60).optional(),customHeaders:$.string().array().optional(),noReport:$.boolean().optional(),report:$.boolean().optional(),env:$.string().optional(),urlOverride:$.string().url().optional(),all:$.boolean().optional(),parallel:$.coerce.number().optional(),retries:$.coerce.number().optional(),shardIndex:$.coerce.number().optional(),shardCount:$.coerce.number().optional(),inputCsv:$.string().optional(),tests:$.array($.string()).optional(),suites:$.array($.string()).optional(),paths:$.array($.string()).optional(),envs:$.array($.string()).optional()}),cr=async r=>{let e={};process.stdin.isTTY||Object.assign(e,await tb());let t;try{let n=Object.assign(e,Oa.partial().parse(r));t=Oa.parse(n)}catch(n){T.error(`Error parsing command line arguments: ${n.message}`),process.exit(1)}try{nb(t)}catch(n){T.error(`Invalid command line arguments: ${n.message}`),process.exit(1)}return t};function Qw(r){try{return Oa.partial().parse(r)}catch(e){T.error(`Config object does not match expected schema: ${e.message}`),process.exit(1)}}function eb(r){let e;try{if(e=Zw(r),typeof e!="object"||e===null)throw new Error("The top-level document should parse as a map with key-value pairs")}catch(t){console.error(`Config file does not parse as valid YAML: ${t.message}`),process.exit(1)}return Qw(e)}async function tb(){return new Promise(r=>{let e="";process.stdin.setEncoding("utf8"),process.stdin.on("data",t=>e+=t),process.stdin.on("end",()=>{try{if(!e)return r({});r(eb(e))}catch(t){console.error(`Failed to parse YAML from stdin: ${t.message}`),process.exit(1)}})})}var nb=r=>{for(let[e,t]of Object.entries(r))switch(e){case"shardIndex":if(!r.shardCount)throw new Error("The --shard-count flag must be provided alongside --shard-index");if(r.shardCount&&r.shardIndex&&r.shardIndex>r.shardCount)throw new Error("Shard index cannot be greater than shard count");if(r.shardIndex!==void 0&&r.shardIndex<1)throw new Error("Shard index must be greater than 0");break;case"waitTimeout":case"pixelRatio":try{r[e]=$.number().int().optional().parse(t)}catch{throw new Error(`Invalid ${e} provided does not parse a number: ${t}`)}break;case"urlOverride":if(t===void 0)break;try{$.string().url().parse(t)}catch(n){throw new Error(`Invalid URL provided for ${e}`,{cause:n})}break;case"server":if(typeof t!="string")throw new Error(`Expected a string for ${e}`);if(!t.startsWith("http"))throw new Error("--server option must be a fully qualified URL beginning with http");break;case"parallel":if(t===void 0)break;if(typeof t!="number"||isNaN(t))throw new Error(`Expected a number for ${e}`);km().length<t*2&&T.warn(`You requested to run ${t} tests in parallel on a machine with ${km().length} cores. This may cause performance issues and test failures as Chrome requires at least 2 cores per browser instance.`);break;default:break}};import{registry as Da}from"playwright-core/lib/server";function ob(r){let e=[],t=[];for(let n of r){let o=Da.findExecutable(n);!o||o.installType==="none"?e.push(n):t.push(o)}return t}async function Hs(){let r=ob(["chromium"]);await Da.installDeps(r,!1),await Da.install(r,!1)}async function js(r){let e=process.versions.node,t=parseInt(e.split(".")[0]);(isNaN(t)||t<20)&&(T.error(`Node.js version 20 or higher is required to run the Momentic CLI. Detected: ${process.versions.node}.`),process.exit(1));let n=await r.client.getOrgId();return r.installBrowsers&&await Hs(),n}import Gm from"log-update";import jm from"chalk";import{Console as Wm}from"console";import{format as go}from"util";var Fa=class extends Error{constructor(e,t,n){let o=Error.stackTraceLimit;n&&(Error.stackTraceLimit=Math.max(n,o||10)),super(e),Error.captureStackTrace&&Error.captureStackTrace(this,t),Error.stackTraceLimit=o}},Gs=class r extends Wm{_buffer=[];_groupDepth=0;Console=Wm;constructor(){super({write:e=>(r.write(this._buffer,"log",e),!0)})}static write(e,t,n,o=2){let s=new Fa(void 0,r.write).stack;if(!s)return e;let i=s.split(`
|
|
1793
1793
|
`).slice(o).filter(Boolean).join(`
|
|
1794
|
-
`);return e.push({message:n,origin:i,type:t}),e}_log(e,t){r.write(this._buffer,e," ".repeat(this._groupDepth)+t,3)}debug(e,...t){this._log("debug",
|
|
1794
|
+
`);return e.push({message:n,origin:i,type:t}),e}_log(e,t){r.write(this._buffer,e," ".repeat(this._groupDepth)+t,3)}debug(e,...t){this._log("debug",go(e,...t))}error(e,...t){this._log("error",go(e,...t))}info(e,...t){this._log("info",go(e,...t))}log(e,...t){this._log("log",go(e,...t))}warn(e,...t){this._log("warn",go(e,...t))}getBuffer(){return this._buffer.length>0?this._buffer:void 0}};function Hm(r){let e=globalThis.console,t=new Gs;globalThis.console=t;try{r()}finally{let o=t.getBuffer()?.map(s=>s.message).join(`
|
|
1795
1795
|
`);process.stderr.write(`${o}
|
|
1796
|
-
`),globalThis.console=e}}var
|
|
1797
|
-
`)
|
|
1798
|
-
|
|
1799
|
-
${
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
`)
|
|
1796
|
+
`),globalThis.console=e}}var sb=30*60*1e3,ib=5;async function Vs({getResults:r,checkDone:e,name:t,timeoutMs:n=sb}){let o=Date.now(),s=0;for(;Date.now()-o<n;){let i;s>ib&&(T.error(`Failed to fetch ${t} status too many times.`),process.exit(1));try{i=await r(),s=0}catch(c){s++,z.warn({err:c},"Failed to fetch run status, retrying..."),T.warn({err:c},"Failed to fetch run status, retrying..."),await new Promise(u=>setTimeout(u,1500*s));continue}if(e(i))return i;let l=Math.max(1e4,Math.floor(n/100));await new Promise(c=>setTimeout(c,l))}T.error(`Timeout elapsed waiting for ${t} to complete (${Math.floor(n/1e3)}s).`),process.exit(1)}function dr({results:r,startTime:e,entity:t,getDisplayLine:n,onFailed:o}){let s=r.filter(l=>l.status==="PASSED"),i=r.filter(l=>l.status==="FAILED"),a=r.filter(l=>l.status==="CANCELLED");return Hm(()=>{i.forEach(l=>{T.log(""),o(l)}),i.length&&(T.log(""),T.error(`${i.length} ${t}s failed:`),i.forEach(l=>{T.error(n(l))})),a.length&&(T.log(""),T.warn(`${a.length} ${t}s cancelled:`),a.forEach(l=>{T.warn(n(l))})),s.length&&(T.log(""),T.success(`${s.length} ${t}s passed:`),s.forEach(l=>{T.success(n(l))})),T.log(""),T.dimmed(`Total time: ${Math.round((Date.now()-e)/1e3)}s`)}),{passed:s.length,failed:i.length,cancelled:a.length}}var qs=(r,e)=>{if(!r.failureDetails||!r.failureReason)return;let t=ol[r.failureDetails?.classification?.reason||r.failureReason],n=r.failureDetails?.classification?.summary||sl[r.failureReason];T.error(e),T.log(` Reason: ${jm.red(t)}`),T.log(` Description: ${jm.red(n)}`)};async function Vm({client:r,suitePaths:e,wait:t,waitTimeout:n,...o}){let s=(await r.queueSuiteRuns({paths:e,...o})).suiteRunIds;T.dimmed(`Queued ${e.length} suites.`),t||process.exit(0);let i=Date.now();T.dimmed(`Waiting for ${e.length} suites to complete.`);let a=new Set,l=await Vs({name:"suites",getResults:async()=>r.bulkGetSuiteStatus(s),timeoutMs:n?n*1e3:void 0,checkDone:m=>(m.forEach(p=>{if(p.status==="RUNNING"&&!a.has(p.id)){a.add(p.id);let f=p.suite?.name??"Unknown suite";f&&Gm(`${a.size}/${s.length} ${xe(f)}`)}}),m.every(p=>p.runs.every(h=>h.status==="FAILED"&&h.failureReason||h.status==="PASSED"||h.status==="CANCELLED")&&(p.status==="FAILED"||p.status==="PASSED"||p.status==="CANCELLED")))});Gm.clear();let c=r.getAppUrl(),d=dr({results:l,startTime:i,onFailed:m=>{let p=m.suite?.name?xe(m.suite.name):"Unknown suite",f=m.runs.filter(g=>g.status==="FAILED").length,h=m.runs.length;T.error(`${p} (${f}/${h} tests failed):`);for(let g of m.runs)if(g.status==="FAILED"){let y=g.testName||g.test?.name;T.error(` ${y?xe(y):"Unknown test"} (${c}/runs/${g.id})`)}},entity:"suite",getDisplayLine:m=>` ${m.suite?.name?xe(m.suite.name):"Unknown suite"} (${c}/suite-runs/${m.id})`});process.exit(d.failed>0?1:0)}import qm from"log-update";async function Km({tests:r,client:e,...t}){!t.yes&&!await vt(`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:n,runIds:o}=await e.queueTests({testPaths:r,...t});if(T.dimmed(`Queued ${n.length} tests. Processing time may depend on a variety of factors, including how many tests have already been queued from your organization.`),t.wait||process.exit(0),!o.length)return;T.dimmed(`Waiting for ${n.length} tests to complete.`);let s=new Set,i=e.getAppUrl(),a=Date.now(),l=await Vs({name:"runs",getResults:async()=>e.bulkGetRunStatus(o),timeoutMs:t.waitTimeout?t.waitTimeout*1e3:void 0,checkDone:u=>(u.forEach(d=>{if(d.status==="RUNNING"&&!s.has(d.id)){s.add(d.id);let m=d.testName||d.test?.name;m&&qm(`${s.size}/${n.length} ${xe(m)}`)}}),u.every(d=>d.status==="FAILED"&&d.failureReason||d.status==="PASSED"||d.status==="CANCELLED"))});qm.clear();let c=dr({results:l,startTime:a,onFailed:u=>{let d=u.testName||u.test?.name;qs(u,d?xe(d):"Unknown test")},getDisplayLine:u=>{let d=u.testName||u.test?.name,m=` ${d?xe(d):"Unknown test"}`;return u.id&&(m+=` (${i}/runs/${u.id})`),m},entity:"test"});process.exit(c.failed>0?1:0)}import{existsSync as pb,statSync as hb}from"fs";import Jm from"log-update";import Zm from"path";import fb from"wait-on";import{diff as ab}from"deep-object-diff";import{cloneDeep as Ym}from"lodash-es";import lb from"semver";import{debounce as cb}from"ts-debounce";import{v4 as db}from"uuid";var Ks=class extends he{async runTemplateMatching(e){let t=await this.sendRequest(`/${he.API_VERSION}/web-agent/template-matching`,e);return vo.parse(t)}};async function Xm({path:r,momenticFiles:e,ws:t,apiClient:n,generator:o,orgId:s,retriesOverride:i,noReport:a,envName:l,urlOverride:c,devicePixelRatio:u,customHeaders:d,testInputs:m}){let p=new $n(n,s);T.info(`Reading ${r} from local filesystem`);let f=await _s(r,z,e);if(await p.resolveStepCacheEntries({schemaVersion:f.schemaVersion,organizationId:s,steps:f.steps,testId:f.id,logger:z}),lb.gt(f.schemaVersion,ke)&&z.warn(`Test ${r} has schema version ${f.schemaVersion}, which is greater than what is currently supported by this SDK. Please update your momentic package version to avoid unexpected behavior.`),!l){for(let A of f.envs??[])if(A.default){l=A.name;break}}let h,g={};l&&(h=wa(l,t),g=h.variables);let y=f.baseUrl;if(c?y=c:y||(y=g[ae]),!y){let A=`Cannot run test with no base URL and no ${ae} variable defined in its environment`;throw new Error(A)}let S;if(a)S=db();else try{S=(await n.createRun({testId:f.id,testName:f.name,trigger:"CLI",resolvedBaseUrl:y})).id}catch(A){throw z.error({err:A,testId:f.id},"Error creating run on Momentic Cloud"),new Error("Error creating run on Momentic Cloud. Please ensure Momentic is accessible from your environment or pass the --no-report flag.")}let b=z.child({testId:f.id,runId:S}),C=async A=>{if(!a)try{await n.updateRun(S,A)}catch(O){b.warn({err:O},`Failed to update run status for test ${S}. You may see stale data on the Momentic Cloud Server.`)}},v,E=Math.max(i??f.retries,0),P=[];for(let A=0;A<=E;A++)try{await C({status:"RUNNING",attempts:A+1});let{controller:O,context:M}=await ub({baseUrl:y,envName:l,apiClient:n,devicePixelRatio:u,logger:b,storageClient:p,test:f,generator:o,orgId:s,variables:g,customHeaders:d});if(v=await mb({testInputs:m,logger:b,storageClient:p,apiClient:n,test:f,orgId:s,runId:S,context:M,controller:O,noReport:a}),P.unshift(v.status),v.status!=="FAILED")return await C({status:v.status,finishedAt:new Date,flake:cl(P)}),{...v,runId:S};let Z=v.failedStepResult,R=Z?.message||"Unknown failure";if(A<E){b.warn({errResult:Z},`Test '${f.name}' failed attempt ${A+1} of ${E+1}, retrying...`);continue}b.error({errResult:Z},`Test '${f.name}' failed after all exhausting ${E+1} attempts: ${R}
|
|
1797
|
+
`),await C({status:"FAILED",failureReason:Z?.failureReason,finishedAt:new Date});let H,Y;b.info(`Classifying failure for test ${f.name}`);try{let oe=await o.getTestResultClassification({results:v.results,errorMessage:R});H={classification:oe,errorMessage:R},Y=oe.reason,await C({status:"FAILED",finishedAt:new Date,failureDetails:H,failureReason:Y})}catch(oe){b.debug({err:oe},"Failed to classify test failure with AI, continuing...")}return{...v,runId:S,failureDetails:H,failureReason:Y}}catch(O){b.error({err:O},`Encountered fatal platform error while running test '${f.name}': ${O}`);let M={errorMessage:O.message,errStack:O.stack},Z={status:"FAILED",failureDetails:M,failureReason:"InternalPlatformError",finishedAt:new Date};return await C(Z),{...Z,runId:S}}throw new Error("This code should not be reachable")}async function ub({baseUrl:r,envName:e,devicePixelRatio:t,apiClient:n,test:o,storageClient:s,generator:i,orgId:a,variables:l,logger:c,customHeaders:u}){let d=Rr.parse(o.advanced);u&&(d.extraHeaders={...d.extraHeaders??{},...u});let m=await Mt.init({baseUrl:r,logger:c,userBrowserSettings:d,storage:s,enricher:new Ks({baseURL:n.baseUrl,apiKey:n.apiKey}),timeout:d.pageLoadTimeoutMs,contextArgs:{viewport:o.advanced.viewport??Rt,deviceScaleFactor:t}}),p=new Gn({browser:m,generator:i,config:os,logger:c,orgId:a,storage:s,flagStore:await Hn.init(a),localCodeEvalTools:new Lt({baseUrl:n.baseUrl,apiKey:n.apiKey})}),f=new le({baseUrl:r,currentUrl:p.browser.url(),variablesFromEnvironment:l,envName:e});return{controller:p,context:f}}async function mb({storageClient:r,apiClient:e,test:t,orgId:n,runId:o,context:s,controller:i,noReport:a,logger:l,testInputs:c}){z.info(`Running test '${t.name}' locally${a?"":` and reporting results to https://app.momentic.ai/runs/${o}`}`);let u=Ym(t.steps),d=async C=>{try{if(C.results){let v=Ym(C.results);Fo(v),C.results=v}await e.updateRun(o,C)}catch(v){l.warn({err:v},"Failed to update run data. You may see stale data on the Momentic Cloud Server.")}},m,p=cb(async C=>{if(!a){try{JSON.stringify(C)}catch(v){throw new Error(`The test results contain circular references: ${v}`)}await d(C)}},1e4,{maxWait:3e4}),f=new Lt({baseUrl:e.baseUrl,apiKey:e.apiKey});t.parameters&&await Promise.all(t.parameters.map(async C=>{let{name:v,defaultValue:E,required:P}=C,A=c?.[v];P&&A===void 0&&(T.error(`Required parameter '${v}' is required by test '${t.name}' but not provided`),process.exit(1));let O=await Ze({s:A??E,localTools:f,logger:l,context:le.dummyContext(s.getEnvName())});s.setMomenticSystemVariable(v,O)}));let h={controller:i,storage:r,context:s,logger:l,codeEvalTools:f},g={orgId:n,runId:o,testMetadata:t,steps:t.steps},b=await Dr({fixtures:h,inputs:g,options:{takeScreenshots:!0,consumeDebuggingData:!0},callbacks:{step:{},test:{onTestComplete:async()=>{await i.browser.cleanup()},onSaveScreenshot:async C=>{if(a)return"";let{key:v}=await e.uploadScreenshot({screenshot:C.toString("base64")});return v},onUpdateRun:async C=>{m=Promise.resolve(p(C))},onProposedTestSteps:async C=>e.uploadProposedSteps(C,l),onTestSuccess:async C=>{let v=ab(u,C);if(Object.keys(v).length===0){l.debug("No changes to test steps after success");return}l.debug({changes:v},"Updating steps post-run success in worker");try{let{cachesToSave:E}=await yt({steps:C,cacheCreationParams:{testId:t.id,orgId:n}});await e.updateStepCaches({testId:t.id,entries:E})}catch(E){l.error({err:E},"Failed to save step caches after successful execution. This is not critical, but can impact future performance.")}}}}});return m&&(l.info("Waiting for last run update to finish"),await Promise.resolve(m)),b}async function Qm(r){let{tests:e,start:t,waitOn:n,client:o,ws:s,report:i,retriesOverride:a,urlOverride:l,envName:c,orgId:u,devicePixelRatio:d,customHeaders:m,testInputMatrix:p,waitOnTimeout:f=60,parallel:h=1,shardIndex:g=1,shardCount:y=1}=r;t&&(z.info(`Executing start command: ${t}`),await Tm(t,!1)),n&&(z.info(`Waiting for url: ${n} with timeout: ${f} seconds.`),await fb({resources:[n],timeout:f*1e3,headers:{Accept:"*/*"},followRedirect:!0,verbose:!0,log:!0,strictSSL:!1}));let S=new Vn({baseURL:o.baseUrl,apiKey:o.apiKey}),b=new Set;z.info({tests:e},`Reading tests from the following local file paths:
|
|
1798
|
+
${e.map(R=>` - ${R}`).join(`
|
|
1799
|
+
`)}`);let C=Ft(s,T);e.forEach(R=>{if(!pb(R))throw new Error(`Path '${R}' does not exist.`);let H,Y;try{H=hb(R),Y=H.isDirectory()}catch(oe){z.error({err:oe},`Skipping path ${R} because it cannot be read`);return}if(Y){let oe=Zm.resolve(R);Object.values(C.tests).filter(He=>He.fullFilePath.startsWith(oe)).map(He=>{b.add(He.fullFilePath)})}else if(R.endsWith(ut.TEST))b.add(Zm.resolve(R));else throw new Error(`Path '${R}' is neither a directory nor a ${ut.TEST} file.`)});let v=Array.from(b),E=[];if(v.forEach((R,H)=>{p?p.forEach((Y,oe)=>{E.push({path:R,testIndex:H,inputs:Y,inputIndex:oe})}):E.push({path:R,testIndex:H,inputs:void 0,inputIndex:void 0})}),y&&y>1){E=gb(E,g,y);let R=E[0],H=E[E.length-1];if(T.dimmed(`Assigned shard ${g} of ${y} of all available tests:`),R){let Y=`(test ${R.testIndex+1}/${v.length})`,oe=R.inputIndex===void 0?"":` (input set ${R.inputIndex+1}/${p.length})`;T.dimmed(` - First test assigned to this worker ${Y}${oe}: ${R.path}`)}if(H){let Y=`(test ${H.testIndex+1}/${v.length})`,oe=H.inputIndex===void 0?"":` (input set ${H.inputIndex+1}/${p.length})`;T.dimmed(` - Last test assigned to this worker ${Y}${oe}: ${H.path}`)}T.dimmed()}z.info({allTestsToRunWithInputs:E,shardCount:y,shardIndex:g},`Running ${E.length} tests with ${h} workers`),T.dimmed(`Running ${E.length} tests with ${h} workers:
|
|
1800
|
+
${E.map(R=>` - ${R.path}${R.inputIndex?` with input set ${R.inputIndex}`:""}`).join(`
|
|
1801
|
+
`)}`);let P=[],A=Date.now(),O=new Set;for(let R=0;R<E.length;R+=h){let H=await Promise.all(E.slice(R,R+h).map(async({path:Y,inputs:oe})=>{try{O.add(Y),Jm(`${O.size}/${E.length} ${Y}`);let He=await Xm({path:Y,momenticFiles:C,ws:s,testInputs:oe,orgId:u,devicePixelRatio:d,apiClient:o,generator:S,retriesOverride:a,urlOverride:l,envName:c,noReport:!i,customHeaders:m});return{identifier:Y,...He}}catch(He){let Sn=`A fatal error occurred while setting up the test '${Y}': ${He.message}`;return z.error({err:He},"A fatal error occurred while setting up the test"),T.error(Sn),{identifier:Y,status:"FAILED",failureDetails:{errorMessage:Sn,errorStack:He.stack}}}}));P.push(...H)}Jm.clear();let M=o.getAppUrl();return dr({results:P,startTime:A,onFailed:R=>{qs(R,R.identifier)},getDisplayLine:R=>{let H=` ${R.identifier}`;return i&&R.runId&&(H+=` (${M}/runs/${R.runId})`),H},entity:"test"})}function gb(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.toSorted().filter((s,i)=>i>=n&&i<o)}var ot=new yb;ot.name("momentic").description("Momentic CLI");ot.command("install-browsers").action(async()=>{await Hs()});ot.addOption(new qt("--log-level <level>").choices(["debug","info","warn","error"]).default("info")).on("option:log-level",r=>{z.setMinLevel(r.toLowerCase()),T.setMinLevel(r.toLowerCase())});ot.addOption(new qt("--verbose","enable verbose logging")).on("option:verbose",()=>{z.enableConsoleLogs()});ot.command("check-config").addOption(fo).action(async r=>{mo(r.config)});ot.command("migrate-from-v0").addOption(yn).action(async r=>{!r.yes&&!await vt("This command will migrate and then delete your previous Momentic files. All members of your team should transition to the V1 CLI at the same time. Please backup your local directory for safety before proceeding. Continue?",!0)&&process.exit(1),Nm()});ot.command("import-from-cloud").addOption(ar).addOption(lr).addOption(fo).addOption(yn).action(async r=>{let e=await cr(r),{apiKey:t,server:n,config:o,yes:s}=e,i=mo(o),a=new Ue({baseUrl:n,apiKey:t,logger:z});await Mm({client:a,ws:i,skipPrompts:s}),process.exit(0)});ot.command("init").description("Initialize an empty Momentic workspace in the current working directory").addOption(new qt("--name <name>","Name of the workspace")).action(async r=>{T.info(`Welcome to the Momentic workspace setup wizard! \u{1F680}
|
|
1802
|
+
`),T.info("This wizard will help you bootstrap a new Momentic workspace. If need to import existing assets from Momentic Cloud, you can call the 'import-from-cloud' command after initialization."),ep.existsSync(uo)&&(T.error("A momentic.config.yaml file already exists in this directory. Please rename or remove it to initialize a new workspace."),process.exit(1));let t={name:r.name??(await Am("Choose an identifier for your workspace, such as a service, product, or team name (default: 'app'):")||"app"),include:lo};or(t,uo),T.success(`Initialized Momentic workspace file at ${Ys.resolve(uo)}`)});ot.command("app").addOption(ar).addOption(lr).addOption(yn).addOption(_a).addOption(Dm).addOption(fo).action(async r=>{let e=await cr(r),{apiKey:t,port:n=Us,yes:o,server:s,pixelRatio:i}=e,a=new Ue({baseUrl:s,apiKey:t,logger:z});await js({client:a,skipPrompts:o,installBrowsers:!0});let l=mo(e.config);wb(l.rootDir);let c=bb(import.meta.url),u=Ys.dirname(c),d=Ys.resolve(u,"..","static"),m=Ys.resolve(u,"..","assets"),p=i??xa();Aa(p),await bm({momenticServerUrl:s,apiKey:t,serverPort:n,appPort:n,staticDir:d,assetsDir:m,devicePixelRatio:p,workspace:l})});var tp=ot.command("queue").description("Queue tests or suites to run on Momentic Cloud");tp.command("suites").description("Run one or more suites on Momentic Cloud").addOption(ar).addOption(lr).addOption(La).addOption(Ma).addOption(yn).addArgument($m).addOption(Ws).addOption(zs).addOption($s).action(async(r,e)=>{let{apiKey:t,server:n,wait:o,waitTimeout:s,yes:i,env:a,urlOverride:l,customHeaders:c}=await cr(e),u=new Ue({baseUrl:n,apiKey:t,logger:z});await js({client:u,skipPrompts:i,installBrowsers:!1}),(!r||!Array.isArray(r)||!r.length)&&(T.error("Must pass at least one suite to run."),process.exit(1)),await Vm({client:u,wait:o,suitePaths:r,waitTimeout:s,env:a,urlOverride:l,customHeaders:Bs(c)})});tp.command("tests").description("Run one or more tests on Momentic Cloud").addOption(ar).addOption(lr).addOption(yn).addOption($s).addOption(ka).addOption(Ws).addOption(zs).addOption(La).addOption(Ma).addArgument(Fm).action(async(r,e)=>{let t=await cr(e),{all:n,apiKey:o,customHeaders:s,env:i,server:a,inputCsv:l,urlOverride:c,wait:u,waitTimeout:d,yes:m}=t,p=Bs(s);for(let g of r)(g.endsWith(".yaml")||ep.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 f=new Ue({baseUrl:a,apiKey:o,logger:z}),h;l&&(h=await Ra(l)),await Km({client:f,tests:r,all:n,customHeaders:p,env:i,urlOverride:c,wait:u,waitTimeout:d,testInputMatrix:h,yes:m}),process.exit(0)});var Cb=ot.command("run").description("Run tests on the local machine");Cb.addOption(ar).addOption(lr).addOption(fo).addOption(yn).addOption($s).addOption(ka).addOption(zs).addOption(Ws).addOption(Na).addOption(_a).addOption(new qt("--start <start>","Arbitrary setup command that will run before Momentic steps begin.")).addOption(new qt("--wait-on <waitOn>","URL to wait to become accessible before Momentic tests begin.")).addOption(new qt("--wait-on-timeout <waitOnTimeout>","Max time in seconds to wait for the --wait-on URL to become accessible.")).addOption(new qt("--retries <retries>","Number of retries to attempt when running tests locally. Defaults to each test's own retry configuration.")).addOption(new qt("-p, --parallel <parallel>","When running with the --local flag, the number of tests to run in parallel. Defaults to 1.")).addOption(Na).addOption(Bm).addOption(zm).addArgument(Um).action(async(r,e)=>{let t=await cr(e),{apiKey:n,customHeaders:o,env:s,parallel:i,pixelRatio:a,report:l,retries:c,server:u,start:d,inputCsv:m,urlOverride:p,waitOn:f,waitOnTimeout:h,yes:g,shardIndex:y,shardCount:S,config:b}=t,C=Bs(o),v=mo(b);(!r||!r.length)&&(T.error("You must pass at least one test file path."),process.exit(1));let E=new Ue({baseUrl:u,apiKey:n,logger:z}),P;m&&(P=await Ra(m));let A=await js({client:E,skipPrompts:g,installBrowsers:!0}),O=a??xa();Aa(O);try{(await Qm({tests:r,ws:v,client:E,customHeaders:C,start:d,waitOn:f,waitOnTimeout:h,retriesOverride:c,parallel:i,report:l,devicePixelRatio:O,envName:s,orgId:A,urlOverride:p,shardIndex:y,shardCount:S,testInputMatrix:P})).failed>0?process.exit(1):process.exit(0)}catch(M){T.error("Failed to run tests locally. Please check the error message below or run with the --verbose flag."),T.error(M),process.exit(1)}});async function Tb(){try{await ot.parseAsync(process.argv)}catch(r){let e={};try{e.playwrightVersion=Sb("npx playwright --version").toString()}catch(t){z.error({err:t},"Error fetching debug information")}z.error({err:r,debugInfo:e},"Uncaught error in CLI"),z.flush(),T.error(r),process.exit(1)}}Tb();
|