deflake 1.0.12 → 1.1.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.
Files changed (3) hide show
  1. package/cli.js +35 -24
  2. package/client.js +27 -7
  3. package/package.json +1 -1
package/cli.js CHANGED
@@ -7,13 +7,29 @@ const fs = require('fs');
7
7
  const path = require('path');
8
8
  const pkg = require('./package.json');
9
9
 
10
+ // --- COLORS ---
11
+ const C = {
12
+ RESET: "\x1b[0m",
13
+ BRIGHT: "\x1b[1m",
14
+ RED: "\x1b[31m",
15
+ GREEN: "\x1b[32m",
16
+ YELLOW: "\x1b[33m",
17
+ CYAN: "\x1b[36m",
18
+ BLUE: "\x1b[34m",
19
+ GRAY: "\x1b[90m",
20
+ WHITE: "\x1b[37m"
21
+ };
22
+
10
23
  // --- DETERMINISTIC COMMAND INTERCEPTION ---
11
24
  // Check for diagnostic commands before yargs or main logic even starts
12
25
  const rawArgs = process.argv.slice(2);
13
26
  if (rawArgs.includes('doctor') || rawArgs.includes('--doctor')) {
14
27
  // We run the doctor logic and force exit to prevent any wrapper loops
15
28
  const doctorArgv = yargs(hideBin(process.argv)).argv;
16
- runDoctor(doctorArgv).then(() => process.exit(0)).catch(() => process.exit(1));
29
+ runDoctor(doctorArgv).then(() => process.exit(0)).catch((err) => {
30
+ console.error(`${C.RED}Doctor failed:${C.RESET} ${err.message}`);
31
+ process.exit(1);
32
+ });
17
33
  return; // Safety for some environments
18
34
  }
19
35
  // ------------------------------------------
@@ -346,18 +362,7 @@ function extractFailureLocation(logText) {
346
362
  return null;
347
363
  }
348
364
 
349
- // --- COLORS ---
350
- const C = {
351
- RESET: "\x1b[0m",
352
- BRIGHT: "\x1b[1m",
353
- RED: "\x1b[31m",
354
- GREEN: "\x1b[32m",
355
- YELLOW: "\x1b[33m",
356
- CYAN: "\x1b[36m",
357
- BLUE: "\x1b[34m",
358
- GRAY: "\x1b[90m",
359
- WHITE: "\x1b[37m"
360
- };
365
+ // --- COLORS Moved to top ---
361
366
 
