UNPKG

smartui-migration-tool

Version:

Enterprise-grade CLI tool for migrating visual testing platforms to LambdaTest SmartUI

587 lines (566 loc) โ€ข 19.1 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; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.EnvironmentManager = void 0; const path = __importStar(require("path")); const fs = __importStar(require("fs/promises")); const Logger_1 = require("../utils/Logger"); class EnvironmentManager { constructor(projectPath, verbose = false) { this.projectPath = projectPath; this.verbose = verbose; } /** * Setup CI/CD environment for SmartUI */ async setupCIEnvironment(ciType) { if (this.verbose) Logger_1.logger.debug(`Setting up ${ciType} environment...`); const environment = await this.generateCIEnvironment(ciType); await this.writeCIConfig(ciType, environment); return environment; } /** * Generate environment setup scripts */ async generateEnvironmentScripts() { if (this.verbose) Logger_1.logger.debug('Generating environment setup scripts...'); const scripts = { setup: this.generateSetupScript(), test: this.generateTestScript(), cleanup: this.generateCleanupScript(), validate: this.generateValidationScript() }; // Write scripts to project await this.writeScripts(scripts); return scripts; } /** * Validate environment configuration */ async validateEnvironment() { const errors = []; const warnings = []; const suggestions = []; // Check for required environment variables const requiredVars = ['LT_USERNAME', 'LT_ACCESS_KEY']; for (const varName of requiredVars) { if (!process.env[varName]) { errors.push(`Required environment variable ${varName} is not set`); } } // Check for optional but recommended variables const optionalVars = ['LT_PROJECT_TOKEN', 'SMARTUI_BROWSER', 'SMARTUI_VIEWPORT']; for (const varName of optionalVars) { if (!process.env[varName]) { warnings.push(`Optional environment variable ${varName} is not set`); suggestions.push(`Consider setting ${varName} for better SmartUI configuration`); } } // Check for .smartui.json try { await fs.access(path.join(this.projectPath, '.smartui.json')); } catch { errors.push('.smartui.json configuration file not found'); suggestions.push('Run the migration tool to generate SmartUI configuration'); } // Check for .env file try { await fs.access(path.join(this.projectPath, '.env')); } catch { warnings.push('.env file not found'); suggestions.push('Create .env file with your SmartUI credentials'); } return { valid: errors.length === 0, errors, warnings, suggestions }; } /** * Generate environment variables template */ generateEnvironmentVariables() { return [ { name: 'LT_USERNAME', value: '${LT_USERNAME}', description: 'LambdaTest username for SmartUI authentication', required: true, secret: false }, { name: 'LT_ACCESS_KEY', value: '${LT_ACCESS_KEY}', description: 'LambdaTest access key for SmartUI authentication', required: true, secret: true }, { name: 'LT_PROJECT_TOKEN', value: '${LT_PROJECT_TOKEN}', description: 'SmartUI project token for test organization', required: false, secret: true }, { name: 'SMARTUI_BROWSER', value: 'chrome', description: 'Default browser for SmartUI tests', required: false, secret: false }, { name: 'SMARTUI_VIEWPORT', value: '1920x1080', description: 'Default viewport size for SmartUI tests', required: false, secret: false }, { name: 'SMARTUI_TIMEOUT', value: '30000', description: 'Screenshot timeout in milliseconds', required: false, secret: false }, { name: 'SMARTUI_THRESHOLD', value: '0.1', description: 'Visual comparison threshold (0.0-1.0)', required: false, secret: false } ]; } // Private methods async generateCIEnvironment(ciType) { const environmentVariables = this.generateEnvironmentVariables(); switch (ciType.toLowerCase()) { case 'github-actions': return this.generateGitHubActionsConfig(environmentVariables); case 'jenkins': return this.generateJenkinsConfig(environmentVariables); case 'gitlab-ci': return this.generateGitLabCIConfig(environmentVariables); case 'azure-devops': return this.generateAzureDevOpsConfig(environmentVariables); case 'circleci': return this.generateCircleCIConfig(environmentVariables); case 'travis-ci': return this.generateTravisCIConfig(environmentVariables); default: throw new Error(`Unsupported CI type: ${ciType}`); } } generateGitHubActionsConfig(envVars) { const config = { name: 'SmartUI Visual Testing', on: { push: { branches: ['main', 'develop'] }, pull_request: { branches: ['main'] } }, jobs: { 'smartui-tests': { 'runs-on': 'ubuntu-latest', steps: [ { name: 'Checkout code', uses: 'actions/checkout@v3' }, { name: 'Setup Node.js', uses: 'actions/setup-node@v3', with: { 'node-version': '18' } }, { name: 'Install dependencies', run: 'npm install' }, { name: 'Run SmartUI tests', run: 'npm run test:smartui', env: { LT_USERNAME: '${{ secrets.LT_USERNAME }}', LT_ACCESS_KEY: '${{ secrets.LT_ACCESS_KEY }}', LT_PROJECT_TOKEN: '${{ secrets.LT_PROJECT_TOKEN }}' } } ] } } }; return { type: 'github-actions', config, environmentVariables: envVars, scripts: ['npm run test:smartui'] }; } generateJenkinsConfig(envVars) { const config = { pipeline: { agent: 'any', environment: { LT_USERNAME: '${LT_USERNAME}', LT_ACCESS_KEY: '${LT_ACCESS_KEY}', LT_PROJECT_TOKEN: '${LT_PROJECT_TOKEN}' }, stages: [ { stage: 'Checkout', steps: ['git checkout'] }, { stage: 'Install Dependencies', steps: ['npm install'] }, { stage: 'Run SmartUI Tests', steps: ['npm run test:smartui'] } ] } }; return { type: 'jenkins', config, environmentVariables: envVars, scripts: ['npm run test:smartui'] }; } generateGitLabCIConfig(envVars) { const config = { image: 'node:18', stages: ['test'], smartui_tests: { stage: 'test', script: [ 'npm install', 'npm run test:smartui' ], variables: { LT_USERNAME: '$LT_USERNAME', LT_ACCESS_KEY: '$LT_ACCESS_KEY', LT_PROJECT_TOKEN: '$LT_PROJECT_TOKEN' } } }; return { type: 'gitlab-ci', config, environmentVariables: envVars, scripts: ['npm run test:smartui'] }; } generateAzureDevOpsConfig(envVars) { const config = { trigger: ['main', 'develop'], pool: { vmImage: 'ubuntu-latest' }, variables: { LT_USERNAME: '$(LT_USERNAME)', LT_ACCESS_KEY: '$(LT_ACCESS_KEY)', LT_PROJECT_TOKEN: '$(LT_PROJECT_TOKEN)' }, steps: [ { task: 'NodeTool@0', inputs: { versionSpec: '18.x' } }, { script: 'npm install', displayName: 'Install dependencies' }, { script: 'npm run test:smartui', displayName: 'Run SmartUI tests' } ] }; return { type: 'azure-devops', config, environmentVariables: envVars, scripts: ['npm run test:smartui'] }; } generateCircleCIConfig(envVars) { const config = { version: 2.1, jobs: { smartui_tests: { docker: [ { image: 'cimg/node:18.0' } ], steps: [ 'checkout', { run: 'npm install' }, { run: 'npm run test:smartui', environment: { LT_USERNAME: '$LT_USERNAME', LT_ACCESS_KEY: '$LT_ACCESS_KEY', LT_PROJECT_TOKEN: '$LT_PROJECT_TOKEN' } } ] } }, workflows: { version: 2, smartui_workflow: { jobs: ['smartui_tests'] } } }; return { type: 'circleci', config, environmentVariables: envVars, scripts: ['npm run test:smartui'] }; } generateTravisCIConfig(envVars) { const config = { language: 'node_js', node_js: ['18'], script: ['npm run test:smartui'], env: { global: [ 'LT_USERNAME=$LT_USERNAME', 'LT_ACCESS_KEY=$LT_ACCESS_KEY', 'LT_PROJECT_TOKEN=$LT_PROJECT_TOKEN' ] } }; return { type: 'travis-ci', config, environmentVariables: envVars, scripts: ['npm run test:smartui'] }; } async writeCIConfig(ciType, environment) { const configPath = this.getCIConfigPath(ciType); const configContent = this.formatCIConfig(ciType, environment.config); // Create directory if it doesn't exist const configDir = path.dirname(configPath); await fs.mkdir(configDir, { recursive: true }); await fs.writeFile(configPath, configContent, 'utf-8'); if (this.verbose) Logger_1.logger.debug(`${ciType} configuration written to ${configPath}`); } getCIConfigPath(ciType) { const configPaths = { 'github-actions': '.github/workflows/smartui.yml', 'jenkins': 'Jenkinsfile', 'gitlab-ci': '.gitlab-ci.yml', 'azure-devops': 'azure-pipelines.yml', 'circleci': '.circleci/config.yml', 'travis-ci': '.travis.yml' }; return path.join(this.projectPath, configPaths[ciType] || 'ci-config.yml'); } formatCIConfig(ciType, config) { switch (ciType.toLowerCase()) { case 'github-actions': case 'jenkins': case 'gitlab-ci': case 'azure-devops': case 'circleci': case 'travis-ci': return `# SmartUI ${ciType} Configuration # Generated by SmartUI Migration Tool ${JSON.stringify(config, null, 2)}`; default: return JSON.stringify(config, null, 2); } } generateSetupScript() { return `#!/bin/bash # SmartUI Environment Setup Script echo "๐Ÿ”ง Setting up SmartUI environment..." # Check if .env file exists if [ ! -f .env ]; then echo "๐Ÿ“ Creating .env file..." cat > .env << EOF # SmartUI Configuration LT_USERNAME=your_username_here LT_ACCESS_KEY=your_access_key_here LT_PROJECT_TOKEN=your_project_token_here SMARTUI_BROWSER=chrome SMARTUI_VIEWPORT=1920x1080 SMARTUI_TIMEOUT=30000 SMARTUI_THRESHOLD=0.1 EOF echo "โš ๏ธ Please edit .env file with your credentials" else echo "โœ… .env file already exists" fi # Load environment variables if [ -f .env ]; then export $(cat .env | grep -v '^#' | xargs) echo "โœ… Environment variables loaded" fi # Validate required variables if [ -z "$LT_USERNAME" ] || [ -z "$LT_ACCESS_KEY" ]; then echo "โŒ Required environment variables not set" echo " Please set LT_USERNAME and LT_ACCESS_KEY in .env file" exit 1 fi echo "โœ… SmartUI environment setup complete" `; } generateTestScript() { return `#!/bin/bash # SmartUI Test Runner Script echo "๐Ÿงช Running SmartUI tests..." # Load environment variables if [ -f .env ]; then export $(cat .env | grep -v '^#' | xargs) fi # Check if SmartUI config exists if [ ! -f .smartui.json ]; then echo "โŒ .smartui.json not found. Please run migration tool first." exit 1 fi # Run tests based on project type if [ -f package.json ]; then echo "๐Ÿ“ฆ Running Node.js tests..." npm run test:smartui elif [ -f pom.xml ]; then echo "โ˜• Running Maven tests..." mvn test -Dtest=*SmartUITest elif [ -f build.gradle ]; then echo "๐Ÿ˜ Running Gradle tests..." ./gradlew test --tests "*SmartUITest" elif [ -f requirements.txt ]; then echo "๐Ÿ Running Python tests..." python -m pytest tests/test_smartui.py else echo "โš ๏ธ Unknown project type. Please run tests manually." fi echo "โœ… SmartUI tests completed" `; } generateCleanupScript() { return `#!/bin/bash # SmartUI Cleanup Script echo "๐Ÿงน Cleaning up SmartUI artifacts..." # Remove temporary files rm -f smartui-*.log rm -f smartui-*.tmp rm -rf .smartui-temp # Clean up test artifacts rm -rf test-results/ rm -rf screenshots/ rm -rf reports/ echo "โœ… Cleanup completed" `; } generateValidationScript() { return `#!/bin/bash # SmartUI Validation Script echo "๐Ÿ” Validating SmartUI configuration..." # Check for required files required_files=(".smartui.json" ".env") for file in "\${required_files[@]}"; do if [ ! -f "\$file" ]; then echo "โŒ Required file missing: \$file" exit 1 else echo "โœ… Found: \$file" fi done # Load environment variables if [ -f .env ]; then export \$(cat .env | grep -v '^#' | xargs) fi # Validate required environment variables required_vars=("LT_USERNAME" "LT_ACCESS_KEY") for var in "\${required_vars[@]}"; do if [ -z "\${!var}" ]; then echo "โŒ Required environment variable not set: \$var" exit 1 else echo "โœ… Environment variable set: \$var" fi done # Validate SmartUI config if command -v jq &> /dev/null; then if jq empty .smartui.json 2>/dev/null; then echo "โœ… .smartui.json is valid JSON" else echo "โŒ .smartui.json is not valid JSON" exit 1 fi else echo "โš ๏ธ jq not found, skipping JSON validation" fi echo "โœ… SmartUI configuration validation passed" `; } async writeScripts(scripts) { const scriptFiles = [ { name: 'setup-smartui.sh', content: scripts.setup }, { name: 'test-smartui.sh', content: scripts.test }, { name: 'cleanup-smartui.sh', content: scripts.cleanup }, { name: 'validate-smartui.sh', content: scripts.validate } ]; for (const script of scriptFiles) { const scriptPath = path.join(this.projectPath, script.name); await fs.writeFile(scriptPath, script.content, 'utf-8'); await fs.chmod(scriptPath, 0o755); } if (this.verbose) Logger_1.logger.debug('Environment scripts written to project'); } } exports.EnvironmentManager = EnvironmentManager; //# sourceMappingURL=EnvironmentManager.js.map