deflake 1.2.41 → 1.2.42
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/cli.js +45 -6
- package/package.json +1 -1
package/cli.js
CHANGED
|
@@ -101,6 +101,18 @@ async function main() {
|
|
|
101
101
|
break;
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
+
// Detect compilation errors: exit code != 0 but no test artifacts
|
|
105
|
+
// This means the code has syntax errors and tests didn't even run
|
|
106
|
+
const postArtifacts = detectFailures();
|
|
107
|
+
if (postArtifacts.length === 0 && rerun.code !== 0) {
|
|
108
|
+
console.log(`${C.RED}⚠️ Compilation error detected (tests did not run). Rolling back all changes...${C.RESET}`);
|
|
109
|
+
for (const [filePath, originalContent] of backups) {
|
|
110
|
+
fs.writeFileSync(filePath, originalContent);
|
|
111
|
+
console.log(` ${C.YELLOW}↩️ Restored: ${path.basename(filePath)}${C.RESET}`);
|
|
112
|
+
}
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
|
|
104
116
|
if (attempt === MAX_ATTEMPTS) {
|
|
105
117
|
console.log(`\n${C.YELLOW}⚠️ Max attempts (${MAX_ATTEMPTS}) reached. Some failures may persist.${C.RESET}`);
|
|
106
118
|
}
|
|
@@ -341,16 +353,13 @@ async function applyFix(res, loc, backups = new Map()) {
|
|
|
341
353
|
} else {
|
|
342
354
|
// REPLACE action
|
|
343
355
|
// SMART: Handle multi-line expression replacement
|
|
344
|
-
// If the original line starts a multi-line expression (has unclosed parens)
|
|
345
|
-
// and the replacement is a complete statement, remove continuation lines
|
|
346
356
|
const origOpen = (originalLine.match(/\(/g) || []).length;
|
|
347
357
|
const origClose = (originalLine.match(/\)/g) || []).length;
|
|
348
358
|
const replOpen = (cleanLine.match(/\(/g) || []).length;
|
|
349
359
|
const replClose = (cleanLine.match(/\)/g) || []).length;
|
|
350
360
|
|
|
361
|
+
// Case A: Target line is the OPENER of a multi-line expression
|
|
351
362
|
if (origOpen > origClose && replOpen <= replClose) {
|
|
352
|
-
// Original has unclosed parens, replacement is complete
|
|
353
|
-
// Find the closing of the multi-line expression
|
|
354
363
|
let depth = origOpen - origClose;
|
|
355
364
|
let endIdx = idx;
|
|
356
365
|
for (let j = idx + 1; j < lines.length && depth > 0; j++) {
|
|
@@ -360,8 +369,7 @@ async function applyFix(res, loc, backups = new Map()) {
|
|
|
360
369
|
endIdx = j;
|
|
361
370
|
}
|
|
362
371
|
if (endIdx > idx) {
|
|
363
|
-
|
|
364
|
-
console.log(` ${C.GRAY}🔧 Expanding REPLACE to cover ${removedLines + 1}-line expression (lines ${p.line}-${endIdx + 1})${C.RESET}`);
|
|
372
|
+
console.log(` ${C.GRAY}🔧 Expanding REPLACE to cover ${endIdx - idx + 1}-line expression (lines ${p.line}-${endIdx + 1})${C.RESET}`);
|
|
365
373
|
for (let j = idx; j <= endIdx; j++) {
|
|
366
374
|
console.log(` ${C.RED}- Line ${j + 1}: ${lines[j].trim()}${C.RESET}`);
|
|
367
375
|
}
|
|
@@ -372,6 +380,37 @@ async function applyFix(res, loc, backups = new Map()) {
|
|
|
372
380
|
console.log(` ${C.RED}- Line ${p.line}: ${originalLine.trim()}${C.RESET}`);
|
|
373
381
|
console.log(` ${C.GREEN}+ Line ${p.line}: ${cleanLine.trim()}${C.RESET}`);
|
|
374
382
|
}
|
|
383
|
+
// Case B: Target line is a MIDDLE/CONTINUATION line of a multi-line expression
|
|
384
|
+
// Detect: replacement is a complete assignment (this.x = ...; ) but current line is just a string
|
|
385
|
+
} else if (/^\s*this\.\w+\s*=/.test(cleanLine) && cleanLine.trim().endsWith(';') && !/^\s*this\./.test(originalLine)) {
|
|
386
|
+
// Search BACKWARD for the opening line (this.xxx = page.locator()
|
|
387
|
+
let startIdx = idx;
|
|
388
|
+
for (let j = idx - 1; j >= 0; j--) {
|
|
389
|
+
startIdx = j;
|
|
390
|
+
const lo = (lines[j].match(/\(/g) || []).length;
|
|
391
|
+
const lc = (lines[j].match(/\)/g) || []).length;
|
|
392
|
+
if (lo > lc) break; // Found the opener
|
|
393
|
+
}
|
|
394
|
+
// Search FORWARD for the closing );
|
|
395
|
+
let endIdx = idx;
|
|
396
|
+
let depth = 0;
|
|
397
|
+
for (let j = startIdx; j < lines.length; j++) {
|
|
398
|
+
const lo = (lines[j].match(/\(/g) || []).length;
|
|
399
|
+
const lc = (lines[j].match(/\)/g) || []).length;
|
|
400
|
+
depth += lo - lc;
|
|
401
|
+
endIdx = j;
|
|
402
|
+
if (depth <= 0 && j >= idx) break;
|
|
403
|
+
}
|
|
404
|
+
const totalLines = endIdx - startIdx + 1;
|
|
405
|
+
console.log(` ${C.GRAY}🔧 Expanding REPLACE to cover ${totalLines}-line expression (lines ${startIdx + 1}-${endIdx + 1})${C.RESET}`);
|
|
406
|
+
for (let j = startIdx; j <= endIdx; j++) {
|
|
407
|
+
console.log(` ${C.RED}- Line ${j + 1}: ${lines[j].trim()}${C.RESET}`);
|
|
408
|
+
}
|
|
409
|
+
// Use indentation from the opener line
|
|
410
|
+
const openerIndent = lines[startIdx].match(/^\s*/)[0];
|
|
411
|
+
const expandedClean = openerIndent + cleanLine.trim();
|
|
412
|
+
lines.splice(startIdx, totalLines, expandedClean);
|
|
413
|
+
console.log(` ${C.GREEN}+ Line ${startIdx + 1}: ${expandedClean.trim()}${C.RESET}`);
|
|
375
414
|
} else {
|
|
376
415
|
lines[idx] = cleanLine;
|
|
377
416
|
console.log(` ${C.RED}- Line ${p.line}: ${originalLine.trim()}${C.RESET}`);
|