362
367
  function printDetailedFix(fixText, location, sourceCode = null, isApplied = false) {
363
368
 
@@ -505,13 +510,11 @@ async function runDoctor(argv) {
505
510
 
506
511
  // 2. Framework Detection
507
512
  console.log(`${C.BRIGHT}Detecting Frameworks:${C.RESET}`);
508
- const frameworks = [];
509
- if (fs.existsSync('playwright.config.ts') || fs.existsSync('playwright.config.js')) frameworks.push('Playwright');
510
- if (fs.existsSync('cypress.config.ts') || fs.existsSync('cypress.config.js') || fs.existsSync('cypress.json')) frameworks.push('Cypress');
511
- if (fs.existsSync('wdio.conf.ts') || fs.existsSync('wdio.conf.js')) frameworks.push('WebdriverIO');
513
+ const activeFramework = DeFlakeClient.detectFramework();
512
514
 
513
- if (frameworks.length > 0) {
514
- console.log(` ✅ Found: ${C.GREEN}${frameworks.join(', ')}${C.RESET}`);
515
+ if (activeFramework !== 'generic') {
516
+ const capitalized = activeFramework.charAt(0).toUpperCase() + activeFramework.slice(1);
517
+ console.log(` ✅ Active: ${C.GREEN}${C.BRIGHT}${capitalized}${C.RESET}`);
515
518
  } else {
516
519
  console.log(` ⚠️ ${C.YELLOW}No supported frameworks detected in the current directory.${C.RESET}`);
517
520
  console.log(` (Checked for Playwright, Cypress, WebdriverIO files)`);
@@ -543,12 +546,18 @@ async function runDoctor(argv) {
543
546
  const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'));
544
547
  const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
545
548
  const detectedDeps = [];
546
- if (deps['@playwright/test']) detectedDeps.push('@playwright/test');
547
- if (deps['cypress']) detectedDeps.push('cypress');
548
- if (deps['webdriverio']) detectedDeps.push('webdriverio');
549
+
550
+ // Core frameworks
551
+ if (deps['@playwright/test']) detectedDeps.push(`${C.CYAN}@playwright/test${C.RESET}`);
552
+ if (deps['cypress']) detectedDeps.push(`${C.CYAN}cypress${C.RESET}`);
553
+ if (deps['webdriverio'] || deps['@wdio/cli']) detectedDeps.push(`${C.CYAN}webdriverio${C.RESET}`);
554
+
555
+ // Common plugins
556
+ if (deps['dotenv']) detectedDeps.push('dotenv');
557
+ if (deps['typescript']) detectedDeps.push('typescript');
549
558
 
550
559
  if (detectedDeps.length > 0) {
551
- console.log(` Installed: ${C.GREEN}${detectedDeps.join(', ')}${C.RESET}`);
560
+ console.log(` 📦 Installed: ${detectedDeps.join(', ')}`);
552
561
  }
553
562
  } catch (e) {
554
563
  console.log(` ❌ ${C.RED}Error reading package.json${C.RESET}`);
@@ -816,8 +825,10 @@ async function main() {
816
825
  // If 'doctor' was called, don't proceed to wrapper logic
817
826
  if (command.includes('doctor')) return;
818
827
 
819
- console.log("🚑 DeFlake JS Client (Batch Mode)");
828
+ console.log(`🚑 DeFlake JS Client (Batch Mode) - ${C.CYAN}v${pkg.version}${C.RESET}`);
820
829
  const client = new DeFlakeClient(argv.apiUrl);
830
+ const fw = client.framework.charAt(0).toUpperCase() + client.framework.slice(1);
831
+ console.log(`🔍 Detected Framework: ${C.GREEN}${fw}${C.RESET}`);
821
832
 
822
833
  if (command.length > 0) {
823
834
  const cmd = command[0];
package/client.js CHANGED
@@ -10,8 +10,8 @@ class DeFlakeClient {
10
10
  this.productionUrl = 'https://deflake-api.up.railway.app/api/deflake';
11
11
  this.apiUrl = apiUrl || process.env.DEFLAKE_API_URL || this.productionUrl;
12
12
  this.apiKey = apiKey || process.env.DEFLAKE_API_KEY;
13
- this.projectName = this.detectProjectName();
14
- this.framework = this.detectFramework();
13
+ this.projectName = DeFlakeClient.detectProjectName();
14
+ this.framework = DeFlakeClient.detectFramework();
15
15
 
16
16
  if (!this.apiKey) {
17
17
  // We no longer exit here to allow diagnostic tools (like 'doctor') to run.
@@ -19,8 +19,10 @@ class DeFlakeClient {
19
19
  }
20
20
  }
21
21
 
22
- detectProjectName() {
22
+ static detectProjectName() {
23
23
  try {
24
+ const fs = require('fs');
25
+ const path = require('path');
24
26
  // 1. Try package.json
25
27
  if (fs.existsSync('package.json')) {
26
28
  const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
@@ -40,14 +42,32 @@ class DeFlakeClient {
40
42
  }
41
43
  }
42
44
 
43
- detectFramework() {
45
+ static detectFramework() {
46
+ const fs = require('fs');
44
47
  // 1. Manual override via environment variable
45
48
  if (process.env.DEFLAKE_FRAMEWORK) return process.env.DEFLAKE_FRAMEWORK.toLowerCase();
46
49
 
47
50
  // 2. Automated detection via configuration files
48
- if (fs.existsSync('cypress.config.js') || fs.existsSync('cypress.config.ts') || fs.existsSync('cypress')) return 'cypress';
49
- if (fs.existsSync('playwright.config.js') || fs.existsSync('playwright.config.ts')) return 'playwright';
50
- if (fs.existsSync('wdio.conf.js') || fs.existsSync('wdio.conf.ts')) return 'webdriverio';
51
+ const hasFile = (pattern) => {
52
+ const files = fs.readdirSync('.');
53
+ return files.some(f => f.match(pattern));
54
+ };
55
+
56
+ if (hasFile(/^cypress\.config\.(js|ts|mjs|cjs)$/) || fs.existsSync('cypress.json') || fs.existsSync('cypress')) return 'cypress';
57
+ if (hasFile(/^playwright\.config\.(js|ts|mjs|cjs)$/)) return 'playwright';
58
+ if (hasFile(/^wdio\.conf\.(js|ts|mjs|cjs)$/)) return 'webdriverio';
59
+
60
+ // 3. Fallback to package.json dependencies
61
+ if (fs.existsSync('package.json')) {
62
+ try {
63
+ const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
64
+ const deps = { ...pkg.dependencies, ...pkg.devDependencies };
65
+ if (deps['cypress']) return 'cypress';
66
+ if (deps['@playwright/test']) return 'playwright';
67
+ if (deps['webdriverio'] || deps['@wdio/cli']) return 'webdriverio';
68
+ } catch (e) { }
69
+ }
70
+
51
71
  return 'generic';
52
72
  }
53
73
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deflake",
3
- "version": "1.0.12",
3
+ "version": "1.1.2",
4
4
  "description": "AI-powered self-healing tool for Playwright, Cypress, and WebdriverIO tests.",
5
5
  "main": "client.js",
6
6
  "bin": {