#!/usr/bin/env node // ============================================================================ // AI Testing Suite - Quick Setup Script // Installs and configures the test suite in an existing project // ============================================================================ import * as fs from 'fs'; import * as path from 'path'; import chalk from 'chalk'; import boxen from 'boxen'; import figures from 'figures'; import { execSync } from 'child_process'; const BANNER = boxen( [ '', chalk.bold.redBright('AI TESTING SUITE'), chalk.gray('Quick Setup'), '', ].join('\n'), { padding: { top: 0, bottom: 0, left: 3, right: 3 }, margin: { top: 1, bottom: 1, left: 0, right: 0 }, borderStyle: 'double', borderColor: 'red', textAlignment: 'center', } ); async function setup(): Promise { console.log(BANNER); const projectPath = process.argv[2] || process.cwd(); const resolvedPath = path.resolve(projectPath); console.log(`${chalk.blue(figures.info)} ${chalk.cyan(`Setting up in: ${chalk.white(resolvedPath)}`)}\n`); // 1. Check for package.json const pkgPath = path.join(resolvedPath, 'package.json'); if (!fs.existsSync(pkgPath)) { console.log(`${chalk.yellow(figures.warning)} No package.json found! Initializing...`); execSync('npm init -y', { cwd: resolvedPath, stdio: 'inherit' }); } // 2. Create directories const dirs = ['tests', 'tests/unit', 'tests/integration', 'tests/e2e', 'tests/security', 'tests/performance', 'reports']; for (const dir of dirs) { const dirPath = path.join(resolvedPath, dir); if (!fs.existsSync(dirPath)) { fs.mkdirSync(dirPath, { recursive: true }); console.log(` ${chalk.green(figures.tick)} Created: ${chalk.white(dir + '/')}`); } } // 3. Detect test runner preference const runner = process.argv.includes('--jest') ? 'jest' : 'vitest'; const usePlaywright = !process.argv.includes('--no-playwright'); console.log(`\n${chalk.blue(figures.info)} Test Runner: ${chalk.bold.white(runner)}`); if (usePlaywright) { console.log(`${chalk.blue(figures.info)} E2E Runner: ${chalk.bold.white('Playwright')}`); } // 4. Install dependencies console.log(`\n${chalk.blue(figures.info)} Installing dependencies...\n`); const coreDeps = ['typescript', 'ts-node', '@types/node', 'ai-testing-suite']; // Test runner deps const runnerDeps = runner === 'vitest' ? ['vitest', '@vitest/coverage-v8'] : ['jest', 'ts-jest', '@types/jest']; // API testing deps const apiDeps = ['supertest', '@types/supertest', 'nock']; // E2E deps const e2eDeps = usePlaywright ? ['@playwright/test'] : []; const devDeps = [...coreDeps, ...runnerDeps, ...apiDeps, ...e2eDeps]; try { console.log(chalk.gray(' npm install --save-dev ' + devDeps.join(' '))); execSync(`npm install --save-dev ${devDeps.join(' ')}`, { cwd: resolvedPath, stdio: 'inherit' }); // Install Playwright browsers if (usePlaywright) { console.log(`\n${chalk.blue(figures.info)} Installing Playwright browsers...`); execSync('npx playwright install chromium', { cwd: resolvedPath, stdio: 'inherit' }); } } catch (err) { console.log(`\n${chalk.yellow(figures.warning)} Some dependencies could not be installed.`); console.log(`${chalk.yellow(figures.warning)} Please install manually.`); } // 4. Create tsconfig if missing const tsconfigPath = path.join(resolvedPath, 'tsconfig.json'); if (!fs.existsSync(tsconfigPath)) { fs.writeFileSync(tsconfigPath, JSON.stringify({ compilerOptions: { target: 'ES2022', module: 'commonjs', lib: ['ES2022'], outDir: './dist', rootDir: './src', strict: true, esModuleInterop: true, skipLibCheck: true, forceConsistentCasingInFileNames: true, resolveJsonModule: true, declaration: true, sourceMap: true, moduleResolution: 'node', }, include: ['src/**/*'], exclude: ['node_modules', 'dist', 'tests'], }, null, 2)); console.log(`\n ${chalk.green(figures.tick)} tsconfig.json created`); } // 6. Add scripts to package.json const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8')); pkg.scripts = pkg.scripts || {}; if (runner === 'vitest') { pkg.scripts['test'] = pkg.scripts['test'] === 'echo "Error: no test specified" && exit 1' ? 'vitest run' : (pkg.scripts['test'] || 'vitest run'); pkg.scripts['test:watch'] = 'vitest'; pkg.scripts['test:unit'] = 'vitest run tests/unit'; pkg.scripts['test:integration'] = 'vitest run tests/integration'; pkg.scripts['test:security'] = 'vitest run tests/security'; pkg.scripts['test:performance'] = 'vitest run tests/performance'; pkg.scripts['test:all'] = 'vitest run'; pkg.scripts['test:coverage'] = 'vitest run --coverage'; } else { pkg.scripts['test'] = pkg.scripts['test'] === 'echo "Error: no test specified" && exit 1' ? 'jest' : (pkg.scripts['test'] || 'jest'); pkg.scripts['test:unit'] = 'jest --testPathPattern=tests/unit'; pkg.scripts['test:integration'] = 'jest --testPathPattern=tests/integration'; pkg.scripts['test:security'] = 'jest --testPathPattern=tests/security'; pkg.scripts['test:performance'] = 'jest --testPathPattern=tests/performance'; pkg.scripts['test:all'] = 'jest --verbose --forceExit'; pkg.scripts['test:coverage'] = 'jest --coverage --verbose'; } if (usePlaywright) { pkg.scripts['test:e2e'] = 'playwright test'; pkg.scripts['test:e2e:ui'] = 'playwright test --ui'; pkg.scripts['test:e2e:debug'] = 'playwright test --debug'; } else { pkg.scripts['test:e2e'] = runner === 'vitest' ? 'vitest run tests/e2e' : 'jest --testPathPattern=tests/e2e'; } pkg.scripts['ai-test'] = 'npx ai-test --mode full'; pkg.scripts['ai-test:analyze'] = 'npx ai-test --mode analyze'; pkg.scripts['ai-test:generate'] = 'npx ai-test --mode generate'; pkg.scripts['ai-test:security'] = 'npx ai-test --mode security'; pkg.scripts['ai-test:interactive'] = 'npx ai-test --mode interactive'; fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2)); console.log(` ${chalk.green(figures.tick)} package.json scripts updated`); // 7. Create .env.example const envContent = `# AI Testing Suite Configuration OPENAI_API_KEY=your-key-here # ANTHROPIC_API_KEY=your-key-here # For Ollama (local): LLM_PROVIDER=ollama LLM_PROVIDER=openai LLM_MODEL=gpt-4o TARGET_PROJECT_PATH=./ TESTS_OUTPUT_DIR=./tests REPORTS_OUTPUT_DIR=./reports SECURITY_SCAN_DEPTH=deep # Test Runner Configuration # TEST_RUNNER=vitest # vitest | jest | node # E2E_RUNNER=playwright # playwright | supertest | none # COVERAGE_TOOL=v8 # v8 | c8 | istanbul `; const envExPath = path.join(resolvedPath, '.env.example'); if (!fs.existsSync(envExPath)) { fs.writeFileSync(envExPath, envContent); console.log(` ${chalk.green(figures.tick)} .env.example created`); } // Done - styled completion panel console.log( boxen( `${chalk.green(figures.tick)} ${chalk.bold.green('Setup completed!')}`, { padding: { top: 0, bottom: 0, left: 2, right: 2 }, margin: { top: 1, bottom: 1, left: 0, right: 0 }, borderStyle: 'round', borderColor: 'green', textAlignment: 'center', } ) ); const nextSteps = [ `${chalk.white('Next steps:')}`, ` ${chalk.gray(`1. Copy .env.example to .env`)}`, ` ${chalk.gray(`2. Enter your API key`)}`, ` ${chalk.gray(`3. Start with: ${chalk.cyan('npm run ai-test')}`)}`, '', `${chalk.white('Or directly with npx:')}`, ` ${chalk.cyan('npx ai-test --mode full')}`, ` ${chalk.cyan('npx ai-test --mode interactive')}`, ` ${chalk.cyan('npx ai-test --mode security')}`, '', `${chalk.white('Available npm scripts:')}`, ` ${chalk.gray('npm run ai-test - Full test suite')}`, ` ${chalk.gray('npm run ai-test:analyze - Analysis only')}`, ` ${chalk.gray('npm run ai-test:generate - Generate tests')}`, ` ${chalk.gray('npm run ai-test:security - Security scan only')}`, ` ${chalk.gray('npm run ai-test:interactive - Interactive mode')}`, '', `${chalk.white('Run generated tests:')}`, ]; if (runner === 'vitest') { nextSteps.push( ` ${chalk.gray('npm test - All tests (vitest)')}`, ` ${chalk.gray('npm run test:watch - Watch mode')}`, ` ${chalk.gray('npm run test:unit - Unit Tests')}`, ` ${chalk.gray('npm run test:security - Security Tests')}`, ` ${chalk.gray('npm run test:coverage - With v8 coverage')}`, ); } else { nextSteps.push( ` ${chalk.gray('npm test - All tests (jest)')}`, ` ${chalk.gray('npm run test:unit - Unit Tests')}`, ` ${chalk.gray('npm run test:security - Security Tests')}`, ` ${chalk.gray('npm run test:coverage - With coverage')}`, ); } if (usePlaywright) { nextSteps.push( ` ${chalk.gray('npm run test:e2e - E2E Tests (Playwright)')}`, ` ${chalk.gray('npm run test:e2e:ui - Playwright UI mode')}`, ); } nextSteps.push( '', `${chalk.white('Setup flags:')}`, ` ${chalk.gray('--jest Use Jest instead of Vitest')}`, ` ${chalk.gray('--no-playwright Skip Playwright installation')}`, '', ); console.log(nextSteps.join('\n')); } setup().catch(err => { console.error(`${chalk.red(figures.cross)} Setup failed:`, err); process.exit(1); });