@checksum-ai/runtime 1.1.23 → 1.1.24
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/checksumlib.js +18073 -9946
- package/cli.js +1 -1
- package/package.json +1 -1
package/cli.js
CHANGED
|
@@ -134,7 +134,7 @@ show-report [options] [report] show HTML report
|
|
|
134
134
|
`);break;case"test":try{let n=(await this.getCmdOutput("npx playwright test --help")).replace(/npx playwright/g,"yarn checksum").split(`
|
|
135
135
|
`);n.splice(5,0," --checksum-config=<config> Checksum configuration in JSON format").join(`
|
|
136
136
|
`),console.log(n.join(`
|
|
137
|
-
`))}catch(r){console.log("Error",r.message)}break;case"show-report":try{let n=(await this.getCmdOutput("npx playwright show-report --help")).replace(/npx playwright/g,"yarn checksum");console.log(n)}catch(r){console.log("Error",r.message)}break;case"generate":console.log("Not implemented yet");break}}};i(Fm,"CLIHelp");var Rs=Fm;var Im=class Im extends hr{constructor(t,r=!1){super(t,r)}async run(){let t=`npx playwright show-report ${this.args.join(" ")}`;try{await this.execCmd(t)}catch(r){console.log("Error showing report",r.message)}}};i(Im,"CLIShowReport");var vu=Im;var xt=require("fs"),kn=require("path");var Rm=class Rm extends hr{constructor(t,r=!1){super(t,r)}run(){console.log("Creating Checksum directory and necessary files to run your tests");try{this.findProjectRoot()}catch(s){console.log(s.message),process.exit(1)}let t=(0,kn.join)(process.cwd(),yl);if((0,xt.existsSync)(t)||(0,xt.mkdirSync)(t),!(0,xt.existsSync)(this.getChecksumRootOrigin()))throw new Error("Could not find checksum root directory, please install @checksum-ai/runtime package");let r=(0,xt.existsSync)((0,kn.join)(t,"checksum.config.ts"));pb({isInit:!r}).forEach(s=>{let l=(0,kn.join)(t,s);(0,xt.existsSync)(l)||(0,xt.copyFileSync)((0,kn.join)(this.getChecksumRootOrigin(),s),l)});let n=(0,kn.join)(t,".gitignore.example"),o=(0,kn.join)(t,".gitignore");(0,xt.existsSync)(n)&&!(0,xt.existsSync)(o)&&((0,xt.copyFileSync)(n,o),(0,xt.unlinkSync)(n)),this.validateAuthExists(),(0,xt.mkdirSync)((0,kn.join)(t,"tests"),{recursive:!0}),["esra","har","trace","log"].forEach(s=>{(0,xt.mkdirSync)((0,kn.join)(t,"test-data",s),{recursive:!0})})}};i(Rm,"CLIInstall");var xu=Rm;var Om=St(require("path")),yu=St(require("fs"));function Mm(e,t){let r=e.match(/^data:([A-Za-z-+\/]+);base64,(.+)$/);if(!r||r.length!==3)throw new Error("Invalid base64 string");let n=r[1],o=r[2],s=Buffer.from(o,"base64");return{name:t,type:n,buffer:s,size:s.length}}i(Mm,"base64ToFile");function Ok(e,t){let r=Mm(e,t),n=Om.default.join(__dirname,"..","uploads");yu.default.existsSync(n)||yu.default.mkdirSync(n,{recursive:!0});let o=Om.default.join(n,t);return yu.default.writeFileSync(o,r.buffer),console.log(`File written successfully: ${o}`),o}i(Ok,"writeBase64ToFile");var Lm=class Lm{constructor(t,r,n,o,s,l){this.config=t;this.checksumRoot=r;this.pageInteractor=n;this.apiService=o;this.userStoryService=s;this.actionsManager=l;this.executeAction=i(async(t,r={valueChanged:!1,playMode:!1})=>{try{if(await this.pageInteractor.performAction(t),!r.playMode)return t.timestamp=Date.now(),this.actionsManager.onActionExecuted(t,{parentAction:r.parentAction}),t}catch(n){throw console.error(n),new Error(n)}},"executeAction")}async uploadFiles(t){let r=t.map(({data:n,fileName:o},s)=>Mm(n,o));await Promise.all(r.map(async n=>{let o=await this.getUploadFileSignedUrl({fileName:n.name,contentType:n.type});await this.apiService.putFile(o,n)})),t.forEach(({data:n,fileName:o},s)=>Ok(n,o))}async getUploadFileSignedUrl(t){if(!this.userStoryService.hasTestGenerationData()){console.log("No generationBatchId, can't upload");return}let r=await this.apiService.post("test-generation/get-upload-file-signed-url",{...t,batchId:this.userStoryService.getTestGenerationData().generationBatchId}),{url:n}=await r.json();return n}async login(t){let r=Am({config:this.config,folder:this.checksumRoot}),n=this.userStoryService.getStory();await r(t,{role:n.environment.userRole,environment:n.environment.name}),this.didLogin=!0}hasLoggedIn(){return this.didLogin}};i(Lm,"VtgActionsService");var bu=Lm;var Dm=class Dm{constructor(t,r={},n=!0){this.requests=[];this.watcherConfig={minimumWaitTime:250,maximumWaitTime:1e4,followingRequestsWaitTime:250};this.resolved=!0;this.hasMinimumWaitTimePassed=!1;this.useLog=!1;this.logStack=[];this.resolve=i(()=>{this.resolved||(this.resolved=!0,clearTimeout(this.minimumWaitTimer),clearTimeout(this.maximumWaitTimer),clearTimeout(this.followingRequestWaitTimeoutId),this.loadResolve({totalTime:Date.now()-this.startTS,logs:this.logStack,pendingRequests:this.requests.length,totalRequests:this.observedRequestsCount}))},"resolve");this.watcherConfig={...this.watcherConfig,...r},this.initListeners(t),this.useLog=n}initListeners(t){t.on("request",r=>{var n;this.hasMinimumWaitTimePassed||(n=this.watcherConfig.whitelist)!=null&&n.length&&!this.watcherConfig.whitelist.some(o=>o.test(r.url()))||(this.useLog&&this.logStack.push(`${r.method()} ${r.url().substring(0,60)}`),this.requests.push(r),this.observedRequestsCount+=1)}),t.on("response",r=>{this.requests=this.requests.filter(n=>n!==r.request()),this.hasMinimumWaitTimePassed&&(this.requests.length||(clearTimeout(this.followingRequestWaitTimeoutId),this.followingRequestWaitTimeoutId=setTimeout(()=>{this.requests.length||this.resolve()},this.watcherConfig.followingRequestsWaitTime)))})}async wait(){return new Promise(t=>{this.loadResolve=t,this.resolved=!1,this.minimumWaitTimer=setTimeout(()=>{this.hasMinimumWaitTimePassed=!0,this.requests.length||this.resolve()},this.watcherConfig.minimumWaitTime),this.maximumWaitTimer=setTimeout(this.resolve,this.watcherConfig.maximumWaitTime)})}startListening(){this.requests=[],this.startTS=Date.now(),this.hasMinimumWaitTimePassed=!1,this.observedRequestsCount=0,this.useLog&&(this.logStack=[])}};i(Dm,"NetworkWatcher");var wu=Dm;var Mk=require("crypto");var qm=class qm{constructor(t,r,n,o,s){this.webDriver=t;this.pageInteractor=r;this.actionsService=n;this.actionsManager=o;this.apiService=s;this.previousActionFailed=!1;this.currentChecksumId="0";this.executeAction=i(async(t,r={valueChanged:!1,playMode:!1})=>{await this.webDriver.clearHighlights(),this.previousActionFailed=!1;let n;try{let o=new wu(this.webDriver.liveMainFrame.page());o.startListening(),n=await this.actionsService.executeAction(t),await o.wait(),await De(2e3)}catch(o){throw this.previousActionFailed=!0,console.error(o),new Error(o)}return r.valueChanged&&await this.init(),n},"executeAction")}async init(){this.clear(),this.executedActions=this.actionsManager.actions,await this.startSession()}setStory(t){this.story=t}clear(){this.executedActions=[],this.remoteSessionId=void 0,this.previousActionFailed=!1,this.currentChecksumId="0"}async startSession({retriesLeft:t=3}={}){let r={type:"test-generation",storyTitle:this.story.goal,storyInstructions:this.story.instructions,testId:void 0,testSuiteId:void 0,thoughtsAndActions:{previous:(this.executedActions??[]).filter(n=>!!n.description).map(n=>({thought:n.description,action:void 0}))}};try{let n=await this.apiService.post("ai-fallback/init",r);this.remoteSessionId=await n.text()}catch(n){if(console.error(n),await De(2e3),t>0)return this.startSession({retriesLeft:t-1});throw n}}async iterate({guidance:t}={}){await this.webDriver.toggleTimeMachineHandleEvents(!1);let{reducedHTML:r,flashingHTML:n,elementsForNodeInterpretation:o,currentChecksumId:s}=await this.webDriver.evaluateWithChecksum(async({appRules:p,currentChecksumId:d})=>window.checksum.testGenerator.reduceHTML(p,{stopFlashingElementsDetection:!0,assignChecksumIdsToAllElements:!0,initialChecksumId:d}),{appRules:{appSpecificInteractableElementsSelectors:[]},currentChecksumId:this.currentChecksumId});this.currentChecksumId=s;let l=await this.getNextAction({reducedHTML:r,flashingHTML:n,elementsForNodeInterpretation:o,guidance:t});try{let d={...await this.pageInteractor.translateActionResponseToAgentPotentialAction(l),id:(0,Mk.randomUUID)(),timestamp:Date.now()};return await this.webDriver.highlightElementByLocator(this.pageInteractor.makeLocator(d.selector,d.parentFramesSelectors),d.clickOffset,"10px solid rgba(255,0,0,1)"),d}catch(p){console.error("error in ai iterate",p)}}async stop(){}async getNextAction({reducedHTML:t,flashingHTML:r,elementsForNodeInterpretation:n,guidance:o}){let s={reduction:{reducedHTML:t,flashingHTML:r,elementsForNodeInterpretation:n},currentURL:this.webDriver.liveMainFrame.url(),previousActionOverview:{success:!this.previousActionFailed,userCorrection:o}};try{return await(await this.apiService.post("ai-fallback/iterate",{sessionId:this.remoteSessionId,iterationData:s})).json()}catch(l){throw console.error(l),l}}};i(qm,"VtgAITestGenerationService");var _u=qm;var Bm=class Bm{constructor(t,r){this.config=t;this.baseURL=r+"/client-api/runtime"}getBaseURL(){return this.baseURL}post(t,r){return fetch(`${this.baseURL}/${t}`,{method:"POST",headers:{"Content-Type":"application/json",ChecksumAppCode:this.config.apiKey},body:r?JSON.stringify(r):void 0})}putFile(t,r){return fetch(t,{method:"PUT",headers:{"Content-Type":r.type},body:r})}};i(Bm,"VtgCloudAPIService");var ku=Bm;var Nm=class Nm{constructor(t){this.webDriver=t}async run(t,r,{thought:n,matcher:o,index:s,assertionIndex:l}){let p=!1;Array.isArray(t)||(p=!0);try{let d=await this.processAssertion(r,{thought:n,matcher:o}),f=p?t:t[s];return f?(f.assertions||(f.assertions=[]),l!==void 0?f.assertions[l]=d:f.assertions.push(d),d):void 0}finally{this.webDriver.tmFrame.evaluate(async()=>{await window.checksum.timeMachine.goLive()})}}async processAssertion(t,{thought:r,matcher:n}){let o={...t};return{thought:r,selected:!0,selector:o.selector,locator:o.locator,matcher:n}}};i(Nm,"VisualAssertionsGenerator");var Su=Nm;var qs=require("@playwright/test"),ng=St(nS());var tg=class tg{constructor(t){this.options=t;this.harData={methodIndex:{GET:0,POST:0,PUT:0,DELETE:0}};this.interceptors={recordHar:this.harInterceptor.bind(this),completeOriginHeader:this.completeOriginHeaderInterceptor.bind(this)};this.intercept=i(async(t,r,n)=>{let o=[],s=i(l=>{if(l)switch(l.type){case"abort":return t.abort(l.errorCode);case"fulfill":return t.fulfill(l.fulfillOptions);default:case"continue":o.push(l)}},"processResult");for(let[l,p]of Object.entries(this.interceptors))if(this.options[l]){let d=s(await p(t,r,n));if(d)return d}return this.applyContinueResults(t,o)},"intercept")}setOptions(t){this.options=t}mergeOptions(t){this.options={...this.options,...t}}applyContinueResults(t,r){let n=r.filter(s=>!!s),o={};return n.forEach(s=>{s.options&&(s.options.headers&&(o.headers={...o.headers,...s.options.headers}),s.options.method&&(o.method=s.options.method),s.options.postData&&(o.postData=s.options.postData),s.options.url&&(o.url=s.options.url))}),t.continue(o)}async harInterceptor(t){let r=t.request().headers(),n=t.request().method();return r["Checksum-Id"]=(++this.harData.methodIndex[n]).toString(),{options:{headers:r}}}async completeOriginHeaderInterceptor(t,r,{page:n}){let o=t.request().headers();if(!o.Origin){try{let s=new URL(n.url()).origin;o.Origin=s}catch{}return{options:{headers:o}}}}};i(tg,"RouteInterceptors");var Pu=tg;var iS=require("path");var rg=class rg{constructor(t){this.options=t;this.navigatingFrames={};this.trackedFramesGuid=[];this.frameNavigationPromises={};this.onFrameNavigated=i(async t=>{let r=Bt(t);if(this.trackedFramesGuid.includes(r))return this.frameNavigationPromises[r]=new Promise(async n=>{await this.loadScript(t),n()}),this.frameNavigationPromises[r]},"onFrameNavigated");this.addScriptTagOptions=this.makeFrameInjectedScriptOptions()}setScriptLoadCallback(t){this.scriptLoadCallback=t}setScriptLoadCheck(t){this.scriptLoadCheck=t}async addTrackedFrame(t,r=!0){let n="mainFrame"in t?t.mainFrame():t,o=Bt(n);if(this.trackedFramesGuid.includes(o)||this.trackedFramesGuid.push(o),r)return this.onFrameNavigated(n)}getNavigationPromise(t){let r=typeof t=="string"?t:"mainFrame"in t?Bt(t.mainFrame()):Bt(t);return this.frameNavigationPromises[r]}makeFrameInjectedScriptOptions(){switch(this.options.scriptSource){case"file":return this.options.scriptFile?{path:(0,iS.join)(process.cwd(),this.options.scriptFile)}:void 0;case"url":return this.options.scriptURL?{url:this.options.scriptURL}:void 0;default:return}}isFrameClosed(t){return t.isDetached()||t.page().isClosed()}async loadScript(t,{retriesLeft:r=3,retryWaitMS:n=2e3}={}){var p,d;if(!this.addScriptTagOptions){console.warn("[InjectedScriptManager] addScriptTagOptions not set, skipping loadScript");return}if(this.isFrameClosed(t)||(this.scriptLoadCheck?await((p=this.scriptLoadCheck)==null?void 0:p.call(this,t)):!1)||this.isFrameClosed(t))return;try{await t.addScriptTag(this.addScriptTagOptions)}catch(f){if(r>0)return console.warn(`[InjectedScriptManager] Failed to add script to frame ${Bt(t)}, trying again in ${n/1e3} seconds, ${r-1} retries left.`,f),await De(n),this.loadScript(t,{retriesLeft:r-1,retryWaitMS:n});throw f}let s=Bt(t),l=Date.now().toString(36)+Math.random().toString(36).substr(2);if(this.navigatingFrames[s]=l,this.options.scriptInitWait&&(console.log(`Waiting ${this.options.scriptInitWait}[ms] before onScriptLoad...`),await De(this.options.scriptInitWait),console.log("Done waiting before onScriptLoad")),!this.isFrameClosed(t)){if(this.navigatingFrames[s]&&this.navigatingFrames[s]!==l)return console.log("Page navigated again, waiting on new promise..."),this.frameNavigationPromises[s];try{await((d=this.scriptLoadCallback)==null?void 0:d.call(this,t))}catch(f){console.error("[WebDriver] onScriptLoad error",f)}}}};i(rg,"InjectedScriptManager");var Fu=rg;var ig=class ig{constructor(t={},r={}){this.browserConfig={devtools:!1,executablePath:process.env.PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH??void 0};this.options={fullScreenResolution:!1,defaultTimeout:3e4,defaultNavigationTimeout:3e4,disableWebSecurity:!0};this.contextClosePromise=void 0;this.eventListeners=[];this.lastSnapshot={selector:void 0,eventCode:void 0};this.snapshotTimeout=3e4;this.cacheScript=!1;this.pagesIndexToGuid={};this.onRequestFinished=i(async t=>{try{let r=await t.response();if(!r.ok())return;let n=t.resourceType(),o=t.url(),s=i(async()=>{try{return await r.text()}catch{try{return await(await fetch(o)).text()}catch{return}}},"getBody");if(["document","script","stylesheet"].includes(n))try{let l=await s();if(!l)return;let p={url:o,source:l,type:n};await this.forEachEventListener(d=>{var f;return(f=d.onWebDriverResourceLoaded)==null?void 0:f.call(d,p)})}catch(l){console.error("[WebDriver] requestfinished event handler error",n,o,l)}}catch(r){console.error("[WebDriver] requestfinished event handler error",r)}},"onRequestFinished");this.onFrameNavigated=i(async t=>{let r=i(async n=>{await this.forEachEventListener(o=>{var s;return(s=o.onWebDriverFrameNavigated)==null?void 0:s.call(o,t,n)})},"notifyFrameNavigated");await r(!1),await this.injectedScriptManager.onFrameNavigated(t),await r(!0)},"onFrameNavigated");this.tracing=!1;this.tracingChunk=!1;this.chunkIndex=0;var n;if(this.options={...this.options,...t},this.browserConfig={...this.browserConfig,...r},this.injectedScriptManager=new Fu(this.options),this.browserConfig.args||(this.browserConfig.args=[]),this.options.disableWebSecurity&&this.browserConfig.args.push("--disable-web-security"),this.options.allowFileAccess&&this.browserConfig.args.push("--allow-file-access-from-files"),this.browserConfig.args.push("--disable-site-isolation-trials"),this.browserConfig.args.push("--allow-running-insecure-content"),this.options.forceHeadless&&(this.browserConfig.headless=!0,this.browserConfig.devtools=!1),this.options.useProxy)if((n=this.options.webProxy)!=null&&n.server){console.log("[WebDriver] using proxy");let{server:o,username:s,password:l}=this.options.webProxy;this.browserConfig.proxy={server:o,username:s,password:l},this.browserConfig.args.push("--proxy-bypass-list=localhost,127.0.0.1")}else console.error("[WebDriver] useProxy=true but proxy not configured");this.routeInterceptor=new Pu({completeOriginHeader:this.options.completeOriginHeader,recordHar:this.options.recordHAR})}async prepare({storageState:t}={}){if(await this.shutdown(),this.options.useStealth){let n=require("puppeteer-extra-plugin-stealth");ng.chromium.use(n()),this.browser=await ng.chromium.launch(this.browserConfig)}else this.browser=await qs.chromium.launch(this.browserConfig);let r={};return r.bypassCSP=!0,r.ignoreHTTPSErrors=!0,r.baseURL=this.options.baseURL,this.options.timezoneId&&(r.timezoneId=this.options.timezoneId),this.options.fullScreenResolution?r.viewport={width:1280,height:720}:this.options.hostWindowViewport&&(r.viewport=null),t&&(r.storageState=t),this.context=await this.browser.newContext(r),this.options.defaultTimeout&&this.context.setDefaultTimeout(this.options.defaultTimeout),this.options.defaultNavigationTimeout&&this.context.setDefaultNavigationTimeout(this.options.defaultNavigationTimeout),this.context.on("page",async n=>{await this.onNewPage(n),await this.onFrameNavigated(n.mainFrame()),n.on("framenavigated",this.onFrameNavigated)}),this.context.on("close",async()=>{this.contextClosePromise=this.forEachEventListener(n=>{var o;return(o=n.onWebDriverContextClose)==null?void 0:o.call(n)})}),this.activePage=await this.context.newPage(),this.originalPage=this.activePage,this.options.trackLoadedResources&&this.page.on("requestfinished",this.onRequestFinished),this.options.useCDPSession&&(this.cdpSession=await this.context.newCDPSession(this.page)),!0}async onNewPage(t){try{await(t==null?void 0:t.route("**/*",async(r,n)=>this.routeInterceptor.intercept(r,n,{page:t})))}catch(r){console.error("[WebDriver] onPage error",r)}}switchActivePage(t){let r=this.context.pages().find(n=>Bt(n)===t);return!r||r.isClosed()?(console.error(`[WebDriver] Page with guid ${t} not found or has been closed.`),!1):(this.previousPage=this.activePage,this.activePage=r,!0)}getDefaultTimeout(){return this.options.defaultTimeout}getDefaultNavigationTimeout(){return this.options.defaultNavigationTimeout}async addHARMockAPIRecordings(t){if(!this.activePage){console.warn("[addHARMockAPIRecordings] Active page is not set, skipping HAR recording.");return}await this.activePage.routeFromHAR(t,{url:/^(?!.*\.(js|mjs|ts|jsx|tsx|css|jpg|jpeg|png|gif|svg|webp|heif|heic|raw|cr2|nef|arw|bmp|tiff|tif|ico|woff|woff2|ttf|otf|doc|docx|pdf|ws|wasm|mp3|wav|aac|flac|mp4|avi|mov|wmv|flv|zip|rar|7z|tar\.gz|xml|html|py|java|cpp|xls|xlsx|ppt|pptx|gif)$)/i,update:!0,updateMode:"minimal"})}forEachEventListener(t){return Promise.all(this.eventListeners.map(async r=>{try{await t(r)}catch(n){console.log("WebDriver/forEachEventListener exception",n)}}))}registerEventListener(t){this.eventListeners.push(t)}async getScript(){async function t(r){let{exec:n}=require("child_process");return new Promise((o,s)=>{n(r,l=>{l?(console.log("error executing cmd, ",l),s(l)):o()})})}switch(i(t,"execCmd"),this.options.scriptSource){case"file":return this.options.scriptFile;case"url":if(this.cacheScript)return this.options.scriptFile;try{return await t(`curl -o ${this.options.scriptFile} '${this.options.scriptURL}'`),this.options.scriptFile}catch(r){console.log("[web-driver] Failed fetching frontend script",r)}break}}async startJSCoverageTracking(){return await this.page.coverage.startJSCoverage(),[];return await this.cdpSession.send("Debugger.enable"),await this.cdpSession.send("Profiler.enable"),await this.cdpSession.send("Profiler.startPreciseCoverage",{callCount:!1,detailed:!0}),this.getCurrentJSCoverage()}stopJSCoverageTracking(){return this.page.coverage.stopJSCoverage()}async getCurrentJSCoverage(){let t=await this.page.coverage.stopJSCoverage();return await this.page.coverage.startJSCoverage(),t;return(await this.cdpSession.send("Profiler.takePreciseCoverage")).result}async startCSSCoverageTracking(){return await this.cdpSession.send("DOM.enable"),await this.cdpSession.send("CSS.enable"),await this.cdpSession.send("CSS.startRuleUsageTracking"),this.getCurrentCSSCoverage()}async getCurrentCSSCoverage(){return(await this.cdpSession.send("CSS.takeCoverageDelta")).coverage}getCDPSession(){return this.cdpSession}async navigate(t){return this.page.goto(t)}async setViewportSize(t,r){return this.page.setViewportSize({width:t,height:r})}async getStorageState(){return this.page.context().storageState()}async shutdown(){try{this.page&&(await this.page.close(),this.activePage=void 0),this.context&&(await this.context.close(),this.context=void 0),this.browser&&(await this.browser.close(),this.browser=void 0)}catch(t){console.warn("[WebDriver] shutdown error",t)}}async wrapWithBrowserLogs(t,{disabled:r=!1,onErrorOnly:n=!1}={}){if(r)return t();let o=[],s=i(d=>{o.push(d.text())},"log");this.page.on("console",s);let l,p;try{p=await t()}catch(d){l=d}if(this.page.off("console",s),(!n||l)&&console.log("browser console messages:",o),l)throw l;return p}async takeElementSnapshot(t,r,n={},o={}){if(t===this.lastSnapshot.selector&&r===this.lastSnapshot.eventCode)return{};if(!t)return{};try{let{snapshot:s,elementLocator:l}=await this.takeSnapshot(t,o,{frameLocatorSelector:n.frameLocatorSelector});return this.lastSnapshot={selector:t,eventCode:r},{snapshot:s,elementLocator:l}}catch(s){return console.error("takeElementSnapshot error",s),{}}}getScreenshotTimeout(t=!1){return t?this.snapshotTimeout:this.snapshotTimeout+5e3}async takePageSnapshot(t){let r=this.page.screenshot({...t,timeout:this.getScreenshotTimeout()});return await Promise.race([r,De(this.getScreenshotTimeout(!0))])}async takeSnapshot(t,r,{frameLocatorSelector:n}={}){let o=n?this.page.frameLocator(n).locator(t):this.page.locator(t),s=o.screenshot({...r,timeout:this.getScreenshotTimeout()});return{snapshot:await Promise.race([s,De(this.getScreenshotTimeout(!0))]),elementLocator:o}}async getCurrentURL(){return this.page.url()}async getClientScreenResolution(){return await this.page.evaluate(async()=>({width:window.screen.width,height:window.screen.height}))}async awaitContextClose(){return this.contextClosePromise||await De(100),this.contextClosePromise}get page(){return this.activePage}getPage(){return this.activePage}startPlaywrightTrace(){return this.tracing=!0,this.context.tracing.start({name:"trace",screenshots:!0,snapshots:!0})}startPlaywrightTraceChunk(){return this.tracingChunk=!0,this.context.tracing.startChunk({name:`trace-chunk-${this.chunkIndex}`})}stopPlaywrightTraceChunk(t){return this.tracingChunk=!1,this.context.tracing.stopChunk({path:`${t.replace(".zip",`.${this.chunkIndex++}.zip`)}`})}stopPlaywrightTrace(t){return this.tracing=!1,this.context.tracing.stop({path:t})}isTracing(){return this.tracing}isTracingChunk(){return this.tracingChunk}};i(ig,"WebDriver");var Iu=ig;var ag=class ag{constructor(t,r){this.webDriver=t;this.actionsManager=r}async playAssertion({selector:t,matcher:r}){try{let o=this.webDriver.tmFrame.frameLocator("iframe").locator(t),s=(0,qs.expect)(o),l=`async (expectCall) => expectCall.${r}`;return await(0,eval)(l)(s),{success:!0,message:"Assertion played successfully!"}}catch(n){return{success:!1,message:String(n)}}}async generateAssertionForAction({action:t,selector:r,locator:n,thought:o,matcher:s,assertionIndex:l}){let p=this.actionsManager.actions.findIndex(({id:h})=>h===t.id);if(p===-1)throw new Error(`[generateAssertionForAction] No action with id ${t.id} was found in executed actions`);let{success:d,message:f}=await this.playAssertion({selector:r,matcher:s});if(!d)throw new Error(f);return await new Su(this.webDriver).run(this.actionsManager.actions,{selector:r,locator:n},{index:p,thought:o,matcher:s,assertionIndex:l})}};i(ag,"VtgAssertionsService");var Ru=ag;var og=class og{constructor(){this.executedActions=[];this.onActionExecuted=this.pushExecutedActionOrAddAfterParent.bind(this)}get actions(){return this.executedActions}pushExecutedActionOrAddAfterParent(t,r={}){if(r.parentAction){let n=this.executedActions.findIndex(({timestamp:o})=>o===r.parentAction.timestamp);n!==-1&&this.executedActions.splice(n+1,0,{...t,timestamp:this.executedActions[n].timestamp+1})}else Array.isArray(t)?this.executedActions.push(...t):this.executedActions.push(t)}addManualActionsToExecuted(t){Array.isArray(t)?this.executedActions.push(...t):this.executedActions.push(t)}updateExecutedAction(t){let r=this.executedActions.findIndex(({id:n})=>n===t.id);this.executedActions[r]={...this.executedActions[r],...t}}deleteStep(t,r){Number.isNaN(+r)?this.executedActions.splice(t,1):this.executedActions[t].assertions.splice(r,1)}};i(og,"VtgActionsManager");var Ou=og;var xx=St(_4()),T4=St(require("net")),P4=St(yv()),F4=St(A4());var yx=class yx{constructor(t,r,n,o,s,l){this.actionsService=t;this.assertionsService=r;this.locatorsService=n;this.aiTestGenerationService=o;this.actionsManager=s;this.storageService=l}async start(){return this.app=(0,xx.default)(),this.app.use((0,F4.default)()),this.app.use(P4.default.json({limit:"50mb"})),this.app.use(xx.default.raw({type:"multipart/form-data",limit:"50mb"})),this.port=await this.acquirePortNumber(),this.setupEndpoints(),new Promise(t=>{this.app.listen(this.port,()=>{console.log(`Express server running on port ${this.port}`),t()})})}setupEndpoints(){this.app.get("/api",async(t,r)=>{r.send("success")}),this.app.post("/api/test/upload",async(t,r)=>(await this.storageService.saveToCloud(),r.send("success"))),this.app.post("/api/test/backup",async(t,r)=>{await this.storageService.localSave(),r.send("success")}),this.app.post("/api/ai/init",async(t,r)=>{await this.aiTestGenerationService.init(),r.send("success")}),this.app.post("/api/ai/iterate",async(t,r)=>{let n=t.body,o=await this.aiTestGenerationService.iterate(n);return o?r.status(200).json(o):r.status(400).send("no action generated")}),this.app.post("/ai/stop",async(t,r)=>{this.aiTestGenerationService.stop()}),this.app.post("/api/selector/play",async(t,r)=>{let n=t.body;try{let o=await this.locatorsService.verifySelector(n);return r.status(200).send({success:o})}catch(o){return r.status(400).send({error:o.message})}}),this.app.post("/api/assertion/play",async(t,r)=>{let n=t.body,o=await this.assertionsService.playAssertion(n);return r.status(200).send(o)}),this.app.post("/api/assertion/generate",async(t,r)=>{let n=t.body;try{let o=await this.assertionsService.generateAssertionForAction(n);r.status(200).json(o)}catch(o){r.status(400).send({error:o.message})}}),this.app.post("/api/steps/execute",async(t,r)=>{let n=t.body,o=n.isAISuggestion?this.aiTestGenerationService.executeAction:this.actionsService.executeAction;try{let s=await o(n.action,n.options);return r.status(200).json(s)}catch(s){return r.status(404).send({error:s.message})}}),this.app.post("/api/upload-files",async(t,r)=>{try{await this.actionsService.uploadFiles(t.body.files)}catch(n){return r.status(500).send(n)}return r.status(200).send({message:"File uploaded successfully!"})}),this.app.post("/api/steps/add-manual-actions",async(t,r)=>{let n=t.body;return this.actionsManager.addManualActionsToExecuted(n.actions),r.send("success")}),this.app.patch("/api/steps",async(t,r)=>{let n=t.body;return this.actionsManager.updateExecutedAction(n.action),r.send("success")}),this.app.put("/api/steps",async(t,r)=>{let n=t.body;try{this.actionsManager.pushExecutedActionOrAddAfterParent(n.action,n.options)}catch(o){return r.status(500).send(o)}return r.send("success")}),this.app.delete("/api/step",async(t,r)=>{let{actionIndex:n,assertionIndex:o}=t.body;try{this.actionsManager.deleteStep(n,o)}catch(s){return r.status(500).send(s)}return r.status(200).send({message:"Success!"})})}async acquirePortNumber(){return await new Promise((t,r)=>{let n=T4.default.createServer();n.unref(),n.on("error",r),n.listen(0,()=>{let o=n.address().port;n.close(()=>{t(o)})})})}async evaluateServerPort(t){if(!t)throw new Error("Page not initialized");await t.evaluate(r=>{window.checksum.serverPort=r,localStorage.setItem("serverPort",r.toString()),console.log(`Server port set to: ${r}`)},this.port)}};i(yx,"VtgExpressServer");var Kp=yx;var bx=require("fs");var wx=class wx{constructor(t){this.projectRootDirectory=t}createTestGenerationAssetsFolders(){this.assetsFolderPath=this.projectRootDirectory+`/tg-assets/${Date.now()}`,(0,bx.mkdirSync)(this.assetsFolderPath,{recursive:!0}),(0,bx.mkdirSync)(this.getHarFolderPath(),{recursive:!0})}getAssetsFolderPath(){return this.assetsFolderPath}getHarFolderPath(){return this.assetsFolderPath+"/har"}getHarFilePath(){return`${this.getHarFolderPath()}/har.har`}getTraceFilePath(){return`${this.assetsFolderPath}/trace.zip`}};i(wx,"VtgTestAssetsManager");var Xp=wx;var lV={useCDPSession:!0,trackLoadedResources:!0},_x=class _x extends Iu{constructor(r={},n={devtools:!0},o={}){super({...lV,...r},n);this.settings={frontendAppSpecificRules:void 0,initTestGenerator:!0,frontendTestGenerationConfig:void 0};this.isScriptLoaded=i(async(r,n=1e3)=>{try{return await r.waitForFunction(()=>!!window.checksum,void 0,{timeout:n}),!0}catch{return!1}},"isScriptLoaded");this.initInjectedScript=i(async r=>{try{return await r.waitForFunction(()=>{var n;return!!((n=window.checksum)!=null&&n.testGenerator)}),r.evaluate(async({appSpecificRules:n,config:o,initModules:s})=>{window.checksum.testGenerator.init(n,o,s),n.hasGoals&&await window.checksum.goalTracker.init()},{appSpecificRules:this.settings.frontendAppSpecificRules,config:this.getFrontendTestGenerationConfig(),initModules:this.getInjectedScriptInitModules(r)})}catch(n){console.log("initInjectedScript exception",n)}},"initInjectedScript");this.settings={...this.settings,...o},this.injectedScriptManager.setScriptLoadCheck(this.isScriptLoaded),this.settings.initTestGenerator&&this.injectedScriptManager.setScriptLoadCallback(this.initInjectedScript)}async prepare(r={}){let n=await super.prepare(r);return this.evaluateWithChecksumTargetFrame=this.page.mainFrame(),this.settings.loadScriptOnPrepare&&await this.injectedScriptManager.addTrackedFrame(this.page),await this.page.addInitScript(()=>{window.sessionStorage.setItem("checksumai:disable","true")}),n}setEvaluateWithChecksumTargetFrame(r){this.evaluateWithChecksumTargetFrame=r}getInjectedScriptInitModules(r){return{assertionGenerator:!0,sessionRecorder:!0,filesObserver:!1}}getFrontendTestGenerationConfig(){return this.settings.frontendTestGenerationConfig}async evaluateWithChecksum(r,n,o=this.evaluateWithChecksumTargetFrame){let s=this.injectedScriptManager.getNavigationPromise(o);s&&await s;try{return o.evaluate(r,n)}catch(l){throw console.error("evaluateWithChecksum error",l,r.toString()),l}}async getBestMatchingElementSimilarityScore(r){return this.evaluateWithChecksum(async n=>await window.checksum.testGenerator.getBestMatchingElementSimilarityScore(n),r)}async getInteractableElements(){return this.evaluateWithChecksum(async()=>await window.checksum.testGenerator.getInteractableElements())}async getAllInteractableElementsForLastSelectQuery(){return this.evaluateWithChecksum(async()=>await window.checksum.testGenerator.getAllInteractableElementsForLastSelectQuery())}async overlayInteractableElementsWithChecksumId(r){return this.evaluateWithChecksum(n=>window.checksum.testGenerator.overlayInteractableElementsWithChecksumId(n),r)}async postRRwebEvents(r){return this.evaluateWithChecksum(n=>window.checksum.testGenerator.postRRwebEvents(n),r)}async getRRwebEvents(r=0){return this.evaluateWithChecksum(async({index:n})=>window.checksum.testGenerator.getRRwebEvents(n),{index:r})}async getGoals(){return await this.evaluateWithChecksum(async()=>window.checksum.goalTracker.getGoals())}async takeElementSnapshot(r,n,o={},s={}){try{let{snapshot:l,elementLocator:p}=await super.takeElementSnapshot(r,n,o);if(!l||!o.takeBodyScreenshot)return l?{snapshot:l}:{};await this.highlightElementByLocator(p,o.mousePosition);let d=await this.takePageSnapshot(s);return await this.clearHighlights(),{snapshot:l,bodySnapshot:d}}catch(l){return console.error("[ChecksumWebDriver] takeElementSnapshot error",l),{}}}async highlightElementByLocator(r,n,o="20px solid rgba(255,0,0,1)"){return this.evaluateWithChecksum(async([s,l,p])=>{window.checksum.testGenerator.highlightElement(s,{highlightStyle:{outline:l},mousePosition:p})},[await r.elementHandle(),o,n])}async clearHighlights(){return this.evaluateWithChecksum(async()=>window.checksum.testGenerator.clearHighlights())}};i(_x,"ChecksumWebDriver");var Jp=_x;var O4=require("fs"),M4=St(require("path"));var kx=require("fs"),R4=St(require("path"));var I4=!0,uV=R4.join(__dirname,"..","..","..","vtg-build","index.html"),Sx=class Sx{constructor(t,r=uV){this.page=t;this.filePath=r;this.filePath=r}async start(){try{await this.modifyVTGBuildHtmlFile(),await this.startReactApp()}catch(t){console.error("An error occurred:",t)}}async startReactApp(){if(!this.page)throw new Error("Page not initialized");let t=I4?"http://localhost:3003":`file://${this.filePath}`;await this.page.goto(t,{waitUntil:"networkidle",timeout:6e4})}async modifyVTGBuildHtmlFile(){if(!I4)try{let t=await kx.promises.readFile(this.filePath,"utf8"),r=/(src|href)=(["'])(\/)static/g,n=t.replace(r,"$1=$2.$3static");await kx.promises.writeFile(this.filePath,n,"utf8"),console.log(`Successfully modified ${this.filePath}`)}catch(t){console.error(`Error processing file ${this.filePath}:`,t)}}};i(Sx,"VtgFrontendLauncher");var Yp=Sx;var _FramesMsgBroker=class _FramesMsgBroker{constructor(){this.frames={};this.pages=[]}register(name,frame,frameMsgHandler){if(this.frames[name])return;this.frames[name]=frame;let page=frame.page();this.pages.includes(page)||(this.pages.push(page),page.exposeFunction("checksumSendMessage",async(e,t)=>{let r=this.frames[e];if(!r)throw new Error(`Frame ${e} not found`);if(frameMsgHandler){frameMsgHandler(t);return}try{await r.evaluate(({message:n})=>{window.postMessage(n,"*")},{message:t})}catch(n){console.error("Error sending message to frame",n)}}),page.exposeFunction("checksumGetLiveSelectorFromLocator",async(target,locator)=>{let frame=this.frames[target];if(frame)try{let resLocator=await frame.evaluate(locator=>{let locatorObject=eval("window.playwright."+locator);if(!(locatorObject!=null&&locatorObject.element))return null;let selectorSymbol=Object.getOwnPropertySymbols(locatorObject).find(e=>e.toString()==="Symbol(selector)");return locatorObject[selectorSymbol]},locator);return resLocator}catch(e){console.error("Error getting frame window",e)}}),page.exposeFunction("checksumGetFilesFromLive",async e=>{let t=this.frames.live;if(!t){console.log("no live frime detected");return}try{return t.evaluate(r=>window.checksum.testGenerator.filesObserver.getFilesByRrwebId(r),e)}catch(r){console.error("Error getting frame window",r)}}),page.exposeFunction("checksumBringPageToFront",async e=>{let t=this.frames[e];t&&await t.page().bringToFront()}))}};i(_FramesMsgBroker,"FramesMsgBroker");var Qp=_FramesMsgBroker;var pV=!0,Cx=class Cx extends Jp{constructor(r={},n={devtools:!0},o={}){super(r,n,o);this.frameMsgBroker=new Qp;this.onLiveFrameCreated=i(async r=>{this.liveFrame=r,this.frameMsgBroker.register("live",this.liveFrame),this.setEvaluateWithChecksumTargetFrame(this.liveFrame),await this.injectedScriptManager.addTrackedFrame(this.liveFrame)},"onLiveFrameCreated")}get liveMainFrame(){return this.liveFrame}get tmFrame(){return this.timeMachineFrame}async prepare(r={}){let n=await super.prepare(r);if(this.frameMsgBroker.register("vtg",this.page.mainFrame()),this.page.on("dialog",()=>{}),await new Yp(this.page).start(),await De(2e3),this.timeMachineFrame=this.page.frames()[2],await this.injectedScriptManager.addTrackedFrame(this.timeMachineFrame),pV){let o=await this.context.newPage();await this.onLiveFrameCreated(o.mainFrame())}else await this.interceptPageRequests(),await this.onLiveFrameCreated(this.page.frames()[1]);return await this.timeMachineFrame.evaluate(()=>window.checksum.timeMachine.start({firstEventTimestamp:Date.now()})),n}async navigate(r){return this.liveFrame.goto(r)}async getCurrentURL(){return this.liveFrame.url()}getInjectedScriptInitModules(r){return r===this.timeMachineFrame?{assertionGenerator:!1,sessionRecorder:!1,filesObserver:!1}:{...super.getInjectedScriptInitModules(r),filesObserver:!0}}async interceptPageRequests(){async function r(o){try{return await O4.promises.readFile(o,"utf8")}catch(s){return console.error(`Error reading file ${o}:`,s),null}}i(r,"readLocalFile");function n(o){switch(M4.extname(o).toLowerCase()){case".html":return"text/html";case".js":return"application/javascript";case".css":return"text/css";case".json":return"application/json";case".png":return"image/png";case".jpg":case".jpeg":return"image/jpeg";default:return"application/octet-stream"}}i(n,"getContentType"),await this.page.route("**/*",async o=>{try{let s=o.request().url();if(console.log("intercepted!",s),s.startsWith("file://")){let l=s.replace("file://",""),p=await r(l);p!==null?await o.fulfill({status:200,contentType:n(l),body:p}):await o.abort()}else{let l=0,p=5;for(;l<p;){let d=await o.fetch(),f=d.status();if(f>299&&f<400){l++;let h=d.headers().location;if(!h){console.warn("Redirect without Location header"),await o.abort();return}console.log(`Redirect ${l} to: ${h}`),o.request().url=()=>new URL(h,s).toString()}else{let h={};h["Access-Control-Allow-Origin"]="*",h["Access-Control-Allow-Methods"]="GET, POST, PUT, DELETE, OPTIONS",h["Access-Control-Allow-Headers"]="Content-Type, Authorization",await o.fulfill({response:d,headers:{...d.headers(),...h,"content-security-policy":"","X-Frame-Options":"","x-frame-options":""}});return}}console.warn(`Max redirects (${p}) exceeded`),await o.abort()}}catch(s){console.warn("intercept error",s)}})}async toggleTimeMachineHandleEvents(r){try{await this.tmFrame.evaluate(n=>window.checksum.timeMachine.setShouldHandleEvents(n),r)}catch{}}};i(Cx,"ChecksumVTGWebDriver");var ef=Cx;var L4=require("request"),rf=require("fs");var Ex=class Ex{constructor(t,r,n,o,s){this.apiBaseURL=t;this.apiKey=r;this.uploadTimeout=n;this.makeGetUploadUrlAPIPath=o;this.onOutstandingUpload=s}async uploadAsset(t){try{let{path:r}=t.info;if(console.log("Uploading file",r),await this.getSignedURLForUpload(t),!t.uploadURL){console.log("Error getting signed URL for asset",r),t.error=!0;return}let o=(0,rf.statSync)(r).size,s=(0,rf.createReadStream)(r),l=mt(new Promise((p,d)=>{var h;let f=(0,L4.put)(t.uploadURL,{body:s},(v,x)=>{v&&d(v),p(x)});(h=this.onOutstandingUpload)==null||h.call(this,{request:f,size:o})}),this.uploadTimeout);l.then(p=>{if(p.statusCode!==200)throw new Error("Upload failed");console.log("File uploaded successfully",r),t.complete=!0}).catch(p=>{console.log("Error uploading asset",r,p),t.error=!0}),t.response=l}catch{t.error=!0}}async getSignedURLForUpload(t){try{let r=t.info,n=await fetch(`${this.apiBaseURL}/${this.makeGetUploadUrlAPIPath(t)}`,{method:"POST",headers:{Accept:"application/json","Content-Type":"application/json",ChecksumAppCode:this.apiKey},body:JSON.stringify(r)}),{url:o}=await n.json();t.uploadURL=o}catch(r){return console.log("Error getting signed URL for artifact",r),null}}};i(Ex,"TestAssetUploader");var tf=Ex;var D4=St(_m()),Vi=require("path"),ai=require("fs");async function q4(e,t){let r=await(0,ai.readdirSync)(t);await Promise.all(r.map(async n=>{let o=(0,Vi.join)(t,n);if((await(0,ai.statSync)(o)).isDirectory()){let l=e.folder(n);await q4(l,o)}else{let l=await(0,ai.readFileSync)(o);e.file(n,l)}}))}i(q4,"addFolderToZip");async function B4(e){try{let t=await(0,D4.loadAsync)("UEsFBgAAAAAAAAAAAAAAAAAAAAAAAA==",{base64:!0});await q4(t,e);let r=await t.generateAsync({type:"nodebuffer",compression:"DEFLATE"}),n=(0,Vi.join)((0,Vi.dirname)(e),`${(0,Vi.basename)(e)}.zip`);return(0,ai.writeFileSync)(n,r),n}catch(t){return console.error("Error creating zip:",t),null}}i(B4,"zipFolder");var N4=require("fs");var Ax=class Ax{constructor(t,r,n,o,s,l){this.config=t;this.userStoryService=r;this.apiService=n;this.actionsManager=o;this.testAssetsManager=s;this.actionsService=l}async localSave(){let t={executedActions:this.actionsManager.actions,testGenerationData:this.userStoryService.getTestGenerationData(),settings:{baseURL:this.config.baseURL,assetsFolderPath:this.testAssetsManager.getAssetsFolderPath(),didLogin:this.actionsService.hasLoggedIn(),traceFilePath:this.testAssetsManager.getTraceFilePath(),harFilePath:this.testAssetsManager.getHarFilePath()}};(0,N4.writeFileSync)(`${this.testAssetsManager.getAssetsFolderPath()}/test.json`,JSON.stringify(t,null,2))}async saveToCloud(){try{if(!this.userStoryService.hasTestGenerationData()){console.log("No test generation data, can't upload");return}let t=await this.userStoryService.createTestGeneration(),r=new tf(this.apiService.getBaseURL(),this.config.apiKey,null,()=>`test-generation/${t}/get-upload-url`),n=i(p=>({complete:!1,error:!1,response:void 0,info:p}),"buildUploadAsset"),o=n({type:"trace",path:this.testAssetsManager.getTraceFilePath()}),s=n({type:"har",path:await B4(this.testAssetsManager.getHarFolderPath())});await Promise.all([r.uploadAsset(o),r.uploadAsset(s)]);let l=this.actionsManager.actions.map(p=>({...p,parentFramesSelectors:p.parentFramesSelectors?p.parentFramesSelectors.filter(d=>d!=="iframe"):void 0}));await this.apiService.post(`test-generation/${t}/completed`,{actions:l})}catch(t){console.error("Failed to upload test",t)}}};i(Ax,"VtgStorageService");var nf=Ax;var fV=!1,dV={goal:"Send email via outreach list",instructions:"Make sure to select a user from the list first",environment:{name:void 0,userRole:void 0}},Tx=class Tx{constructor(t){this.apiService=t}getStory(){return this.story}getTestGenerationData(){return this.userStoryTestGeneration}hasTestGenerationData(){return!!this.userStoryTestGeneration.internalTestId}async fetchStory(t){if(fV){this.story=dV;return}if(!t)throw new Error("no story id provided");let r=await this.apiService.post(`test-generation/info/${t}`),{id:n,title:o,steps:s,startUrl:l,userRole:p,environment:d,internalTestId:f,generationBatchId:h}=await r.json();this.userStoryTestGeneration={internalTestId:f,generationBatchId:h},this.story={id:n,goal:o,instructions:s,url:l,environment:{userRole:p,name:d}}}async createTestGeneration(){if(!this.story.id)return;let t=await this.apiService.post(`test-generation/create/${this.story.id}`,{internalTestId:this.userStoryTestGeneration.internalTestId,testGenerationBatchId:this.userStoryTestGeneration.generationBatchId}),{testGenerationId:r}=await t.json();return this.userStoryTestGeneration.testGenerationId=r,r}};i(Tx,"VtgUserStoryService");var af=Tx;var Px=class Px{constructor(t){this.webDriver=t}async verifySelector({selector:t}){try{let n=this.webDriver.tmFrame.frameLocator("iframe").locator(t);if(!n)throw new Error(`Selector ${t} not found`);return await n.count()===1}catch{return!1}}};i(Px,"VtgLocatorsService");var of=Px;var Fx=class Fx extends hr{constructor(r,n=!1){super(r,n);this.checksumScriptFilePath="node_modules/@checksum-ai/runtime/checksumlib.js";this.initTimeMachine=i(async()=>{await this.webDriver.tmFrame.evaluate(()=>window.checksum.visualTestGenerator.init(!1))},"initTimeMachine");this.storyId=r[0],this.actionsManager=new Ou}async run(){await this.init(),this.buildServices(),this.buildServer(),await this.start()}async init({createAssetsFolder:r=!0}={}){await this.patchPlaywright(),this.loadChecksumData(),this.webDriver=this.buildWebDriver(),this.pageInteractor=new Fs(this.webDriver.evaluateWithChecksum.bind(this.webDriver),()=>this.webDriver.liveMainFrame,()=>{},{log:console.log,logError:console.error},{navigationTimeout:30*1e3,actionTimeout:5*1e3,waitActionDelay:1e3,testAssetsDir:__dirname}),this.testAssetsManager=new Xp(this.projectRootDirectory),r&&this.testAssetsManager.createTestGenerationAssetsFolders()}buildServices(){this.apiService=new ku(this.config,this.checksumApiUrl),this.userStoryService=new af(this.apiService),this.actionsService=new bu(this.config,this.checksumRoot,this.pageInteractor,this.apiService,this.userStoryService,this.actionsManager),this.assertionsService=new Ru(this.webDriver,this.actionsManager),this.locatorsService=new of(this.webDriver),this.aiTestGenerationService=new _u(this.webDriver,this.pageInteractor,this.actionsService,this.actionsManager,this.apiService),this.storageService=new nf(this.config,this.userStoryService,this.apiService,this.actionsManager,this.testAssetsManager,this.actionsService)}buildServer(){this.reactAppServer=new Kp(this.actionsService,this.assertionsService,this.locatorsService,this.aiTestGenerationService,this.actionsManager,this.storageService)}async start(){var o;await this.userStoryService.fetchStory(this.storyId),await this.webDriver.prepare(),await this.webDriver.addHARMockAPIRecordings(this.testAssetsManager.getHarFilePath()),await this.initTimeMachine(),await this.reactAppServer.start(),await this.reactAppServer.evaluateServerPort(this.webDriver.page);let r=this.config.baseURL;this.webDriver.liveMainFrame?await this.webDriver.liveMainFrame.goto(r,{waitUntil:"domcontentloaded",timeout:0}):console.error("Iframe not found"),await this.webDriver.toggleTimeMachineHandleEvents(!1),await this.webDriver.page.evaluate(({actions:s})=>{window.checksum.initVtgAfterServerReady(s)},{actions:this.actionsManager.actions}),await fu(this.webDriver.page,this.webDriver.liveMainFrame,async s=>{try{await this.actionsService.login(s)}catch{console.error("Failed to execute login function")}});let n=(o=this.userStoryService.getStory())==null?void 0:o.url;n&&(await this.webDriver.liveMainFrame.goto(n,{waitUntil:"domcontentloaded",timeout:0}),this.actionsManager.actions.push({description:"Navigate to start URL",eventCode:"navigation",fillValue:n})),await new Promise(()=>{})}buildWebDriver(){return new ef({scriptSource:"url",scriptURL:"http://localhost:3001/index.js",scriptFile:this.checksumScriptFilePath,fullScreenResolution:!1,hostWindowViewport:!0,baseURL:this.config.baseURL,disableWebSecurity:!0,allowFileAccess:!0},{devtools:!0,headless:!1},{frontendAppSpecificRules:{},frontendTestGenerationConfig:{logPrefix:"$checksum"}})}};i(Fx,"VisualTestGenerator");var Ec=Fx;var Ix=class Ix{constructor(){}async execute(){let t=!!process.argv.find(n=>n==="--clidebug");t&&Em(!0);let r=process.argv.slice(3);switch(process.argv.find(n=>n==="--help"||n==="-h")&&(await new Rs(r,t).run(process.argv[2]),process.exit(0)),process.argv[2]){case"init":new xu(r,t).run();break;case"test":await new gu(r,t).run();break;case"show-report":await new vu(r,t).run();break;case"generate":try{await new Ec(r,t).run()}catch(n){console.log("Error",n.message)}break;case"vtg":try{await new Ec(r,t).run()}catch(n){console.log("Error",n.message)}break;default:await new Rs(r,t).run()}process.exit(0)}};i(Ix,"CLIDispatcher");var sf=Ix;(async()=>await new sf().execute())();
|
|
137
|
+
`))}catch(r){console.log("Error",r.message)}break;case"show-report":try{let n=(await this.getCmdOutput("npx playwright show-report --help")).replace(/npx playwright/g,"yarn checksum");console.log(n)}catch(r){console.log("Error",r.message)}break;case"generate":console.log("Not implemented yet");break}}};i(Fm,"CLIHelp");var Rs=Fm;var Im=class Im extends hr{constructor(t,r=!1){super(t,r)}async run(){let t=`npx playwright show-report ${this.args.join(" ")}`;try{await this.execCmd(t)}catch(r){console.log("Error showing report",r.message)}}};i(Im,"CLIShowReport");var vu=Im;var xt=require("fs"),kn=require("path");var Rm=class Rm extends hr{constructor(t,r=!1){super(t,r)}run(){console.log("Creating Checksum directory and necessary files to run your tests");try{this.findProjectRoot()}catch(s){console.log(s.message),process.exit(1)}let t=(0,kn.join)(process.cwd(),yl);if((0,xt.existsSync)(t)||(0,xt.mkdirSync)(t),!(0,xt.existsSync)(this.getChecksumRootOrigin()))throw new Error("Could not find checksum root directory, please install @checksum-ai/runtime package");let r=(0,xt.existsSync)((0,kn.join)(t,"checksum.config.ts"));pb({isInit:!r}).forEach(s=>{let l=(0,kn.join)(t,s);(0,xt.existsSync)(l)||(0,xt.copyFileSync)((0,kn.join)(this.getChecksumRootOrigin(),s),l)});let n=(0,kn.join)(t,".gitignore.example"),o=(0,kn.join)(t,".gitignore");(0,xt.existsSync)(n)&&!(0,xt.existsSync)(o)&&((0,xt.copyFileSync)(n,o),(0,xt.unlinkSync)(n)),this.validateAuthExists(),(0,xt.mkdirSync)((0,kn.join)(t,"tests"),{recursive:!0}),["esra","har","trace","log"].forEach(s=>{(0,xt.mkdirSync)((0,kn.join)(t,"test-data",s),{recursive:!0})})}};i(Rm,"CLIInstall");var xu=Rm;var Om=St(require("path")),yu=St(require("fs"));function Mm(e,t){let r=e.match(/^data:([A-Za-z-+\/]+);base64,(.+)$/);if(!r||r.length!==3)throw new Error("Invalid base64 string");let n=r[1],o=r[2],s=Buffer.from(o,"base64");return{name:t,type:n,buffer:s,size:s.length}}i(Mm,"base64ToFile");function Ok(e,t){let r=Mm(e,t),n=Om.default.join(__dirname,"..","uploads");yu.default.existsSync(n)||yu.default.mkdirSync(n,{recursive:!0});let o=Om.default.join(n,t);return yu.default.writeFileSync(o,r.buffer),console.log(`File written successfully: ${o}`),o}i(Ok,"writeBase64ToFile");var Lm=class Lm{constructor(t,r,n,o,s,l){this.config=t;this.checksumRoot=r;this.pageInteractor=n;this.apiService=o;this.userStoryService=s;this.actionsManager=l;this.executeAction=i(async(t,r={valueChanged:!1,playMode:!1})=>{try{if(await this.pageInteractor.performAction(t),!r.playMode)return t.timestamp=Date.now(),this.actionsManager.onActionExecuted(t,{parentAction:r.parentAction}),t}catch(n){throw console.error(n),new Error(n)}},"executeAction")}async uploadFiles(t){let r=t.map(({data:n,fileName:o},s)=>Mm(n,o));await Promise.all(r.map(async n=>{let o=await this.getUploadFileSignedUrl({fileName:n.name,contentType:n.type});await this.apiService.putFile(o,n)})),t.forEach(({data:n,fileName:o},s)=>Ok(n,o))}async getUploadFileSignedUrl(t){if(!this.userStoryService.hasTestGenerationData()){console.log("No generationBatchId, can't upload");return}let r=await this.apiService.post("test-generation/get-upload-file-signed-url",{...t,batchId:this.userStoryService.getTestGenerationData().generationBatchId}),{url:n}=await r.json();return n}async login(t){let r=Am({config:this.config,folder:this.checksumRoot}),n=this.userStoryService.getStory();await r(t,{role:n.environment.userRole,environment:n.environment.name}),this.didLogin=!0}hasLoggedIn(){return this.didLogin}};i(Lm,"VtgActionsService");var bu=Lm;var Dm=class Dm{constructor(t,r={},n=!0){this.requests=[];this.watcherConfig={minimumWaitTime:250,maximumWaitTime:1e4,followingRequestsWaitTime:250};this.resolved=!0;this.hasMinimumWaitTimePassed=!1;this.useLog=!1;this.logStack=[];this.resolve=i(()=>{this.resolved||(this.resolved=!0,clearTimeout(this.minimumWaitTimer),clearTimeout(this.maximumWaitTimer),clearTimeout(this.followingRequestWaitTimeoutId),this.loadResolve({totalTime:Date.now()-this.startTS,logs:this.logStack,pendingRequests:this.requests.length,totalRequests:this.observedRequestsCount}))},"resolve");this.watcherConfig={...this.watcherConfig,...r},this.initListeners(t),this.useLog=n}initListeners(t){t.on("request",r=>{var n;this.hasMinimumWaitTimePassed||(n=this.watcherConfig.whitelist)!=null&&n.length&&!this.watcherConfig.whitelist.some(o=>o.test(r.url()))||(this.useLog&&this.logStack.push(`${r.method()} ${r.url().substring(0,60)}`),this.requests.push(r),this.observedRequestsCount+=1)}),t.on("response",r=>{this.requests=this.requests.filter(n=>n!==r.request()),this.hasMinimumWaitTimePassed&&(this.requests.length||(clearTimeout(this.followingRequestWaitTimeoutId),this.followingRequestWaitTimeoutId=setTimeout(()=>{this.requests.length||this.resolve()},this.watcherConfig.followingRequestsWaitTime)))})}async wait(){return new Promise(t=>{this.loadResolve=t,this.resolved=!1,this.minimumWaitTimer=setTimeout(()=>{this.hasMinimumWaitTimePassed=!0,this.requests.length||this.resolve()},this.watcherConfig.minimumWaitTime),this.maximumWaitTimer=setTimeout(this.resolve,this.watcherConfig.maximumWaitTime)})}startListening(){this.requests=[],this.startTS=Date.now(),this.hasMinimumWaitTimePassed=!1,this.observedRequestsCount=0,this.useLog&&(this.logStack=[])}};i(Dm,"NetworkWatcher");var wu=Dm;var Mk=require("crypto");var qm=class qm{constructor(t,r,n,o,s){this.webDriver=t;this.pageInteractor=r;this.actionsService=n;this.actionsManager=o;this.apiService=s;this.previousActionFailed=!1;this.currentChecksumId="0";this.executeAction=i(async(t,r={valueChanged:!1,playMode:!1})=>{await this.webDriver.clearHighlights(),this.previousActionFailed=!1;let n;try{let o=new wu(this.webDriver.liveMainFrame.page());o.startListening(),n=await this.actionsService.executeAction(t),await o.wait(),await De(2e3)}catch(o){throw this.previousActionFailed=!0,console.error(o),new Error(o)}return r.valueChanged&&await this.init(),n},"executeAction")}async init(){this.clear(),this.executedActions=this.actionsManager.actions,await this.startSession()}setStory(t){this.story=t}clear(){this.executedActions=[],this.remoteSessionId=void 0,this.previousActionFailed=!1,this.currentChecksumId="0"}async startSession({retriesLeft:t=3}={}){let r={type:"test-generation",storyTitle:this.story.goal,storyInstructions:this.story.instructions,testId:void 0,testSuiteId:void 0,thoughtsAndActions:{previous:(this.executedActions??[]).filter(n=>!!n.description).map(n=>({thought:n.description,action:void 0}))}};try{let n=await this.apiService.post("ai-fallback/init",r);this.remoteSessionId=await n.text()}catch(n){if(console.error(n),await De(2e3),t>0)return this.startSession({retriesLeft:t-1});throw n}}async iterate({guidance:t}={}){await this.webDriver.toggleTimeMachineHandleEvents(!1);let{reducedHTML:r,flashingHTML:n,elementsForNodeInterpretation:o,currentChecksumId:s}=await this.webDriver.evaluateWithChecksum(async({appRules:p,currentChecksumId:d})=>window.checksum.testGenerator.reduceHTML(p,{stopFlashingElementsDetection:!0,assignChecksumIdsToAllElements:!0,initialChecksumId:d}),{appRules:{appSpecificInteractableElementsSelectors:[]},currentChecksumId:this.currentChecksumId});this.currentChecksumId=s;let l=await this.getNextAction({reducedHTML:r,flashingHTML:n,elementsForNodeInterpretation:o,guidance:t});try{let d={...await this.pageInteractor.translateActionResponseToAgentPotentialAction(l),id:(0,Mk.randomUUID)(),timestamp:Date.now()};return await this.webDriver.highlightElementByLocator(this.pageInteractor.makeLocator(d.selector,d.parentFramesSelectors),d.clickOffset,"10px solid rgba(255,0,0,1)"),d}catch(p){console.error("error in ai iterate",p)}}async stop(){}async getNextAction({reducedHTML:t,flashingHTML:r,elementsForNodeInterpretation:n,guidance:o}){let s={reduction:{reducedHTML:t,flashingHTML:r,elementsForNodeInterpretation:n},currentURL:this.webDriver.liveMainFrame.url(),previousActionOverview:{success:!this.previousActionFailed,userCorrection:o}};try{return await(await this.apiService.post("ai-fallback/iterate",{sessionId:this.remoteSessionId,iterationData:s})).json()}catch(l){throw console.error(l),l}}};i(qm,"VtgAITestGenerationService");var _u=qm;var Bm=class Bm{constructor(t,r){this.config=t;this.baseURL=r+"/client-api/runtime"}getBaseURL(){return this.baseURL}post(t,r){return fetch(`${this.baseURL}/${t}`,{method:"POST",headers:{"Content-Type":"application/json",ChecksumAppCode:this.config.apiKey},body:r?JSON.stringify(r):void 0})}putFile(t,r){return fetch(t,{method:"PUT",headers:{"Content-Type":r.type},body:r})}};i(Bm,"VtgCloudAPIService");var ku=Bm;var Nm=class Nm{constructor(t){this.webDriver=t}async run(t,r,{thought:n,matcher:o,index:s,assertionIndex:l}){let p=!1;Array.isArray(t)||(p=!0);try{let d=await this.processAssertion(r,{thought:n,matcher:o}),f=p?t:t[s];return f?(f.assertions||(f.assertions=[]),l!==void 0?f.assertions[l]=d:f.assertions.push(d),d):void 0}finally{this.webDriver.tmFrame.evaluate(async()=>{await window.checksum.timeMachine.goLive()})}}async processAssertion(t,{thought:r,matcher:n}){let o={...t};return{thought:r,selected:!0,selector:o.selector,locator:o.locator,matcher:n}}};i(Nm,"VisualAssertionsGenerator");var Su=Nm;var qs=require("@playwright/test"),ng=St(nS());var tg=class tg{constructor(t){this.options=t;this.harData={methodIndex:{GET:0,POST:0,PUT:0,DELETE:0}};this.interceptors={recordHar:this.harInterceptor.bind(this),completeOriginHeader:this.completeOriginHeaderInterceptor.bind(this)};this.intercept=i(async(t,r,n)=>{let o=[],s=i(l=>{if(l)switch(l.type){case"abort":return t.abort(l.errorCode);case"fulfill":return t.fulfill(l.fulfillOptions);default:case"continue":o.push(l)}},"processResult");for(let[l,p]of Object.entries(this.interceptors))if(this.options[l]){let d=s(await p(t,r,n));if(d)return d}return this.applyContinueResults(t,o)},"intercept")}setOptions(t){this.options=t}mergeOptions(t){this.options={...this.options,...t}}applyContinueResults(t,r){let n=r.filter(s=>!!s),o={};return n.forEach(s=>{s.options&&(s.options.headers&&(o.headers={...o.headers,...s.options.headers}),s.options.method&&(o.method=s.options.method),s.options.postData&&(o.postData=s.options.postData),s.options.url&&(o.url=s.options.url))}),t.continue(o)}async harInterceptor(t){let r=t.request().headers(),n=t.request().method();return r["Checksum-Id"]=(++this.harData.methodIndex[n]).toString(),{options:{headers:r}}}async completeOriginHeaderInterceptor(t,r,{page:n}){let o=t.request().headers();if(!o.Origin){try{let s=new URL(n.url()).origin;o.Origin=s}catch{}return{options:{headers:o}}}}};i(tg,"RouteInterceptors");var Pu=tg;var iS=require("path");var rg=class rg{constructor(t){this.options=t;this.navigatingFrames={};this.trackedFramesGuid=[];this.frameNavigationPromises={};this.onFrameNavigated=i(async t=>{let r=Bt(t);if(this.trackedFramesGuid.includes(r))return this.frameNavigationPromises[r]=new Promise(async n=>{await this.loadScript(t),n()}),this.frameNavigationPromises[r]},"onFrameNavigated");this.addScriptTagOptions=this.makeFrameInjectedScriptOptions()}setScriptLoadCallback(t){this.scriptLoadCallback=t}setScriptLoadCheck(t){this.scriptLoadCheck=t}async addTrackedFrame(t,r=!0){let n="mainFrame"in t?t.mainFrame():t,o=Bt(n);if(this.trackedFramesGuid.includes(o)||this.trackedFramesGuid.push(o),r)return this.onFrameNavigated(n)}getNavigationPromise(t){let r=typeof t=="string"?t:"mainFrame"in t?Bt(t.mainFrame()):Bt(t);return this.frameNavigationPromises[r]}makeFrameInjectedScriptOptions(){switch(this.options.scriptSource){case"file":return this.options.scriptFile?{path:(0,iS.join)(process.cwd(),this.options.scriptFile)}:void 0;case"url":return this.options.scriptURL?{url:this.options.scriptURL}:void 0;default:return}}isFrameClosed(t){return t.isDetached()||t.page().isClosed()}async loadScript(t,{retriesLeft:r=3,retryWaitMS:n=2e3}={}){var p,d;if(!this.addScriptTagOptions){console.warn("[InjectedScriptManager] addScriptTagOptions not set, skipping loadScript");return}if(this.isFrameClosed(t)||(this.scriptLoadCheck?await((p=this.scriptLoadCheck)==null?void 0:p.call(this,t)):!1)||this.isFrameClosed(t))return;try{await t.addScriptTag(this.addScriptTagOptions)}catch(f){if(r>0)return console.warn(`[InjectedScriptManager] Failed to add script to frame ${Bt(t)}, trying again in ${n/1e3} seconds, ${r-1} retries left.`,f),await De(n),this.loadScript(t,{retriesLeft:r-1,retryWaitMS:n});throw f}let s=Bt(t),l=Date.now().toString(36)+Math.random().toString(36).substr(2);if(this.navigatingFrames[s]=l,this.options.scriptInitWait&&(console.log(`Waiting ${this.options.scriptInitWait}[ms] before onScriptLoad...`),await De(this.options.scriptInitWait),console.log("Done waiting before onScriptLoad")),!this.isFrameClosed(t)){if(this.navigatingFrames[s]&&this.navigatingFrames[s]!==l)return console.log("Page navigated again, waiting on new promise..."),this.frameNavigationPromises[s];try{await((d=this.scriptLoadCallback)==null?void 0:d.call(this,t))}catch(f){console.error("[WebDriver] onScriptLoad error",f)}}}};i(rg,"InjectedScriptManager");var Fu=rg;var ig=class ig{constructor(t={},r={}){this.browserConfig={devtools:!1,executablePath:process.env.PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH??void 0};this.options={fullScreenResolution:!1,defaultTimeout:3e4,defaultNavigationTimeout:3e4,disableWebSecurity:!0};this.contextClosePromise=void 0;this.eventListeners=[];this.lastSnapshot={selector:void 0,eventCode:void 0};this.snapshotTimeout=3e4;this.cacheScript=!1;this.pagesIndexToGuid={};this.onRequestFinished=i(async t=>{try{let r=await t.response();if(!r.ok())return;let n=t.resourceType(),o=t.url(),s=i(async()=>{try{return await r.text()}catch{try{return await(await fetch(o)).text()}catch{return}}},"getBody");if(["document","script","stylesheet"].includes(n))try{let l=await s();if(!l)return;let p={url:o,source:l,type:n};await this.forEachEventListener(d=>{var f;return(f=d.onWebDriverResourceLoaded)==null?void 0:f.call(d,p)})}catch(l){console.error("[WebDriver] requestfinished event handler error",n,o,l)}}catch(r){console.error("[WebDriver] requestfinished event handler error",r)}},"onRequestFinished");this.onFrameNavigated=i(async t=>{let r=i(async n=>{await this.forEachEventListener(o=>{var s;return(s=o.onWebDriverFrameNavigated)==null?void 0:s.call(o,t,n)})},"notifyFrameNavigated");await r(!1),await this.injectedScriptManager.onFrameNavigated(t),await r(!0)},"onFrameNavigated");this.tracing=!1;this.tracingChunk=!1;this.chunkIndex=0;var n;if(this.options={...this.options,...t},this.browserConfig={...this.browserConfig,...r},this.injectedScriptManager=new Fu(this.options),this.browserConfig.args||(this.browserConfig.args=[]),this.options.disableWebSecurity&&this.browserConfig.args.push("--disable-web-security"),this.options.allowFileAccess&&this.browserConfig.args.push("--allow-file-access-from-files"),this.browserConfig.args.push("--disable-site-isolation-trials"),this.browserConfig.args.push("--allow-running-insecure-content"),this.options.forceHeadless&&(this.browserConfig.headless=!0,this.browserConfig.devtools=!1),this.options.useProxy)if((n=this.options.webProxy)!=null&&n.server){console.log("[WebDriver] using proxy");let{server:o,username:s,password:l}=this.options.webProxy;this.browserConfig.proxy={server:o,username:s,password:l},this.browserConfig.args.push("--proxy-bypass-list=localhost,127.0.0.1")}else console.error("[WebDriver] useProxy=true but proxy not configured");this.routeInterceptor=new Pu({completeOriginHeader:this.options.completeOriginHeader,recordHar:this.options.recordHAR})}async prepare({storageState:t}={}){if(await this.shutdown(),this.options.useStealth){let n=require("puppeteer-extra-plugin-stealth");ng.chromium.use(n()),this.browser=await ng.chromium.launch(this.browserConfig)}else this.browser=await qs.chromium.launch(this.browserConfig);let r={};return r.bypassCSP=!0,r.ignoreHTTPSErrors=!0,r.baseURL=this.options.baseURL,this.options.timezoneId&&(r.timezoneId=this.options.timezoneId),this.options.fullScreenResolution?r.viewport={width:1280,height:720}:this.options.hostWindowViewport&&(r.viewport=null),t&&(r.storageState=t),this.context=await this.browser.newContext(r),this.options.defaultTimeout&&this.context.setDefaultTimeout(this.options.defaultTimeout),this.options.defaultNavigationTimeout&&this.context.setDefaultNavigationTimeout(this.options.defaultNavigationTimeout),this.context.on("page",async n=>{await this.onNewPage(n),await this.onFrameNavigated(n.mainFrame()),n.on("framenavigated",this.onFrameNavigated)}),this.context.on("close",async()=>{this.contextClosePromise=this.forEachEventListener(n=>{var o;return(o=n.onWebDriverContextClose)==null?void 0:o.call(n)})}),this.activePage=await this.context.newPage(),this.originalPage=this.activePage,this.options.trackLoadedResources&&this.page.on("requestfinished",this.onRequestFinished),this.options.useCDPSession&&(this.cdpSession=await this.context.newCDPSession(this.page)),!0}async onNewPage(t){try{await(t==null?void 0:t.route("**/*",async(r,n)=>this.routeInterceptor.intercept(r,n,{page:t})))}catch(r){console.error("[WebDriver] onPage error",r)}}switchActivePage(t){let r=this.context.pages().find(n=>Bt(n)===t);return!r||r.isClosed()?(console.error(`[WebDriver] Page with guid ${t} not found or has been closed.`),!1):(this.previousPage=this.activePage,this.activePage=r,!0)}getDefaultTimeout(){return this.options.defaultTimeout}getDefaultNavigationTimeout(){return this.options.defaultNavigationTimeout}async addHARMockAPIRecordings(t){if(!this.activePage){console.warn("[addHARMockAPIRecordings] Active page is not set, skipping HAR recording.");return}await this.activePage.routeFromHAR(t,{url:/^(?!.*\.(js|mjs|ts|jsx|tsx|css|jpg|jpeg|png|gif|svg|webp|heif|heic|raw|cr2|nef|arw|bmp|tiff|tif|ico|woff|woff2|ttf|otf|doc|docx|pdf|ws|wasm|mp3|wav|aac|flac|mp4|avi|mov|wmv|flv|zip|rar|7z|tar\.gz|xml|html|py|java|cpp|xls|xlsx|ppt|pptx|gif)$)/i,update:!0,updateMode:"minimal"})}forEachEventListener(t){return Promise.all(this.eventListeners.map(async r=>{try{await t(r)}catch(n){console.log("WebDriver/forEachEventListener exception",n)}}))}registerEventListener(t){this.eventListeners.push(t)}async getScript(){async function t(r){let{exec:n}=require("child_process");return new Promise((o,s)=>{n(r,l=>{l?(console.log("error executing cmd, ",l),s(l)):o()})})}switch(i(t,"execCmd"),this.options.scriptSource){case"file":return this.options.scriptFile;case"url":if(this.cacheScript)return this.options.scriptFile;try{return await t(`curl -o ${this.options.scriptFile} '${this.options.scriptURL}'`),this.options.scriptFile}catch(r){console.log("[web-driver] Failed fetching frontend script",r)}break}}async startJSCoverageTracking(){return await this.page.coverage.startJSCoverage(),[];return await this.cdpSession.send("Debugger.enable"),await this.cdpSession.send("Profiler.enable"),await this.cdpSession.send("Profiler.startPreciseCoverage",{callCount:!1,detailed:!0}),this.getCurrentJSCoverage()}stopJSCoverageTracking(){return this.page.coverage.stopJSCoverage()}async getCurrentJSCoverage(){let t=await this.page.coverage.stopJSCoverage();return await this.page.coverage.startJSCoverage(),t;return(await this.cdpSession.send("Profiler.takePreciseCoverage")).result}async startCSSCoverageTracking(){return await this.cdpSession.send("DOM.enable"),await this.cdpSession.send("CSS.enable"),await this.cdpSession.send("CSS.startRuleUsageTracking"),this.getCurrentCSSCoverage()}async getCurrentCSSCoverage(){return(await this.cdpSession.send("CSS.takeCoverageDelta")).coverage}getCDPSession(){return this.cdpSession}async navigate(t){return this.page.goto(t)}async setViewportSize(t,r){return this.page.setViewportSize({width:t,height:r})}async getStorageState(){return this.page.context().storageState()}async shutdown(){try{this.page&&(await this.page.close(),this.activePage=void 0),this.context&&(await this.context.close(),this.context=void 0),this.browser&&(await this.browser.close(),this.browser=void 0)}catch(t){console.warn("[WebDriver] shutdown error",t)}}async wrapWithBrowserLogs(t,{disabled:r=!1,onErrorOnly:n=!1}={}){if(r)return t();let o=[],s=i(d=>{o.push(d.text())},"log");this.page.on("console",s);let l,p;try{p=await t()}catch(d){l=d}if(this.page.off("console",s),(!n||l)&&console.log("browser console messages:",o),l)throw l;return p}async takeElementSnapshot(t,r,n={},o={}){if(t===this.lastSnapshot.selector&&r===this.lastSnapshot.eventCode)return{};if(!t)return{};try{let{snapshot:s,elementLocator:l}=await this.takeSnapshot(t,o,{frameLocatorSelector:n.frameLocatorSelector});return this.lastSnapshot={selector:t,eventCode:r},{snapshot:s,elementLocator:l}}catch(s){return console.error("takeElementSnapshot error",s),{}}}getScreenshotTimeout(t=!1){return t?this.snapshotTimeout:this.snapshotTimeout+5e3}async takePageSnapshot(t){let r=this.page.screenshot({...t,timeout:this.getScreenshotTimeout()});return await Promise.race([r,De(this.getScreenshotTimeout(!0))])}async takeSnapshot(t,r,{frameLocatorSelector:n}={}){let o=n?this.page.frameLocator(n).locator(t):this.page.locator(t),s=o.screenshot({...r,timeout:this.getScreenshotTimeout()});return{snapshot:await Promise.race([s,De(this.getScreenshotTimeout(!0))]),elementLocator:o}}async getCurrentURL(){return this.page.url()}async getClientScreenResolution(){return await this.page.evaluate(async()=>({width:window.screen.width,height:window.screen.height}))}async awaitContextClose(){return this.contextClosePromise||await De(100),this.contextClosePromise}get page(){return this.activePage}getPage(){return this.activePage}startPlaywrightTrace(){return this.tracing=!0,this.context.tracing.start({name:"trace",screenshots:!0,snapshots:!0})}startPlaywrightTraceChunk(){return this.tracingChunk=!0,this.context.tracing.startChunk({name:`trace-chunk-${this.chunkIndex}`})}stopPlaywrightTraceChunk(t){return this.tracingChunk=!1,this.context.tracing.stopChunk({path:`${t.replace(".zip",`.${this.chunkIndex++}.zip`)}`})}stopPlaywrightTrace(t){return this.tracing=!1,this.context.tracing.stop({path:t})}isTracing(){return this.tracing}isTracingChunk(){return this.tracingChunk}};i(ig,"WebDriver");var Iu=ig;var ag=class ag{constructor(t,r){this.webDriver=t;this.actionsManager=r}async playAssertion({selector:t,matcher:r}){try{let o=this.webDriver.tmFrame.frameLocator("iframe").locator(t),s=(0,qs.expect)(o),l=`async (expectCall) => expectCall.${r}`;return await(0,eval)(l)(s),{success:!0,message:"Assertion played successfully!"}}catch(n){return{success:!1,message:String(n)}}}async generateAssertionForAction({action:t,selector:r,locator:n,thought:o,matcher:s,assertionIndex:l}){let p=this.actionsManager.actions.findIndex(({id:h})=>h===t.id);if(p===-1)throw new Error(`[generateAssertionForAction] No action with id ${t.id} was found in executed actions`);let{success:d,message:f}=await this.playAssertion({selector:r,matcher:s});if(!d)throw new Error(f);return await new Su(this.webDriver).run(this.actionsManager.actions,{selector:r,locator:n},{index:p,thought:o,matcher:s,assertionIndex:l})}};i(ag,"VtgAssertionsService");var Ru=ag;var og=class og{constructor(){this.executedActions=[];this.onActionExecuted=this.pushExecutedActionOrAddAfterParent.bind(this)}get actions(){return this.executedActions}pushExecutedActionOrAddAfterParent(t,r={}){if(r.parentAction){let n=this.executedActions.findIndex(({timestamp:o})=>o===r.parentAction.timestamp);n!==-1&&this.executedActions.splice(n+1,0,{...t,timestamp:this.executedActions[n].timestamp+1})}else Array.isArray(t)?this.executedActions.push(...t):this.executedActions.push(t)}addManualActionsToExecuted(t){Array.isArray(t)?this.executedActions.push(...t):this.executedActions.push(t)}updateExecutedAction(t){let r=this.executedActions.findIndex(({id:n})=>n===t.id);this.executedActions[r]={...this.executedActions[r],...t}}deleteStep(t,r){Number.isNaN(+r)?this.executedActions.splice(t,1):this.executedActions[t].assertions.splice(r,1)}};i(og,"VtgActionsManager");var Ou=og;var xx=St(_4()),T4=St(require("net")),P4=St(yv()),F4=St(A4());var yx=class yx{constructor(t,r,n,o,s,l){this.actionsService=t;this.assertionsService=r;this.locatorsService=n;this.aiTestGenerationService=o;this.actionsManager=s;this.storageService=l}async start(){return this.app=(0,xx.default)(),this.app.use((0,F4.default)()),this.app.use(P4.default.json({limit:"50mb"})),this.app.use(xx.default.raw({type:"multipart/form-data",limit:"50mb"})),this.port=await this.acquirePortNumber(),this.setupEndpoints(),new Promise(t=>{this.app.listen(this.port,()=>{console.log(`Express server running on port ${this.port}`),t()})})}setupEndpoints(){this.app.get("/api",async(t,r)=>{r.send("success")}),this.app.post("/api/test/upload",async(t,r)=>(await this.storageService.saveToCloud(),r.send("success"))),this.app.post("/api/test/backup",async(t,r)=>{await this.storageService.localSave(),r.send("success")}),this.app.post("/api/ai/init",async(t,r)=>{await this.aiTestGenerationService.init(),r.send("success")}),this.app.post("/api/ai/iterate",async(t,r)=>{let n=t.body,o=await this.aiTestGenerationService.iterate(n);return o?r.status(200).json(o):r.status(400).send("no action generated")}),this.app.post("/ai/stop",async(t,r)=>{this.aiTestGenerationService.stop()}),this.app.post("/api/selector/play",async(t,r)=>{let n=t.body;try{let o=await this.locatorsService.verifySelector(n);return r.status(200).send({success:o})}catch(o){return r.status(400).send({error:o.message})}}),this.app.post("/api/assertion/play",async(t,r)=>{let n=t.body,o=await this.assertionsService.playAssertion(n);return r.status(200).send(o)}),this.app.post("/api/assertion/generate",async(t,r)=>{let n=t.body;try{let o=await this.assertionsService.generateAssertionForAction(n);r.status(200).json(o)}catch(o){r.status(400).send({error:o.message})}}),this.app.post("/api/steps/execute",async(t,r)=>{let n=t.body,o=n.isAISuggestion?this.aiTestGenerationService.executeAction:this.actionsService.executeAction;try{let s=await o(n.action,n.options);return r.status(200).json(s)}catch(s){return r.status(404).send({error:s.message})}}),this.app.post("/api/upload-files",async(t,r)=>{try{await this.actionsService.uploadFiles(t.body.files)}catch(n){return r.status(500).send(n)}return r.status(200).send({message:"File uploaded successfully!"})}),this.app.post("/api/steps/add-manual-actions",async(t,r)=>{let n=t.body;return this.actionsManager.addManualActionsToExecuted(n.actions),r.send("success")}),this.app.patch("/api/steps",async(t,r)=>{let n=t.body;return this.actionsManager.updateExecutedAction(n.action),r.send("success")}),this.app.put("/api/steps",async(t,r)=>{let n=t.body;try{this.actionsManager.pushExecutedActionOrAddAfterParent(n.action,n.options)}catch(o){return r.status(500).send(o)}return r.send("success")}),this.app.delete("/api/step",async(t,r)=>{let{actionIndex:n,assertionIndex:o}=t.body;try{this.actionsManager.deleteStep(n,o)}catch(s){return r.status(500).send(s)}return r.status(200).send({message:"Success!"})})}async acquirePortNumber(){return await new Promise((t,r)=>{let n=T4.default.createServer();n.unref(),n.on("error",r),n.listen(0,()=>{let o=n.address().port;n.close(()=>{t(o)})})})}async evaluateServerPort(t){if(!t)throw new Error("Page not initialized");await t.evaluate(r=>{window.checksum.serverPort=r,localStorage.setItem("serverPort",r.toString()),console.log(`Server port set to: ${r}`)},this.port)}};i(yx,"VtgExpressServer");var Kp=yx;var bx=require("fs");var wx=class wx{constructor(t){this.projectRootDirectory=t}createTestGenerationAssetsFolders(){this.assetsFolderPath=this.projectRootDirectory+`/tg-assets/${Date.now()}`,(0,bx.mkdirSync)(this.assetsFolderPath,{recursive:!0}),(0,bx.mkdirSync)(this.getHarFolderPath(),{recursive:!0})}getAssetsFolderPath(){return this.assetsFolderPath}getHarFolderPath(){return this.assetsFolderPath+"/har"}getHarFilePath(){return`${this.getHarFolderPath()}/har.har`}getTraceFilePath(){return`${this.assetsFolderPath}/trace.zip`}};i(wx,"VtgTestAssetsManager");var Xp=wx;var lV={useCDPSession:!0,trackLoadedResources:!0},_x=class _x extends Iu{constructor(r={},n={devtools:!0},o={}){super({...lV,...r},n);this.settings={frontendAppSpecificRules:void 0,initTestGenerator:!0,frontendTestGenerationConfig:void 0};this.isScriptLoaded=i(async(r,n=1e3)=>{try{return await r.waitForFunction(()=>!!window.checksum,void 0,{timeout:n}),!0}catch{return!1}},"isScriptLoaded");this.initInjectedScript=i(async r=>{try{return await r.waitForFunction(()=>{var n;return!!((n=window.checksum)!=null&&n.testGenerator)}),r.evaluate(async({appSpecificRules:n,config:o,initModules:s})=>{window.checksum.testGenerator.init(n,o,s),n.hasGoals&&await window.checksum.goalTracker.init()},{appSpecificRules:this.settings.frontendAppSpecificRules,config:this.getFrontendTestGenerationConfig(),initModules:this.getInjectedScriptInitModules(r)})}catch(n){console.log("initInjectedScript exception",n)}},"initInjectedScript");this.settings={...this.settings,...o},this.injectedScriptManager.setScriptLoadCheck(this.isScriptLoaded),this.settings.initTestGenerator&&this.injectedScriptManager.setScriptLoadCallback(this.initInjectedScript)}async prepare(r={}){let n=await super.prepare(r);return this.evaluateWithChecksumTargetFrame=this.page.mainFrame(),this.settings.loadScriptOnPrepare&&await this.injectedScriptManager.addTrackedFrame(this.page),await this.page.addInitScript(()=>{window.sessionStorage.setItem("checksumai:disable","true")}),n}setEvaluateWithChecksumTargetFrame(r){this.evaluateWithChecksumTargetFrame=r}getInjectedScriptInitModules(r){return{assertionGenerator:!0,sessionRecorder:!0,filesObserver:!1}}getFrontendTestGenerationConfig(){return this.settings.frontendTestGenerationConfig}async evaluateWithChecksum(r,n,o=this.evaluateWithChecksumTargetFrame){let s=this.injectedScriptManager.getNavigationPromise(o);s&&await s;try{return o.evaluate(r,n)}catch(l){throw console.error("evaluateWithChecksum error",l,r.toString()),l}}async getBestMatchingElementSimilarityScore(r){return this.evaluateWithChecksum(async n=>await window.checksum.testGenerator.getBestMatchingElementSimilarityScore(n),r)}async getInteractableElements(){return this.evaluateWithChecksum(async()=>await window.checksum.testGenerator.getInteractableElements())}async getAllInteractableElementsForLastSelectQuery(){return this.evaluateWithChecksum(async()=>await window.checksum.testGenerator.getAllInteractableElementsForLastSelectQuery())}async overlayInteractableElementsWithChecksumId(r){return this.evaluateWithChecksum(n=>window.checksum.testGenerator.overlayInteractableElementsWithChecksumId(n),r)}async postRRwebEvents(r){return this.evaluateWithChecksum(n=>window.checksum.testGenerator.postRRwebEvents(n),r)}async getRRwebEvents(r=0){return this.evaluateWithChecksum(async({index:n})=>window.checksum.testGenerator.getRRwebEvents(n),{index:r})}async getGoals(){return await this.evaluateWithChecksum(async()=>window.checksum.goalTracker.getGoals())}async takeElementSnapshot(r,n,o={},s={}){try{let{snapshot:l,elementLocator:p}=await super.takeElementSnapshot(r,n,o);if(!l||!o.takeBodyScreenshot)return l?{snapshot:l}:{};await this.highlightElementByLocator(p,o.mousePosition);let d=await this.takePageSnapshot(s);return await this.clearHighlights(),{snapshot:l,bodySnapshot:d}}catch(l){return console.error("[ChecksumWebDriver] takeElementSnapshot error",l),{}}}async highlightElementByLocator(r,n,o="20px solid rgba(255,0,0,1)"){return this.evaluateWithChecksum(async([s,l,p])=>{window.checksum.testGenerator.highlightElement(s,{highlightStyle:{outline:l},mousePosition:p})},[await r.elementHandle(),o,n])}async clearHighlights(){return this.evaluateWithChecksum(async()=>window.checksum.testGenerator.clearHighlights())}};i(_x,"ChecksumWebDriver");var Jp=_x;var O4=require("fs"),M4=St(require("path"));var kx=require("fs"),R4=St(require("path"));var I4=!0,uV=R4.join(__dirname,"..","..","..","vtg-build","index.html"),Sx=class Sx{constructor(t,r=uV){this.page=t;this.filePath=r;this.filePath=r}async start(){try{await this.modifyVTGBuildHtmlFile(),await this.startReactApp()}catch(t){console.error("An error occurred:",t)}}async startReactApp(){if(!this.page)throw new Error("Page not initialized");let t=I4?"http://localhost:3003":`file://${this.filePath}`;await this.page.goto(t,{waitUntil:"networkidle",timeout:6e4})}async modifyVTGBuildHtmlFile(){if(!I4)try{let t=await kx.promises.readFile(this.filePath,"utf8"),r=/(src|href)=(["'])(\/)static/g,n=t.replace(r,"$1=$2.$3static");await kx.promises.writeFile(this.filePath,n,"utf8"),console.log(`Successfully modified ${this.filePath}`)}catch(t){console.error(`Error processing file ${this.filePath}:`,t)}}};i(Sx,"VtgFrontendLauncher");var Yp=Sx;var _FramesMsgBroker=class _FramesMsgBroker{constructor(){this.frames={};this.pages=[]}register(name,frame,frameMsgHandler){if(this.frames[name])return;this.frames[name]=frame;let page=frame.page();this.pages.includes(page)||(this.pages.push(page),page.exposeFunction("checksumSendMessage",async(e,t)=>{let r=this.frames[e];if(!r)throw new Error(`Frame ${e} not found`);if(frameMsgHandler){frameMsgHandler(t);return}try{await r.evaluate(({message:n})=>{window.postMessage(n,"*")},{message:t})}catch(n){console.error("Error sending message to frame",n)}}),page.exposeFunction("checksumGetLiveSelectorFromLocator",async(target,locator)=>{let frame=this.frames[target];if(frame)try{let resLocator=await frame.evaluate(locator=>{let locatorObject=eval("window.playwright."+locator);if(!(locatorObject!=null&&locatorObject.element))return null;let selectorSymbol=Object.getOwnPropertySymbols(locatorObject).find(e=>e.toString()==="Symbol(selector)");return locatorObject[selectorSymbol]},locator);return resLocator}catch(e){console.error("Error getting frame window",e)}}),page.exposeFunction("checksumGetFilesFromLive",async e=>{let t=this.frames.live;if(!t){console.log("no live frime detected");return}try{return t.evaluate(r=>window.checksum.testGenerator.filesObserver.getFilesByRrwebId(r),e)}catch(r){console.error("Error getting frame window",r)}}),page.exposeFunction("checksumBringPageToFront",async e=>{let t=this.frames[e];t&&await t.page().bringToFront()}))}};i(_FramesMsgBroker,"FramesMsgBroker");var Qp=_FramesMsgBroker;var pV=!0,Cx=class Cx extends Jp{constructor(r={},n={devtools:!0},o={}){super(r,n,o);this.frameMsgBroker=new Qp;this.onLiveFrameCreated=i(async r=>{this.liveFrame=r,this.frameMsgBroker.register("live",this.liveFrame),this.setEvaluateWithChecksumTargetFrame(this.liveFrame),await this.injectedScriptManager.addTrackedFrame(this.liveFrame)},"onLiveFrameCreated")}get liveMainFrame(){return this.liveFrame}get tmFrame(){return this.timeMachineFrame}async prepare(r={}){let n=await super.prepare(r);if(this.frameMsgBroker.register("vtg",this.page.mainFrame()),this.page.on("dialog",()=>{}),await new Yp(this.page).start(),await De(2e3),this.timeMachineFrame=this.page.frames()[2],await this.injectedScriptManager.addTrackedFrame(this.timeMachineFrame),pV){let o=await this.context.newPage();await this.onLiveFrameCreated(o.mainFrame())}else await this.interceptPageRequests(),await this.onLiveFrameCreated(this.page.frames()[1]);return await this.timeMachineFrame.evaluate(()=>window.checksum.timeMachine.start({firstEventTimestamp:Date.now()})),n}async navigate(r){return this.liveFrame.goto(r)}async getCurrentURL(){return this.liveFrame.url()}getInjectedScriptInitModules(r){return r===this.timeMachineFrame?{assertionGenerator:!1,sessionRecorder:!1,filesObserver:!1}:{...super.getInjectedScriptInitModules(r),filesObserver:!0}}async interceptPageRequests(){async function r(o){try{return await O4.promises.readFile(o,"utf8")}catch(s){return console.error(`Error reading file ${o}:`,s),null}}i(r,"readLocalFile");function n(o){switch(M4.extname(o).toLowerCase()){case".html":return"text/html";case".js":return"application/javascript";case".css":return"text/css";case".json":return"application/json";case".png":return"image/png";case".jpg":case".jpeg":return"image/jpeg";default:return"application/octet-stream"}}i(n,"getContentType"),await this.page.route("**/*",async o=>{try{let s=o.request().url();if(console.log("intercepted!",s),s.startsWith("file://")){let l=s.replace("file://",""),p=await r(l);p!==null?await o.fulfill({status:200,contentType:n(l),body:p}):await o.abort()}else{let l=0,p=5;for(;l<p;){let d=await o.fetch(),f=d.status();if(f>299&&f<400){l++;let h=d.headers().location;if(!h){console.warn("Redirect without Location header"),await o.abort();return}console.log(`Redirect ${l} to: ${h}`),o.request().url=()=>new URL(h,s).toString()}else{let h={};h["Access-Control-Allow-Origin"]="*",h["Access-Control-Allow-Methods"]="GET, POST, PUT, DELETE, OPTIONS",h["Access-Control-Allow-Headers"]="Content-Type, Authorization",await o.fulfill({response:d,headers:{...d.headers(),...h,"content-security-policy":"","X-Frame-Options":"","x-frame-options":""}});return}}console.warn(`Max redirects (${p}) exceeded`),await o.abort()}}catch(s){console.warn("intercept error",s)}})}async toggleTimeMachineHandleEvents(r){try{await this.tmFrame.evaluate(n=>window.checksum.timeMachine.setShouldHandleEvents(n),r)}catch{}}};i(Cx,"ChecksumVTGWebDriver");var ef=Cx;var L4=require("request"),rf=require("fs");var Ex=class Ex{constructor(t,r,n,o,s){this.apiBaseURL=t;this.apiKey=r;this.uploadTimeout=n;this.makeGetUploadUrlAPIPath=o;this.onOutstandingUpload=s}async uploadAsset(t){try{let{path:r}=t.info;if(console.log("Uploading file",r),await this.getSignedURLForUpload(t),!t.uploadURL){console.log("Error getting signed URL for asset",r),t.error=!0;return}let o=(0,rf.statSync)(r).size,s=(0,rf.createReadStream)(r),l=mt(new Promise((p,d)=>{var h;let f=(0,L4.put)(t.uploadURL,{body:s},(v,x)=>{v&&d(v),p(x)});(h=this.onOutstandingUpload)==null||h.call(this,{request:f,size:o})}),this.uploadTimeout);l.then(p=>{if(p.statusCode!==200)throw new Error("Upload failed");console.log("File uploaded successfully",r),t.complete=!0}).catch(p=>{console.log("Error uploading asset",r,p),t.error=!0}),t.response=l}catch{t.error=!0}}async getSignedURLForUpload(t){try{let r=t.info,n=await fetch(`${this.apiBaseURL}/${this.makeGetUploadUrlAPIPath(t)}`,{method:"POST",headers:{Accept:"application/json","Content-Type":"application/json",ChecksumAppCode:this.apiKey},body:JSON.stringify(r)}),{url:o}=await n.json();t.uploadURL=o}catch(r){return console.log("Error getting signed URL for artifact",r),null}}};i(Ex,"TestAssetUploader");var tf=Ex;var D4=St(_m()),Vi=require("path"),ai=require("fs");async function q4(e,t){let r=await(0,ai.readdirSync)(t);await Promise.all(r.map(async n=>{let o=(0,Vi.join)(t,n);if((await(0,ai.statSync)(o)).isDirectory()){let l=e.folder(n);await q4(l,o)}else{let l=await(0,ai.readFileSync)(o);e.file(n,l)}}))}i(q4,"addFolderToZip");async function B4(e){try{let t=await(0,D4.loadAsync)("UEsFBgAAAAAAAAAAAAAAAAAAAAAAAA==",{base64:!0});await q4(t,e);let r=await t.generateAsync({type:"nodebuffer",compression:"DEFLATE"}),n=(0,Vi.join)((0,Vi.dirname)(e),`${(0,Vi.basename)(e)}.zip`);return(0,ai.writeFileSync)(n,r),n}catch(t){return console.error("Error creating zip:",t),null}}i(B4,"zipFolder");var N4=require("fs");var Ax=class Ax{constructor(t,r,n,o,s,l){this.config=t;this.userStoryService=r;this.apiService=n;this.actionsManager=o;this.testAssetsManager=s;this.actionsService=l}async localSave(){let t={executedActions:this.actionsManager.actions,testGenerationData:this.userStoryService.getTestGenerationData(),settings:{baseURL:this.config.baseURL,assetsFolderPath:this.testAssetsManager.getAssetsFolderPath(),didLogin:this.actionsService.hasLoggedIn(),traceFilePath:this.testAssetsManager.getTraceFilePath(),harFilePath:this.testAssetsManager.getHarFilePath()}};(0,N4.writeFileSync)(`${this.testAssetsManager.getAssetsFolderPath()}/test.json`,JSON.stringify(t,null,2))}async saveToCloud(){try{if(!this.userStoryService.hasTestGenerationData()){console.log("No test generation data, can't upload");return}let t=await this.userStoryService.createTestGeneration(),r=new tf(this.apiService.getBaseURL(),this.config.apiKey,null,()=>`test-generation/${t}/get-upload-url`),n=i(p=>({complete:!1,error:!1,response:void 0,info:p}),"buildUploadAsset"),o=n({type:"trace",path:this.testAssetsManager.getTraceFilePath()}),s=n({type:"har",path:await B4(this.testAssetsManager.getHarFolderPath())});await Promise.all([r.uploadAsset(o),r.uploadAsset(s)]);let l=this.actionsManager.actions.map(p=>({...p,parentFramesSelectors:p.parentFramesSelectors?p.parentFramesSelectors.filter(d=>d!=="iframe"):void 0}));await this.apiService.post(`test-generation/${t}/completed`,{actions:l})}catch(t){console.error("Failed to upload test",t)}}};i(Ax,"VtgStorageService");var nf=Ax;var fV=!1,dV={goal:"Send email via outreach list",instructions:"Make sure to select a user from the list first",environment:{name:void 0,userRole:void 0}},Tx=class Tx{constructor(t){this.apiService=t}getStory(){return this.story}getTestGenerationData(){return this.userStoryTestGeneration}hasTestGenerationData(){return!!this.userStoryTestGeneration.internalTestId}async fetchStory(t){if(fV){console.log("Using fake flow data"),this.story=dV;return}if(!t)throw new Error("no story id provided");let n=await(await this.apiService.post(`test-generation/info/${t}`)).json();console.log("Received flow data:",n);let{id:o,title:s,steps:l,startUrl:p,userRole:d,environment:f,internalTestId:h,generationBatchId:v}=n;this.userStoryTestGeneration={internalTestId:h,generationBatchId:v},this.story={id:o,goal:s,instructions:l,url:p,environment:{userRole:d,name:f}}}async createTestGeneration(){if(!this.story.id)return;let t=await this.apiService.post(`test-generation/create/${this.story.id}`,{internalTestId:this.userStoryTestGeneration.internalTestId,testGenerationBatchId:this.userStoryTestGeneration.generationBatchId}),{testGenerationId:r}=await t.json();return this.userStoryTestGeneration.testGenerationId=r,r}};i(Tx,"VtgUserStoryService");var af=Tx;var Px=class Px{constructor(t){this.webDriver=t}async verifySelector({selector:t}){try{let n=this.webDriver.tmFrame.frameLocator("iframe").locator(t);if(!n)throw new Error(`Selector ${t} not found`);return await n.count()===1}catch{return!1}}};i(Px,"VtgLocatorsService");var of=Px;var Fx=class Fx extends hr{constructor(r,n=!1){super(r,n);this.checksumScriptFilePath="node_modules/@checksum-ai/runtime/checksumlib.js";this.initTimeMachine=i(async()=>{await this.webDriver.tmFrame.evaluate(()=>window.checksum.visualTestGenerator.init(!1))},"initTimeMachine");this.storyId=r[0],this.actionsManager=new Ou}async run(){await this.init(),this.buildServices(),this.buildServer(),await this.start()}async init({createAssetsFolder:r=!0}={}){await this.patchPlaywright(),this.loadChecksumData(),this.webDriver=this.buildWebDriver(),this.pageInteractor=new Fs(this.webDriver.evaluateWithChecksum.bind(this.webDriver),()=>this.webDriver.liveMainFrame,()=>{},{log:console.log,logError:console.error},{navigationTimeout:30*1e3,actionTimeout:5*1e3,waitActionDelay:1e3,testAssetsDir:__dirname}),this.testAssetsManager=new Xp(this.projectRootDirectory),r&&this.testAssetsManager.createTestGenerationAssetsFolders()}buildServices(){this.apiService=new ku(this.config,this.checksumApiUrl),this.userStoryService=new af(this.apiService),this.actionsService=new bu(this.config,this.checksumRoot,this.pageInteractor,this.apiService,this.userStoryService,this.actionsManager),this.assertionsService=new Ru(this.webDriver,this.actionsManager),this.locatorsService=new of(this.webDriver),this.aiTestGenerationService=new _u(this.webDriver,this.pageInteractor,this.actionsService,this.actionsManager,this.apiService),this.storageService=new nf(this.config,this.userStoryService,this.apiService,this.actionsManager,this.testAssetsManager,this.actionsService)}buildServer(){this.reactAppServer=new Kp(this.actionsService,this.assertionsService,this.locatorsService,this.aiTestGenerationService,this.actionsManager,this.storageService)}async start(){var o;await this.userStoryService.fetchStory(this.storyId),await this.webDriver.prepare(),await this.webDriver.addHARMockAPIRecordings(this.testAssetsManager.getHarFilePath()),await this.initTimeMachine(),await this.reactAppServer.start(),await this.reactAppServer.evaluateServerPort(this.webDriver.page);let r=this.config.baseURL;this.webDriver.liveMainFrame?await this.webDriver.liveMainFrame.goto(r,{waitUntil:"domcontentloaded",timeout:0}):console.error("Iframe not found"),await this.webDriver.toggleTimeMachineHandleEvents(!1),await this.webDriver.page.evaluate(({actions:s})=>{window.checksum.initVtgAfterServerReady(s)},{actions:this.actionsManager.actions}),await fu(this.webDriver.page,this.webDriver.liveMainFrame,async s=>{try{await this.actionsService.login(s)}catch{console.error("Failed to execute login function")}});let n=(o=this.userStoryService.getStory())==null?void 0:o.url;n&&(await this.webDriver.liveMainFrame.goto(n,{waitUntil:"domcontentloaded",timeout:0}),this.actionsManager.actions.push({description:"Navigate to start URL",eventCode:"navigation",fillValue:n})),await new Promise(()=>{})}buildWebDriver(){return new ef({scriptSource:"url",scriptURL:"http://localhost:3001/index.js",scriptFile:this.checksumScriptFilePath,fullScreenResolution:!1,hostWindowViewport:!0,baseURL:this.config.baseURL,disableWebSecurity:!0,allowFileAccess:!0},{devtools:!0,headless:!1},{frontendAppSpecificRules:{},frontendTestGenerationConfig:{logPrefix:"$checksum"}})}};i(Fx,"VisualTestGenerator");var Ec=Fx;var Ix=class Ix{constructor(){}async execute(){let t=!!process.argv.find(n=>n==="--clidebug");t&&Em(!0);let r=process.argv.slice(3);switch(process.argv.find(n=>n==="--help"||n==="-h")&&(await new Rs(r,t).run(process.argv[2]),process.exit(0)),process.argv[2]){case"init":new xu(r,t).run();break;case"test":await new gu(r,t).run();break;case"show-report":await new vu(r,t).run();break;case"generate":try{await new Ec(r,t).run()}catch(n){console.log("Error",n.message)}break;case"vtg":try{await new Ec(r,t).run()}catch(n){console.log("Error",n.message)}break;default:await new Rs(r,t).run()}process.exit(0)}};i(Ix,"CLIDispatcher");var sf=Ix;(async()=>await new sf().execute())();
|
|
138
138
|
/*! Bundled license information:
|
|
139
139
|
|
|
140
140
|
lodash/lodash.js:
|