UNPKG

smartui-migration-tool

Version:

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

510 lines 22.5 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.PackageInstaller = void 0; const path = __importStar(require("path")); const fs = __importStar(require("fs/promises")); const child_process_1 = require("child_process"); const util_1 = require("util"); const Logger_1 = require("../utils/Logger"); const execAsync = (0, util_1.promisify)(child_process_1.exec); class PackageInstaller { constructor(projectPath, verbose = false) { this.projectPath = projectPath; this.verbose = verbose; } /** * Install SmartUI packages for the detected project type */ async installSmartUIPackages(framework, language) { const startTime = Date.now(); const result = { success: true, packagesInstalled: [], packagesUpdated: [], packagesRemoved: [], errors: [], warnings: [], packageManager: 'unknown', installationTime: 0 }; try { if (this.verbose) Logger_1.logger.debug('Installing SmartUI packages...'); // Detect package manager const packageManager = await this.detectPackageManager(); result.packageManager = packageManager; if (packageManager === 'unknown') { result.errors.push('Could not detect package manager'); result.success = false; return result; } // Get SmartUI packages for the framework const packages = this.getSmartUIPackages(framework, language, packageManager); if (packages.length === 0) { result.warnings.push(`No SmartUI packages found for framework: ${framework}`); return result; } // Install packages based on package manager switch (packageManager) { case 'npm': case 'yarn': case 'pnpm': await this.installNodePackages(packages, result); break; case 'maven': await this.installMavenPackages(packages, result); break; case 'gradle': await this.installGradlePackages(packages, result); break; case 'pip': await this.installPythonPackages(packages, result); break; default: result.errors.push(`Unsupported package manager: ${packageManager}`); result.success = false; } result.installationTime = Date.now() - startTime; } catch (error) { result.success = false; result.errors.push(`Installation failed: ${error instanceof Error ? error.message : 'Unknown error'}`); result.installationTime = Date.now() - startTime; } return result; } /** * Remove old visual testing packages */ async removeOldPackages(platform, framework) { const startTime = Date.now(); const result = { success: true, packagesInstalled: [], packagesUpdated: [], packagesRemoved: [], errors: [], warnings: [], packageManager: 'unknown', installationTime: 0 }; try { if (this.verbose) Logger_1.logger.debug(`Removing old ${platform} packages...`); const packageManager = await this.detectPackageManager(); result.packageManager = packageManager; const oldPackages = this.getOldPackages(platform, framework, packageManager); if (oldPackages.length === 0) { result.warnings.push(`No old packages found for platform: ${platform}`); return result; } // Remove packages based on package manager switch (packageManager) { case 'npm': case 'yarn': case 'pnpm': await this.removeNodePackages(oldPackages, result); break; case 'maven': await this.removeMavenPackages(oldPackages, result); break; case 'gradle': await this.removeGradlePackages(oldPackages, result); break; case 'pip': await this.removePythonPackages(oldPackages, result); break; default: result.errors.push(`Unsupported package manager: ${packageManager}`); result.success = false; } result.installationTime = Date.now() - startTime; } catch (error) { result.success = false; result.errors.push(`Removal failed: ${error instanceof Error ? error.message : 'Unknown error'}`); result.installationTime = Date.now() - startTime; } return result; } /** * Update package.json scripts for SmartUI */ async updatePackageScripts(framework) { try { const packageJsonPath = path.join(this.projectPath, 'package.json'); const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf-8')); if (!packageJson.scripts) { packageJson.scripts = {}; } // Add SmartUI scripts packageJson.scripts['test:smartui'] = this.getTestScript(framework); packageJson.scripts['smartui:setup'] = 'smartui setup'; packageJson.scripts['smartui:validate'] = 'smartui validate'; packageJson.scripts['smartui:cleanup'] = 'smartui cleanup'; await fs.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2), 'utf-8'); if (this.verbose) Logger_1.logger.debug('Package.json scripts updated'); return true; } catch (error) { if (this.verbose) Logger_1.logger.debug(`Failed to update package.json scripts: ${error instanceof Error ? error.message : 'Unknown error'}`); return false; } } /** * Validate package installation */ async validateInstallation(framework) { const errors = []; const warnings = []; try { const packageManager = await this.detectPackageManager(); const expectedPackages = this.getSmartUIPackages(framework, 'javascript', packageManager); for (const pkg of expectedPackages) { const isInstalled = await this.isPackageInstalled(pkg.name, packageManager); if (!isInstalled) { errors.push(`Required package not installed: ${pkg.name}`); } } // Check for .smartui.json try { await fs.access(path.join(this.projectPath, '.smartui.json')); } catch { warnings.push('.smartui.json configuration file not found'); } } catch (error) { errors.push(`Validation failed: ${error instanceof Error ? error.message : 'Unknown error'}`); } return { valid: errors.length === 0, errors, warnings }; } // Private methods async detectPackageManager() { // Check for package.json (Node.js) try { await fs.access(path.join(this.projectPath, 'package.json')); // Check for lock files to determine specific package manager try { await fs.access(path.join(this.projectPath, 'yarn.lock')); return 'yarn'; } catch { } try { await fs.access(path.join(this.projectPath, 'pnpm-lock.yaml')); return 'pnpm'; } catch { } return 'npm'; } catch { } // Check for pom.xml (Maven) try { await fs.access(path.join(this.projectPath, 'pom.xml')); return 'maven'; } catch { } // Check for build.gradle (Gradle) try { await fs.access(path.join(this.projectPath, 'build.gradle')); return 'gradle'; } catch { } // Check for requirements.txt (Python) try { await fs.access(path.join(this.projectPath, 'requirements.txt')); return 'pip'; } catch { } return 'unknown'; } getSmartUIPackages(framework, language, packageManager) { const packageMap = { 'npm': { 'Selenium': [ { name: '@lambdatest/smartui-selenium', version: '1.0.0', description: 'SmartUI Selenium integration' } ], 'Playwright': [ { name: '@lambdatest/smartui-playwright', version: '1.0.0', description: 'SmartUI Playwright integration' } ], 'Cypress': [ { name: '@lambdatest/smartui-cypress', version: '1.0.0', description: 'SmartUI Cypress integration' } ], 'Puppeteer': [ { name: '@lambdatest/smartui-puppeteer', version: '1.0.0', description: 'SmartUI Puppeteer integration' } ], 'WebdriverIO': [ { name: '@lambdatest/smartui-webdriverio', version: '1.0.0', description: 'SmartUI WebdriverIO integration' } ] }, 'maven': { 'Selenium': [ { name: 'com.lambdatest:smartui-selenium-java', version: '1.0.0', description: 'SmartUI Selenium Java integration' } ], 'Playwright': [ { name: 'com.lambdatest:smartui-playwright-java', version: '1.0.0', description: 'SmartUI Playwright Java integration' } ], 'Appium': [ { name: 'com.lambdatest:smartui-appium-java', version: '1.0.0', description: 'SmartUI Appium Java integration' } ] }, 'gradle': { 'Selenium': [ { name: 'com.lambdatest:smartui-selenium-java', version: '1.0.0', description: 'SmartUI Selenium Java integration' } ], 'Playwright': [ { name: 'com.lambdatest:smartui-playwright-java', version: '1.0.0', description: 'SmartUI Playwright Java integration' } ], 'Appium': [ { name: 'com.lambdatest:smartui-appium-java', version: '1.0.0', description: 'SmartUI Appium Java integration' } ] }, 'pip': { 'Selenium': [ { name: 'lambdatest-smartui-selenium', version: '1.0.0', description: 'SmartUI Selenium Python integration' } ], 'Playwright': [ { name: 'lambdatest-smartui-playwright', version: '1.0.0', description: 'SmartUI Playwright Python integration' } ], 'Pytest': [ { name: 'lambdatest-smartui-pytest', version: '1.0.0', description: 'SmartUI Pytest integration' } ] } }; return packageMap[packageManager]?.[framework] || []; } getOldPackages(platform, framework, packageManager) { const oldPackageMap = { 'npm': { 'Percy': [ { name: '@percy/cli', version: '*', description: 'Percy CLI' }, { name: '@percy/cypress', version: '*', description: 'Percy Cypress integration' }, { name: '@percy/playwright', version: '*', description: 'Percy Playwright integration' }, { name: '@percy/selenium-webdriver', version: '*', description: 'Percy Selenium integration' } ], 'Applitools': [ { name: '@applitools/eyes-cypress', version: '*', description: 'Applitools Eyes Cypress integration' }, { name: '@applitools/eyes-playwright', version: '*', description: 'Applitools Eyes Playwright integration' }, { name: '@applitools/eyes-selenium', version: '*', description: 'Applitools Eyes Selenium integration' } ] }, 'maven': { 'Percy': [ { name: 'io.percy:percy-playwright-java', version: '*', description: 'Percy Playwright Java integration' }, { name: 'io.percy:percy-selenium-java', version: '*', description: 'Percy Selenium Java integration' } ], 'Applitools': [ { name: 'com.applitools:eyes-selenium-java', version: '*', description: 'Applitools Eyes Selenium Java integration' }, { name: 'com.applitools:eyes-playwright-java', version: '*', description: 'Applitools Eyes Playwright Java integration' } ] } }; return oldPackageMap[packageManager]?.[platform] || []; } async installNodePackages(packages, result) { const packageManager = await this.detectPackageManager(); const installCommand = packageManager === 'yarn' ? 'yarn add' : packageManager === 'pnpm' ? 'pnpm add' : 'npm install'; for (const pkg of packages) { try { const command = `${installCommand} ${pkg.name}@${pkg.version}`; if (this.verbose) Logger_1.logger.debug(`Running: ${command}`); // In a real implementation, this would execute the command // await execAsync(command, { cwd: this.projectPath }); result.packagesInstalled.push(`${pkg.name}@${pkg.version}`); if (this.verbose) Logger_1.logger.debug(`Installed: ${pkg.name}@${pkg.version}`); } catch (error) { result.errors.push(`Failed to install ${pkg.name}: ${error instanceof Error ? error.message : 'Unknown error'}`); } } } async installMavenPackages(packages, result) { // In a real implementation, this would update pom.xml for (const pkg of packages) { try { result.packagesInstalled.push(`${pkg.name}:${pkg.version}`); if (this.verbose) Logger_1.logger.debug(`Would add Maven dependency: ${pkg.name}:${pkg.version}`); } catch (error) { result.errors.push(`Failed to add Maven dependency ${pkg.name}: ${error instanceof Error ? error.message : 'Unknown error'}`); } } } async installGradlePackages(packages, result) { // In a real implementation, this would update build.gradle for (const pkg of packages) { try { result.packagesInstalled.push(`${pkg.name}:${pkg.version}`); if (this.verbose) Logger_1.logger.debug(`Would add Gradle dependency: ${pkg.name}:${pkg.version}`); } catch (error) { result.errors.push(`Failed to add Gradle dependency ${pkg.name}: ${error instanceof Error ? error.message : 'Unknown error'}`); } } } async installPythonPackages(packages, result) { for (const pkg of packages) { try { const command = `pip install ${pkg.name}==${pkg.version}`; if (this.verbose) Logger_1.logger.debug(`Running: ${command}`); // In a real implementation, this would execute the command // await execAsync(command, { cwd: this.projectPath }); result.packagesInstalled.push(`${pkg.name}==${pkg.version}`); if (this.verbose) Logger_1.logger.debug(`Installed: ${pkg.name}==${pkg.version}`); } catch (error) { result.errors.push(`Failed to install ${pkg.name}: ${error instanceof Error ? error.message : 'Unknown error'}`); } } } async removeNodePackages(packages, result) { const packageManager = await this.detectPackageManager(); const removeCommand = packageManager === 'yarn' ? 'yarn remove' : packageManager === 'pnpm' ? 'pnpm remove' : 'npm uninstall'; for (const pkg of packages) { try { const command = `${removeCommand} ${pkg.name}`; if (this.verbose) Logger_1.logger.debug(`Running: ${command}`); // In a real implementation, this would execute the command // await execAsync(command, { cwd: this.projectPath }); result.packagesRemoved.push(pkg.name); if (this.verbose) Logger_1.logger.debug(`Removed: ${pkg.name}`); } catch (error) { result.errors.push(`Failed to remove ${pkg.name}: ${error instanceof Error ? error.message : 'Unknown error'}`); } } } async removeMavenPackages(packages, result) { // In a real implementation, this would update pom.xml for (const pkg of packages) { try { result.packagesRemoved.push(pkg.name); if (this.verbose) Logger_1.logger.debug(`Would remove Maven dependency: ${pkg.name}`); } catch (error) { result.errors.push(`Failed to remove Maven dependency ${pkg.name}: ${error instanceof Error ? error.message : 'Unknown error'}`); } } } async removeGradlePackages(packages, result) { // In a real implementation, this would update build.gradle for (const pkg of packages) { try { result.packagesRemoved.push(pkg.name); if (this.verbose) Logger_1.logger.debug(`Would remove Gradle dependency: ${pkg.name}`); } catch (error) { result.errors.push(`Failed to remove Gradle dependency ${pkg.name}: ${error instanceof Error ? error.message : 'Unknown error'}`); } } } async removePythonPackages(packages, result) { for (const pkg of packages) { try { const command = `pip uninstall -y ${pkg.name}`; if (this.verbose) Logger_1.logger.debug(`Running: ${command}`); // In a real implementation, this would execute the command // await execAsync(command, { cwd: this.projectPath }); result.packagesRemoved.push(pkg.name); if (this.verbose) Logger_1.logger.debug(`Removed: ${pkg.name}`); } catch (error) { result.errors.push(`Failed to remove ${pkg.name}: ${error instanceof Error ? error.message : 'Unknown error'}`); } } } async isPackageInstalled(packageName, packageManager) { try { switch (packageManager) { case 'npm': case 'yarn': case 'pnpm': const packageJsonPath = path.join(this.projectPath, 'package.json'); const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf-8')); return !!(packageJson.dependencies?.[packageName] || packageJson.devDependencies?.[packageName]); case 'maven': const pomPath = path.join(this.projectPath, 'pom.xml'); const pomContent = await fs.readFile(pomPath, 'utf-8'); return pomContent.includes(packageName); case 'gradle': const gradlePath = path.join(this.projectPath, 'build.gradle'); const gradleContent = await fs.readFile(gradlePath, 'utf-8'); return gradleContent.includes(packageName); case 'pip': const requirementsPath = path.join(this.projectPath, 'requirements.txt'); const requirementsContent = await fs.readFile(requirementsPath, 'utf-8'); return requirementsContent.includes(packageName); default: return false; } } catch { return false; } } getTestScript(framework) { const scriptMap = { 'Selenium': 'smartui-selenium test', 'Playwright': 'smartui-playwright test', 'Cypress': 'smartui-cypress test', 'Puppeteer': 'smartui-puppeteer test', 'WebdriverIO': 'smartui-webdriverio test' }; return scriptMap[framework] || 'smartui test'; } } exports.PackageInstaller = PackageInstaller; //# sourceMappingURL=PackageInstaller.js.map