deflake 1.2.48 → 1.2.50
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 +18 -6
- package/package.json +1 -1
package/cli.js
CHANGED
|
@@ -406,8 +406,8 @@ async function analyzeAndFix(artifacts, client, argv, capturedOutput = '', backu
|
|
|
406
406
|
if (loc) {
|
|
407
407
|
console.log(` ${C.GRAY}📍 Location:${C.RESET} ${path.basename(loc.path)}:${loc.line} ${C.GRAY}(from ${locSource})${C.RESET}`);
|
|
408
408
|
|
|
409
|
-
// Dedup: skip if this
|
|
410
|
-
const fileKey = loc.path
|
|
409
|
+
// Dedup: skip if this EXACT file:line was already fixed by a previous artifact
|
|
410
|
+
const fileKey = `${loc.path}:${loc.line}`;
|
|
411
411
|
if (fixedFiles.has(fileKey)) {
|
|
412
412
|
console.log(` ${C.GREEN}⏭️ Already fixed by a previous artifact — skipping duplicate${C.RESET}`);
|
|
413
413
|
console.log('');
|
|
@@ -464,9 +464,16 @@ async function analyzeAndFix(artifacts, client, argv, capturedOutput = '', backu
|
|
|
464
464
|
if (p.new_line && p.action === 'REPLACE') {
|
|
465
465
|
const validation = validateSelectorAgainstAxTree(p.new_line, content);
|
|
466
466
|
if (!validation.valid) {
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
467
|
+
// On last retry: allow getByRole/getByText through (dynamic elements not in initial AX tree)
|
|
468
|
+
const isLastRetry = retryIdx === MAX_VALIDATION_RETRIES - 1;
|
|
469
|
+
const isAccessibilitySelector = /getBy(Role|Text|Label|Placeholder)/.test(p.new_line);
|
|
470
|
+
if (isLastRetry && isAccessibilitySelector) {
|
|
471
|
+
console.log(` ${C.YELLOW}🔍 Validation SOFT-PASS for line ${p.line}: ${validation.reason} (last retry, allowing accessibility selector)${C.RESET}`);
|
|
472
|
+
} else {
|
|
473
|
+
allValid = false;
|
|
474
|
+
rejections.push(`Line ${p.line}: "${p.new_line.trim()}" → REJECTED: ${validation.reason}`);
|
|
475
|
+
console.log(` ${C.YELLOW}🔍 Validation FAILED for line ${p.line}: ${validation.reason}${C.RESET}`);
|
|
476
|
+
}
|
|
470
477
|
} else {
|
|
471
478
|
console.log(` ${C.GREEN}🔍 Validation OK for line ${p.line}: ${validation.reason}${C.RESET}`);
|
|
472
479
|
}
|
|
@@ -529,7 +536,7 @@ async function analyzeAndFix(artifacts, client, argv, capturedOutput = '', backu
|
|
|
529
536
|
console.log(` ${C.BRIGHT}💉 Applying patches...${C.RESET}`);
|
|
530
537
|
if (await applyFix(res, fixLoc, backups)) {
|
|
531
538
|
count++;
|
|
532
|
-
fixedFiles.add(fixLoc.path); // Track: don't fix this
|
|
539
|
+
fixedFiles.add(`${fixLoc.path}:${fixLoc.line}`); // Track: don't fix this exact location again
|
|
533
540
|
console.log(` ${C.GREEN}${C.BRIGHT}✅ Fix applied to ${path.basename(fixLoc.path)}:${fixLoc.line}${C.RESET}`);
|
|
534
541
|
} else {
|
|
535
542
|
console.log(` ${C.YELLOW}⚠️ Patches could not be applied (see details above)${C.RESET}`);
|
|
@@ -611,6 +618,11 @@ async function applyFix(res, loc, backups = new Map()) {
|
|
|
611
618
|
console.log(` ${C.GRAY}⏭️ Skipped (already present): ${p.new_line.trim().substring(0, 60)}...${C.RESET}`);
|
|
612
619
|
continue;
|
|
613
620
|
}
|
|
621
|
+
// Safety: block constructor patterns (this.xxx =) from being inserted into spec/test files
|
|
622
|
+
if (/\.(spec|test)\.(ts|js)$/.test(loc.path) && /^\s*this\.\w+\s*=/.test(p.new_line)) {
|
|
623
|
+
console.log(` ${C.YELLOW}⏭️ Blocked: constructor assignment in spec file (${p.new_line.trim().substring(0, 50)})${C.RESET}`);
|
|
624
|
+
continue;
|
|
625
|
+
}
|
|
614
626
|
if (p.action === 'INSERT_AFTER') {
|
|
615
627
|
// SAFETY: Detect if we'd insert at class scope (outside any method)
|
|
616
628
|
// Pattern: line is '}' (end of constructor/method) and next non-blank line starts a new method
|