deflake 1.1.9 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/cli.js +11 -5
  2. package/client.js +3 -2
  3. package/package.json +1 -1
package/cli.js CHANGED
@@ -220,7 +220,7 @@ function parseCypressLogs(fullLog) {
220
220
  return specBlocks;
221
221
  }
222
222
 
223
- async function runHealer(logContent, htmlPath, apiUrl, testName) {
223
+ async function runHealer(logContent, htmlPath, apiUrl, testName, applyFix = false) {
224
224
  // Check file size limit (Basic check to avoid 429s on huge files)
225
225
  if (htmlPath && fs.existsSync(htmlPath)) {
226
226
  const stats = fs.statSync(htmlPath);
@@ -282,7 +282,7 @@ async function runHealer(logContent, htmlPath, apiUrl, testName) {
282
282
  }
283
283
 
284
284
  try {
285
- const result = await client.heal(finalLogPath, htmlPath, failureLoc, sourceCodeContent);
285
+ const result = await client.heal(finalLogPath, htmlPath, failureLoc, sourceCodeContent, applyFix);
286
286
 
287
287
  if (result && result.status === 'success') {
288
288
  // Return structured object for grouping
@@ -640,7 +640,10 @@ async function runDoctor(argv) {
640
640
  if (result.status === 'success') {
641
641
  const usage = result.data;
642
642
  process.stdout.write(`\r ✅ API Connected! (Tier: ${C.GREEN}${usage.tier.toUpperCase()}${C.RESET}) \n`);
643
- console.log(` Quota: ${usage.usage}/${usage.limit}`);
643
+ const u = usage;
644
+ const remaining = u.limit - u.usage;
645
+ console.log(` Fix Quota: ${C.GREEN}${remaining}/${u.limit} remaining${C.RESET}`);
646
+ console.log(` Analysis: ${C.GREEN}FREE${C.RESET} (Pay-per-fix model enabled)`);
644
647
  } else {
645
648
  process.stdout.write(`\r ❌ ${C.RED}API Connectivity Failed${C.RESET} \n`);
646
649
  if (result.code === 401 || result.code === 403) {
@@ -731,6 +734,9 @@ async function analyzeFailures(artifacts, fullLog, client) {
731
734
  }
732
735
 
733
736
  const framework = artifacts.length > 0 && artifacts[0].htmlPath?.includes('cypress') ? 'Cypress' : 'Playwright';
737
+ const results = [];
738
+ const processLimit = Math.min(artifacts.length, limit);
739
+ const batchArtifacts = artifacts.slice(0, processLimit);
734
740
 
735
741
  console.log(`🔍 Analyzing ${batchArtifacts.length} failure(s)...`);
736
742
 
@@ -768,7 +774,7 @@ async function analyzeFailures(artifacts, fullLog, client) {
768
774
  process.stdout.write(`\r⏳ Analyzing ${displayName}... `);
769
775
 
770
776
  try {
771
- const result = await runHealer(specificLog, art.htmlPath, argv.apiUrl, art.name);
777
+ const result = await runHealer(specificLog, art.htmlPath, argv.apiUrl, art.name, argv.fix);
772
778
 
773
779
  if (result && result.status === 'success') {
774
780
  results.push(result);
@@ -824,7 +830,7 @@ async function analyzeFailures(artifacts, fullLog, client) {
824
830
  if (updatedUsage.status === 'success') {
825
831
  const u = updatedUsage.data;
826
832
  const remaining = u.limit - u.usage;
827
- console.log(` - Monthly Quota: ${C.GREEN}${remaining}/${u.limit} remaining${C.RESET}`);
833
+ console.log(` - Fix Quota: ${C.GREEN}${remaining}/${u.limit} remaining (Analysis is FREE)${C.RESET}`);
828
834
  }
829
835
  } catch (e) {
830
836
  // usage fetch failed is non-critical
package/client.js CHANGED
@@ -94,7 +94,7 @@ class DeFlakeClient {
94
94
  }
95
95
  }
96
96
 
97
- async heal(logPath, htmlPath, failureLocation = null, sourceCode = null) {
97
+ async heal(logPath, htmlPath, failureLocation = null, sourceCode = null, applyFix = false) {
98
98
  try {
99
99
  // ... (rest of the check logic) ...
100
100
  if (!fs.existsSync(logPath)) throw new Error(`Log file not found: ${logPath}`);
@@ -119,7 +119,8 @@ class DeFlakeClient {
119
119
  html_snapshot: htmlContent || "",
120
120
  failing_line: failureLocation ? `Line ${failureLocation.rootLine}` : "",
121
121
  source_code: sourceCode || "",
122
- framework: this.framework
122
+ framework: this.framework,
123
+ apply_fix: applyFix
123
124
  };
124
125
 
125
126
  const response = await axios.post(this.apiUrl, payload, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deflake",
3
- "version": "1.1.9",
3
+ "version": "1.2.1",
4
4
  "description": "AI-powered self-healing tool for Playwright, Cypress, and WebdriverIO tests.",
5
5
  "main": "client.js",
6
6
  "bin": {