@checksum-ai/runtime 1.1.64 → 1.1.65

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.
Files changed (3) hide show
  1. package/.env +1 -1
  2. package/cli.js +1 -1
  3. package/package.json +1 -1
package/.env CHANGED
@@ -1 +1 @@
1
- BUILD_TIME=2025-03-04T16:29:39.112Z
1
+ BUILD_TIME=2025-03-05T08:44:36.089Z
package/cli.js CHANGED
@@ -1914,7 +1914,7 @@ if (typeof globalThis.requireTs === "undefined") {
1914
1914
  `).find(d=>d.includes(".checksum.spec.ts"));if(p)return{lineNumber:parseInt(p.split(":")[1]),columnNumber:parseInt(p.split(":")[2])}},"findCodeLocationFromStackTrace"),Orr=class Orr{constructor(){this.store={};this.activeVariablesSet=new Set;return new Proxy(this,this)}clearAll(){for(let p in this.store)Object.prototype.hasOwnProperty.call(this.store,p)&&delete this.store[p];this.activeVariablesSet.clear()}getActiveVariables(){return Array.from(this.activeVariablesSet).map(p=>this.store[p])}setVariable(p,d){this.store[p]={name:p,value:d,type:d instanceof Function?"RandomValueGenerator":"FillValue"}}set(p,d,y){if(typeof d!="string")return!1;let E=UAn();return p.store[d]={name:d,value:y,type:y instanceof Function?"RandomValueGenerator":"FillValue",...E,line:""},!0}get(p,d){var y;if(d in p)return p[d];if(!(d in p.store))throw new Error(`Variable ${d} is not defined`);return p.activeVariablesSet.add(d),(y=p.store[d])==null?void 0:y.value}};e(Orr,"VariableStore");var iRt=Orr;var Lrr=class Lrr{constructor(p=new iRt){this._variableStore=p}get variableStore(){return this._variableStore}};e(Lrr,"VTGVariableStoreService");var aRt=Lrr;var _VtgEvaluatorService=class _VtgEvaluatorService{constructor(l,p){this.variableStoreService=l;this.vtgTestFileMode=p;this.listenerBody=e(async({vtg})=>{await vtg.eval(async(code,callback)=>{try{callback(null,await eval(`(async () => {
1915
1915
  ${code}
1916
1916
  })()`))}catch(l){callback(l,null)}})},"listenerBody")}setPage(l){this.page=l}async execute(l,p={}){return this.vtgTestFileMode?this.executeInPlaywrightTest(l,p):this.executeOnLive(l,p)}get vtgContext(){return{page:this.page,vs:this.variableStoreService.variableStore,expect:PZe.expect,checksumAI:e((l,p)=>p(),"checksumAI")}}async executeOnLive(l,p={}){let d={...this.vtgContext,...p},y=this.wrapCodeInContext(l,d);return await(0,eval)(y)(d)}wrapCodeInContext(l,p){return`(async ({${Object.keys(p).join(", ")}}) => { ${l} })`}async executeInPlaywrightTest(l,p={}){let d=p?this.wrapCodeInContext(l,p)+"(context)":l;return new Promise((y,E)=>{this.listener&&this.listener(d,p,(N,F)=>{N?E(N):y(F)})})}async listenForExecution(l){return new Promise(p=>{this.resolveEvaluator=p,this.listener=l})}stopListening(){this.resolveEvaluator()}getFunctionContentToInject(){return this.listenerBody.toString()}};e(_VtgEvaluatorService,"VtgEvaluatorService");var sRt=_VtgEvaluatorService;var Rrr=class Rrr extends sce{constructor(d,y=!1){y||(y=!!d.find(E=>E==="--debug"));super(d,y);this.checksumScriptFilePath="node_modules/@checksum-ai/runtime/checksumlib.js";this.vtgMode="start";this.initTimeMachine=e(async()=>{await this.webDriver.tmFrame.evaluate(()=>window.checksum.visualTestGenerator.init(!1))},"initTimeMachine");this.initVtgMode(d),Nh.setLogLevel(y?"all":vC.isDevMode?vC.logLevel:"errors")}async run(d){await this.init(d),this.buildServices(),this.buildServer();let y=await this.getInitialServicesData();y&&this.setServicesData(y),await this.start()}async init(d){await this.patchPlaywright(),this.loadChecksumData(),this.loadPlaywrightConfigForVTG(),this.webDriver=this.buildWebDriver(d),this.webDriver.registerEventListener(this),this.taskTimeMachine=new wNe(this.webDriver.frameMsgBroker,this.webDriver.injectedScriptManager,{headless:!vC.vtg.taskTimeMachine.showTaskTimeMachine,timestampBatchingEnabled:!1,sortByTimestamp:!0,taskTimeout:vC.vtg.taskTimeMachine.taskTimeout}),this.pageInteractor=new pEt(this.webDriver.evaluateWithChecksum.bind(this.webDriver),()=>this.webDriver.appMainFrame,this.webDriver.getTimeMachine.bind(this.webDriver),{log:Nh.info,logError:Nh.error},{...this.getTimeoutParams(),waitActionDelay:1e3,testAssetsDir:__dirname,listenToDialog:!0,listenToFileChooser:!1},new _Et(this.config)),this.testAssetsManager=new KMt(this.projectRootDirectory,this.checksumRoot,this.vtgTestFileRunConfig),(vC.vtg.writeLogFile||this.debugMode)&&this.addLogFile()}buildServices(){this.actionsManager=new CLt,this.apiService=new wOt(this.config),this.userStoryService=new DLt(this.apiService,this.config),this.variableStoreService=new aRt,this.evaluatorService=new sRt(this.variableStoreService,this.vtgTestFileMode),this.actionsService=new COt(this.config,this.checksumRoot,this.pageInteractor,this.apiService,this.userStoryService,this.actionsManager,this.testAssetsManager,this.webDriver,this.evaluatorService),this.assertionsService=new jOt(this.webDriver,this.actionsManager,this.evaluatorService),this.locatorsService=new KOt(this.webDriver,this.taskTimeMachine,this.apiService,this.userStoryService,this.evaluatorService),this.aiTestGenerationService=new kOt(this.webDriver,this.pageInteractor,this.actionsService,this.actionsManager,this.apiService,this.userStoryService),this.aiAssertionsService=new BOt(this.actionsManager,this.apiService,this.userStoryService,this.taskTimeMachine,this.webDriver,this.evaluatorService),this.aiThoughtsService=new nRt(this.actionsManager,this.apiService,this.userStoryService,this.taskTimeMachine,this.webDriver),this.storageService=new TLt(this.config,this.userStoryService,this.apiService,this.actionsManager,this.testAssetsManager,this.actionsService,this.vtgTestFileRunConfig,this.evaluatorService),this.settingsService=new tRt(this.checksumRoot),this.actionsManager.setStorageService(this.storageService)}buildServer(){this.reactAppServer=new HMt(this.actionsService,this.assertionsService,this.locatorsService,this.aiTestGenerationService,this.aiAssertionsService,this.aiThoughtsService,this.actionsManager,this.storageService,this.settingsService)}loadPlaywrightConfigForVTG(){try{let d=`${this.checksumRoot}/playwright.config.ts`;if((0,wwt.existsSync)(d)){let y=require(d).default;y&&(this.playwrightConfigForVTG=y)}}catch{console.warn("Could not find playwright config file, will run with defaults")}}async getInitialServicesData(){if(this.vtgMode==="cloud")return this.getInitialServicesDataFromCloud();if(this.vtgMode==="edit")return this.vtgTestFileMode?await this.getInitialServicesDataByInternalTestId():this.getInitialServicesDataFromEditLocationPath()}getInitialServicesDataFromEditLocationPath(){let d=this.storageService.getLocalSavedData(this.editLocationPath);return{actions:d.executedActions,story:d.story,testGenerationData:d.testGenerationData}}async getInitialServicesDataFromCloud(){let y=await(await this.apiService.post(`test-generation/${this.cloudTestGenerationId}/info`)).json(),{actionsDownloadSignedURL:E,story:N,testGenerationData:F}=y,R=await fetch(E,{mode:"cors",credentials:"same-origin",headers:{"Content-Type":"application/json"}});if(!R.ok)throw new Error(`HTTP error! Status: ${R.status}`);let V=await R.json();return{actions:this.addIdsToActionsAndAssertions(V),story:N,testGenerationData:F}}addIdsToActionsAndAssertions(d){return d.map((y,E)=>({...y,id:(0,Mrr.randomUUID)(),assertions:(y.assertions??[]).map(N=>({...N,id:(0,Mrr.randomUUID)()}))}))}async getInitialServicesDataByInternalTestId(){var N,F,R;if(((N=this.vtgTestFileRunConfig)==null?void 0:N.mode)!=="edit")return;let d=[];d=this.storageService.readJsonFile((F=this.vtgTestFileRunConfig)==null?void 0:F.actionsJsonFilePath),d=this.addIdsToActionsAndAssertions(d);let y=await this.apiService.post(`test-generation-by-internal-test-id/${(R=this.vtgTestFileRunConfig)==null?void 0:R.internalTestId}/info`);if(!y.ok)throw new Error(`Error fetching test generation data: ${y.statusText}`);let E=await y.json();return{actions:d,story:E.story,testGenerationData:E.testGenerationData}}setServicesData({actions:d,story:y,testGenerationData:E}){this.actionsManager.setActions(d),this.userStoryService.setStoryInfo(y,E),this.testAssetsManager.setCurrentSaveAsLocation(this.editLocationPath),this.storyId=y.id}async start({createAssetsFolder:d=!0}={}){var N,F;(this.vtgMode==="start"||this.vtgTestFileMode)&&await this.userStoryService.fetchStory(this.storyId),d&&this.testAssetsManager.createTestGenerationAssetsFolders(),this.testAssetsManager.createTestGenerationLocalAutoSaveFolder(this.storyId);let{environment:y}=this.userStoryService.getEnvInfo();await this.webDriver.prepare({baseURL:y.baseURL,shutdown:!this.vtgTestFileMode}),await this.webDriver.addHARMockAPIRecordings(this.testAssetsManager.getHarFilePath()),await this.initTimeMachine(),this.pageInteractor.init(),this.assertionsService.setPage(this.webDriver.appMainFrame.page()),this.actionsService.setPage(this.webDriver.appMainFrame.page()),this.evaluatorService.setPage(this.webDriver.appMainFrame.page()),await this.taskTimeMachine.prepare(this.webDriver.appMainFrame,void 0,R=>this.webDriver.registerTimeMachineFrame(R)),await this.reactAppServer.start(),await this.reactAppServer.evaluateServerPort(this.webDriver.page);let E=(()=>{let R=this.config.environments.find(V=>V.name===y.name);return!R||!R.baseURL?"/":R.baseURL})();this.webDriver.appMainFrame?await this.webDriver.appMainFrame.goto(E,{waitUntil:"domcontentloaded",timeout:0}):Nh.error("Iframe not found"),await this.webDriver.getTimeMachine().toggleTimeMachineHandleEvents(!1),this.vtgMode==="start"&&(await this.actionsService.addInitialLoginAction(),await this.actionsService.addStartURLNavigationAction(),this.vtgTestFileMode&&await this.storageService.saveTestFile()),console.log("VTG is ready",(N=this.userStoryService.getStory())==null?void 0:N.goal),await this.webDriver.page.evaluate(({localSaveFolderPath:R,actions:V,appViewport:H,userStoryGoal:Q,isLoadedFromFile:se})=>{window.vtg.initClient(R,V,H,this.checksumRuntimeVersion,Q,se)},{localSaveFolderPath:this.editLocationPath,actions:this.actionsManager.actions,appViewport:this.webDriver.getApplicationViewport(),userStoryGoal:(F=this.userStoryService.getStory())==null?void 0:F.goal,isLoadedFromFile:this.vtgTestFileMode}),this.vtgTestFileMode||await new Promise(()=>{})}getTimeoutParams(){var E,N,F,R;let d=((N=(E=this.playwrightConfigForVTG)==null?void 0:E.use)==null?void 0:N.navigationTimeout)||3e4,y=((R=(F=this.playwrightConfigForVTG)==null?void 0:F.use)==null?void 0:R.actionTimeout)||5e3;return{navigationTimeout:d,actionTimeout:y}}getPlaywrightProxySettings(){var F,R;let d=(R=(F=this.playwrightConfigForVTG)==null?void 0:F.use)==null?void 0:R.proxy,{server:y,username:E,password:N}=d||{};if(E&&N&&y)return{username:E,password:N,server:y}}getPlaywrightViewportSettings(){var E,N;let{width:d=1280,height:y=720}=((N=(E=this.playwrightConfigForVTG)==null?void 0:E.use)==null?void 0:N.viewport)||{};return{width:d,height:y}}buildWebDriver(d){var N;let y=this.getPlaywrightProxySettings(),E=this.getPlaywrightViewportSettings();return new ZMt({scriptSource:vC.checksumScript.source,scriptURL:vC.checksumScript.url,scriptFile:vC.checksumScript.path,isScriptFileAbsolute:!0,fullScreenResolution:!1,hostWindowViewport:!0,baseURL:(N=this.config.environments.find(F=>F.default))==null?void 0:N.baseURL,useProxy:!!y,webProxy:y,disableWebSecurity:!0,allowFileAccess:!0,remoteDebugging:vC.vtg.remoteDebugging},{devtools:!1,headless:!1},{frontendAppSpecificRules:{},frontendTestGenerationConfig:{logPrefix:"$checksum"},viewport:E},d)}async onWebDriverContextClose(){var d,y,E;this.evaluatorService.stopListening(),(d=this.vtgTestFileRunConfig)!=null&&d.evalFilePath&&(0,wwt.rmSync)((y=this.vtgTestFileRunConfig)==null?void 0:y.evalFilePath,{force:!0}),this.vtgTestFileRunConfig.mode==="edit"&&(0,wwt.rmSync)((E=this.vtgTestFileRunConfig)==null?void 0:E.actionsJsonFilePath,{force:!0})}initVtgMode(d){var N;let y=d.indexOf("--edit"),E=d.indexOf("--cloud");if(d.indexOf("--test-file")!==-1){this.vtgTestFileMode=!0,this.vtgTestFileRunConfig=JSON.parse(process.env.CHECKSUM_VTG_TEST_FILE_RUN_CONFIG),this.vtgMode=this.vtgTestFileRunConfig.mode,this.storyId=((N=this.vtgTestFileRunConfig)==null?void 0:N.mode)==="start"?this.vtgTestFileRunConfig.storyId:void 0;return}y!==-1&&(this.vtgMode="edit",this.editLocationPath=d.at(y+1)),E!==-1&&(this.vtgMode="cloud",this.cloudTestGenerationId=d.at(E+1)),this.vtgMode==="start"&&(this.storyId=d[0])}addLogFile(){let d=require("fs"),y=`${this.testAssetsManager.getLogsPath()}/vtg_${new Date().toISOString()}.log`;d.existsSync(this.testAssetsManager.getLogsPath())||d.mkdirSync(this.testAssetsManager.getLogsPath(),{recursive:!0}),Nh.addLogListener({onLog:e((...E)=>{let N=E.map(F=>{if(typeof F=="object")try{return JSON.stringify(F,null,2)}catch{}return String(F)}).join(" ")+`
1917
- `;try{d.appendFile(y,N,F=>{F&&console.error(F)})}catch{}},"onLog")})}async eval(d){return this.evaluatorService.listenForExecution(d)}};e(Rrr,"VisualTestGenerator");var Awt=Rrr;var gce=x7(Kae());var Brr=class Brr{constructor(p,d=!1){this.desiredType=p;this.recursive=d}changeAssignmentType(p){let d=p.declarationList.declarations.map(E=>gce.factory.createVariableDeclaration(E.name,E.exclamationToken,E.type,E.initializer)),y=gce.factory.createVariableDeclarationList(d,this.desiredType);return gce.factory.updateVariableStatement(p,p.modifiers,y)}transform(p){let d=e(y=>(gce.isVariableStatement(y)&&(y=this.changeAssignmentType(y)),gce.isSourceFile(y)||gce.isStatement(y)||this.recursive?gce.visitEachChild(y,d,p):y),"visit");return y=>gce.visitNode(y,d)}};e(Brr,"ChangeAllAssignmentsTypesTransformer");var oRt=Brr;var H5r=x7(Kae());var jrr=class jrr extends sce{constructor(d,y=!1,E=!1){super(d,y);this.vtgMode=E;this.MAX_COMPLETION_WAIT=2*3600*1e3;this.TEST_RUN_MONITOR_PATH=(0,a4e.join)(__dirname,"test-run-monitor.js");this.didFail=!1;this.isolationMode=!1;this.trmMessagesBuffer="";this.completeIndicators={upload:!1,tests:!1,report:!1};this.uploadProgress=0;this.fileNameTimestamp=new Date().toString().split(" ").slice(0,5).join(" ")}get replMode(){return this.getChecksumArg("repl")??!1}get vtgLegacyMode(){return this.getChecksumArg("legacy")||!1}get vtgEditMode(){return this.getChecksumArg("edit")||!1}async run(){var F;if(this.loadTracer(),this.loadChecksumData(),this.validateAuthExists(),this.vtgMode&&this.vtgLegacyMode&&(this.config.options.hostReports=!1),!await this.getSession())return;this.trace.log(`Project root found at ${this.projectRootDirectory}`,`Checksum root found at ${this.checksumRoot}`);let d;try{d=await Dj(this.startTestRunMonitor(this.testSession),1e4,"test run monitor timeout")}catch{this.logAndTrace("Error starting test run monitor. Test results will not be available on checksum.","Test Run Monitor Error")}this.buildVolatileConfig();let y={CHECKSUM_ROOT_FOLDER:this.checksumRoot};d&&(y.CHECKSUM_UPLOAD_AGENT_PORT=d),this.config.options.hostReports&&(y.PW_TEST_HTML_REPORT_OPEN="never"),this.testSession&&this.testSession!=="isolated-session"&&(y.CHECKSUM_TEST_SUITE_ID=this.testSession),this.replMode&&(y.CHECKSUM_REPL="true"),(F=this.trace)!=null&&F.internalId&&(y.CHECKSUM_TRACE_INTERNAL_ID=this.trace.internalId),this.getChecksumArg("tm")&&(y.CHECKSUM_SHOW_TIME_MACHINE="true");let E=this.getNonChecksumArgs();if(this.vtgMode&&this.vtgLegacyMode&&(E.unshift("--reporter=line"),y.CHECKSUM_VTG_TEST_FILE_MODE="true",this.vtgEditMode?y.CHECKSUM_VTG_TEST_FILE_EDIT_MODE="true":y.CHECKSUM_VTG_STORY_ID=E[E.length-1],y.PW_TEST_HTML_REPORT_OPEN="never"),this.vtgMode&&this.vtgLegacyMode){let R,V;if(this.vtgEditMode){R=E[E.length-1];let H=this.loadVtgTestFileMirror(R);this.createActionJsonFileForExistingChecksumSpec(H,R),this.createEvalFileForExistingChecksumSpec(H,R),V={mode:"edit",actionsJsonFilePath:this.getActionJsonFilePath(R),internalTestId:H.testMirrors[0].internalTestId,evalFilePath:this.getEvalFilePath(R),sourceFilePath:R}}else this.createEvalFileForNewChecksumSpec(),cRt.writeFileSync(this.getSavePathForNewChecksumSpec(),SXt({body:"",testFunctionParams:["page","vs"]})),V={mode:"start",sourceFilePath:this.getSavePathForNewChecksumSpec(),evalFilePath:this.getEvalFilePath(),storyId:E[E.length-1]};y.CHECKSUM_VTG_TEST_FILE_RUN_CONFIG=JSON.stringify(V),E[E.length-1]=this.getEvalFilePath(this.vtgEditMode?R:void 0)}this.replMode&&E.push("--debug");let N=`npx playwright test --config "${this.getPlaywrightConfigFilePath()}" ${E.map(R=>R.includes(" ")?Y6r(R):R).join(" ")}`;await this.patchPlaywright();try{console.log(`Tests running with @checksum-ai/runtime version ${this.checksumRuntimeVersion}`),this.replMode?(console.log("Running in REPL mode"),this.execCmd(N,y),await this.execCmd(`node ${__dirname}/repl.js`,y)):(this.trace.testsStart(),await this.execCmd(N,y),this.trace.testsEnd()),console.log("Tests execution finished")}catch{this.didFail=!0,console.log("Error during test execution: Failed passing test"),this.trace.testsFailed()}finally{this.isolationMode||console.log("Waiting for test files to upload to Checksum..."),this.sendReportUploadRequest(),await this.patchPlaywright(!0),this.completeIndicators.tests=!0,await this.handleCompleteMessage()}}createEvalFileForExistingChecksumSpec(d,y){let E=new wZe(d.sourceFile);E.transformSourceFile([new grt(y),new yrt(d.sourceFile,d.testMirrors.map(N=>N.testBody),SOt(EXt),["page","vs","vtg"]),new oRt(H5r.NodeFlags.Let,!0)]),E.write(this.getEvalFilePath(y))}loadVtgTestFileMirror(d){if(!d||!d.startsWith("/"))throw new Error("Currently vtg mode can only run with absolute path to file");let y=new sPe(d);return y.loadTestFromFile(),y}createActionJsonFileForExistingChecksumSpec(d,y){let E=d.testMirrors[0].translateStatementsToActions(),N=this.getActionJsonFilePath(y);cRt.writeFileSync(N,JSON.stringify(E,null,2))}createFolderIfNotExists(d){return(0,Pwt.existsSync)(d)||(0,Pwt.mkdirSync)(d,{recursive:!0}),d}getSavePathForNewChecksumSpec(){let d=this.createFolderIfNotExists((0,a4e.join)(this.checksumRoot,"tests"));return(0,a4e.join)(d,`test-${this.fileNameTimestamp}.checksum.spec.ts`)}createEvalFileForNewChecksumSpec(){let d=this.getEvalFilePath();cRt.writeFileSync(d,SXt({body:EXt,testFunctionParams:["page","vs","vtg"],importMode:"require",useLocalChecksumImport:!!process.env.DEV_MODE}))}getTempFolder(){return this.createFolderIfNotExists((0,a4e.join)(this.checksumRoot,"drafts","temp"))}getActionJsonFilePath(d){let y=this.getFileName(d).replace(".spec.ts",".json");return(0,a4e.join)(this.getTempFolder(),y)}getFileName(d){return d.split("/").pop()}getEvalFilePath(d){let y=d?this.getFileName(d).replace(/(\.eval)?(\.checksum\.spec\.ts)$/,(E,N,F)=>N?F:".eval"+F):`test-${this.fileNameTimestamp}.eval.checksum.spec.ts`;return(0,a4e.join)(this.getTempFolder(),y)}getPlaywrightReportPath(){var E;let d=e(N=>(XG("Using report folder",N),(0,a4e.join)(N,"index.html")),"makeFilePath");if(process.env.PLAYWRIGHT_HTML_OUTPUT_DIR)return d(process.env.PLAYWRIGHT_HTML_OUTPUT_DIR);let y=(E=this.playwrightConfig)==null?void 0:E.reporter;if(y instanceof Array){let F=y.filter(R=>R instanceof Array&&R[0]==="html").find(R=>{var V;return(V=R[1])==null?void 0:V.outputFolder});if(F)return d((0,a4e.join)(this.checksumRoot,F[1].outputFolder))}return d((0,a4e.join)(this.projectRootDirectory,"playwright-report"))}sendReportUploadRequest(){let d=this.getPlaywrightReportPath();if(!(0,Pwt.existsSync)(d)){this.logAndTrace(`Could not find report file at ${d}`,"Runtime Error"),this.completeIndicators.report=!0,this.testRunMonitorProcess.stdin.write("cli:report=false");return}XG("Sending report upload request",d),this.testRunMonitorProcess.stdin.write(`cli:report=${d}`)}startTestRunMonitor(d){return new Promise(y=>{console.log("Starting test run monitor"),this.testRunMonitorProcess=$5r.spawn("node",[this.TEST_RUN_MONITOR_PATH,JSON.stringify({sessionId:d,apiURL:this.config.apiURL,apiKey:this.config.apiKey}),...this.isolationMode?["isolated"]:[]]),this.testRunMonitorProcess.stdout.on("data",E=>{let N=this.parseTRMMessages(E.toString().trim());if(N.length){this.logTRMMessage(N);for(let F of N){if(F.startsWith("trace")&&this.handleTestRunMonitorTrace(F.substring("trace".length+1)),!F.startsWith("monitor"))continue;let R=F.substring("monitor".length+1),V=R.indexOf("=");if(V===-1){this.handleTestRunMonitorMessage(R,"");continue}let[H,Q]=[R.substring(0,V),R.substring(V+1)];if(!Object.values(HUt).includes(H)){console.warn(`Unknown test run monitor message: ${H}`);continue}H==="port"?y(Q):this.handleTestRunMonitorMessage(H,Q)}}}),this.testRunMonitorProcess.on("exit",(E,N)=>{this.logAndTrace(`test run monitor process exited with code ${E} and signal ${N}`,"Test Run Monitor Error")}),this.testRunMonitorProcess.stderr.on("data",E=>{this.logAndTrace(`TRM Error: ${E.toString().substring(0,300)}`,"Test Run Monitor Error")}),this.testRunMonitorProcess.on("error",E=>{this.logAndTrace(`Error starting test run monitor: ${E.message}`,"Test Run Monitor Error")})})}parseTRMMessages(d){let y=this.trmMessagesBuffer+d,E,N,F=e(()=>{E=y.indexOf("{trm}"),N=y.indexOf("{/trm}")},"findIndexes");F();let R=[];for(;E!==-1&&N!==-1&&N>E;){if(R.push(y.substring(E+"{trm}".length,N)),y=y.slice(N+"{/trm}".length).trim(),y.length&&!y.startsWith("{trm}"))return console.warn("Buffered data does not start with start delimiter",y),this.trmMessagesBuffer="",R;this.trmMessagesBuffer=y,F()}return R}async handleTestRunMonitorTrace(d){let y=d.indexOf("="),[E,N]=y>-1?[d.substring(0,y),d.substring(y+1)]:[d,""];if(!Object.values(irt).includes(E)){XG("Unknown trace event",E);return}try{let F=N?JSON.parse(N):{};switch(E){case"Upload Start":this.trace.uploadStart(F.filename);break;case"Upload Complete":this.trace.uploadComplete(F.filename);break;case"Upload Failed":this.trace.uploadFailed(F.filename,F.error);break}}catch(F){XG(`Error parsing trace payload, ${F.message}`)}}async handleTestRunMonitorMessage(d,y){switch(d){case"uploads-complete-with-errors":console.log("Error uploading test files to Checksum");try{let N=JSON.parse(y);this.trace.uploadsCompleteWithErrors(N)}catch{}this.sendProcessingError().then(()=>{this.completeIndicators.upload=!0});break;case"uploads-complete":this.isolationMode||console.log("Test files uploaded successfully"),this.trace.allUploadsComplete(),this.sendUploadsComplete().then(()=>{this.completeIndicators.upload=!0});break;case"report-complete":{if(this.isolationMode){this.completeIndicators.report=!0;break}let N=y.slice(0,y.indexOf(":"))==="true",F=y.slice(y.indexOf(":")+1),R={};try{F&&F.length>0?R=JSON.parse(F):XG("No stats received from test run monitor")}catch(V){this.logAndTrace(`Error parsing stats - ${V.message}`,"Runtime Error")}if(await this.sendTestRunEnd(R),this.completeIndicators.report=!0,N){let V=`${this.checksumAppUrl}/#/test-runs/${this.testSession}`,H=`Checksum report URL: ${V}`,Q="*".repeat(H.length);console.log(`${Q}
1917
+ `;try{d.appendFile(y,N,F=>{F&&console.error(F)})}catch{}},"onLog")})}async eval(d){return this.evaluatorService.listenForExecution(d)}};e(Rrr,"VisualTestGenerator");var Awt=Rrr;var gce=x7(Kae());var Brr=class Brr{constructor(p,d=!1){this.desiredType=p;this.recursive=d}changeAssignmentType(p){let d=p.declarationList.declarations.map(E=>gce.factory.createVariableDeclaration(E.name,E.exclamationToken,E.type,E.initializer)),y=gce.factory.createVariableDeclarationList(d,this.desiredType);return gce.factory.updateVariableStatement(p,p.modifiers,y)}transform(p){let d=e(y=>(gce.isVariableStatement(y)&&(y=this.changeAssignmentType(y)),gce.isSourceFile(y)||gce.isStatement(y)||this.recursive?gce.visitEachChild(y,d,p):y),"visit");return y=>gce.visitNode(y,d)}};e(Brr,"ChangeAllAssignmentsTypesTransformer");var oRt=Brr;var H5r=x7(Kae());var jrr=class jrr extends sce{constructor(d,y=!1,E=!1){super(d,y);this.vtgMode=E;this.MAX_COMPLETION_WAIT=2*3600*1e3;this.TEST_RUN_MONITOR_PATH=(0,a4e.join)(__dirname,"test-run-monitor.js");this.didFail=!1;this.isolationMode=!1;this.trmMessagesBuffer="";this.completeIndicators={upload:!1,tests:!1,report:!1};this.uploadProgress=0;this.fileNameTimestamp=new Date().toString().split(" ").slice(0,5).join(" ")}get replMode(){return this.getChecksumArg("repl")??!1}get vtgLegacyMode(){return this.getChecksumArg("legacy")||!1}get vtgEditMode(){return this.getChecksumArg("edit")||!1}async run(){var F;if(this.loadTracer(),this.loadChecksumData(),this.validateAuthExists(),this.vtgMode&&!this.vtgLegacyMode&&(this.config.options.hostReports=!1),!await this.getSession())return;this.trace.log(`Project root found at ${this.projectRootDirectory}`,`Checksum root found at ${this.checksumRoot}`);let d;try{d=await Dj(this.startTestRunMonitor(this.testSession),1e4,"test run monitor timeout")}catch{this.logAndTrace("Error starting test run monitor. Test results will not be available on checksum.","Test Run Monitor Error")}this.buildVolatileConfig();let y={CHECKSUM_ROOT_FOLDER:this.checksumRoot};d&&(y.CHECKSUM_UPLOAD_AGENT_PORT=d),this.config.options.hostReports&&(y.PW_TEST_HTML_REPORT_OPEN="never"),this.testSession&&this.testSession!=="isolated-session"&&(y.CHECKSUM_TEST_SUITE_ID=this.testSession),this.replMode&&(y.CHECKSUM_REPL="true"),(F=this.trace)!=null&&F.internalId&&(y.CHECKSUM_TRACE_INTERNAL_ID=this.trace.internalId),this.getChecksumArg("tm")&&(y.CHECKSUM_SHOW_TIME_MACHINE="true");let E=this.getNonChecksumArgs();if(this.vtgMode&&!this.vtgLegacyMode&&(E.unshift("--reporter=line"),y.CHECKSUM_VTG_TEST_FILE_MODE="true",this.vtgEditMode?y.CHECKSUM_VTG_TEST_FILE_EDIT_MODE="true":y.CHECKSUM_VTG_STORY_ID=E[E.length-1],y.PW_TEST_HTML_REPORT_OPEN="never"),this.vtgMode&&!this.vtgLegacyMode){let R,V;if(this.vtgEditMode){R=E[E.length-1];let H=this.loadVtgTestFileMirror(R);this.createActionJsonFileForExistingChecksumSpec(H,R),this.createEvalFileForExistingChecksumSpec(H,R),V={mode:"edit",actionsJsonFilePath:this.getActionJsonFilePath(R),internalTestId:H.testMirrors[0].internalTestId,evalFilePath:this.getEvalFilePath(R),sourceFilePath:R}}else this.createEvalFileForNewChecksumSpec(),cRt.writeFileSync(this.getSavePathForNewChecksumSpec(),SXt({body:"",testFunctionParams:["page","vs"]})),V={mode:"start",sourceFilePath:this.getSavePathForNewChecksumSpec(),evalFilePath:this.getEvalFilePath(),storyId:E[E.length-1]};y.CHECKSUM_VTG_TEST_FILE_RUN_CONFIG=JSON.stringify(V),E[E.length-1]=this.getEvalFilePath(this.vtgEditMode?R:void 0)}this.replMode&&E.push("--debug");let N=`npx playwright test --config "${this.getPlaywrightConfigFilePath()}" ${E.map(R=>R.includes(" ")?Y6r(R):R).join(" ")}`;await this.patchPlaywright();try{console.log(`Tests running with @checksum-ai/runtime version ${this.checksumRuntimeVersion}`),this.replMode?(console.log("Running in REPL mode"),this.execCmd(N,y),await this.execCmd(`node ${__dirname}/repl.js`,y)):(this.trace.testsStart(),await this.execCmd(N,y),this.trace.testsEnd()),console.log("Tests execution finished")}catch{this.didFail=!0,console.log("Error during test execution: Failed passing test"),this.trace.testsFailed()}finally{this.isolationMode||console.log("Waiting for test files to upload to Checksum..."),this.sendReportUploadRequest(),await this.patchPlaywright(!0),this.completeIndicators.tests=!0,await this.handleCompleteMessage()}}createEvalFileForExistingChecksumSpec(d,y){let E=new wZe(d.sourceFile);E.transformSourceFile([new grt(y),new yrt(d.sourceFile,d.testMirrors.map(N=>N.testBody),SOt(EXt),["page","vs","vtg"]),new oRt(H5r.NodeFlags.Let,!0)]),E.write(this.getEvalFilePath(y))}loadVtgTestFileMirror(d){if(!d||!d.startsWith("/"))throw new Error("Currently vtg mode can only run with absolute path to file");let y=new sPe(d);return y.loadTestFromFile(),y}createActionJsonFileForExistingChecksumSpec(d,y){let E=d.testMirrors[0].translateStatementsToActions(),N=this.getActionJsonFilePath(y);cRt.writeFileSync(N,JSON.stringify(E,null,2))}createFolderIfNotExists(d){return(0,Pwt.existsSync)(d)||(0,Pwt.mkdirSync)(d,{recursive:!0}),d}getSavePathForNewChecksumSpec(){let d=this.createFolderIfNotExists((0,a4e.join)(this.checksumRoot,"tests"));return(0,a4e.join)(d,`test-${this.fileNameTimestamp}.checksum.spec.ts`)}createEvalFileForNewChecksumSpec(){let d=this.getEvalFilePath();cRt.writeFileSync(d,SXt({body:EXt,testFunctionParams:["page","vs","vtg"],importMode:"require",useLocalChecksumImport:!!process.env.DEV_MODE}))}getTempFolder(){return this.createFolderIfNotExists((0,a4e.join)(this.checksumRoot,"drafts","temp"))}getActionJsonFilePath(d){let y=this.getFileName(d).replace(".spec.ts",".json");return(0,a4e.join)(this.getTempFolder(),y)}getFileName(d){return d.split("/").pop()}getEvalFilePath(d){let y=d?this.getFileName(d).replace(/(\.eval)?(\.checksum\.spec\.ts)$/,(E,N,F)=>N?F:".eval"+F):`test-${this.fileNameTimestamp}.eval.checksum.spec.ts`;return(0,a4e.join)(this.getTempFolder(),y)}getPlaywrightReportPath(){var E;let d=e(N=>(XG("Using report folder",N),(0,a4e.join)(N,"index.html")),"makeFilePath");if(process.env.PLAYWRIGHT_HTML_OUTPUT_DIR)return d(process.env.PLAYWRIGHT_HTML_OUTPUT_DIR);let y=(E=this.playwrightConfig)==null?void 0:E.reporter;if(y instanceof Array){let F=y.filter(R=>R instanceof Array&&R[0]==="html").find(R=>{var V;return(V=R[1])==null?void 0:V.outputFolder});if(F)return d((0,a4e.join)(this.checksumRoot,F[1].outputFolder))}return d((0,a4e.join)(this.projectRootDirectory,"playwright-report"))}sendReportUploadRequest(){let d=this.getPlaywrightReportPath();if(!(0,Pwt.existsSync)(d)){this.logAndTrace(`Could not find report file at ${d}`,"Runtime Error"),this.completeIndicators.report=!0,this.testRunMonitorProcess.stdin.write("cli:report=false");return}XG("Sending report upload request",d),this.testRunMonitorProcess.stdin.write(`cli:report=${d}`)}startTestRunMonitor(d){return new Promise(y=>{console.log("Starting test run monitor"),this.testRunMonitorProcess=$5r.spawn("node",[this.TEST_RUN_MONITOR_PATH,JSON.stringify({sessionId:d,apiURL:this.config.apiURL,apiKey:this.config.apiKey}),...this.isolationMode?["isolated"]:[]]),this.testRunMonitorProcess.stdout.on("data",E=>{let N=this.parseTRMMessages(E.toString().trim());if(N.length){this.logTRMMessage(N);for(let F of N){if(F.startsWith("trace")&&this.handleTestRunMonitorTrace(F.substring("trace".length+1)),!F.startsWith("monitor"))continue;let R=F.substring("monitor".length+1),V=R.indexOf("=");if(V===-1){this.handleTestRunMonitorMessage(R,"");continue}let[H,Q]=[R.substring(0,V),R.substring(V+1)];if(!Object.values(HUt).includes(H)){console.warn(`Unknown test run monitor message: ${H}`);continue}H==="port"?y(Q):this.handleTestRunMonitorMessage(H,Q)}}}),this.testRunMonitorProcess.on("exit",(E,N)=>{this.logAndTrace(`test run monitor process exited with code ${E} and signal ${N}`,"Test Run Monitor Error")}),this.testRunMonitorProcess.stderr.on("data",E=>{this.logAndTrace(`TRM Error: ${E.toString().substring(0,300)}`,"Test Run Monitor Error")}),this.testRunMonitorProcess.on("error",E=>{this.logAndTrace(`Error starting test run monitor: ${E.message}`,"Test Run Monitor Error")})})}parseTRMMessages(d){let y=this.trmMessagesBuffer+d,E,N,F=e(()=>{E=y.indexOf("{trm}"),N=y.indexOf("{/trm}")},"findIndexes");F();let R=[];for(;E!==-1&&N!==-1&&N>E;){if(R.push(y.substring(E+"{trm}".length,N)),y=y.slice(N+"{/trm}".length).trim(),y.length&&!y.startsWith("{trm}"))return console.warn("Buffered data does not start with start delimiter",y),this.trmMessagesBuffer="",R;this.trmMessagesBuffer=y,F()}return R}async handleTestRunMonitorTrace(d){let y=d.indexOf("="),[E,N]=y>-1?[d.substring(0,y),d.substring(y+1)]:[d,""];if(!Object.values(irt).includes(E)){XG("Unknown trace event",E);return}try{let F=N?JSON.parse(N):{};switch(E){case"Upload Start":this.trace.uploadStart(F.filename);break;case"Upload Complete":this.trace.uploadComplete(F.filename);break;case"Upload Failed":this.trace.uploadFailed(F.filename,F.error);break}}catch(F){XG(`Error parsing trace payload, ${F.message}`)}}async handleTestRunMonitorMessage(d,y){switch(d){case"uploads-complete-with-errors":console.log("Error uploading test files to Checksum");try{let N=JSON.parse(y);this.trace.uploadsCompleteWithErrors(N)}catch{}this.sendProcessingError().then(()=>{this.completeIndicators.upload=!0});break;case"uploads-complete":this.isolationMode||console.log("Test files uploaded successfully"),this.trace.allUploadsComplete(),this.sendUploadsComplete().then(()=>{this.completeIndicators.upload=!0});break;case"report-complete":{if(this.isolationMode){this.completeIndicators.report=!0;break}let N=y.slice(0,y.indexOf(":"))==="true",F=y.slice(y.indexOf(":")+1),R={};try{F&&F.length>0?R=JSON.parse(F):XG("No stats received from test run monitor")}catch(V){this.logAndTrace(`Error parsing stats - ${V.message}`,"Runtime Error")}if(await this.sendTestRunEnd(R),this.completeIndicators.report=!0,N){let V=`${this.checksumAppUrl}/#/test-runs/${this.testSession}`,H=`Checksum report URL: ${V}`,Q="*".repeat(H.length);console.log(`${Q}
1918
1918
  ${H}
1919
1919
  ${Q}`),this.trace.reportComplete(R,V)}else this.trace.event("Report Upload Error"),console.log("An error occurred while uploading the test report to Checksum");break}case"upload-progress":{if(this.isolationMode)break;let N=parseInt(y);(N<this.uploadProgress||N>=this.uploadProgress+10||N===100&&this.uploadProgress!==100)&&(this.uploadProgress=N,console.log(`[ Uploads progress: ${this.uploadProgress}% ]`))}break;case"log":console.log(y);break;case"trace":let E=y;if(!Object.values(irt).includes(E))return;this.trace.event(E);break;case"playwrightConfig":try{this.playwrightConfig||(this.playwrightConfig=JSON.parse(y),this.trace.playwrightConfig(this.playwrightConfig))}catch(N){this.logAndTrace(`Error parsing playwright config - ${N.message}`,"Runtime Error")}break;default:this.logAndTrace(`Unhandled test run monitor message: ${d}=${y}`,"Runtime Error")}}async handleCompleteMessage(){let d=Date.now(),y=12;for(;;){if(Date.now()-d>this.MAX_COMPLETION_WAIT){console.log("Warning: Checksum wasn't able to upload all test assets or expected a file the couldn't be found. This might cause issues when viewing the report/trace."),this.trace.event("Runtime Timeout"),this.shutdown(1);return}if(Object.keys(this.completeIndicators).find(E=>!this.completeIndicators[E]))XG(this.completeIndicators),--y===0&&(this.trace.completionStatus(this.completeIndicators),y=12),await aA(5e3);else{this.trace.event("Runtime Complete"),console.log("Checksum test run complete"),await this.shutdown(this.didFail?1:0);return}}}async shutdown(d=0){await this.cleanup(),process.exit(d)}async cleanup(){var d,y;await super.cleanup(),(d=this.testRunMonitorProcess)==null||d.stdin.write("cli:shutdown"),(y=this.testRunMonitorProcess)==null||y.kill()}async getSession(){let d,y;try{if(!this.config.options.hostReports)return this.setIsolatedMode(),!0;if(y=this.config.apiKey,!y||y==="<API key>")return this.logAndTrace("No API key found in checksum config - please set it in the config file - checksum.config.ts","Checksum Config Error",!0),this.shutdown(1),!1;let E=await this.getEnvInfo(),N=JSON.stringify({...E,isHidden:!!this.config.options.hideReports}),F=await fetch(`${this.config.apiURL}/client-api/test-runs`,{method:"POST",headers:{Accept:"application/json","Content-Type":"application/json",ChecksumAppCode:y},body:N}),{uuid:R,appName:V}=await F.json();return this.testSession=R,E.commit=E.name,E.name=V,await this.trace.identify(this.testSession,{...E,company:V,apiKey:y}),!0}catch(E){return this.logAndTrace(`Error connecting to Checksum, the report will not be hosted - ${E.message}`,"Initialization Error"),this.setIsolatedMode(),!0}}setIsolatedMode(){this.isolationMode=!0,this.testSession="isolated-session",this.trace.setIsolatedMode()}async sendTestRunEnd(d){if(!this.isolationMode)try{let y="{}";try{y=JSON.stringify({...d,endedAt:Date.now()})}catch(E){this.logAndTrace(`Error stringifying stats ${E.message}`,"Runtime Error")}await this.updateTestRun(`${this.config.apiURL}/client-api/test-runs/${this.testSession}`,"PATCH",y)}catch(y){return this.logAndTrace(`Error sending test run end ${y.message}`,"Runtime Error"),null}}async sendUploadsComplete(){if(!this.isolationMode)try{await this.updateTestRun(`${this.config.apiURL}/client-api/test-runs/${this.testSession}/uploads-completed`,"PATCH")}catch(d){this.logAndTrace(`Error sending test run uploads complete - ${d.message}`,"Runtime Error")}}async sendProcessingError(){if(!this.isolationMode)try{await this.updateTestRun(`${this.config.apiURL}/client-api/test-runs/${this.testSession}/process-error`,"PATCH")}catch(d){this.logAndTrace(`Error sending test run processing error - ${d.message}`,"Runtime Error")}}async updateTestRun(d,y,E=void 0){let N=await fetch(d,{method:y,headers:{Accept:"application/json","Content-Type":"application/json",ChecksumAppCode:this.config.apiKey},body:E});return XG("Received update test run response from url:",d),await this.logApiResponse(N),N}async logApiResponse(d){try{if(!d.ok){let{status:E,statusText:N}=d,F=await d.text();this.trace.runtimeError({status:E,statusText:N,errorText:F});return}d.headers.get("Content-Type").includes("application/json")?d.json().then(E=>{XG("API Response:",E)}):d.text().then(E=>{XG("API Response:",E)})}catch(y){this.trace.eventWithMessage("Runtime Error",`Error logging API response - ${y.message}`)}}logTRMMessage(d){(Array.isArray(d)?d:[d]).forEach(y=>{XG("\x1B[33m","[trm]","\x1B[0m",y)})}};e(jrr,"TestsRunner");var Nwt=jrr;var Jrr=class Jrr extends sce{constructor(p,d=!1){super(p,d)}async run(p){switch(p){default:console.log(`
1920
1920
  Checksum CLI
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@checksum-ai/runtime",
3
- "version": "1.1.64",
3
+ "version": "1.1.65",
4
4
  "description": "Checksum.ai test runtime",
5
5
  "main": "index.js",
6
6
  "dependencies": {