assuremind 1.6.0 → 1.6.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/README.md +24 -12
- package/dist/cli/index.js +197 -197
- package/dist/index.d.mts +13 -6
- package/dist/index.d.ts +13 -6
- package/dist/index.js +16 -16
- package/dist/index.mjs +17 -17
- package/docs/GETTING-STARTED.md +13 -2
- package/package.json +1 -1
- package/templates/docs/GETTING-STARTED.md +1 -1
- package/ui/dist/assets/index-BsxznSas.css +1 -0
- package/ui/dist/assets/index-DdWg6Y6w.js +1032 -0
- package/ui/dist/index.html +2 -2
- package/ui/dist/assets/index-6jqOR-Hh.js +0 -1029
- package/ui/dist/assets/index-BGDCUDyt.css +0 -1
package/dist/index.d.mts
CHANGED
|
@@ -2344,6 +2344,8 @@ declare const RunResultSchema: z.ZodObject<{
|
|
|
2344
2344
|
passed: z.ZodNumber;
|
|
2345
2345
|
failed: z.ZodNumber;
|
|
2346
2346
|
skipped: z.ZodNumber;
|
|
2347
|
+
/** Number of auto-healed steps in this run that are pending review/approval. */
|
|
2348
|
+
healed: z.ZodOptional<z.ZodNumber>;
|
|
2347
2349
|
logFilePath: z.ZodOptional<z.ZodString>;
|
|
2348
2350
|
}, "strip", z.ZodTypeAny, {
|
|
2349
2351
|
status: "pending" | "running" | "passed" | "failed" | "skipped";
|
|
@@ -2439,6 +2441,7 @@ declare const RunResultSchema: z.ZodObject<{
|
|
|
2439
2441
|
}[];
|
|
2440
2442
|
totalTests: number;
|
|
2441
2443
|
environment?: string | undefined;
|
|
2444
|
+
healed?: number | undefined;
|
|
2442
2445
|
logFilePath?: string | undefined;
|
|
2443
2446
|
}, {
|
|
2444
2447
|
status: "pending" | "running" | "passed" | "failed" | "skipped";
|
|
@@ -2534,6 +2537,7 @@ declare const RunResultSchema: z.ZodObject<{
|
|
|
2534
2537
|
}[];
|
|
2535
2538
|
totalTests: number;
|
|
2536
2539
|
environment?: string | undefined;
|
|
2540
|
+
healed?: number | undefined;
|
|
2537
2541
|
logFilePath?: string | undefined;
|
|
2538
2542
|
}>;
|
|
2539
2543
|
type StepResult = z.infer<typeof StepResultSchema>;
|
|
@@ -2972,13 +2976,16 @@ declare function readEnvVariables(rootDir: string, env: string): Promise<Variabl
|
|
|
2972
2976
|
* Merges global + env-specific variables, resolving all values to strings.
|
|
2973
2977
|
*
|
|
2974
2978
|
* Resolution priority (highest wins):
|
|
2975
|
-
* 1. process.env[
|
|
2976
|
-
* 2. <env>.env.json
|
|
2977
|
-
* 3. global.json
|
|
2979
|
+
* 1. process.env[AM_KEY] — CI/CD secrets prefixed with AM_ override stored values
|
|
2980
|
+
* 2. <env>.env.json — environment-specific value
|
|
2981
|
+
* 3. global.json — default value
|
|
2978
2982
|
*
|
|
2979
|
-
*
|
|
2980
|
-
*
|
|
2981
|
-
*
|
|
2983
|
+
* The AM_ prefix prevents accidental collisions with OS/shell env vars such as
|
|
2984
|
+
* USERNAME, HOME, PATH, PORT, USER that exist on every machine. Without the
|
|
2985
|
+
* prefix, {{USERNAME}} would always resolve to the OS login name, not the
|
|
2986
|
+
* stored value.
|
|
2987
|
+
*
|
|
2988
|
+
* In CI/CD: set AM_MY_VAR=secret to override {{MY_VAR}} at runtime.
|
|
2982
2989
|
*
|
|
2983
2990
|
* Secrets are resolved to their plain values (never sent to AI — caller must redact).
|
|
2984
2991
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -2344,6 +2344,8 @@ declare const RunResultSchema: z.ZodObject<{
|
|
|
2344
2344
|
passed: z.ZodNumber;
|
|
2345
2345
|
failed: z.ZodNumber;
|
|
2346
2346
|
skipped: z.ZodNumber;
|
|
2347
|
+
/** Number of auto-healed steps in this run that are pending review/approval. */
|
|
2348
|
+
healed: z.ZodOptional<z.ZodNumber>;
|
|
2347
2349
|
logFilePath: z.ZodOptional<z.ZodString>;
|
|
2348
2350
|
}, "strip", z.ZodTypeAny, {
|
|
2349
2351
|
status: "pending" | "running" | "passed" | "failed" | "skipped";
|
|
@@ -2439,6 +2441,7 @@ declare const RunResultSchema: z.ZodObject<{
|
|
|
2439
2441
|
}[];
|
|
2440
2442
|
totalTests: number;
|
|
2441
2443
|
environment?: string | undefined;
|
|
2444
|
+
healed?: number | undefined;
|
|
2442
2445
|
logFilePath?: string | undefined;
|
|
2443
2446
|
}, {
|
|
2444
2447
|
status: "pending" | "running" | "passed" | "failed" | "skipped";
|
|
@@ -2534,6 +2537,7 @@ declare const RunResultSchema: z.ZodObject<{
|
|
|
2534
2537
|
}[];
|
|
2535
2538
|
totalTests: number;
|
|
2536
2539
|
environment?: string | undefined;
|
|
2540
|
+
healed?: number | undefined;
|
|
2537
2541
|
logFilePath?: string | undefined;
|
|
2538
2542
|
}>;
|
|
2539
2543
|
type StepResult = z.infer<typeof StepResultSchema>;
|
|
@@ -2972,13 +2976,16 @@ declare function readEnvVariables(rootDir: string, env: string): Promise<Variabl
|
|
|
2972
2976
|
* Merges global + env-specific variables, resolving all values to strings.
|
|
2973
2977
|
*
|
|
2974
2978
|
* Resolution priority (highest wins):
|
|
2975
|
-
* 1. process.env[
|
|
2976
|
-
* 2. <env>.env.json
|
|
2977
|
-
* 3. global.json
|
|
2979
|
+
* 1. process.env[AM_KEY] — CI/CD secrets prefixed with AM_ override stored values
|
|
2980
|
+
* 2. <env>.env.json — environment-specific value
|
|
2981
|
+
* 3. global.json — default value
|
|
2978
2982
|
*
|
|
2979
|
-
*
|
|
2980
|
-
*
|
|
2981
|
-
*
|
|
2983
|
+
* The AM_ prefix prevents accidental collisions with OS/shell env vars such as
|
|
2984
|
+
* USERNAME, HOME, PATH, PORT, USER that exist on every machine. Without the
|
|
2985
|
+
* prefix, {{USERNAME}} would always resolve to the OS login name, not the
|
|
2986
|
+
* stored value.
|
|
2987
|
+
*
|
|
2988
|
+
* In CI/CD: set AM_MY_VAR=secret to override {{MY_VAR}} at runtime.
|
|
2982
2989
|
*
|
|
2983
2990
|
* Secrets are resolved to their plain values (never sent to AI — caller must redact).
|
|
2984
2991
|
*/
|
package/dist/index.js
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
"use strict";var Gt=Object.create;var Y=Object.defineProperty;var Mt=Object.getOwnPropertyDescriptor;var Bt=Object.getOwnPropertyNames;var Wt=Object.getPrototypeOf,Jt=Object.prototype.hasOwnProperty;var Kt=(e,t)=>{for(var n in t)Y(e,n,{get:t[n],enumerable:!0})},De=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of Bt(t))!Jt.call(e,i)&&i!==n&&Y(e,i,{get:()=>t[i],enumerable:!(r=Mt(t,i))||r.enumerable});return e};var h=(e,t,n)=>(n=e!=null?Gt(Wt(e)):{},De(t||!e||!e.__esModule?Y(n,"default",{value:e,enumerable:!0}):n,e)),Yt=e=>De(Y({},"__esModule",{value:!0}),e);var Yn={};Kt(Yn,{AssuremindError:()=>v,ConfigError:()=>T,ExecutionError:()=>Z,HealingError:()=>Q,ProviderError:()=>X,StorageError:()=>g,ValidationError:()=>p,acceptHealingEvent:()=>Ct,appendPendingEvent:()=>Pt,callFaker:()=>kt,clearEnvCache:()=>Ft,configExists:()=>gt,createCase:()=>nt,createChildLogger:()=>b,createSuite:()=>qe,defineConfig:()=>Kn,deleteCase:()=>it,deleteGlobalVariable:()=>mt,deleteResult:()=>yt,deleteSuite:()=>Ze,formatError:()=>Ge,generateCacheKey:()=>Lt,getAvailableGenerators:()=>Ut,getCasePath:()=>ot,getHealingStats:()=>Nt,isAssuremindError:()=>ke,listCasePaths:()=>ye,listCases:()=>at,listHealingReportIds:()=>$t,listResultIds:()=>Oe,listResults:()=>St,listSuiteDirs:()=>ne,listSuites:()=>Qe,listSuitesWithCounts:()=>et,listVariableFiles:()=>ut,logger:()=>xe,normalizeUrl:()=>Ve,pruneResolvedEvents:()=>Ot,readCase:()=>ae,readConfig:()=>le,readEnvVariables:()=>Ae,readGlobalVariables:()=>ve,readHealingReport:()=>Tt,readPendingEvents:()=>L,readResult:()=>_e,readSuite:()=>G,readVariables:()=>H,redactSecrets:()=>Je,rejectHealingEvent:()=>_t,resolveVariables:()=>ct,sanitizeGeneratedCode:()=>We,screenshotsDir:()=>Et,setGlobalVariable:()=>lt,sha256:()=>$e,toSlug:()=>O,tracesDir:()=>vt,tryGetEnv:()=>zt,updateCase:()=>rt,updateConfig:()=>dt,updateSuite:()=>Xe,validateConfig:()=>ft,validateEnv:()=>Le,videosDir:()=>wt,writeCase:()=>oe,writeConfig:()=>je,writeHealingReport:()=>jt,writeResult:()=>bt,writeSuite:()=>te,writeVariables:()=>se});module.exports=Yt(Yn);var c=require("zod"),qt=c.z.enum(["off","on","only-on-failure"]),Xt=c.z.enum(["off","on","on-first-retry","retain-on-failure"]),Zt=c.z.enum(["off","on","on-first-retry","retain-on-failure"]),He=c.z.enum(["chromium","firefox","webkit"]),Qt=c.z.enum(["commit","domcontentloaded","load","networkidle"]),Fe=c.z.string().min(1),ze=["DEV","TEST","STAGE","INT","PROD"],en=c.z.record(c.z.string(),c.z.string()).default({}),tn=c.z.object({enabled:c.z.boolean(),maxLevel:c.z.number().int().min(1).max(5),dailyBudget:c.z.number().positive(),autoPR:c.z.boolean(),healAssertionLocators:c.z.boolean().default(!1)}),nn=c.z.object({allure:c.z.boolean(),html:c.z.boolean(),json:c.z.boolean()}),rn=c.z.object({width:c.z.number().int().positive(),height:c.z.number().int().positive()}),an=c.z.object({name:c.z.string().min(1),environment:Fe,baseUrl:c.z.string().url(),browsers:c.z.array(He).min(1),headless:c.z.boolean().optional()}),z=c.z.object({baseUrl:c.z.string().url(),environment:Fe.default("DEV"),environments:c.z.array(c.z.string().min(1)).default([...ze]),environmentUrls:en.default({DEV:"",TEST:"",STAGE:"",INT:"",PROD:""}),browsers:c.z.array(He).min(1),headless:c.z.boolean(),viewport:rn.default({width:1280,height:720}),timeout:c.z.number().int().positive(),retries:c.z.number().int().min(0),parallel:c.z.number().int().positive(),pageLoad:Qt.default("domcontentloaded"),screenshot:qt,video:Xt,trace:Zt,healing:tn,reporting:nn,studioPort:c.z.number().int().min(1024).max(65535),profiles:c.z.array(an).default([]),activeProfile:c.z.string().optional(),device:c.z.string().optional(),rag:c.z.object({enabled:c.z.boolean(),codeCorpus:c.z.object({enabled:c.z.boolean(),maxEntries:c.z.number().int().positive(),similarityThreshold:c.z.number().min(0).max(1),directUseThreshold:c.z.number().min(0).max(1)}),healingCorpus:c.z.object({enabled:c.z.boolean(),maxEntries:c.z.number().int().positive(),similarityThreshold:c.z.number().min(0).max(1)}),errorCatalog:c.z.object({enabled:c.z.boolean(),maxEntries:c.z.number().int().positive()}),embedder:c.z.literal("tfidf")}).default({enabled:!0,codeCorpus:{enabled:!0,maxEntries:500,similarityThreshold:.65,directUseThreshold:.9},healingCorpus:{enabled:!0,maxEntries:300,similarityThreshold:.6},errorCatalog:{enabled:!0,maxEntries:200},embedder:"tfidf"}),mcp:c.z.object({enabled:c.z.boolean(),headless:c.z.boolean(),actThenScript:c.z.boolean(),proactiveHealing:c.z.boolean(),actionTimeout:c.z.number().int().positive(),idleTimeout:c.z.number().int().positive()}).default({enabled:!0,headless:!0,actThenScript:!1,proactiveHealing:!1,actionTimeout:15e3,idleTimeout:3e4}),ci:c.z.object({writeToRepo:c.z.boolean()}).default({writeToRepo:!1})}),q={baseUrl:"http://localhost:3000",environment:"DEV",environments:[...ze],environmentUrls:{DEV:"http://localhost:3000",TEST:"",STAGE:"",INT:"",PROD:""},browsers:["chromium"],headless:!0,viewport:{width:1280,height:720},timeout:3e4,retries:1,parallel:1,pageLoad:"domcontentloaded",screenshot:"only-on-failure",video:"off",trace:"on-first-retry",healing:{enabled:!0,maxLevel:5,dailyBudget:5,autoPR:!1,healAssertionLocators:!1},reporting:{allure:!0,html:!0,json:!0},studioPort:4400,profiles:[],rag:{enabled:!0,codeCorpus:{enabled:!0,maxEntries:500,similarityThreshold:.65,directUseThreshold:.9},healingCorpus:{enabled:!0,maxEntries:300,similarityThreshold:.6},errorCatalog:{enabled:!0,maxEntries:200},embedder:"tfidf"},mcp:{enabled:!0,headless:!0,actThenScript:!1,proactiveHealing:!1,actionTimeout:15e3,idleTimeout:3e4},ci:{writeToRepo:!1}};var S=h(require("path")),I=h(require("fs-extra")),Ye=require("uuid");var l=require("zod"),U=l.z.object({id:l.z.string().min(1),order:l.z.number().int().positive(),instruction:l.z.string().min(1),generatedCode:l.z.string(),strategy:l.z.enum(["template","cache","rag","batch","fast","primary","recorder"]),stepType:l.z.enum(["ui","api","mock"]).default("ui"),lastHealed:l.z.string().nullable(),timeout:l.z.number().int().positive().optional(),retries:l.z.number().int().min(0).optional(),mockUrl:l.z.string().optional(),mockResponse:l.z.string().optional(),mockStatus:l.z.number().int().optional(),runAudit:l.z.boolean().optional(),soft:l.z.boolean().optional(),visualCheck:l.z.boolean().optional()}),on=l.z.object({type:l.z.enum(["inline","json-file","csv-file"]),path:l.z.string().optional(),data:l.z.array(l.z.record(l.z.string())).optional()}).optional(),Ue=l.z.object({id:l.z.string(),instruction:l.z.string(),generatedCode:l.z.string().default(""),order:l.z.number().int().default(0)}),sn=l.z.object({before:l.z.array(Ue).default([]),after:l.z.array(Ue).default([])}).default({before:[],after:[]}),ge=l.z.object({id:l.z.string().min(1),name:l.z.string().min(1),description:l.z.string(),tags:l.z.array(l.z.string()),priority:l.z.enum(["critical","high","medium","low"]),timeout:l.z.number().int().positive().optional(),dataSource:on,steps:l.z.array(U),caseHooks:sn,lighthouseCategories:l.z.array(l.z.enum(["performance","accessibility","seo"])).default(["performance","accessibility","seo"]),createdAt:l.z.string().datetime(),updatedAt:l.z.string().datetime()}),fe=l.z.object({id:l.z.string().min(1),name:l.z.string().min(1),description:l.z.string(),tags:l.z.array(l.z.string()),type:l.z.enum(["ui","api","audit","performance"]).default("ui"),timeout:l.z.number().int().positive().optional(),createdAt:l.z.string().datetime(),updatedAt:l.z.string().datetime()}),Qn=l.z.enum(["before_all","before_each","after_each","after_all"]),er=l.z.object({before_all:l.z.array(U).default([]),before_each:l.z.array(U).default([]),after_each:l.z.array(U).default([]),after_all:l.z.array(U).default([])});var v=class extends Error{code;constructor(t,n){super(t),this.name="AssuremindError",this.code=n,Object.setPrototypeOf(this,new.target.prototype)}},X=class extends v{provider;constructor(t,n,r="PROVIDER_ERROR"){super(t,r),this.name="ProviderError",this.provider=n}},Z=class extends v{stepId;constructor(t,n,r="EXECUTION_ERROR"){super(t,r),this.name="ExecutionError",this.stepId=n}},T=class extends v{constructor(t,n="CONFIG_ERROR"){super(t,n),this.name="ConfigError"}},p=class extends v{field;constructor(t,n,r="VALIDATION_ERROR"){super(t,r),this.name="ValidationError",this.field=n}},Q=class extends v{level;constructor(t,n,r="HEALING_ERROR"){super(t,r),this.name="HealingError",this.level=n}},g=class extends v{path;constructor(t,n,r="STORAGE_ERROR"){super(t,r),this.name="StorageError",this.path=n}};function ke(e){return e instanceof v}function Ge(e){return e instanceof v?`[${e.code}] ${e.message}`:e instanceof Error?e.message:String(e)}var he=h(require("pino")),cn=h(require("fs-extra"));var ln=process.env.NODE_ENV!=="production",Me=ln?{target:"pino-pretty",options:{colorize:!0,translateTime:"HH:MM:ss",ignore:"pid,hostname",messageFormat:"[assuremind] {msg}"}}:void 0,xe=(0,he.default)({level:process.env.LOG_LEVEL??"info",base:{name:"assuremind"}},Me?he.default.transport(Me):void 0);function b(e){return xe.child({component:e})}function mn(e){let t=/^```(?:typescript|javascript|ts|js)?\n?([\s\S]*?)```\s*$/m,n=e.match(t);return n?.[1]!==void 0?n[1].trim():e.trim()}var un=[/\brequire\s*\(/,/\bimport\s*\(/,/\bprocess\b/,/\bchild_process\b/,/\bexec\s*\(/,/\bspawn\s*\(/,/\beval\s*\(/,/\bFunction\s*\(/,/\b__dirname\b/,/\b__filename\b/,/\bglobal\b/,/\bwindow\.location\.href\s*=/,/\bdocument\.cookie\b/,/\blocalStorage\b/,/\bsessionStorage\b/,/\bIndexedDB\b/,/\bXMLHttpRequest\b/,/\bfetch\s*\(/,/\bWebSocket\s*\(/];function pn(e){for(let t of un)if(t.test(e))throw new p(`Generated code contains forbidden pattern: ${t.source}. This may be a prompt injection attempt. Please regenerate the step.`,"generatedCode","UNSAFE_CODE")}var dn=/\s+(?:field|input|box|textbox|text\s?box|drop-?\s?down|dropdown|combo\s?box|combobox|menu|selector|element|checkbox|radio\s?button|radio)$/i;function Be(e){let t=e.replace(dn,"").trim();return t.length>0?t:e}function gn(e){let t=e;return t=t.replace(/(getBy(?:Label|Placeholder)\(\s*)(['"`])([\s\S]*?)\2/g,(n,r,i,a)=>`${r}${i}${Be(a)}${i}`),t=t.replace(/(name:\s*)(['"`])([\s\S]*?)\2/g,(n,r,i,a)=>`${r}${i}${Be(a)}${i}`),t}function fn(e){return e.replace(/\blocator\((['"`])([\s\S]*?)\1\)/g,(t,n,r)=>{if(!r.includes(" >> "))return t;let i=r.split(" >> ").map(a=>a.trim()).filter(Boolean);return i.length<2?t:i.map(a=>`locator(${n}${a}${n})`).join(".")})}function hn(e){let t=e;return t=fn(t),t=t.replace(/\.or\((?:[^()]*|\([^()]*\))*\)(?:\.(?:first|last)\(\))?/g,""),t=t.replace(/\.(?:first|last)\(\)(?=\.\w)/g,""),t=gn(t),t}function We(e){let t=mn(e);if(!t)throw new p("AI returned an empty code response. Please try regenerating.","generatedCode","EMPTY_CODE");let n=hn(t);return pn(n),n}function O(e){return e.toLowerCase().trim().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")}function Je(e,t){let n=e;for(let r of t)r.length>0&&(n=n.replaceAll(r,"[REDACTED]"));return n}var be=h(require("path")),R=h(require("fs-extra"));async function x(e,t){let n=be.default.dirname(e);await R.default.ensureDir(n);let r=`${e}.${process.pid}.tmp`;try{await R.default.writeJson(r,t,{spaces:2}),await R.default.rename(r,e)}catch(i){throw await R.default.remove(r).catch(()=>{}),new g(`Failed to write file "${e}": ${i instanceof Error?i.message:String(i)}`,e,"WRITE_FAILED")}}async function E(e){try{return await R.default.readJson(e)}catch(t){throw new g(`Failed to read JSON file "${e}": ${t instanceof Error?t.message:String(t)}`,e,"READ_FAILED")}}async function Ke(e,t){let n=be.default.dirname(e);await R.default.ensureDir(n);let r=`${e}.${process.pid}.tmp`;try{await R.default.writeFile(r,t,"utf8"),await R.default.rename(r,e)}catch(i){throw await R.default.remove(r).catch(()=>{}),new g(`Failed to write file "${e}": ${i instanceof Error?i.message:String(i)}`,e,"WRITE_FAILED")}}var k=b("suite-store"),ee="suite.json";async function G(e){let t=S.default.join(e,ee);if(!await I.default.pathExists(t))throw new g(`Suite file not found at "${t}". Ensure the suite directory exists and contains a suite.json file.`,t,"SUITE_NOT_FOUND");let n=await E(t),r=fe.safeParse(n);if(!r.success){let a=r.error.issues.map(m=>` \u2022 ${m.path.join(".")}: ${m.message}`).join(`
|
|
1
|
+
"use strict";var Bt=Object.create;var X=Object.defineProperty;var Wt=Object.getOwnPropertyDescriptor;var Jt=Object.getOwnPropertyNames;var Kt=Object.getPrototypeOf,Yt=Object.prototype.hasOwnProperty;var Xt=(e,t)=>{for(var n in t)X(e,n,{get:t[n],enumerable:!0})},De=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of Jt(t))!Yt.call(e,i)&&i!==n&&X(e,i,{get:()=>t[i],enumerable:!(r=Wt(t,i))||r.enumerable});return e};var h=(e,t,n)=>(n=e!=null?Bt(Kt(e)):{},De(t||!e||!e.__esModule?X(n,"default",{value:e,enumerable:!0}):n,e)),qt=e=>De(X({},"__esModule",{value:!0}),e);var qn={};Xt(qn,{AssuremindError:()=>v,ConfigError:()=>T,ExecutionError:()=>Q,HealingError:()=>ee,ProviderError:()=>Z,StorageError:()=>g,ValidationError:()=>p,acceptHealingEvent:()=>Ot,appendPendingEvent:()=>_t,callFaker:()=>Mt,clearEnvCache:()=>Ut,configExists:()=>ft,createCase:()=>nt,createChildLogger:()=>b,createSuite:()=>Xe,defineConfig:()=>Xn,deleteCase:()=>it,deleteGlobalVariable:()=>ut,deleteResult:()=>wt,deleteSuite:()=>Ze,formatError:()=>Ge,generateCacheKey:()=>Ht,getAvailableGenerators:()=>Gt,getCasePath:()=>ot,getHealingStats:()=>Vt,isAssuremindError:()=>ke,listCasePaths:()=>ve,listCases:()=>at,listHealingReportIds:()=>Lt,listResultIds:()=>de,listResults:()=>Et,listSuiteDirs:()=>re,listSuites:()=>Qe,listSuitesWithCounts:()=>et,listVariableFiles:()=>pt,logger:()=>ye,normalizeUrl:()=>Ve,pruneResolvedEvents:()=>$t,readCase:()=>oe,readConfig:()=>me,readEnvVariables:()=>je,readGlobalVariables:()=>Ie,readHealingReport:()=>Ct,readPendingEvents:()=>L,readResult:()=>Oe,readSuite:()=>G,readVariables:()=>H,redactSecrets:()=>Je,rejectHealingEvent:()=>Nt,resolveVariables:()=>lt,sanitizeGeneratedCode:()=>We,screenshotsDir:()=>vt,setGlobalVariable:()=>mt,sha256:()=>$e,toSlug:()=>$,tracesDir:()=>Rt,tryGetEnv:()=>kt,updateCase:()=>rt,updateConfig:()=>gt,updateSuite:()=>qe,validateConfig:()=>ht,validateEnv:()=>Le,videosDir:()=>At,writeCase:()=>se,writeConfig:()=>Ce,writeHealingReport:()=>Pt,writeResult:()=>yt,writeSuite:()=>ne,writeVariables:()=>ce});module.exports=qt(qn);var c=require("zod"),Zt=c.z.enum(["off","on","only-on-failure"]),Qt=c.z.enum(["off","on","on-first-retry","retain-on-failure"]),en=c.z.enum(["off","on","on-first-retry","retain-on-failure"]),He=c.z.enum(["chromium","firefox","webkit"]),tn=c.z.enum(["commit","domcontentloaded","load","networkidle"]),Fe=c.z.string().min(1),ze=["DEV","TEST","STAGE","INT","PROD"],nn=c.z.record(c.z.string(),c.z.string()).default({}),rn=c.z.object({enabled:c.z.boolean(),maxLevel:c.z.number().int().min(1).max(5),dailyBudget:c.z.number().positive(),autoPR:c.z.boolean(),healAssertionLocators:c.z.boolean().default(!1)}),an=c.z.object({allure:c.z.boolean(),html:c.z.boolean(),json:c.z.boolean()}),on=c.z.object({width:c.z.number().int().positive(),height:c.z.number().int().positive()}),sn=c.z.object({name:c.z.string().min(1),environment:Fe,baseUrl:c.z.string().url(),browsers:c.z.array(He).min(1),headless:c.z.boolean().optional()}),z=c.z.object({baseUrl:c.z.string().url(),environment:Fe.default("DEV"),environments:c.z.array(c.z.string().min(1)).default([...ze]),environmentUrls:nn.default({DEV:"",TEST:"",STAGE:"",INT:"",PROD:""}),browsers:c.z.array(He).min(1),headless:c.z.boolean(),viewport:on.default({width:1280,height:720}),timeout:c.z.number().int().positive(),retries:c.z.number().int().min(0),parallel:c.z.number().int().positive(),pageLoad:tn.default("domcontentloaded"),screenshot:Zt,video:Qt,trace:en,healing:rn,reporting:an,studioPort:c.z.number().int().min(1024).max(65535),profiles:c.z.array(sn).default([]),activeProfile:c.z.string().optional(),device:c.z.string().optional(),rag:c.z.object({enabled:c.z.boolean(),codeCorpus:c.z.object({enabled:c.z.boolean(),maxEntries:c.z.number().int().positive(),similarityThreshold:c.z.number().min(0).max(1),directUseThreshold:c.z.number().min(0).max(1)}),healingCorpus:c.z.object({enabled:c.z.boolean(),maxEntries:c.z.number().int().positive(),similarityThreshold:c.z.number().min(0).max(1)}),errorCatalog:c.z.object({enabled:c.z.boolean(),maxEntries:c.z.number().int().positive()}),embedder:c.z.literal("tfidf")}).default({enabled:!0,codeCorpus:{enabled:!0,maxEntries:500,similarityThreshold:.65,directUseThreshold:.9},healingCorpus:{enabled:!0,maxEntries:300,similarityThreshold:.6},errorCatalog:{enabled:!0,maxEntries:200},embedder:"tfidf"}),mcp:c.z.object({enabled:c.z.boolean(),headless:c.z.boolean(),actThenScript:c.z.boolean(),proactiveHealing:c.z.boolean(),actionTimeout:c.z.number().int().positive(),idleTimeout:c.z.number().int().positive()}).default({enabled:!0,headless:!0,actThenScript:!1,proactiveHealing:!1,actionTimeout:15e3,idleTimeout:3e4}),ci:c.z.object({writeToRepo:c.z.boolean()}).default({writeToRepo:!1})}),q={baseUrl:"http://localhost:3000",environment:"DEV",environments:[...ze],environmentUrls:{DEV:"http://localhost:3000",TEST:"",STAGE:"",INT:"",PROD:""},browsers:["chromium"],headless:!0,viewport:{width:1280,height:720},timeout:3e4,retries:1,parallel:1,pageLoad:"domcontentloaded",screenshot:"only-on-failure",video:"off",trace:"on-first-retry",healing:{enabled:!0,maxLevel:5,dailyBudget:5,autoPR:!1,healAssertionLocators:!1},reporting:{allure:!0,html:!0,json:!0},studioPort:4400,profiles:[],rag:{enabled:!0,codeCorpus:{enabled:!0,maxEntries:500,similarityThreshold:.65,directUseThreshold:.9},healingCorpus:{enabled:!0,maxEntries:300,similarityThreshold:.6},errorCatalog:{enabled:!0,maxEntries:200},embedder:"tfidf"},mcp:{enabled:!0,headless:!0,actThenScript:!1,proactiveHealing:!1,actionTimeout:15e3,idleTimeout:3e4},ci:{writeToRepo:!1}};var S=h(require("path")),j=h(require("fs-extra")),Ye=require("uuid");var m=require("zod"),U=m.z.object({id:m.z.string().min(1),order:m.z.number().int().positive(),instruction:m.z.string().min(1),generatedCode:m.z.string(),strategy:m.z.enum(["template","cache","rag","batch","fast","primary","recorder"]),stepType:m.z.enum(["ui","api","mock"]).default("ui"),lastHealed:m.z.string().nullable(),timeout:m.z.number().int().positive().optional(),retries:m.z.number().int().min(0).optional(),mockUrl:m.z.string().optional(),mockResponse:m.z.string().optional(),mockStatus:m.z.number().int().optional(),runAudit:m.z.boolean().optional(),soft:m.z.boolean().optional(),visualCheck:m.z.boolean().optional()}),cn=m.z.object({type:m.z.enum(["inline","json-file","csv-file"]),path:m.z.string().optional(),data:m.z.array(m.z.record(m.z.string())).optional()}).optional(),Ue=m.z.object({id:m.z.string(),instruction:m.z.string(),generatedCode:m.z.string().default(""),order:m.z.number().int().default(0)}),ln=m.z.object({before:m.z.array(Ue).default([]),after:m.z.array(Ue).default([])}).default({before:[],after:[]}),xe=m.z.object({id:m.z.string().min(1),name:m.z.string().min(1),description:m.z.string(),tags:m.z.array(m.z.string()),priority:m.z.enum(["critical","high","medium","low"]),timeout:m.z.number().int().positive().optional(),dataSource:cn,steps:m.z.array(U),caseHooks:ln,lighthouseCategories:m.z.array(m.z.enum(["performance","accessibility","seo"])).default(["performance","accessibility","seo"]),createdAt:m.z.string().datetime(),updatedAt:m.z.string().datetime()}),be=m.z.object({id:m.z.string().min(1),name:m.z.string().min(1),description:m.z.string(),tags:m.z.array(m.z.string()),type:m.z.enum(["ui","api","audit","performance"]).default("ui"),timeout:m.z.number().int().positive().optional(),createdAt:m.z.string().datetime(),updatedAt:m.z.string().datetime()}),tr=m.z.enum(["before_all","before_each","after_each","after_all"]),nr=m.z.object({before_all:m.z.array(U).default([]),before_each:m.z.array(U).default([]),after_each:m.z.array(U).default([]),after_all:m.z.array(U).default([])});var v=class extends Error{code;constructor(t,n){super(t),this.name="AssuremindError",this.code=n,Object.setPrototypeOf(this,new.target.prototype)}},Z=class extends v{provider;constructor(t,n,r="PROVIDER_ERROR"){super(t,r),this.name="ProviderError",this.provider=n}},Q=class extends v{stepId;constructor(t,n,r="EXECUTION_ERROR"){super(t,r),this.name="ExecutionError",this.stepId=n}},T=class extends v{constructor(t,n="CONFIG_ERROR"){super(t,n),this.name="ConfigError"}},p=class extends v{field;constructor(t,n,r="VALIDATION_ERROR"){super(t,r),this.name="ValidationError",this.field=n}},ee=class extends v{level;constructor(t,n,r="HEALING_ERROR"){super(t,r),this.name="HealingError",this.level=n}},g=class extends v{path;constructor(t,n,r="STORAGE_ERROR"){super(t,r),this.name="StorageError",this.path=n}};function ke(e){return e instanceof v}function Ge(e){return e instanceof v?`[${e.code}] ${e.message}`:e instanceof Error?e.message:String(e)}var Se=h(require("pino")),mn=h(require("fs-extra"));var un=process.env.NODE_ENV!=="production",Me=un?{target:"pino-pretty",options:{colorize:!0,translateTime:"HH:MM:ss",ignore:"pid,hostname",messageFormat:"[assuremind] {msg}"}}:void 0,ye=(0,Se.default)({level:process.env.LOG_LEVEL??"info",base:{name:"assuremind"}},Me?Se.default.transport(Me):void 0);function b(e){return ye.child({component:e})}function pn(e){let t=/^```(?:typescript|javascript|ts|js)?\n?([\s\S]*?)```\s*$/m,n=e.match(t);return n?.[1]!==void 0?n[1].trim():e.trim()}var dn=[/\brequire\s*\(/,/\bimport\s*\(/,/\bprocess\b/,/\bchild_process\b/,/\bexec\s*\(/,/\bspawn\s*\(/,/\beval\s*\(/,/\bFunction\s*\(/,/\b__dirname\b/,/\b__filename\b/,/\bglobal\b/,/\bwindow\.location\.href\s*=/,/\bdocument\.cookie\b/,/\blocalStorage\b/,/\bsessionStorage\b/,/\bIndexedDB\b/,/\bXMLHttpRequest\b/,/\bfetch\s*\(/,/\bWebSocket\s*\(/];function gn(e){for(let t of dn)if(t.test(e))throw new p(`Generated code contains forbidden pattern: ${t.source}. This may be a prompt injection attempt. Please regenerate the step.`,"generatedCode","UNSAFE_CODE")}var fn=/\s+(?:field|input|box|textbox|text\s?box|drop-?\s?down|dropdown|combo\s?box|combobox|menu|selector|element|checkbox|radio\s?button|radio)$/i;function Be(e){let t=e.replace(fn,"").trim();return t.length>0?t:e}function hn(e){let t=e;return t=t.replace(/(getBy(?:Label|Placeholder)\(\s*)(['"`])([\s\S]*?)\2/g,(n,r,i,a)=>`${r}${i}${Be(a)}${i}`),t=t.replace(/(name:\s*)(['"`])([\s\S]*?)\2/g,(n,r,i,a)=>`${r}${i}${Be(a)}${i}`),t}function xn(e){return e.replace(/\blocator\((['"`])([\s\S]*?)\1\)/g,(t,n,r)=>{if(!r.includes(" >> "))return t;let i=r.split(" >> ").map(a=>a.trim()).filter(Boolean);return i.length<2?t:i.map(a=>`locator(${n}${a}${n})`).join(".")})}function bn(e){let t=e;return t=xn(t),t=t.replace(/\.or\((?:[^()]*|\([^()]*\))*\)(?:\.(?:first|last)\(\))?/g,""),t=t.replace(/\.(?:first|last)\(\)(?=\.\w)/g,""),t=hn(t),t}function We(e){let t=pn(e);if(!t)throw new p("AI returned an empty code response. Please try regenerating.","generatedCode","EMPTY_CODE");let n=bn(t);return gn(n),n}function $(e){return e.toLowerCase().trim().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")}function Je(e,t){let n=e;for(let r of t)r.length>0&&(n=n.replaceAll(r,"[REDACTED]"));return n}var Ee=h(require("path")),I=h(require("fs-extra"));async function x(e,t){let n=Ee.default.dirname(e);await I.default.ensureDir(n);let r=`${e}.${process.pid}.tmp`;try{await I.default.writeJson(r,t,{spaces:2}),await I.default.rename(r,e)}catch(i){throw await I.default.remove(r).catch(()=>{}),new g(`Failed to write file "${e}": ${i instanceof Error?i.message:String(i)}`,e,"WRITE_FAILED")}}async function E(e){try{return await I.default.readJson(e)}catch(t){throw new g(`Failed to read JSON file "${e}": ${t instanceof Error?t.message:String(t)}`,e,"READ_FAILED")}}async function Ke(e,t){let n=Ee.default.dirname(e);await I.default.ensureDir(n);let r=`${e}.${process.pid}.tmp`;try{await I.default.writeFile(r,t,"utf8"),await I.default.rename(r,e)}catch(i){throw await I.default.remove(r).catch(()=>{}),new g(`Failed to write file "${e}": ${i instanceof Error?i.message:String(i)}`,e,"WRITE_FAILED")}}var k=b("suite-store"),te="suite.json";async function G(e){let t=S.default.join(e,te);if(!await j.default.pathExists(t))throw new g(`Suite file not found at "${t}". Ensure the suite directory exists and contains a suite.json file.`,t,"SUITE_NOT_FOUND");let n=await E(t),r=be.safeParse(n);if(!r.success){let a=r.error.issues.map(l=>` \u2022 ${l.path.join(".")}: ${l.message}`).join(`
|
|
2
2
|
`);throw new p(`Invalid suite.json at "${t}":
|
|
3
|
-
${a}`,"suite","INVALID_SUITE")}if(!n.type){let a=S.default.basename(S.default.dirname(e));a==="api"?r.data.type="api":a==="audit"||a==="performance"?r.data.type="audit":r.data.type="ui"}return r.data}async function
|
|
3
|
+
${a}`,"suite","INVALID_SUITE")}if(!n.type){let a=S.default.basename(S.default.dirname(e));a==="api"?r.data.type="api":a==="audit"||a==="performance"?r.data.type="audit":r.data.type="ui"}return r.data}async function ne(e,t){await j.default.ensureDir(e);let n=S.default.join(e,te),r=be.safeParse(t);if(!r.success){let i=r.error.issues.map(a=>` \u2022 ${a.path.join(".")}: ${a.message}`).join(`
|
|
4
4
|
`);throw new p(`Cannot write invalid suite to "${n}":
|
|
5
|
-
${i}`,"suite","INVALID_SUITE")}await x(n,r.data),k.debug({suiteId:t.id,path:n},"Suite written")}async function
|
|
5
|
+
${i}`,"suite","INVALID_SUITE")}await x(n,r.data),k.debug({suiteId:t.id,path:n},"Suite written")}async function Xe(e,t){let n=new Date().toISOString(),r=t.type??"ui",i={...t,type:r,id:(0,Ye.v4)(),createdAt:n,updatedAt:n},a=S.default.join(e,r),l=S.default.join(a,$(i.name));if(await j.default.pathExists(S.default.join(l,te)))throw new g(`Suite directory already exists at "${l}". Choose a different name or delete the existing suite first.`,l,"SUITE_ALREADY_EXISTS");return await ne(l,i),k.info({suiteId:i.id,path:l},"Suite created"),{suiteDir:l,suiteId:i.id}}async function qe(e,t){let n=await G(e),r={...n,...t,id:n.id,createdAt:n.createdAt,updatedAt:new Date().toISOString()};return await ne(e,r),r}async function Ze(e){if(!await j.default.pathExists(e))throw new g(`Suite directory not found at "${e}".`,e,"SUITE_NOT_FOUND");await j.default.remove(e),k.info({path:e},"Suite deleted")}async function re(e){let t=[],n=[S.default.join(e,"ui"),S.default.join(e,"api"),S.default.join(e,"audit"),S.default.join(e,"performance"),e];for(let r of n){if(!await j.default.pathExists(r))continue;let i=await j.default.readdir(r,{withFileTypes:!0});for(let a of i){if(!a.isDirectory()||r===e&&(a.name==="ui"||a.name==="api"||a.name==="audit"||a.name==="performance"))continue;let l=S.default.join(r,a.name,te);await j.default.pathExists(l)&&t.push(S.default.join(r,a.name))}}return t}async function Qe(e){let t=await re(e),n=[];for(let r of t)try{n.push(await G(r))}catch(i){k.warn({path:r,err:i},"Failed to read suite \u2014 skipping")}return n}async function et(e){let t=await re(e),n=[];for(let r of t)try{let i=await G(r),l=(await j.default.readdir(r,{withFileTypes:!0})).filter(y=>y.isFile()&&y.name.endsWith(".test.json")).length;n.push({...i,caseCount:l})}catch(i){k.warn({path:r,err:i},"Failed to read suite \u2014 skipping")}return n}var ie=h(require("path")),D=h(require("fs-extra")),tt=require("uuid");var ae=b("case-store"),we=".test.json";async function oe(e){if(!await D.default.pathExists(e))throw new g(`Test case file not found at "${e}".`,e,"CASE_NOT_FOUND");let t=await E(e),n=xe.safeParse(t);if(!n.success){let r=n.error.issues.map(i=>` \u2022 ${i.path.join(".")}: ${i.message}`).join(`
|
|
6
6
|
`);throw new p(`Invalid test case file at "${e}":
|
|
7
|
-
${r}`,"case","INVALID_CASE")}return n.data}async function
|
|
7
|
+
${r}`,"case","INVALID_CASE")}return n.data}async function se(e,t){let n=xe.safeParse(t);if(!n.success){let r=n.error.issues.map(i=>` \u2022 ${i.path.join(".")}: ${i.message}`).join(`
|
|
8
8
|
`);throw new p(`Cannot write invalid test case to "${e}":
|
|
9
|
-
${r}`,"case","INVALID_CASE")}await x(e,n.data),
|
|
9
|
+
${r}`,"case","INVALID_CASE")}await x(e,n.data),ae.debug({caseId:t.id,path:e},"Test case written")}async function nt(e,t){let n=new Date().toISOString(),r={...t,id:(0,tt.v4)(),createdAt:n,updatedAt:n},i=ie.default.join(e,`${$(r.name)}${we}`);return await se(i,r),ae.info({caseId:r.id,path:i},"Test case created"),i}async function rt(e,t){let n=await oe(e),r={...n,...t,id:n.id,createdAt:n.createdAt,updatedAt:new Date().toISOString()};return await se(e,r),r}async function it(e){if(!await D.default.pathExists(e))throw new g(`Test case file not found at "${e}".`,e,"CASE_NOT_FOUND");await D.default.remove(e),ae.info({path:e},"Test case deleted")}async function ve(e){return await D.default.pathExists(e)?(await D.default.readdir(e,{withFileTypes:!0})).filter(n=>n.isFile()&&n.name.endsWith(we)).map(n=>ie.default.join(e,n.name)):[]}async function at(e){let t=await ve(e),n=[];for(let r of t)try{n.push(await oe(r))}catch(i){ae.warn({path:r,err:i},"Failed to read test case \u2014 skipping")}return n.sort((r,i)=>r.name.localeCompare(i.name))}function ot(e,t){return ie.default.join(e,`${$(t)}${we}`)}var C=h(require("path")),M=h(require("fs-extra"));var P=require("zod"),Sn=P.z.object({value:P.z.string(),secret:P.z.literal(!0)}),yn=P.z.union([P.z.string(),Sn]),Ae=P.z.record(P.z.string(),yn);function En(e){return typeof e=="object"&&e.secret===!0}function st(e){return En(e)?e.value:e}var ct=b("variable-store"),B="variables",Re="global.json";function wn(e){return`${e}.env.json`}async function H(e){if(!await M.default.pathExists(e))return{};let t=await E(e),n=Ae.safeParse(t);if(!n.success){let r=n.error.issues.map(i=>` \u2022 ${i.path.join(".")}: ${i.message}`).join(`
|
|
10
10
|
`);throw new p(`Invalid variables file at "${e}":
|
|
11
|
-
${r}`,"variables","INVALID_VARIABLES")}return n.data}async function
|
|
11
|
+
${r}`,"variables","INVALID_VARIABLES")}return n.data}async function ce(e,t){let n=Ae.safeParse(t);if(!n.success){let r=n.error.issues.map(i=>` \u2022 ${i.path.join(".")}: ${i.message}`).join(`
|
|
12
12
|
`);throw new p(`Cannot write invalid variables to "${e}":
|
|
13
|
-
${r}`,"variables","INVALID_VARIABLES")}await x(e,n.data),
|
|
13
|
+
${r}`,"variables","INVALID_VARIABLES")}await x(e,n.data),ct.debug({path:e},"Variables written")}async function Ie(e){let t=C.default.join(e,B,Re);return H(t)}async function je(e,t){let n=C.default.join(e,B,wn(t));return H(n)}async function lt(e,t){let n=await Ie(e),r=t?await je(e,t):{},i={...n,...r},a={};for(let[l,y]of Object.entries(i)){let he=process.env[`AM_${l}`];he!==void 0&&he!==""?(ct.debug({key:l},`Variable overridden by AM_${l} CI secret`),a[l]=he):a[l]=st(y)}return a}async function mt(e,t,n){let r=C.default.join(e,B,Re);await M.default.ensureDir(C.default.dirname(r));let i=await H(r);i[t]=n,await ce(r,i)}async function ut(e,t){let n=C.default.join(e,B,Re),r=await H(n);if(!(t in r))throw new g(`Variable "${t}" not found in global variables.`,n,"VARIABLE_NOT_FOUND");delete r[t],await ce(n,r)}async function pt(e){let t=C.default.join(e,B);return await M.default.pathExists(t)?(await M.default.readdir(t,{withFileTypes:!0})).filter(r=>r.isFile()&&r.name.endsWith(".json")).map(r=>C.default.join(t,r.name)):[]}var F=h(require("path")),le=h(require("fs-extra"));var Te=b("config-store"),Pe="autotest.config.json",dt="autotest.config.ts";async function me(e){let t=F.default.join(e,Pe);if(!await le.default.pathExists(t))return Te.debug({rootDir:e},"No autotest.config.json found \u2014 using defaults"),q;let n=await E(t),r=z.safeParse(n);if(!r.success){let a=r.error.issues.map(l=>` \u2022 ${l.path.join(".")}: ${l.message}`).join(`
|
|
14
14
|
`);throw new p(`Invalid autotest.config.json at "${t}":
|
|
15
15
|
${a}
|
|
16
16
|
|
|
17
|
-
How to fix: Run "npx assuremind init" to reset to defaults, or manually correct the file using autotest.config.ts as reference.`,"config","INVALID_CONFIG")}let i=r.data;if(n&&typeof n=="object"&&"environments"in n)i.environment&&!i.environments.includes(i.environment)&&(i.environments=[...i.environments,i.environment]);else{let a=new Set;for(let
|
|
17
|
+
How to fix: Run "npx assuremind init" to reset to defaults, or manually correct the file using autotest.config.ts as reference.`,"config","INVALID_CONFIG")}let i=r.data;if(n&&typeof n=="object"&&"environments"in n)i.environment&&!i.environments.includes(i.environment)&&(i.environments=[...i.environments,i.environment]);else{let a=new Set;for(let l of Object.keys(i.environmentUrls??{}))a.add(l);i.environment&&a.add(i.environment),a.size>0&&(i.environments=[...a])}return i}async function Ce(e,t){let n=z.safeParse(t);if(!n.success){let a=n.error.issues.map(l=>` \u2022 ${l.path.join(".")}: ${l.message}`).join(`
|
|
18
18
|
`);throw new p(`Cannot write invalid config:
|
|
19
|
-
${a}`,"config","INVALID_CONFIG")}let r=F.default.join(e,
|
|
19
|
+
${a}`,"config","INVALID_CONFIG")}let r=F.default.join(e,Pe);await x(r,n.data);let i=F.default.join(e,dt);await Ke(i,vn(n.data)),Te.info({rootDir:e},"Config saved")}async function gt(e,t){let n=await me(e),r={...n,...t,healing:{...n.healing,...t.healing??{}},reporting:{...n.reporting,...t.reporting??{}},environmentUrls:{...n.environmentUrls,...t.environmentUrls??{}}};return await Ce(e,r),r}async function ft(e){let t=F.default.join(e,Pe),n=F.default.join(e,dt);return await le.default.pathExists(t)||await le.default.pathExists(n)}async function ht(e){let t=await me(e);if(!t.baseUrl)throw new T('baseUrl is required in autotest.config.ts. Set it to your application URL, e.g. "http://localhost:3000".',"CONFIG_BASE_URL_MISSING");Te.debug({config:t},"Config validated successfully")}function vn(e){return`import { defineConfig } from 'assuremind';
|
|
20
20
|
|
|
21
21
|
export default defineConfig({
|
|
22
22
|
baseUrl: '${e.baseUrl}',
|
|
@@ -41,22 +41,22 @@ export default defineConfig({
|
|
|
41
41
|
},
|
|
42
42
|
studioPort: ${e.studioPort},
|
|
43
43
|
});
|
|
44
|
-
`}var
|
|
44
|
+
`}var R=h(require("path")),_=h(require("fs-extra"));var s=require("zod"),ue=s.z.enum(["pending","running","passed","failed","skipped"]),An=s.z.object({method:s.z.string(),url:s.z.string(),headers:s.z.record(s.z.string()).optional(),body:s.z.string().optional()}).optional(),Rn=s.z.object({status:s.z.number(),statusText:s.z.string(),headers:s.z.record(s.z.string()).optional(),body:s.z.string().optional(),duration:s.z.number()}).optional(),A=s.z.number().nullish().transform(e=>e??void 0),xt=s.z.object({id:s.z.string(),title:s.z.string(),passed:s.z.boolean(),partial:s.z.boolean().optional(),na:s.z.boolean().optional()}),In=s.z.object({url:s.z.string(),stepIndex:s.z.number().int(),stepInstruction:s.z.string(),score:A,a11yScore:A,seoScore:A,fcp:A,lcp:A,cls:A,ttfb:A,tbt:A,si:A,tti:A,inp:A,a11yAudits:s.z.array(xt).optional(),seoAudits:s.z.array(xt).optional(),lighthouseError:s.z.string().optional()}),jn=s.z.object({stepId:s.z.string(),instruction:s.z.string(),status:ue,code:s.z.string(),error:s.z.string().optional(),duration:s.z.number(),screenshotPath:s.z.string().optional(),healed:s.z.boolean().optional(),healedCode:s.z.string().optional(),stepType:s.z.enum(["ui","api","mock"]).optional(),apiRequest:An,apiResponse:Rn,navigatedToUrl:s.z.string().optional(),auditUrl:s.z.string().optional()}),Tn=s.z.object({caseId:s.z.string(),caseName:s.z.string(),status:ue,steps:s.z.array(jn),duration:s.z.number(),browser:s.z.string(),device:s.z.string().optional(),startedAt:s.z.string().datetime(),finishedAt:s.z.string().datetime(),videoPath:s.z.string().optional(),tracePath:s.z.string().optional(),downloadPaths:s.z.array(s.z.string()).default([]),dataRowIndex:s.z.number().int().optional(),dataRow:s.z.record(s.z.string()).optional(),pageLoads:s.z.array(In).default([])}),Pn=s.z.object({suiteId:s.z.string(),suiteName:s.z.string(),suiteType:s.z.enum(["ui","api","audit","performance"]).optional(),status:ue,cases:s.z.array(Tn),duration:s.z.number(),browser:s.z.string(),startedAt:s.z.string().datetime(),finishedAt:s.z.string().datetime()}),_e=s.z.object({runId:s.z.string(),status:ue,environment:s.z.string().optional(),suites:s.z.array(Pn),duration:s.z.number(),startedAt:s.z.string().datetime(),finishedAt:s.z.string().datetime(),totalTests:s.z.number().int(),passed:s.z.number().int(),failed:s.z.number().int(),skipped:s.z.number().int(),healed:s.z.number().int().optional(),logFilePath:s.z.string().optional()});var W=b("result-store"),O="results",St="runs",bt=15;function pe(e,t){return R.default.join(e,St,`${t}.json`)}async function yt(e,t){let n=_e.safeParse(t);if(!n.success){let i=n.error.issues.map(a=>` \u2022 ${a.path.join(".")}: ${a.message}`).join(`
|
|
45
45
|
`);throw new p(`Cannot write invalid run result:
|
|
46
|
-
${i}`,"result","INVALID_RESULT")}let r=
|
|
46
|
+
${i}`,"result","INVALID_RESULT")}let r=pe(R.default.join(e,O),t.runId);await x(r,n.data),W.info({runId:t.runId,status:t.status},"Run result saved"),await Cn(e).catch(i=>{W.warn({err:i},"Failed to prune old run results")})}async function Cn(e){let n=(await de(e)).slice(bt);if(n.length===0)return;let r=R.default.join(e,O);for(let i of n)await _.default.remove(pe(r,i)).catch(()=>{});W.info({pruned:n.length,retained:bt},"Pruned old run results")}async function Oe(e,t){let n=pe(R.default.join(e,O),t);if(!await _.default.pathExists(n))throw new g(`Run result not found for runId "${t}".`,n,"RESULT_NOT_FOUND");let r=await E(n),i=_e.safeParse(r);if(!i.success){let a=i.error.issues.map(l=>` \u2022 ${l.path.join(".")}: ${l.message}`).join(`
|
|
47
47
|
`);throw new p(`Invalid run result at "${n}":
|
|
48
|
-
${a}`,"result","INVALID_RESULT")}return i.data}async function
|
|
48
|
+
${a}`,"result","INVALID_RESULT")}return i.data}async function de(e){let t=R.default.join(e,O,St);if(!await _.default.pathExists(t))return[];let r=(await _.default.readdir(t,{withFileTypes:!0})).filter(a=>a.isFile()&&a.name.endsWith(".json")).map(a=>a.name.replace(".json",""));return(await Promise.all(r.map(async a=>{let l=await _.default.stat(R.default.join(t,`${a}.json`));return{id:a,mtime:l.mtimeMs}}))).sort((a,l)=>l.mtime-a.mtime).map(a=>a.id)}async function Et(e,t=20){let n=await de(e),r=[];for(let i of n.slice(0,t))try{let a=await Oe(e,i);r.push({runId:a.runId,status:a.status,environment:a.environment,startedAt:a.startedAt,finishedAt:a.finishedAt,totalTests:a.totalTests,passed:a.passed,failed:a.failed,skipped:a.skipped,duration:a.duration,suiteIds:a.suites.map(l=>l.suiteId)})}catch(a){W.warn({runId:i,err:a},"Failed to read run result \u2014 skipping")}return r}async function wt(e,t){let n=pe(R.default.join(e,O),t);if(!await _.default.pathExists(n))throw new g(`Run result not found for runId "${t}".`,n,"RESULT_NOT_FOUND");await _.default.remove(n),W.info({runId:t},"Run result deleted")}function vt(e){return R.default.join(e,O,"screenshots")}function At(e){return R.default.join(e,O,"videos")}function Rt(e){return R.default.join(e,O,"traces")}var w=h(require("path")),V=h(require("fs-extra"));var d=require("zod"),_n=d.z.enum(["pending","accepted","rejected"]),On=d.z.enum(["retry","regenerate","multi-selector","visual","decompose","manual"]),ge=d.z.object({id:d.z.string(),runId:d.z.string(),suiteId:d.z.string(),caseId:d.z.string(),stepId:d.z.string(),stepInstruction:d.z.string(),failedCode:d.z.string(),healedCode:d.z.string(),error:d.z.string(),strategy:On,level:d.z.number().int().min(1).max(6),status:_n,pageUrl:d.z.string(),timestamp:d.z.string().datetime(),acceptedAt:d.z.string().datetime().optional(),rejectedAt:d.z.string().datetime().optional()}),Ne=d.z.object({runId:d.z.string(),generatedAt:d.z.string().datetime(),totalHeals:d.z.number().int(),accepted:d.z.number().int(),rejected:d.z.number().int(),pending:d.z.number().int(),events:d.z.array(ge)});var J=b("healing-store"),N=w.default.join("results","healing"),Nn="pending.json",fe="healing-report-";function Tt(e,t){return w.default.join(e,`${fe}${t}.json`)}function K(e){return w.default.join(e,Nn)}async function Pt(e,t){let n=Ne.safeParse(t);if(!n.success){let a=n.error.issues.map(l=>` \u2022 ${l.path.join(".")}: ${l.message}`).join(`
|
|
49
49
|
`);throw new p(`Cannot write invalid healing report:
|
|
50
|
-
${a}`,"healingReport","INVALID_HEALING_REPORT")}let r=w.default.join(e,
|
|
50
|
+
${a}`,"healingReport","INVALID_HEALING_REPORT")}let r=w.default.join(e,N),i=Tt(r,t.runId);await x(i,n.data),J.info({runId:t.runId,totalHeals:t.totalHeals},"Healing report saved")}async function Ct(e,t){let n=w.default.join(e,N),r=Tt(n,t);if(!await V.default.pathExists(r))throw new g(`Healing report not found for runId "${t}".`,r,"HEALING_REPORT_NOT_FOUND");let i=await E(r),a=Ne.safeParse(i);if(!a.success){let l=a.error.issues.map(y=>` \u2022 ${y.path.join(".")}: ${y.message}`).join(`
|
|
51
51
|
`);throw new p(`Invalid healing report at "${r}":
|
|
52
|
-
${
|
|
52
|
+
${l}`,"healingReport","INVALID_HEALING_REPORT")}return a.data}async function L(e){let t=w.default.join(e,N),n=K(t);if(!await V.default.pathExists(n))return[];let r=await E(n),i=ge.array().safeParse(r);return i.success?i.data:(J.warn({path:n},"Pending healing file is malformed \u2014 resetting"),[])}var It=50,jt=["pending","rejected","accepted"];function $n(e){if(e.length<=It)return e;let t=[...e].sort((i,a)=>{let l=jt.indexOf(i.status),y=jt.indexOf(a.status);return l!==y?l-y:i.timestamp<a.timestamp?-1:1}),n=e.length-It,r=new Set(t.slice(0,n).map(i=>i.id));return J.info({excess:n,deleted:r.size},"Auto-pruning healing events to enforce cap"),e.filter(i=>!r.has(i.id))}async function _t(e,t){let n=ge.safeParse(t);if(!n.success)throw new p(`Invalid healing event: ${n.error.message}`,"healingEvent","INVALID_HEALING_EVENT");let r=w.default.join(e,N);await V.default.ensureDir(r);let i=await L(e);i.push(n.data),await x(K(r),$n(i))}async function Ot(e,t){let n=await L(e),r=n.findIndex(a=>a.id===t);if(r===-1)throw new g(`Healing event "${t}" not found in pending list.`,t,"HEALING_EVENT_NOT_FOUND");n[r]={...n[r],status:"accepted",acceptedAt:new Date().toISOString()};let i=w.default.join(e,N);return await x(K(i),n),J.info({eventId:t},"Healing event accepted"),n[r]}async function Nt(e,t){let n=await L(e),r=n.findIndex(a=>a.id===t);if(r===-1)throw new g(`Healing event "${t}" not found in pending list.`,t,"HEALING_EVENT_NOT_FOUND");n[r]={...n[r],status:"rejected",rejectedAt:new Date().toISOString()};let i=w.default.join(e,N);return await x(K(i),n),J.info({eventId:t},"Healing event rejected"),n[r]}async function $t(e,t=30){let n=await L(e),r=Date.now()-t*24*60*60*1e3,i=n.length,a=n.filter(l=>{if(l.status==="pending")return!0;let y=l.acceptedAt??l.rejectedAt;return y?new Date(y).getTime()>r:!0});if(a.length<i){let l=w.default.join(e,N);await x(K(l),a)}return i-a.length}async function Vt(e){let t=await L(e),n=t.filter(a=>a.status==="pending").length,r=t.filter(a=>a.status==="accepted").length,i=t.filter(a=>a.status==="rejected").length;return{pending:n,accepted:r,rejected:i,total:t.length}}async function Lt(e){let t=w.default.join(e,N);if(!await V.default.pathExists(t))return[];let r=(await V.default.readdir(t,{withFileTypes:!0})).filter(a=>a.isFile()&&a.name.startsWith(fe)&&a.name.endsWith(".json")).map(a=>a.name.slice(fe.length,-5));return(await Promise.all(r.map(async a=>{let l=await V.default.stat(w.default.join(t,`${fe}${a}.json`));return{id:a,mtime:l.mtimeMs}}))).sort((a,l)=>l.mtime-a.mtime).map(a=>a.id)}var Dt=require("crypto");function $e(e){return(0,Dt.createHash)("sha256").update(e,"utf8").digest("hex")}function Ve(e){try{return new URL(e).pathname.split("/").map(r=>/^\d+$/.test(r)||/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(r)||/^[a-z0-9-]{8,}$/i.test(r)&&/-/.test(r)?"*":r).join("/")}catch{return e}}function Ht(e,t){let n=e.toLowerCase().replace(/\s+/g," ").trim(),r=Ve(t);return $e(`${n}|${r}`).slice(0,16)}var zt=require("dotenv"),u=require("zod");(0,zt.config)();var Ft=["anthropic","openai","google","azure-openai","bedrock","deepseek","groq","together","qwen","perplexity","ollama","custom"],Vn=u.z.object({NODE_ENV:u.z.enum(["development","production","test"]).default("development"),LOG_LEVEL:u.z.enum(["trace","debug","info","warn","error","fatal"]).default("info"),AI_PROVIDER:u.z.enum(Ft),AI_TIERED_ENABLED:u.z.string().transform(e=>e==="true").default("false"),AI_TIERED_FAST_PROVIDER:u.z.enum(Ft).optional(),AI_TIERED_FAST_MODEL:u.z.string().optional(),AI_TIMEOUT:u.z.coerce.number().int().positive().default(30),AI_MAX_RETRIES:u.z.coerce.number().int().min(0).max(10).default(2)}),Ln=u.z.object({ANTHROPIC_API_KEY:u.z.string().min(1),ANTHROPIC_MODEL:u.z.string().default("claude-sonnet-4-20250514")}),Dn=u.z.object({OPENAI_API_KEY:u.z.string().min(1),OPENAI_MODEL:u.z.string().default("gpt-4o")}),Hn=u.z.object({GOOGLE_API_KEY:u.z.string().min(1),GOOGLE_MODEL:u.z.string().default("gemini-2.5-pro")}),Fn=u.z.object({AZURE_OPENAI_API_KEY:u.z.string().min(1),AZURE_OPENAI_ENDPOINT:u.z.string().url(),AZURE_OPENAI_DEPLOYMENT:u.z.string().min(1),AZURE_OPENAI_API_VERSION:u.z.string().default("2024-10-21")}),zn=u.z.object({AWS_ACCESS_KEY_ID:u.z.string().min(1),AWS_SECRET_ACCESS_KEY:u.z.string().min(1),AWS_SESSION_TOKEN:u.z.string().optional(),AWS_REGION:u.z.string().default("us-east-1"),BEDROCK_MODEL:u.z.string().default("anthropic.claude-sonnet-4-20250514-v1:0")}),Un=u.z.object({DEEPSEEK_API_KEY:u.z.string().min(1),DEEPSEEK_MODEL:u.z.string().default("deepseek-chat")}),kn=u.z.object({GROQ_API_KEY:u.z.string().min(1),GROQ_MODEL:u.z.string().default("llama-3.3-70b-versatile")}),Gn=u.z.object({TOGETHER_API_KEY:u.z.string().min(1),TOGETHER_MODEL:u.z.string().default("meta-llama/Llama-3.3-70B-Instruct-Turbo")}),Mn=u.z.object({QWEN_API_KEY:u.z.string().min(1),QWEN_BASE_URL:u.z.string().url().default("https://dashscope-intl.aliyuncs.com/compatible-mode/v1"),QWEN_MODEL:u.z.string().default("qwen-max")}),Bn=u.z.object({PERPLEXITY_API_KEY:u.z.string().min(1),PERPLEXITY_MODEL:u.z.string().default("sonar-pro")}),Wn=u.z.object({OLLAMA_BASE_URL:u.z.string().url().default("http://localhost:11434"),OLLAMA_MODEL:u.z.string().default("llama3.3")}),Jn=u.z.object({CUSTOM_API_KEY:u.z.string().min(1),CUSTOM_BASE_URL:u.z.string().url(),CUSTOM_MODEL:u.z.string().min(1)}),Kn={anthropic:Ln,openai:Dn,google:Hn,"azure-openai":Fn,bedrock:zn,deepseek:Un,groq:kn,together:Gn,qwen:Mn,perplexity:Bn,ollama:Wn,custom:Jn},Y=null;function Le(){if(Y!==null)return Y;let e=Vn.safeParse(process.env);if(!e.success){let a=e.error.issues.map(l=>` \u2022 ${l.path.join(".")}: ${l.message}`).join(`
|
|
53
53
|
`);throw new T(`Missing or invalid environment variables:
|
|
54
54
|
${a}
|
|
55
55
|
|
|
56
|
-
How to fix: Copy .env.example to .env and fill in your AI provider credentials.`,"ENV_VALIDATION_FAILED")}let t=e.data.AI_PROVIDER,r=
|
|
56
|
+
How to fix: Copy .env.example to .env and fill in your AI provider credentials.`,"ENV_VALIDATION_FAILED")}let t=e.data.AI_PROVIDER,r=Kn[t].safeParse(process.env);if(!r.success){let a=r.error.issues.map(l=>` \u2022 ${l.path.join(".")}: ${l.message}`).join(`
|
|
57
57
|
`);throw new T(`Provider "${t}" is missing required environment variables:
|
|
58
58
|
${a}
|
|
59
59
|
|
|
60
|
-
How to fix: Check .env.example for the ${t} section and add the required keys to .env.`,"PROVIDER_ENV_MISSING")}return
|
|
60
|
+
How to fix: Check .env.example for the ${t} section and add the required keys to .env.`,"PROVIDER_ENV_MISSING")}return Y={...e.data,...r.data},Y}function Ut(){Y=null}function kt(){try{return Le()}catch{return null}}var o=require("@faker-js/faker");function Gt(){return[{category:"person",methods:[{name:"fullName",example:o.faker.person.fullName()},{name:"firstName",example:o.faker.person.firstName()},{name:"lastName",example:o.faker.person.lastName()},{name:"middleName",example:o.faker.person.middleName()},{name:"sex",example:o.faker.person.sex()},{name:"prefix",example:o.faker.person.prefix()},{name:"suffix",example:o.faker.person.suffix()},{name:"jobTitle",example:o.faker.person.jobTitle()},{name:"jobArea",example:o.faker.person.jobArea()},{name:"jobType",example:o.faker.person.jobType()},{name:"bio",example:o.faker.person.bio()}]},{category:"internet",methods:[{name:"email",example:o.faker.internet.email()},{name:"userName",example:o.faker.internet.username()},{name:"password",example:o.faker.internet.password()},{name:"url",example:o.faker.internet.url()},{name:"domainName",example:o.faker.internet.domainName()},{name:"domainWord",example:o.faker.internet.domainWord()},{name:"ip",example:o.faker.internet.ip()},{name:"ipv6",example:o.faker.internet.ipv6()},{name:"mac",example:o.faker.internet.mac()},{name:"userAgent",example:o.faker.internet.userAgent()},{name:"emoji",example:o.faker.internet.emoji()}]},{category:"phone",methods:[{name:"number",example:o.faker.phone.number()},{name:"imei",example:o.faker.phone.imei()}]},{category:"location",methods:[{name:"streetAddress",example:o.faker.location.streetAddress()},{name:"street",example:o.faker.location.street()},{name:"city",example:o.faker.location.city()},{name:"state",example:o.faker.location.state()},{name:"zipCode",example:o.faker.location.zipCode()},{name:"country",example:o.faker.location.country()},{name:"countryCode",example:o.faker.location.countryCode()},{name:"county",example:o.faker.location.county()},{name:"latitude",example:String(o.faker.location.latitude())},{name:"longitude",example:String(o.faker.location.longitude())},{name:"timeZone",example:o.faker.location.timeZone()},{name:"buildingNumber",example:o.faker.location.buildingNumber()}]},{category:"company",methods:[{name:"name",example:o.faker.company.name()},{name:"catchPhrase",example:o.faker.company.catchPhrase()},{name:"buzzPhrase",example:o.faker.company.buzzPhrase()},{name:"buzzNoun",example:o.faker.company.buzzNoun()},{name:"buzzVerb",example:o.faker.company.buzzVerb()},{name:"buzzAdjective",example:o.faker.company.buzzAdjective()}]},{category:"finance",methods:[{name:"accountNumber",example:o.faker.finance.accountNumber()},{name:"accountName",example:o.faker.finance.accountName()},{name:"creditCardNumber",example:o.faker.finance.creditCardNumber()},{name:"creditCardCVV",example:o.faker.finance.creditCardCVV()},{name:"currencyCode",example:o.faker.finance.currencyCode()},{name:"currencyName",example:o.faker.finance.currencyName()},{name:"amount",example:o.faker.finance.amount()},{name:"iban",example:o.faker.finance.iban()},{name:"bic",example:o.faker.finance.bic()},{name:"bitcoinAddress",example:o.faker.finance.bitcoinAddress()},{name:"transactionType",example:o.faker.finance.transactionType()}]},{category:"date",methods:[{name:"past",example:o.faker.date.past().toISOString()},{name:"future",example:o.faker.date.future().toISOString()},{name:"recent",example:o.faker.date.recent().toISOString()},{name:"soon",example:o.faker.date.soon().toISOString()},{name:"birthdate",example:o.faker.date.birthdate().toISOString()},{name:"month",example:o.faker.date.month()},{name:"weekday",example:o.faker.date.weekday()}]},{category:"lorem",methods:[{name:"word",example:o.faker.lorem.word()},{name:"words",example:o.faker.lorem.words()},{name:"sentence",example:o.faker.lorem.sentence()},{name:"sentences",example:o.faker.lorem.sentences()},{name:"paragraph",example:o.faker.lorem.paragraph()},{name:"slug",example:o.faker.lorem.slug()},{name:"lines",example:o.faker.lorem.lines(1)}]},{category:"string",methods:[{name:"uuid",example:o.faker.string.uuid()},{name:"alphanumeric",example:o.faker.string.alphanumeric(10)},{name:"numeric",example:o.faker.string.numeric(6)},{name:"alpha",example:o.faker.string.alpha(8)},{name:"nanoid",example:o.faker.string.nanoid()},{name:"hexadecimal",example:o.faker.string.hexadecimal({length:8})},{name:"sample",example:o.faker.string.sample(12)}]},{category:"number",methods:[{name:"int",example:String(o.faker.number.int({max:9999}))},{name:"float",example:String(o.faker.number.float({max:100,fractionDigits:2}))}]},{category:"datatype",methods:[{name:"boolean",example:String(o.faker.datatype.boolean())}]},{category:"image",methods:[{name:"avatar",example:o.faker.image.avatar()},{name:"url",example:o.faker.image.url()}]},{category:"color",methods:[{name:"human",example:o.faker.color.human()},{name:"rgb",example:o.faker.color.rgb()},{name:"hex",example:o.faker.color.rgb({format:"hex"})}]},{category:"commerce",methods:[{name:"productName",example:o.faker.commerce.productName()},{name:"price",example:o.faker.commerce.price()},{name:"department",example:o.faker.commerce.department()},{name:"productDescription",example:o.faker.commerce.productDescription().slice(0,60)+"..."},{name:"isbn",example:o.faker.commerce.isbn()}]},{category:"vehicle",methods:[{name:"vehicle",example:o.faker.vehicle.vehicle()},{name:"manufacturer",example:o.faker.vehicle.manufacturer()},{name:"model",example:o.faker.vehicle.model()},{name:"vin",example:o.faker.vehicle.vin()},{name:"vrm",example:o.faker.vehicle.vrm()}]},{category:"system",methods:[{name:"fileName",example:o.faker.system.fileName()},{name:"mimeType",example:o.faker.system.mimeType()},{name:"fileExt",example:o.faker.system.fileExt()},{name:"filePath",example:o.faker.system.filePath()},{name:"semver",example:o.faker.system.semver()}]}]}var Yn={"internet.userName":"username"};function Mt(e,t){let n=o.faker[e],r=Yn[`${e}.${t}`]??t;if(!n||typeof n[r]!="function")return`[unknown: ${e}.${t}]`;let i=n[r]();return i instanceof Date?i.toISOString():String(i)}function Xn(e){let t={...q,...e},n=z.safeParse(t);if(!n.success){let r=n.error.issues.map(i=>` \u2022 ${i.path.join(".")}: ${i.message}`).join(`
|
|
61
61
|
`);throw new Error(`Invalid assuremind config:
|
|
62
62
|
${r}`)}return n.data}0&&(module.exports={AssuremindError,ConfigError,ExecutionError,HealingError,ProviderError,StorageError,ValidationError,acceptHealingEvent,appendPendingEvent,callFaker,clearEnvCache,configExists,createCase,createChildLogger,createSuite,defineConfig,deleteCase,deleteGlobalVariable,deleteResult,deleteSuite,formatError,generateCacheKey,getAvailableGenerators,getCasePath,getHealingStats,isAssuremindError,listCasePaths,listCases,listHealingReportIds,listResultIds,listResults,listSuiteDirs,listSuites,listSuitesWithCounts,listVariableFiles,logger,normalizeUrl,pruneResolvedEvents,readCase,readConfig,readEnvVariables,readGlobalVariables,readHealingReport,readPendingEvents,readResult,readSuite,readVariables,redactSecrets,rejectHealingEvent,resolveVariables,sanitizeGeneratedCode,screenshotsDir,setGlobalVariable,sha256,toSlug,tracesDir,tryGetEnv,updateCase,updateConfig,updateSuite,validateConfig,validateEnv,videosDir,writeCase,writeConfig,writeHealingReport,writeResult,writeSuite,writeVariables});
|