@checksum-ai/runtime 4.16.1 → 4.16.2
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/.env +1 -1
- package/cli.js +1 -1
- package/package.json +1 -1
package/.env
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
CHECKSUM_RUNTIME_BUILD_TIME=2026-08-
|
|
1
|
+
CHECKSUM_RUNTIME_BUILD_TIME=2026-08-15T07:54:43.482Z
|
package/cli.js
CHANGED
|
@@ -438,7 +438,7 @@ export default {
|
|
|
438
438
|
import { RunMode, getChecksumConfig } from "@checksum-ai/runtime";
|
|
439
439
|
|
|
440
440
|
export default getChecksumConfig(${JSON.stringify(this.config,null,2)});
|
|
441
|
-
`;(0,at.writeFileSync)(n,a)}async cleanup(){this.runtimeAnalytics&&(re("Flushing events..."),await Ye(this.runtimeAnalytics.close(),2e4)),this.deleteVolatileConfig(),this.deleteWrappedPlaywrightConfig(),this.childProcesses.forEach(n=>{n.kill("SIGTERM")})}async getEnvInfo(){let n=this.config?Vae(this.config):void 0,
|
|
441
|
+
`;(0,at.writeFileSync)(n,a)}async cleanup(){this.runtimeAnalytics&&(re("Flushing events..."),await Ye(this.runtimeAnalytics.close(),2e4)),this.deleteVolatileConfig(),this.deleteWrappedPlaywrightConfig(),this.childProcesses.forEach(n=>{n.kill("SIGTERM")})}async getEnvInfo(){let n=this.getExplicitRunTitle(),a=this.config?Vae(this.config):void 0,l={commitHash:"",branch:"branch",environment:process.env.CI?"CI":"local",...a?{testingEnvironment:a}:{},name:"name",startedAt:Date.now(),runtimeVersion:this.checksumRuntimeVersion,request:{...de.testRun.request,...n?{title:n}:{}},platform:de.testRun.platform,runType:de.testRun.runType};try{l.commitHash=await this.getCmdOutput("git rev-parse HEAD")}catch(i){console.log("Error getting git hash",i.message)}try{l.branch=await this.getCmdOutput("git rev-parse --abbrev-ref HEAD")}catch(i){console.log("Error getting branch",i.message)}return l.name=await this.getEnvName(n),l}getExplicitRunTitle(){let n=this.getChecksumArg("title");return typeof n=="string"&&n.length>0?n:void 0}async getEnvName(n){if(n)return n;let a;try{a=await this.getCmdOutput("git log -1 --pretty=%B")}catch(l){console.log("Error getting name",l.message)}return a}getVolatileConfigPath(){return(0,yt.join)(this.checksumRoot??"","checksum.config.tmp.ts")}deleteVolatileConfig(){let n=this.getVolatileConfigPath();(0,at.existsSync)(n)&&(0,at.rmSync)(n)}loadChecksumConfig(n={}){let a={...this.readChecksumConfigFile(n),...this.volatileChecksumConfig??{}};if(this.debugMode){if(!a.options)throw new Error("Checksum config options are not initialized");a.options.printLogs=!0}this.config=a,this.traceChecksumConfig()}readChecksumConfigFile(n={}){let a=(0,yt.join)(this.checksumRoot,"checksum.config.ts");if(!(0,at.existsSync)(a))return n.muteChecksumConfigMissingError||console.warn(`No checksum.config.ts found at ${a}. Continuing with default configuration.`),{};try{return zO(a)}catch(l){return console.log(`Failed to load checksum.config.ts at ${a}:
|
|
442
442
|
${l.message||l}`),process.exit(1)}}traceChecksumConfig(){!this.runtimeAnalytics||!this.config||this.runtimeAnalytics.checksumConfig(this.config)}processConfigArg(){this.deleteVolatileConfig();let n=this.getChecksumArg("config");if(n)try{this.volatileChecksumConfig=JSON.parse(n)}catch(a){this.volatileChecksumConfig=void 0,console.log("Error parsing cksm config",a.message)}}getNonChecksumArgs(){return this.args.filter(n=>!this.isChecksumArg(n))}getArg(n){let a=this.args.find(i=>i.startsWith(`${n}`)),l=a?.split("=")[1]?.trim();return l||!!a}getChecksumArg(n){return this.getArg(`--cksm-${n}`)}getChecksumRootOrigin(){return(0,yt.join)(this.projectRootDirectory,"node_modules","@checksum-ai","runtime","checksum-root")}locateChecksumLibs(){try{this.findProjectRoot(),this.findChecksumRoot()}catch(n){console.log(n.message),process.exit(1)}}findProjectRoot(){let n=process.cwd(),a=n;for(let l=0;l<10;l++){if((0,at.existsSync)((0,yt.join)(a,".git"))){if(this.absoluteProjectRootDirectory)break;this.absoluteProjectRootDirectory=a,re("Project root directory found at (git root)",this.absoluteProjectRootDirectory)}if((0,yt.parse)(a).root===a)break;a=(0,yt.join)(a,"..")}n=process.cwd();for(let l=0;l<6;l++){let i=(0,yt.join)(n,"node_modules","@checksum-ai","runtime");if((0,at.existsSync)(i)){this.projectRootDirectory=n,this.absoluteProjectRootDirectory||(this.absoluteProjectRootDirectory=n),re("Project root directory found at (node_modules fallback)",this.projectRootDirectory);return}if((0,yt.parse)(n).root===n)break;n=(0,yt.join)(n,"..")}if(this.absoluteProjectRootDirectory){this.projectRootDirectory=this.absoluteProjectRootDirectory;return}throw new Error(process.env.CHECKSUM_RUNTIME_DEV_MODE?"Could not resolve checksum root origins, tried to look in .git and node modules. please build the runtime":"Could not resolve checksum root origins")}setChecksumRoot(n){this.checksumRoot=n,re("Checksum root directory found at",this.checksumRoot),this.createInternalFilesDir()}findChecksumRoot(){if(de.checksumRootFolderBypass){let a=(0,yt.isAbsolute)(de.checksumRootFolderBypass)?de.checksumRootFolderBypass:(0,yt.join)(this.projectRootDirectory,de.checksumRootFolderBypass);this.setChecksumRoot(a);return}let n=[this.projectRootDirectory];for(;n.length;){let a=n.pop();if(a===void 0)break;let l=(0,at.readdirSync)(a,{withFileTypes:!0});for(let i of l){let f=(0,yt.join)(a,i.name),d=f;if(i.isSymbolicLink())try{let p=(0,at.readlinkSync)(f);if(!(0,at.lstatSync)(p).isDirectory())continue;d=p}catch{continue}else if(!i.isDirectory())continue;if(i.name===Sv){if(wWe(d)){this.setChecksumRoot(d);return}}else n.push(f)}}throw new Error("Could not find checksum root folder. Run `npx checksumai init` to create one.")}log(n,a=!1){a?this.printError(n):console.log(n)}runtimeTrace(n,a){this.runtimeAnalytics?.eventWithMessage(a,n)}isChecksumArg(n){return n.startsWith("--cksm-")}};function $c(r,n){for(let a of r){if(a===n)return"";if(a.startsWith(`${n}=`))return a.slice(n.length+1).trim()}}u($c,"findFlagValue");function eS(r,n){return $c(r,n)!==void 0}u(eS,"findFlag");var KA="--cksm-auto-heal",Mi={enable:`${KA}`,createPr:`${KA}-create-pr`,repoName:`${KA}-repo-name`,prNumber:`${KA}-pr-number`,branch:`${KA}-branch`};function oce(r){if(!eS(r.args,Mi.enable))return{kind:"disabled"};let n=$c(r.args,Mi.createPr),a=$c(r.args,Mi.repoName),l=$c(r.args,Mi.prNumber),i=$c(r.args,Mi.branch),f=CWe(n,!0);if(f===void 0)return{kind:"error",message:`${Mi.createPr}: expected "true" or "false" (or omit a value), got "${n}"`};let d;if(l!==void 0&&l!==""){let t=Number(l);if(!Number.isInteger(t)||t<=0)return{kind:"error",message:`${Mi.prNumber}: expected a positive integer, got "${l}"`};d=t}let p=SWe(r.env),h=typeof a=="string"&&a!==""?a:p.repoName,o=typeof i=="string"&&i!==""?i:p.branch,c=d??p.prNumber;if(f&&!h)return{kind:"error",message:`${Mi.repoName} is required when auto-create-pr is enabled \u2014 pass --cksm-auto-heal-repo-name=owner/repo or set GITHUB_REPOSITORY / CI_PROJECT_PATH`};if(c!==void 0&&!h)return{kind:"error",message:`${Mi.repoName} is required when ${Mi.prNumber} is set`};let e={autoCreatePR:f};return o&&(e.branch=o),c!==void 0&&(e.prNumber=c),h&&(e.repoName=h),{kind:"enabled",options:e}}u(oce,"resolveAutoHealOptions");function SWe(r){if(r.GITHUB_ACTIONS==="true"){let n=r.GITHUB_REPOSITORY||void 0,a=r.GITHUB_HEAD_REF||r.GITHUB_REF_NAME||void 0,l;if(r.GITHUB_EVENT_NAME==="pull_request"){let f=r.GITHUB_REF?.match(/^refs\/pull\/(\d+)\//);if(f){let d=Number(f[1]);Number.isInteger(d)&&d>0&&(l=d)}}let i={};return n&&(i.repoName=n),a&&(i.branch=a),l!==void 0&&(i.prNumber=l),i}if(r.GITLAB_CI==="true"){let n=r.CI_PROJECT_PATH||void 0,a=r.CI_MERGE_REQUEST_SOURCE_BRANCH_NAME||r.CI_COMMIT_REF_NAME||void 0,l;if(r.CI_MERGE_REQUEST_IID){let f=Number(r.CI_MERGE_REQUEST_IID);Number.isInteger(f)&&f>0&&(l=f)}let i={};return n&&(i.repoName=n),a&&(i.branch=a),l!==void 0&&(i.prNumber=l),i}return{}}u(SWe,"detectCiContext");function CWe(r,n){if(r===void 0)return n;if(r===""||r==="true")return!0;if(r==="false")return!1}u(CWe,"parseBoolFlag");function rce(r){let n=r.body&&typeof r.body=="object"?r.body:{};if(!r.ok){let a=kWe(n.message);return{kind:"fatal",message:`Checksum could not create the test run (HTTP ${r.status})`+(a?`: ${a}`:".")}}return n.uuid?{kind:"success",uuid:n.uuid,...n.appName!==void 0?{appName:n.appName}:{}}:{kind:"fatal",message:`Checksum test-run creation (HTTP ${r.status}) returned no session id; the report cannot be hosted.`}}u(rce,"decideSessionCreateOutcome");function kWe(r){return typeof r=="string"?r:Array.isArray(r)?r.filter(n=>typeof n=="string").join("; "):""}u(kWe,"extractMessage");var TWe="--cksm-affected",PWe="--cksm-affected-dry-run";function ice(r){let n=$c(r.args,TWe),a=eS(r.args,PWe);return n===void 0&&!a?{kind:"disabled"}:{kind:"enabled",baseRef:n?.trim()||xWe(r.env),dryRun:a}}u(ice,"resolveAffectedTestsOptions");function xWe(r){let n=r.GITHUB_BASE_REF?.trim();if(n)return`origin/${n}`;let a=r.CI_MERGE_REQUEST_TARGET_BRANCH_NAME?.trim();if(a)return`origin/${a}`}u(xWe,"detectCiBaseRef");var _We=/^[A-Za-z0-9._/~^@-]+$/,RWe=/^[0-9a-fA-F]{4,40}$/;function ace(r){if(!_We.test(r))throw new Error(`Unsafe git ref for --cksm-affected: "${r}". Only letters, digits and . _ / - are allowed.`);return r}u(ace,"assertSafeRef");async function BWe(r,n){let a=r?.trim();if(a)return ace(a);try{let l=(await n("git symbolic-ref --short refs/remotes/origin/HEAD")).trim();if(l)return ace(l)}catch{}for(let l of["origin/main","origin/master"])try{return await n(`git rev-parse --verify --quiet ${l}`),l}catch{}throw new Error("Could not resolve a base git ref for --cksm-affected. Pass one explicitly, e.g. --cksm-affected=origin/main")}u(BWe,"resolveBaseRef");async function cce(r,n){let a=await BWe(r,n),l="false";try{l=(await n("git rev-parse --is-shallow-repository")).trim()}catch{}if(l==="true")throw new Error("--cksm-affected needs full git history but this is a shallow clone. In GitHub Actions set `fetch-depth: 0` on actions/checkout (or `GIT_DEPTH: 0` / `git fetch --unshallow` in GitLab CI).");let i=(await n(`git merge-base "${a}" HEAD`)).trim();if(!RWe.test(i))throw new Error(`Unexpected merge-base output for --cksm-affected: "${i}"`);return(await n(`git diff --name-only "${i}"`)).split(`
|
|
443
443
|
`).map(d=>d.trim()).filter(Boolean)}u(cce,"computeAffectedChangedFiles");var AUt=require("@playwright/test/reporter"),ip=require("fs"),ap=require("path");var W3=u((r,n,a)=>`v2:${DWe(r)}::${JSON.stringify([...n,a])}`,"computeVariantKey"),DWe=u(r=>(r??"").replace(/\\/g,"/"),"normalizeFilePath");var tS=require("fs"),Kt=ee(require("typescript"));var $3=5,rp={mint(){return fy($3)},parse(r){let n=rp.tryParse(r);if(n===null)throw new TypeError(`Not a usable checksumTestId: ${JSON.stringify(r)}`);return n},tryParse(r){return typeof r!="string"||r.trim()===""?null:r},isSame(r,n){return r===n}};var sce=" - ",lce=/(?:\.fix)?\.checksum\.(?:(?:spec|test)\.(?:ts|js|tsx|jsx)|md)$/i,NWe=/^[A-Za-z0-9_-]+$/,LWe=new RegExp(`^[0-9A-Za-z]{${$3}}$`);function uce(r){return QWe(r).id}u(uce,"readTestIdFromFileName");function QWe(r){let n=MWe(r);if(n===null)return{title:fce(r),id:null};let a=n.lastIndexOf(sce);if(a===-1)return{title:n,id:LWe.test(n)?rp.tryParse(n):null};let l=n.slice(a+sce.length);return NWe.test(l)?{title:n.slice(0,a),id:rp.tryParse(l)}:{title:n,id:null}}u(QWe,"splitFileName");function fce(r){let n=r.replace(/\\/g,"/");return n.slice(n.lastIndexOf("/")+1)}u(fce,"basename");function MWe(r){let n=fce(r);return lce.test(n)?n.replace(lce,""):null}u(MWe,"stemOf");var G3=class{static{u(this,"FileContentReader")}read(n,a){if(!(!n||!(0,tS.existsSync)(n)))try{let l=(0,tS.readFileSync)(n,"utf-8"),i=Kt.createSourceFile(n,l,Kt.ScriptTarget.Latest,!0),f=new Map,d=u(p=>{if(Kt.isCallExpression(p)&&this.isTestCall(p.expression)){let h=p.arguments[0];if(h&&Kt.isCallExpression(h)&&Kt.isIdentifier(h.expression)&&h.expression.text==="defineChecksumTest"){let o=this.extractDefineChecksumTestArgs(h);o&&f.set(o.testTitle,o.checksumTestId)}}Kt.forEachChild(p,d)},"visit");return d(i),a&&f.has(a)?f.get(a):f.size>0?Array.from(f.values())[0]:void 0}catch{return}}isTestCall(n){return Kt.isIdentifier(n)&&n.text==="test"?!0:Kt.isPropertyAccessExpression(n)?Kt.isIdentifier(n.expression)&&n.expression.text==="test":!1}extractDefineChecksumTestArgs(n){let a=n.arguments;if(a.length<2)return;let l=a[0],i=a[1];if(!l||!i)return;let f=this.extractStringLiteral(l),d=rp.tryParse(this.extractStringLiteral(i));if(f&&d)return{testTitle:f,checksumTestId:d}}extractStringLiteral(n){if(Kt.isStringLiteral(n)||Kt.isNoSubstitutionTemplateLiteral(n))return n.text}},FWe=new G3;function dce(r,n){return FWe.read(r,n)??uce(r)??void 0}u(dce,"extractChecksumTestId");function nS(r,n){return n.pwTestIdToChecksumTestId[r.playwrightTestId]||(r.filePath!==void 0?dce(r.filePath,r.title):void 0)}u(nS,"resolveChecksumTestId");var oS=u((r,n)=>Object.values(n[r]??{}).some(a=>a.autoRecoveryMetadata?.data?.autoRecovered),"isAutoRecovered"),J3=u(r=>typeof r=="number"&&!isNaN(r)?r:0,"getStat");function rS(r,n,a){let l=[],i=0,f=0,d=J3(n.expected)+J3(n.flaky),p=J3(n.unexpected);for(let h of r){let o=UWe(h,a);l.push(o),o.recovered&&f++,o.bug&&(i++,o.outcome==="expected"||o.outcome==="flaky"?d--:o.outcome==="unexpected"&&p--)}return{passed:d,failed:p,bug:i,recovered:f,tests:l}}u(rS,"computeReportStats");function UWe(r,n){let a=nS({playwrightTestId:r.playwrightTestId,filePath:r.filePath,title:r.title},n),l=jWe(r),i=HWe(r.annotations),f=oS(r.playwrightTestId,n.playwrightIdToMetadata),d=WWe(a,r,n),p=n.toRelativeFilePath(r.filePath);return{checksumTestId:a,playwrightTestId:r.playwrightTestId,success:r.ok,recovered:f,bug:l,annotations:i,tags:r.tags,outcome:r.outcome,variantKey:W3(r.filePath,r.titlePath,r.title),...r.filePath!==void 0?{filePath:r.filePath}:{},...p!==void 0?{relativeFilePath:p}:{},...r.projectName?{project:r.projectName}:{},...r.errorMessage?{errorMessage:r.errorMessage}:{},...d!==void 0?{usingChecksumTestIdPlaceholder:d}:{}}}u(UWe,"rowToTestWithMetadata");function pce(r,n){let a=r.files,l=u(p=>{let o=nS({playwrightTestId:p.testId,filePath:p.location.file,title:p.title},n)??`${p.location.file}::${p.title}`,c=W3(p.location.file,p.path??[],p.title);return`${o}::${p.projectName}::${c}`},"keyFor"),i=new Map;for(let p of a)for(let h of p.tests)i.set(l(h),h);let f=new Set(i.values()),d={total:0,expected:0,unexpected:0,flaky:0,skipped:0};for(let p of a){p.tests=p.tests.filter(h=>f.has(h));for(let h of p.tests)d.total++,h.outcome==="expected"?d.expected++:h.outcome==="unexpected"?d.unexpected++:h.outcome==="flaky"?d.flaky++:d.skipped++}r.files=a.filter(p=>p.tests.length>0),r.stats={...r.stats,...d}}u(pce,"dedupeReportByChecksumTestId");var jWe=u(r=>r.tags.includes("bug")||r.annotations.some(n=>n.type==="bug")||r.title.includes("@bug"),"detectBug"),HWe=u(r=>r.filter(n=>!!n?.type).map(n=>({type:n.type,description:n.description||""})),"normalizeAnnotations"),WWe=u((r,n,a)=>{if(a.checksumTestIdToUsingPlaceholder)return a.pwTestIdToChecksumTestId[n.playwrightTestId]&&a.checksumTestIdToUsingPlaceholder[r]||!1},"computeUsingPlaceholder");var q3=u((r,n,a)=>{if(!r)return;let l=a||n,i;if((0,ap.isAbsolute)(r))i=r;else{let f=(0,ap.dirname)(n);i=(0,ap.resolve)(f,r)}return i.replace(l+"/","")},"toRelativeFilePath"),hce=u(r=>{let n=[];if(r.specs&&n.push(...r.specs),r.suites)for(let a of r.suites)n.push(...hce(a));return n},"extractSpecsFromSuite"),$We=u(r=>{let n=[];for(let a of r.suites)n.push(...hce(a));return n},"extractFlatSpecsMap"),GWe=u(r=>{let n=[],a=u((l,i)=>{for(let f of l.specs){let d=f.tests[0];n.push({playwrightTestId:f.id,ok:f.ok,outcome:d?.status??"skipped",title:f.title,titlePath:i,filePath:f.file,tags:f.tags,annotations:d?.annotations??[]})}for(let f of l.suites??[])a(f,[...i,f.title])},"walk");for(let l of r.suites)a(l,[]);return n},"jsonReportToRows"),JWe=u((r,n,a,l,i)=>(qWe(r,n),rS(GWe(r),r.stats,{pwTestIdToChecksumTestId:a,playwrightIdToMetadata:n,toRelativeFilePath:u(f=>l?q3(f,l,i):f,"toRelativeFilePath")})),"modifyStatsPerTestFile"),qWe=u((r,n)=>{for(let a of $We(r))oS(a.id,n)&&(a.recovered=!0)},"markRecoveredSpecs"),gce=u((r,n,a,l,i)=>{(0,ip.cpSync)(r,r+".backup");try{let f=JSON.parse((0,ip.readFileSync)(r,"utf-8")),d=JWe(f,n,a,l,i);return f.checksumMetadata=d,(0,ip.writeFileSync)(r,JSON.stringify(f,null,2)),f}catch(f){return console.error("Error processing JSON report",f.message),null}},"processJSONReport");var Pa,ZA=!1,Ace=!1,VWe=u(r=>{if(!Pa||ZA)return;ZA=!0;let n={...Pa,exit_code:r,duration_ms:Date.now()-Pa._startedAtMs};if(delete n._startedAtMs,!!Dv())try{nf({severity:Rv(n),message:`cli ${n.command} exit=${r} ${n.duration_ms}ms`,...n})}catch(a){try{Bv(`[wide-event] cli emit failed: ${String(a)}`)}catch{}}},"emitCliInvocation"),yce=u(r=>{Pa={timestamp:new Date().toISOString(),_startedAtMs:Date.now(),kind:"cli_invocation",command:r,pid:process.pid,node_version:process.version,platform:process.platform,ci:process.env.CI==="true"||process.env.CI==="1"},ZA=!1,Ace||(Ace=!0,process.on("exit",VWe),process.on("uncaughtException",n=>{throw Pa&&!ZA&&(Pa.error={type:n.name,message:n.message,source:"uncaughtException"}),n}),process.on("unhandledRejection",n=>{if(Pa&&!ZA){let a=n instanceof Error?n:new Error(String(n));Pa.error={type:a.name,message:a.message,source:"unhandledRejection"}}}))},"startCliInvocation"),cp=u(()=>Pa,"getCliInvocation");var iS=u(r=>(re("Using report folder",r),(0,bt.join)(r,"index.html")),"makeFilePath"),mce=u(r=>(re("Using JSON report folder",r),(0,bt.join)(r,"report.json")),"makeJsonFilePath"),V3=u(r=>{let n=["B","KB","MB","GB"],a=r,l=0;for(;a>=1024&&l<n.length-1;)a/=1024,l++;return`${l===0?a:a.toFixed(1)} ${n[l]}`},"formatBytes"),XA=class r extends fn{constructor(a,l=!1){super(a,l);this.MAX_COMPLETION_WAIT=jg(process.env).cliHardCapMs;this.testSuiteRunId="";this.didFail=!1;this.reportUploadFailed=!1;this.isolationMode=!1;this.isUploadReportMode=!1;this.dedupeByChecksumTestId=!1;this.reportUploadSucceeded=!1;this.trmMessagesBuffer="";this.completeIndicators={upload:!1,tests:!1,report:!1};this.uploadProgress=0;this.playwrightIdToReportMetadata={};this.pwTestIdToChecksumTestId={};this.logFilter={"upload-progress":{logEveryMS:1e3*30,lastLogTimestamp:0,logOnValueChange:!0,value:""}}}static{u(this,"TestsRunner")}get replMode(){return this.getChecksumArg("repl")??!1}get listMode(){return this.args.includes("--list")}getTestSuiteRunInfo(){if(!this.testSuiteRunInfo)throw new Error("Test suite run info is not initialized");return this.testSuiteRunInfo}getTestRunMonitorProcess(){if(!this.testRunMonitorProcess)throw new Error("Test run monitor process is not initialized");return this.testRunMonitorProcess}getConfig(){if(!this.config)throw new Error("Checksum config is not initialized");return this.config}getConfigOptions(){let a=this.getConfig().options;if(!a)throw new Error("Checksum config options are not initialized");return a}async run(){this.loadTracer(),this.validateAuthExists(),this.buildVolatileChecksumConfig();let a=cp();if(a&&(a.shard_mode=process.env.CHECKSUM_SHARD_MODE==="true",a.list_mode=this.listMode,a.repl_mode=!!this.replMode,a.isolation_mode=!!this.isolationMode,a.runtime_version=this.checksumRuntimeVersion,a.app_name=this.config?.appName??null,a.env_override_name=process.env.CHECKSUM_RUNTIME_ENV_OVERRIDE_NAME??null,a.env_override_role=process.env.CHECKSUM_RUNTIME_ENV_OVERRIDE_ROLE??null),process.env.CHECKSUM_SHARD_MODE==="true"){await this.runShardMode();return}if(this.listMode){await this.runListMode();return}if(!await this.getSession())return;a&&(a.test_suite_run_id=this.testSuiteRunId),this.testSuiteAnalytics=zA.getInstance(this.getTestSuiteRunInfo(),this.isolationMode),this.testSuiteAnalytics.genericEvent(`Project root found at ${this.projectRootDirectory}`,{message:`Checksum root found at ${this.checksumRoot}`});let l={CHECKSUM_ROOT_FOLDER:this.checksumRoot,CHECKSUM_TEST_SUITE_INFO:JSON.stringify(this.getTestSuiteRunInfo())},i;try{i=await Ye(this.startTestRunMonitor(this.testSuiteRunId),1e4,"test run monitor timeout"),l.CHECKSUM_UPLOAD_AGENT_PORT=i}catch{let s="Error starting test run monitor. Test results will not be available on checksum.";this.testSuiteAnalytics.testRunMonitorError({error:s}),this.log(s)}l.PW_TEST_HTML_REPORT_OPEN="never",this.isolationMode&&(l.CHECKSUM_ISOLATED_MODE="true"),this.testSuiteRunId&&(l.CHECKSUM_TEST_SUITE_ID=this.testSuiteRunId),this.replMode&&(l.CHECKSUM_REPL="true"),this.getChecksumArg("tm")&&(l.CHECKSUM_SHOW_TIME_MACHINE="true");let f=this.getNonChecksumArgs(),d=this.getChecksumArg("rerun-failed"),p=ice({args:this.args,env:process.env});if(p.kind==="enabled"&&d){this.printError("--cksm-affected cannot be combined with --cksm-rerun-failed."),await this.shutdown(1);return}if(d)try{let s=await this.fetchFailedTestPaths(typeof d=="string"?d:void 0);if(s.length===0){console.log("No non-passing tests found \u2014 nothing to rerun."),await this.shutdown(0);return}console.log(`Re-running ${s.length} non-passing test file(s)`),f.unshift(...s)}catch(s){this.printError(`Failed to fetch failed tests: ${s.message}`),await this.shutdown(1);return}if(p.kind==="enabled"){if(f.some(g=>g==="--grep"||g==="-g"||g.startsWith("--grep=")||g.startsWith("-g="))){this.printError("--cksm-affected cannot be combined with a manual --grep argument."),await this.shutdown(1);return}try{let g=await cce(p.baseRef,b=>this.getCmdOutput(b));if(g.length===0){console.log("No changed files detected for --cksm-affected \u2014 nothing to run."),await this.shutdown(0);return}let A=await this.fetchAffectedTestIds(g);if(A.length===0){console.log("No tests affected by the current changes \u2014 nothing to run."),await this.shutdown(0);return}let m=`(${A.sort().map(b=>b.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")).join("|")})`;if(p.dryRun){console.log("[--cksm-affected-dry-run] "+JSON.stringify({baseRef:p.baseRef??null,changedFiles:g,affectedTestIds:A,playwrightArg:`--grep=${m}`},null,2)),await this.shutdown(0);return}console.log(`Running ${A.length} affected test(s) from ${g.length} changed file(s)`),f.push(`--grep=${m}`)}catch(g){this.printError(`Failed to determine affected tests: ${g.message}`),await this.shutdown(1);return}}this.replMode&&f.push("--debug");let h=this.isolationMode||this.replMode?this.getPlaywrightConfigFilePath():this.buildRunPlaywrightConfig(),o=f,c=process.env[j3];if(c){let s=nce(f,c);o=s.args,s.jsonOutputName&&(l.PLAYWRIGHT_JSON_OUTPUT_NAME=s.jsonOutputName)}let e=process.env[H3];e&&(o=ece(o),l.PLAYWRIGHT_BLOB_OUTPUT_FILE=(0,bt.join)(e,`blob-${Date.now()}-${(0,aS.randomUUID)().slice(0,8)}.zip`));let t=["test","--config",h,...o];await this.patchPlaywright();try{console.log(`Tests running with @checksum-ai/runtime version ${this.checksumRuntimeVersion}`),this.replMode?(console.log("Running in REPL mode"),this.runPlaywright(t,l),await this.execFile("node",[`${__dirname}/repl.js`],l)):(this.testSuiteAnalytics.testSuiteStart(),await this.runPlaywright(t,l)),console.log(`Tests execution finished. Checksum is finalizing${this.isolationMode?"":" and uploading"} the report, please wait...`)}catch{this.didFail=!0,console.log("Error during test execution: Failed passing test"),this.testSuiteAnalytics.testsFailed()}finally{this.isolationMode||console.log("Waiting for test files to upload to Checksum..."),await this.sendReportUploadRequest(),await this.patchPlaywright(!0),this.completeIndicators.tests=!0,await this.handleCompleteMessage()}}async runShardMode(){console.log(`[shard-mode] Running shard ${process.env.SHARD_INDEX}/${process.env.SHARD_TOTAL} (batch: ${process.env.BATCH_ID})`);let a=this.getNonChecksumArgs(),l=process.env.SHARD_INDEX,i=process.env.SHARD_TOTAL;l&&i&&a.push(`--shard=${l}/${i}`),a.push("--reporter=blob,line");let f={CHECKSUM_ROOT_FOLDER:this.checksumRoot,PW_TEST_HTML_REPORT_OPEN:"never"},d=["test","--config",this.getPlaywrightConfigFilePath(),...a];await this.patchPlaywright();let p=Xi("shard_run",{runtime_version:this.checksumRuntimeVersion,shard_index:process.env.SHARD_INDEX,shard_total:process.env.SHARD_TOTAL,batch_id:process.env.BATCH_ID}),h=0;try{console.log(`[shard-mode] Tests running with @checksum-ai/runtime version ${this.checksumRuntimeVersion}`),await this.runPlaywright(d,f),console.log("[shard-mode] Tests execution finished.")}catch{h=1,console.log("[shard-mode] Tests finished with failures.")}finally{await this.patchPlaywright(!0)}p.emit({outcome:h===0?"success":"error",exit_code:h}),process.exitCode=h}async runListMode(){let a=this.getNonChecksumArgs(),l={CHECKSUM_ROOT_FOLDER:this.checksumRoot,PW_TEST_HTML_REPORT_OPEN:"never"},i=["test","--config",this.getPlaywrightConfigFilePath(),...a];await this.patchPlaywright();let f=0;try{await this.runPlaywright(i,l)}catch{f=1}finally{await this.patchPlaywright(!0)}process.exitCode=f}async uploadReport(){this.loadTracer(),this.validateAuthExists(),this.buildVolatileChecksumConfig(),this.isUploadReportMode=!0,this.getConfigOptions().hostReports=!0,this.tryLoadPlaywrightConfigFromFile(),this.loadPlaywrightConfigOptions();let a=this.resolveUserReportPathArg();a&&this.playwrightConfigOptions&&(this.playwrightConfigOptions.reportPath=a);let l=this.getChecksumArg("merge-blobs");if(l){let f=await this.mergeBlobArchive(l);if(!f){await this.shutdown(1);return}this.playwrightConfigOptions&&(this.playwrightConfigOptions.reportPath=f,this.playwrightConfigOptions.hasJsonReporter=!1),this.dedupeByChecksumTestId=!0}let i=this.playwrightConfigOptions?.reportPath;if(!i||!(0,Qt.existsSync)(i)){this.printError(`Could not find report at ${i??"(unresolved)"}. Pass an explicit path: npx checksumai upload-report <path>`),await this.shutdown(1);return}if(await this.getSession()){this.testSuiteAnalytics=zA.getInstance(this.getTestSuiteRunInfo(),this.isolationMode);try{await Ye(this.startTestRunMonitor(this.testSuiteRunId),1e4,"test run monitor timeout")}catch(f){this.printError(`Failed to start test run monitor: ${f.message}. Report will not be uploaded.`),await this.shutdown(1);return}console.log(`Uploading report from ${i} to Checksum...`),await this.sendReportUploadRequest(),this.completeIndicators.tests=!0,await this.handleCompleteMessage()}}async mergeBlobArchive(a){let l=(0,bt.isAbsolute)(a)?a:(0,bt.resolve)(this.absoluteProjectRootDirectory,a);if(((0,Qt.existsSync)(l)?(0,Qt.readdirSync)(l).filter(p=>p.endsWith(".zip")):[]).length===0)return this.printError(`No blob reports found in ${l}`),null;let f=(0,bt.join)(this.getInternalFilesDirPath(),"merged-report");(0,Qt.mkdirSync)(f,{recursive:!0});try{await this.runMergeReportsPatched(l,f)}catch(p){return this.printError(`merge-reports failed: ${p.message}`),null}let d=(0,bt.join)(f,"index.html");return(0,Qt.existsSync)(d)?d:(this.printError(`Merged report not found at ${d}`),null)}tryLoadPlaywrightConfigFromFile(){if(!this.playwrightConfig)try{let a=this.getPlaywrightConfigFilePath();if((0,Qt.existsSync)(a)){let l=(0,bce.createRequire)(__filename)(a),i=l?.default??l;i&&(this.playwrightConfig=i)}}catch(a){re("Could not load playwright config from file, falling back to defaults: "+a.message)}}resolveUserReportPathArg(){let a=this.args.find(i=>!i.startsWith("-")&&!i.includes("="));if(!a)return;let l=(0,bt.isAbsolute)(a)?a:(0,bt.resolve)(process.cwd(),a);if(!(0,Qt.existsSync)(l))return l;try{if((0,Qt.statSync)(l).isDirectory())return(0,bt.join)(l,"index.html")}catch{}return l}loadPlaywrightConfigOptions(){let a="",l="",i=!1,f="never";process.env.PLAYWRIGHT_HTML_OUTPUT_DIR&&(a=iS(process.env.PLAYWRIGHT_HTML_OUTPUT_DIR));let d=this.playwrightConfig?.reporter;if(d instanceof Array){let p=d.filter(c=>c instanceof Array&&c[0]==="html"),h=d.filter(c=>c instanceof Array&&c[0]==="json");if(!process.env.PLAYWRIGHT_HTML_OUTPUT_DIR){let c=p.find(e=>e[1]?.outputFolder);c&&(a=iS((0,bt.join)(this.checksumRoot,c[1].outputFolder)))}let o=h.find(c=>c[1]?.outputFile);o&&(i=!0,l=(0,bt.join)(this.checksumRoot,o[1].outputFile));for(let c of p){let e=c[1]?.open;if(e==="always"||e==="on-failure"){f=e;break}}}a||(de.isRepoMode?a=iS((0,bt.join)(de.runtimeRoot,"playwright-report")):a=iS((0,bt.join)(this.projectRootDirectory,"playwright-report"))),l||(de.isRepoMode?l=mce((0,bt.join)(de.runtimeRoot,"playwright-report")):l=mce((0,bt.join)(this.projectRootDirectory,"playwright-report"))),this.playwrightConfigOptions={openReportCriteria:f,reportPath:a,jsonReportPath:l,hasJsonReporter:i}}async sendReportUploadRequest(){let a=u(async c=>{this.testSuiteAnalytics?.testSuiteError({error:c}),this.log(c),this.reportUploadFailed=!0,this.completeIndicators.report=!0,this.getTestRunMonitorProcess().stdin.write("cli:report=false"),await this.sendProcessingError(this.buildProcessErrorPayload({stage:"report-upload",reason:"Required Playwright HTML report could not be produced for upload",reportUploaded:!1,evidence:{detail:c}}))},"makeError");if(!this.playwrightConfigOptions){await a("No playwright config options");return}let{reportPath:l,openReportCriteria:i,jsonReportPath:f,hasJsonReporter:d}=this.playwrightConfigOptions;if(d&&f!==void 0&&((0,Qt.existsSync)(f)?gce(f,this.playwrightIdToReportMetadata,this.pwTestIdToChecksumTestId,this.checksumRoot,this.absoluteProjectRootDirectory):console.warn(`Could not find JSON report file at ${f}`)),!(0,Qt.existsSync)(l)){await a(`Could not find report file at ${l}`);return}re("Sending report upload request",l);let p=this.saveMetadataToFile((0,bt.dirname)(l)),h={reportPath:l,pathToChecksumMetadata:p,openReportCriteria:i,didFail:this.didFail,checksumRoot:this.checksumRoot,projectRoot:this.absoluteProjectRootDirectory,isUploadReport:this.isUploadReportMode,dedupeByChecksumTestId:this.dedupeByChecksumTestId},o=Buffer.from(JSON.stringify(h)).toString("base64");this.getTestRunMonitorProcess().stdin.write(`cli:report=${o}`)}saveMetadataToFile(a){try{let l=(0,bt.join)(a,`checksum-metadata-${(0,aS.randomUUID)()}.json`);return(0,Qt.writeFileSync)(l,JSON.stringify(this.playwrightIdToReportMetadata,null,2)),l}catch(l){let i=`Error saving metadata to file - ${l.message}`;this.testSuiteAnalytics?.testSuiteError({error:i}),this.log(i);return}}startTestMonitorProcess(a){let i=[JSON.stringify({sessionId:a,apiURL:this.getConfig().apiURL,apiKey:this.getConfig().apiKey}),...this.isolationMode?["isolated"]:[]],f={command:"node",args:[(0,bt.join)(__dirname,"test-run-monitor.js"),...i]};return de.isRepoMode&&(f.command="yarn",f.args=["test-run-monitor",...i]),vce.spawn(f.command,f.args)}startTestRunMonitor(a){return new Promise(l=>{console.log("Starting test run monitor");let i=this.startTestMonitorProcess(a);this.testRunMonitorProcess=i,i.stdout.on("data",f=>{let d=this.parseTRMMessages(f.toString().trim());if(d.length)for(let p of d){if(p.startsWith("trace")){this.logTRMMessage(p),this.handleTestRunMonitorTrace(p.substring("trace".length+1));continue}if(p.startsWith("wideevent")){this.reEmitMonitorWideEvent(p.substring("wideevent".length+1));continue}if(!p.startsWith("monitor")){this.logTRMMessage(p);continue}let h=u(()=>{let t=p.substring("monitor".length+1),s=t.indexOf("=");if(s===-1)return{key:t,value:""};let[g,A]=[t.substring(0,s),t.substring(s+1)];return{key:g,value:A}},"getKeyAndValue"),{key:o,value:c}=h();if(!Object.values(vx).includes(o)){this.logTRMMessage(`Received unknown monitor message: "${p}"`);continue}let e=o;this.logInterProcessEventMessage(e,c),o==="port"?l(c):this.handleTestRunMonitorMessage(e,c)}}),i.on("exit",(f,d)=>{let p=`test run monitor process exited with code ${f} and signal ${d}`;this.testSuiteAnalytics?.testRunMonitorError({error:p}),this.log(p)}),i.stderr.on("data",f=>{let d=`TRM Error: ${f.toString().substring(0,300)}`;this.testSuiteAnalytics?.testRunMonitorError({error:d}),this.log(d)}),i.on("error",f=>{let d=`Error starting test run monitor: ${f.message}`;this.testSuiteAnalytics?.testRunMonitorError({error:d}),this.log(d)})})}logInterProcessEventMessage(a,l){u(()=>{let f=this.logFilter[a];if(!f)return!0;if(f.logOnValueChange&&f.value!==l)return f.value=l,!0;if(f.logEveryMS){let d=Date.now();if(d-f.lastLogTimestamp>=f.logEveryMS)return f.lastLogTimestamp=d,!0}return!1},"shouldLog")()&&this.logTRMMessage(`Received monitor message: "${a}${l?`=${l}`:""}"`)}parseTRMMessages(a){let l=this.trmMessagesBuffer+a,i=-1,f=-1,d=u(()=>{i=l.indexOf("{trm}"),f=l.indexOf("{/trm}")},"findIndexes");d();let p=[];for(;i!==-1&&f!==-1&&f>i;){if(p.push(l.substring(i+"{trm}".length,f)),l=l.slice(f+"{/trm}".length).trim(),l.length&&!l.startsWith("{trm}"))return console.warn("Buffered data does not start with start delimiter",l),this.trmMessagesBuffer="",p;this.trmMessagesBuffer=l,d()}return p}setChecksumTestMetadata(a){let{retry:l,type:i,pwTestId:f,checksumTestId:d}=a;this.playwrightIdToReportMetadata[f]??={};let p=this.playwrightIdToReportMetadata[f][l]??={};switch(i){case"autoRecoveryMetadata":p.autoRecoveryMetadata=a;break;case"autoRecoverySummaries":p.autoRecoverySummaries=a;break}this.pwTestIdToChecksumTestId[f]=d}handleTestRunMonitorTrace(a){let l=a.indexOf("="),[i,f]=l>-1?[a.substring(0,l),a.substring(l+1)]:[a,""];if(!Object.values(ZO).includes(i)){re("Unknown trace event",i);return}try{let d=f?JSON.parse(f):{};switch(i){case"Upload Start":this.testSuiteAnalytics?.uploadStart({filename:d.filename});break;case"Upload Complete":this.testSuiteAnalytics?.uploadComplete({filename:d.filename});break;case"Upload Failed":this.testSuiteAnalytics?.uploadFailed({filename:d.filename,error:d.error??""});break;case"Trace Processing Error":this.testSuiteAnalytics?.traceProcessingError({error:d.error??""});break}}catch(d){re(`Error parsing trace payload, ${d.message}`)}}logAbandonedAssets(a){let{abandonedAssets:l,finalizeReason:i}=a??{};if(!(!Array.isArray(l)||l.length===0)){(i==="budget"||i==="budget-ceiling")&&this.log("Uploads did not finish within the allotted time. Raise CHECKSUM_RUNTIME_UPLOAD_FINALIZE_BUDGET_MS to allow longer."),this.log(`Artifacts not uploaded (${l.length}):`);for(let f of l){let d=f??{},p=typeof d.file_name=="string"?d.file_name:"unknown",h=typeof d.committed_bytes=="number"&&d.committed_bytes>0?d.committed_bytes:typeof d.loaded_bytes=="number"?d.loaded_bytes:0,o=typeof d.size_bytes=="number"?d.size_bytes:void 0;this.log(o!==void 0&&o>0?` - ${p} (${V3(h)} of ${V3(o)})`:` - ${p} (${V3(h)} sent)`)}}}async handleTestRunMonitorMessage(a,l){switch(a){case"uploads-complete-with-errors":this.log("Error uploading test files to Checksum");try{let i=JSON.parse(l);this.logAbandonedAssets(i),this.testSuiteAnalytics?.uploadsCompleteWithErrors(i);let f=cp();f&&(f.uploads_outcome="complete_with_errors",f.uploads_errored=Array.isArray(i.uploadErrors)?i.uploadErrors.length:void 0)}catch{}this.completeIndicators.upload=!0;break;case"checksumTestMetadata":try{let i=JSON.parse(l);this.setChecksumTestMetadata(i)}catch(i){let f=`Error parsing test metadata event - ${i.message}`;this.testSuiteAnalytics?.testSuiteError({error:f}),this.log(f)}break;case"uploads-complete":this.isolationMode||console.log("Test files uploaded successfully"),this.testSuiteAnalytics?.allUploadsComplete();{let i=cp();i&&(i.uploads_outcome="complete",i.uploads_errored=0)}this.sendUploadsComplete().then(()=>{this.completeIndicators.upload=!0});break;case"report-complete":{let i=l.slice(0,l.indexOf(":"))==="true",f=l.slice(l.indexOf(":")+1),d="{}",p=!1;try{if(f&&(0,Qt.existsSync)(f)){d=(0,Qt.readFileSync)(f,"utf-8"),p=!0;try{(0,Qt.unlinkSync)(f)}catch{console.warn(`Failed to delete temporary stats file: ${f}`)}}else console.warn(`Stats file not found at: ${f}`)}catch(s){console.error(`Error reading stats file: ${s.message}`)}let{stats:h,statsParsed:o}=this.handleStats(d);if(this.skippedTests=Yae(p&&o?h:void 0),this.isolationMode){this.completeIndicators.report=!0;break}this.testSuiteAnalytics?.testSuiteEnd({passed:h.passed,failed:h.failed,bug:h.bug,total:h.tests?.length||0});let c=cp();c&&(c.tests_total=h.tests?.length??0,c.tests_passed=h.passed,c.tests_failed=h.failed,c.tests_bug=h.bug,c.tests_recovered=h.recovered);let e=i?void 0:this.buildReportUploadProcessErrorPayload(h,f),t=await this.sendTestRunEnd(h,i,e);if(this.completeIndicators.report=!0,this.reportUploadSucceeded=i&&t,!t){this.didFail=!0,c&&(c.report_uploaded=!1),this.testSuiteAnalytics?.testSuiteError({error:"Checksum rejected the test run completion update"}),this.log("Checksum rejected the test run completion update",!0),i||await this.handleReportUploadFailure(e);break}if(c&&(c.report_uploaded=i),i){let s=`${this.checksumAppUrl}/#/test-runs/${this.testSuiteRunId}`,g=`Checksum report URL: ${s}`,A="*".repeat(g.length);console.log(`${A}
|
|
444
444
|
${g}
|
package/package.json
CHANGED