smartui-migration-tool
Version:
Enterprise-grade CLI tool for migrating visual testing platforms to LambdaTest SmartUI
510 lines • 22.5 kB
JavaScript
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
;