UNPKG

@raiken/cli

Version:

CLI tool for Raiken - AI-powered Playwright test generator

297 lines (293 loc) 11.4 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.initializeProject = initializeProject; const fs = __importStar(require("fs/promises")); const path = __importStar(require("path")); const chalk_1 = __importDefault(require("chalk")); const project_detector_1 = require("./project-detector"); async function initializeProject(projectPath, force = false) { const projectInfo = await (0, project_detector_1.detectProject)(projectPath); console.log(chalk_1.default.blue(`📁 Setting up ${projectInfo.type} project: ${projectInfo.name}`)); // 1. Create test directory await createTestDirectory(projectPath, projectInfo); // 2. Create test-results directory structure await createTestResultsDirectory(projectPath); // 3. Create Raiken configuration await createRaikenConfig(projectPath, projectInfo, force); // 4. Set up Playwright configuration await setupPlaywrightConfig(projectPath, projectInfo, force); // 5. Update package.json scripts await updatePackageScripts(projectPath, projectInfo); // 6. Create example test await createExampleTest(projectPath, projectInfo); // 7. Install Playwright browsers await installPlaywrightBrowsers(projectPath, projectInfo); console.log(chalk_1.default.green('✓ Project initialization complete')); } async function createTestDirectory(projectPath, projectInfo) { const testDirPath = path.join(projectPath, projectInfo.testDir); try { await fs.access(testDirPath); console.log(chalk_1.default.yellow(`⚠ Test directory ${projectInfo.testDir}/ already exists`)); } catch { await fs.mkdir(testDirPath, { recursive: true }); console.log(chalk_1.default.green(`✓ Created test directory: ${projectInfo.testDir}/`)); } } async function createTestResultsDirectory(projectPath) { const testResultsPath = path.join(projectPath, 'test-results'); const reportsPath = path.join(testResultsPath, 'reports'); try { // Create test-results directory await fs.mkdir(testResultsPath, { recursive: true }); // Create reports subdirectory await fs.mkdir(reportsPath, { recursive: true }); // Create .gitignore to exclude test artifacts from version control const gitignorePath = path.join(testResultsPath, '.gitignore'); const gitignoreContent = `# Test artifacts * !.gitignore !reports/ reports/*.json `; try { await fs.access(gitignorePath); console.log(chalk_1.default.yellow('⚠ test-results/.gitignore already exists')); } catch { await fs.writeFile(gitignorePath, gitignoreContent); console.log(chalk_1.default.green('✓ Created test-results/.gitignore')); } console.log(chalk_1.default.green('✓ Created test-results/ directory structure')); } catch (error) { console.log(chalk_1.default.yellow('⚠ Could not create test-results directory structure')); } } async function createRaikenConfig(projectPath, projectInfo, force) { const configPath = path.join(projectPath, 'raiken.config.json'); const config = { projectType: projectInfo.type, testDirectory: projectInfo.testDir, playwrightConfig: 'playwright.config.ts', outputFormats: ['typescript'], ai: { provider: 'openrouter', model: 'anthropic/claude-3.5-sonnet' }, features: { video: true, screenshots: true, tracing: false, network: true }, browser: { defaultBrowser: 'chromium', headless: true, timeout: 30000, retries: 1 } }; try { await fs.access(configPath); if (!force) { console.log(chalk_1.default.yellow('⚠ raiken.config.json already exists (use --force to overwrite)')); return; } } catch { // File doesn't exist, proceed } await fs.writeFile(configPath, JSON.stringify(config, null, 2)); console.log(chalk_1.default.green('✓ Created raiken.config.json')); } async function setupPlaywrightConfig(projectPath, projectInfo, force) { const configPath = path.join(projectPath, 'playwright.config.ts'); const config = `import { defineConfig, devices } from '@playwright/test'; export default defineConfig({ testDir: './${projectInfo.testDir}', fullyParallel: true, forbidOnly: !!process.env.CI, retries: process.env.CI ? 2 : 0, workers: process.env.CI ? 1 : undefined, reporter: 'html', use: { baseURL: 'http://localhost:${getDefaultPort(projectInfo.type)}', trace: 'on-first-retry', video: 'retain-on-failure', screenshot: 'only-on-failure', }, projects: [ { name: 'chromium', use: { ...devices['Desktop Chrome'] }, }, // Additional browsers can be enabled by uncommenting: // { // name: 'firefox', // use: { ...devices['Desktop Firefox'] }, // }, // { // name: 'webkit', // use: { ...devices['Desktop Safari'] }, // }, ], webServer: { command: '${getDevCommand(projectInfo)}', port: ${getDefaultPort(projectInfo.type)}, reuseExistingServer: !process.env.CI, }, }); `; try { await fs.access(configPath); if (!force) { console.log(chalk_1.default.yellow('⚠ playwright.config.ts already exists (use --force to overwrite)')); return; } } catch { // File doesn't exist, proceed } await fs.writeFile(configPath, config); console.log(chalk_1.default.green('✓ Created playwright.config.ts')); } async function updatePackageScripts(projectPath, projectInfo) { const packageJsonPath = path.join(projectPath, 'package.json'); try { const packageContent = await fs.readFile(packageJsonPath, 'utf-8'); const packageJson = JSON.parse(packageContent); const newScripts = { 'test:e2e': 'playwright test', 'test:e2e:ui': 'playwright test --ui', 'test:e2e:debug': 'playwright test --debug', 'raiken': 'raiken start' }; packageJson.scripts = { ...packageJson.scripts, ...newScripts }; await fs.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2)); console.log(chalk_1.default.green('✓ Updated package.json scripts')); } catch (error) { console.log(chalk_1.default.yellow('⚠ Could not update package.json scripts')); } } async function createExampleTest(projectPath, projectInfo) { const testPath = path.join(projectPath, projectInfo.testDir, 'example.spec.ts'); try { await fs.access(testPath); console.log(chalk_1.default.yellow('⚠ Example test already exists')); return; } catch { // File doesn't exist, create it } const exampleTest = `import { test, expect } from '@playwright/test'; test('example test', async ({ page }) => { await page.goto('/'); // Example: Check if the page loads await expect(page).toHaveTitle(/.*${projectInfo.name}.*/i); // Add your test steps here // await page.click('button[data-testid="my-button"]'); // await expect(page.getByText('Success!')).toBeVisible(); }); `; await fs.writeFile(testPath, exampleTest); console.log(chalk_1.default.green(`✓ Created example test: ${projectInfo.testDir}/example.spec.ts`)); } function getDefaultPort(projectType) { switch (projectType) { case 'nextjs': case 'react': case 'nuxt': return 3000; case 'svelte': case 'vite': return 5173; case 'angular': return 4200; default: return 3000; } } function getDevCommand(projectInfo) { if (projectInfo.scripts.dev) return 'npm run dev'; if (projectInfo.scripts.start) return 'npm run start'; if (projectInfo.scripts.serve) return 'npm run serve'; return 'npm run dev'; } async function installPlaywrightBrowsers(projectPath, projectInfo) { // Only install browsers if Playwright is already a dependency if (!projectInfo.hasPlaywright) { console.log(chalk_1.default.yellow('⚠ Playwright not detected as dependency, skipping browser installation')); return; } console.log(chalk_1.default.blue('📦 Installing Playwright browsers...')); try { const { spawn } = require('child_process'); return new Promise((resolve, reject) => { const child = spawn('npx', ['playwright', 'install'], { cwd: projectPath, stdio: 'inherit' // Show output to user }); child.on('close', (code) => { if (code === 0) { console.log(chalk_1.default.green('✓ Playwright browsers installed successfully')); resolve(); } else { console.log(chalk_1.default.yellow('⚠ Playwright browser installation failed, you may need to run "npx playwright install" manually')); resolve(); // Don't fail the entire setup } }); child.on('error', (error) => { console.log(chalk_1.default.yellow(`⚠ Could not install Playwright browsers: ${error.message}`)); console.log(chalk_1.default.gray(' You can install them manually with: npx playwright install')); resolve(); // Don't fail the entire setup }); }); } catch (error) { console.log(chalk_1.default.yellow('⚠ Could not install Playwright browsers, you may need to run "npx playwright install" manually')); } } //# sourceMappingURL=project-initializer.js.map