smartui-migration-tool
Version:
Enterprise-grade CLI tool for migrating visual testing platforms to LambdaTest SmartUI
375 lines • 15.3 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.CSharpCodeTransformer = void 0;
const fs = __importStar(require("fs/promises"));
const Logger_1 = require("../utils/Logger");
class CSharpCodeTransformer {
constructor(verbose = false) {
this.verbose = verbose;
}
/**
* Transform C# code from Applitools to SmartUI
*/
async transformFile(filePath, platform, framework) {
try {
const content = await fs.readFile(filePath, 'utf-8');
const lines = content.split('\n');
const changes = [];
const errors = [];
if (this.verbose)
Logger_1.logger.debug(`Transforming C# file: ${filePath}`);
// Transform based on platform
switch (platform) {
case 'Applitools':
await this.transformApplitoolsCode(lines, changes, errors, framework);
break;
case 'Percy':
await this.transformPercyCode(lines, changes, errors, framework);
break;
case 'Sauce Labs':
await this.transformSauceLabsCode(lines, changes, errors, framework);
break;
default:
errors.push(`Unsupported platform: ${platform}`);
}
if (changes.length > 0) {
const transformedContent = this.applyChanges(lines, changes);
await fs.writeFile(filePath, transformedContent, 'utf-8');
if (this.verbose)
Logger_1.logger.debug(`Applied ${changes.length} changes to ${filePath}`);
}
return {
success: errors.length === 0,
changes,
errors
};
}
catch (error) {
return {
success: false,
changes: [],
errors: [error instanceof Error ? error.message : 'Unknown error']
};
}
}
/**
* Transform Applitools C# code to SmartUI
*/
async transformApplitoolsCode(lines, changes, errors, framework) {
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
if (!line)
continue;
const trimmedLine = line.trim();
// Transform using statements
if (trimmedLine.startsWith('using Applitools')) {
const newUsing = this.transformApplitoolsUsing(trimmedLine, framework);
if (newUsing) {
changes.push({
type: 'using_statement',
line: i + 1,
oldCode: line,
newCode: line.replace(trimmedLine, newUsing),
description: `Replace Applitools using statement with SmartUI`
});
}
}
// Transform class declarations
if (trimmedLine.includes('Eyes') && !trimmedLine.includes('SmartUI')) {
const newClass = this.transformApplitoolsClass(trimmedLine, framework);
if (newClass) {
changes.push({
type: 'class_instantiation',
line: i + 1,
oldCode: line,
newCode: line.replace(trimmedLine, newClass),
description: `Replace Applitools Eyes class with SmartUI`
});
}
}
// Transform variable declarations
if (trimmedLine.includes('Eyes eyes') || trimmedLine.includes('Eyes eyes =')) {
const newVariable = this.transformApplitoolsVariable(trimmedLine, framework);
if (newVariable) {
changes.push({
type: 'variable',
line: i + 1,
oldCode: line,
newCode: line.replace(trimmedLine, newVariable),
description: `Replace Applitools Eyes variable with SmartUI`
});
}
}
// Transform method calls
if (trimmedLine.includes('eyes.') && !trimmedLine.includes('SmartUI')) {
const newMethodCall = this.transformApplitoolsMethodCall(trimmedLine, framework);
if (newMethodCall) {
changes.push({
type: 'method_call',
line: i + 1,
oldCode: line,
newCode: line.replace(trimmedLine, newMethodCall),
description: `Replace Applitools method call with SmartUI`
});
}
}
}
}
/**
* Transform Percy C# code to SmartUI
*/
async transformPercyCode(lines, changes, errors, framework) {
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
if (!line)
continue;
const trimmedLine = line.trim();
// Transform using statements
if (trimmedLine.startsWith('using Percy')) {
const newUsing = this.transformPercyUsing(trimmedLine, framework);
if (newUsing) {
changes.push({
type: 'using_statement',
line: i + 1,
oldCode: line,
newCode: line.replace(trimmedLine, newUsing),
description: `Replace Percy using statement with SmartUI`
});
}
}
// Transform method calls
if (trimmedLine.includes('percy.') || trimmedLine.includes('Percy.')) {
const newMethodCall = this.transformPercyMethodCall(trimmedLine, framework);
if (newMethodCall) {
changes.push({
type: 'method_call',
line: i + 1,
oldCode: line,
newCode: line.replace(trimmedLine, newMethodCall),
description: `Replace Percy method call with SmartUI`
});
}
}
}
}
/**
* Transform Sauce Labs C# code to SmartUI
*/
async transformSauceLabsCode(lines, changes, errors, framework) {
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
if (!line)
continue;
const trimmedLine = line.trim();
// Transform using statements
if (trimmedLine.startsWith('using SauceLabs')) {
const newUsing = this.transformSauceLabsUsing(trimmedLine, framework);
if (newUsing) {
changes.push({
type: 'using_statement',
line: i + 1,
oldCode: line,
newCode: line.replace(trimmedLine, newUsing),
description: `Replace Sauce Labs using statement with SmartUI`
});
}
}
// Transform method calls
if (trimmedLine.includes('sauce.') || trimmedLine.includes('SauceLabs.')) {
const newMethodCall = this.transformSauceLabsMethodCall(trimmedLine, framework);
if (newMethodCall) {
changes.push({
type: 'method_call',
line: i + 1,
oldCode: line,
newCode: line.replace(trimmedLine, newMethodCall),
description: `Replace Sauce Labs method call with SmartUI`
});
}
}
}
}
// Applitools transformation methods
transformApplitoolsUsing(usingStatement, framework) {
if (usingStatement.includes('Applitools.Eyes')) {
return 'using LambdaTest.SmartUI;';
}
if (usingStatement.includes('Applitools.Selenium')) {
return 'using LambdaTest.SmartUI;';
}
if (usingStatement.includes('Applitools.Playwright')) {
return 'using LambdaTest.SmartUI;';
}
return null;
}
transformApplitoolsClass(classDeclaration, framework) {
if (classDeclaration.includes('Eyes eyes')) {
return classDeclaration.replace('Eyes eyes', 'SmartUI eyes');
}
if (classDeclaration.includes('Eyes eyes =')) {
return classDeclaration.replace('Eyes eyes =', 'SmartUI eyes =');
}
return null;
}
transformApplitoolsVariable(variableDeclaration, framework) {
if (variableDeclaration.includes('Eyes eyes')) {
return variableDeclaration.replace('Eyes eyes', 'SmartUI eyes');
}
return null;
}
transformApplitoolsMethodCall(methodCall, framework) {
// Transform eyes.Open() to SmartUI initialization
if (methodCall.includes('eyes.Open(')) {
return methodCall.replace('eyes.Open(', 'eyes = new SmartUI(');
}
// Transform eyes.Check() to SmartUI snapshot
if (methodCall.includes('eyes.Check(')) {
const snapshotName = this.extractSnapshotName(methodCall);
if (framework === 'Playwright') {
return `SmartUISnapshot.SmartUISnapshot(driver, "${snapshotName}");`;
}
else {
return `SmartUISnapshot.SmartUISnapshot(driver, "${snapshotName}");`;
}
}
// Transform eyes.Close() to SmartUI cleanup
if (methodCall.includes('eyes.Close()')) {
return '// SmartUI cleanup handled automatically';
}
return null;
}
// Percy transformation methods
transformPercyUsing(usingStatement, framework) {
if (usingStatement.includes('Percy')) {
return 'using LambdaTest.SmartUI;';
}
return null;
}
transformPercyMethodCall(methodCall, framework) {
// Transform percy.snapshot() to SmartUI snapshot
if (methodCall.includes('percy.snapshot(') || methodCall.includes('Percy.snapshot(')) {
const snapshotName = this.extractSnapshotName(methodCall);
if (framework === 'Playwright') {
return `SmartUISnapshot.SmartUISnapshot(driver, "${snapshotName}");`;
}
else {
return `SmartUISnapshot.SmartUISnapshot(driver, "${snapshotName}");`;
}
}
return null;
}
// Sauce Labs transformation methods
transformSauceLabsUsing(usingStatement, framework) {
if (usingStatement.includes('SauceLabs')) {
return 'using LambdaTest.SmartUI;';
}
return null;
}
transformSauceLabsMethodCall(methodCall, framework) {
// Transform sauce.screenshot() to SmartUI snapshot
if (methodCall.includes('sauce.screenshot(') || methodCall.includes('SauceLabs.screenshot(')) {
const snapshotName = this.extractSnapshotName(methodCall);
if (framework === 'Playwright') {
return `SmartUISnapshot.SmartUISnapshot(driver, "${snapshotName}");`;
}
else {
return `SmartUISnapshot.SmartUISnapshot(driver, "${snapshotName}");`;
}
}
return null;
}
// Helper methods
extractSnapshotName(methodCall) {
// Extract snapshot name from method call
const match = methodCall.match(/["']([^"']+)["']/);
return match ? match[1] || 'snapshot' : 'snapshot';
}
applyChanges(lines, changes) {
// Sort changes by line number in descending order to avoid index issues
const sortedChanges = changes.sort((a, b) => b.line - a.line);
for (const change of sortedChanges) {
const lineIndex = change.line - 1;
if (lineIndex >= 0 && lineIndex < lines.length) {
lines[lineIndex] = change.newCode;
}
}
return lines.join('\n');
}
/**
* Get import mappings for C# projects
*/
getImportMappings(platform, framework) {
const mappings = {};
switch (platform) {
case 'Applitools':
mappings['Applitools.Eyes'] = 'LambdaTest.SmartUI';
mappings['Applitools.Selenium'] = 'LambdaTest.SmartUI';
mappings['Applitools.Playwright'] = 'LambdaTest.SmartUI';
break;
case 'Percy':
mappings['Percy'] = 'LambdaTest.SmartUI';
break;
case 'Sauce Labs':
mappings['SauceLabs'] = 'LambdaTest.SmartUI';
break;
}
return mappings;
}
/**
* Get method mappings for C# projects
*/
getMethodMappings(platform, framework) {
const mappings = {};
switch (platform) {
case 'Applitools':
mappings['eyes.Open'] = 'new SmartUI';
mappings['eyes.Check'] = 'SmartUISnapshot.SmartUISnapshot';
mappings['eyes.Close'] = '// SmartUI cleanup';
break;
case 'Percy':
mappings['percy.snapshot'] = 'SmartUISnapshot.SmartUISnapshot';
mappings['Percy.snapshot'] = 'SmartUISnapshot.SmartUISnapshot';
break;
case 'Sauce Labs':
mappings['sauce.screenshot'] = 'SmartUISnapshot.SmartUISnapshot';
mappings['SauceLabs.screenshot'] = 'SmartUISnapshot.SmartUISnapshot';
break;
}
return mappings;
}
}
exports.CSharpCodeTransformer = CSharpCodeTransformer;
//# sourceMappingURL=CSharpCodeTransformer.js.map
;