claude-playwright
Version:
Seamless integration between Claude Code and Playwright MCP for efficient browser automation and testing
256 lines (247 loc) • 8.78 kB
JavaScript
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TemplateGenerator = void 0;
const fs_extra_1 = __importDefault(require("fs-extra"));
const path_1 = __importDefault(require("path"));
const chalk_1 = __importDefault(require("chalk"));
class TemplateGenerator {
constructor(projectPath, templateVars = {}) {
this.templatesDir = path_1.default.join(__dirname, '../../templates');
this.projectPath = projectPath;
this.templateVars = templateVars;
}
/**
* Generate project from template
*/
async generateFromTemplate(templateName, metadata) {
const templatePath = path_1.default.join(this.templatesDir, templateName);
if (!await fs_extra_1.default.pathExists(templatePath)) {
throw new Error(`Template directory not found: ${templatePath}`);
}
console.log(chalk_1.default.blue(`\n=� Generating ${metadata.name}...`));
// Create project directories
await this.createDirectories(templateName);
// Process template files
await this.processTemplateFiles(templatePath);
// Generate package.json with template-specific dependencies
await this.generatePackageJson(metadata);
// Create gitignore
await this.createGitIgnore();
// Create additional directories based on template
await this.createTemplateDirs(templateName);
console.log(chalk_1.default.green(` ${metadata.name} generated successfully`));
}
/**
* Create base project directories
*/
async createDirectories(templateName) {
const baseDirs = [
'src/pages/base',
'src/tests',
'src/fixtures',
'src/utils',
'browser-profiles',
'auth-states',
'screenshots',
'test-results',
'playwright-report'
];
// Add template-specific directories
if (templateName === 'enterprise') {
baseDirs.push('src/pages/components', 'docker', 'lighthouse-reports', '.github/workflows');
}
for (const dir of baseDirs) {
await fs_extra_1.default.ensureDir(path_1.default.join(this.projectPath, dir));
}
console.log(chalk_1.default.gray(' Project structure created'));
}
/**
* Process all template files
*/
async processTemplateFiles(templatePath) {
const files = await this.getTemplateFiles(templatePath);
for (const file of files) {
await this.processTemplateFile(file);
}
console.log(chalk_1.default.gray(' Template files processed'));
}
/**
* Get all template files recursively
*/
async getTemplateFiles(dirPath) {
const files = [];
const items = await fs_extra_1.default.readdir(dirPath, { withFileTypes: true });
for (const item of items) {
const fullPath = path_1.default.join(dirPath, item.name);
if (item.isDirectory()) {
const subFiles = await this.getTemplateFiles(fullPath);
files.push(...subFiles);
}
else if (item.isFile() && item.name.endsWith('.template')) {
files.push(fullPath);
}
}
return files;
}
/**
* Process individual template file
*/
async processTemplateFile(filePath) {
const content = await fs_extra_1.default.readFile(filePath, 'utf-8');
const processedContent = this.replaceTemplateVars(content);
// Calculate target path (remove .template extension and adjust path)
const relativePath = path_1.default.relative(path_1.default.join(this.templatesDir, path_1.default.basename(path_1.default.dirname(filePath))), filePath);
const targetPath = path_1.default.join(this.projectPath, relativePath.replace('.template', ''));
// Ensure target directory exists
await fs_extra_1.default.ensureDir(path_1.default.dirname(targetPath));
// Write processed file
await fs_extra_1.default.writeFile(targetPath, processedContent);
}
/**
* Replace template variables in content
*/
replaceTemplateVars(content) {
let processed = content;
for (const [key, value] of Object.entries(this.templateVars)) {
const pattern = new RegExp(`\\{\\{${key}\\}\\}`, 'g');
processed = processed.replace(pattern, value);
}
return processed;
}
/**
* Generate package.json with template dependencies
*/
async generatePackageJson(metadata) {
const packageJsonPath = path_1.default.join(this.projectPath, 'package.json');
const packageJson = {
name: this.templateVars.PROJECT_NAME || 'playwright-project',
version: '1.0.0',
description: `Playwright testing project generated with ${metadata.name}`,
type: 'module',
scripts: {
'test': 'playwright test',
'test:ui': 'playwright test --ui',
'test:debug': 'playwright test --debug',
'test:headed': 'playwright test --headed',
'report': 'playwright show-report',
'codegen': 'playwright codegen'
},
dependencies: {
...metadata.dependencies
},
devDependencies: {
...metadata.devDependencies
}
};
// Add enterprise-specific scripts
if (metadata.name.includes('Enterprise')) {
const enterpriseScripts = {
'test:docker': 'docker-compose up --build playwright-tests',
'test:visual': 'playwright test --grep="@visual"',
'test:performance': 'playwright test --grep="@performance"',
'test:smoke': 'playwright test --grep="@smoke"',
'docker:build': 'docker-compose build',
'docker:up': 'docker-compose up -d',
'docker:down': 'docker-compose down'
};
packageJson.scripts = {
...packageJson.scripts,
...enterpriseScripts
};
}
await fs_extra_1.default.writeJSON(packageJsonPath, packageJson, { spaces: 2 });
console.log(chalk_1.default.gray(' package.json generated'));
}
/**
* Create .gitignore file
*/
async createGitIgnore() {
const gitignoreContent = `# Dependencies
node_modules/
/.pnp
.pnp.js
# Testing
/coverage
test-results/
playwright-report/
playwright/.cache/
# Production
/build
/dist
# Environment variables
.env
.env.local
.env.development.local
.env.test.local
.env.production.local
# Browser data
browser-profiles/
auth-states/
# Screenshots
screenshots/
# Logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# OS
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
# IDEs
.vscode/
.idea/
*.swp
*.swo
# Docker
.dockerignore
`;
await fs_extra_1.default.writeFile(path_1.default.join(this.projectPath, '.gitignore'), gitignoreContent);
console.log(chalk_1.default.gray(' .gitignore created'));
}
/**
* Create template-specific directories
*/
async createTemplateDirs(templateName) {
if (templateName === 'enterprise') {
// Create docker config directory
const dockerDir = path_1.default.join(this.projectPath, 'docker');
await fs_extra_1.default.ensureDir(dockerDir);
// Create nginx config for Docker
const nginxConfig = `events {}
http {
server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html;
try_files $uri $uri/ /index.html;
}
}
}`;
await fs_extra_1.default.writeFile(path_1.default.join(dockerDir, 'nginx.conf'), nginxConfig);
}
if (templateName === 'testing') {
// Create specific test data directories
const testDataDir = path_1.default.join(this.projectPath, 'test-data');
await fs_extra_1.default.ensureDir(testDataDir);
await fs_extra_1.default.ensureDir(path_1.default.join(testDataDir, 'fixtures'));
await fs_extra_1.default.ensureDir(path_1.default.join(testDataDir, 'mocks'));
}
}
/**
* Set template variables
*/
setTemplateVars(vars) {
this.templateVars = { ...this.templateVars, ...vars };
}
}
exports.TemplateGenerator = TemplateGenerator;
//# sourceMappingURL=template-generator.js.map
;