UNPKG

cypress-bootstrap

Version:

Cypress Bootstrap is a project scaffolding tool that sets up a Cypress automation framework with a standardized folder structure and Page Object Model (POM) design. It helps teams quickly start testing with built-in best practices and sample specs.

198 lines (169 loc) 6.19 kB
#!/usr/bin/env node const fs = require('fs'); const path = require('path'); // Get the paths const packageRoot = path.resolve(__dirname, '..'); const userProjectRoot = process.cwd(); // Skip if we're in the package directory (during development) if (packageRoot === userProjectRoot) { console.log('Running in package directory, skipping setup'); process.exit(0); } // Create the directory structure const directories = [ 'cypress', 'cypress/downloads', 'cypress/pages', 'cypress/reports', 'cypress/screenshots', 'cypress/support', 'cypress/testbase', 'cypress/testdata', 'cypress/tests', 'cypress/tests/api', 'cypress/tests/ui', 'cypress/videos', ]; // Create directories if they don't exist directories.forEach(dir => { const dirPath = path.join(userProjectRoot, dir); if (!fs.existsSync(dirPath)) { fs.mkdirSync(dirPath, { recursive: true }); console.log(`Created directory: ${dir}`); } }); // Files that should be copied to the user's project and be modifiable const filesToCopy = [ 'cypress.config.ts', 'cypress.env.json', 'reporter-config.ts', 'tsconfig.json', '.prettierrc', '.prettierignore', ]; // Special case for gitignore (npm doesn't include .gitignore in packages) const specialFiles = [{ source: 'gitignore', dest: '.gitignore' }]; // Copy files filesToCopy.forEach(file => { const sourcePath = path.join(packageRoot, file); const destPath = path.join(userProjectRoot, file); // Only copy if the source file exists and the destination file doesn't exist if (fs.existsSync(sourcePath) && !fs.existsSync(destPath)) { fs.copyFileSync(sourcePath, destPath); console.log(`Copied file: ${file}`); } else if (!fs.existsSync(sourcePath)) { console.log(`Warning: Source file not found: ${file}, skipping`); } }); // Copy special files (with different source and destination names) specialFiles.forEach(fileObj => { const sourcePath = path.join(packageRoot, fileObj.source); const destPath = path.join(userProjectRoot, fileObj.dest); // Only copy if the source file exists and the destination file doesn't exist if (fs.existsSync(sourcePath) && !fs.existsSync(destPath)) { fs.copyFileSync(sourcePath, destPath); console.log(`Copied file: ${fileObj.source} to ${fileObj.dest}`); } else if (!fs.existsSync(sourcePath)) { console.log(`Warning: Source file not found: ${fileObj.source}, skipping`); } }); // Copy directories that should be modifiable const directoriesToCopy = [ 'cypress/testbase', 'cypress/testdata', 'cypress/tests', 'cypress/support', 'cypress/pages', '.husky', ]; // Function to copy a directory recursively function copyDir(src, dest) { // Create destination directory if it doesn't exist if (!fs.existsSync(dest)) { fs.mkdirSync(dest, { recursive: true }); } // Read source directory const entries = fs.readdirSync(src, { withFileTypes: true }); // Copy each entry for (const entry of entries) { const srcPath = path.join(src, entry.name); const destPath = path.join(dest, entry.name); if (entry.isDirectory()) { // Recursively copy subdirectories copyDir(srcPath, destPath); } else { // Copy files if source exists and they don't exist in the destination if (fs.existsSync(srcPath) && !fs.existsSync(destPath)) { fs.copyFileSync(srcPath, destPath); console.log( `Copied file: ${path.relative(packageRoot, srcPath)} to ${path.relative( userProjectRoot, destPath )}` ); } else if (!fs.existsSync(srcPath)) { console.log( `Warning: Source file not found: ${path.relative(packageRoot, srcPath)}, skipping` ); } } } } // Copy modifiable directories directoriesToCopy.forEach(dir => { const sourcePath = path.join(packageRoot, dir); const destPath = path.join(userProjectRoot, dir); if (fs.existsSync(sourcePath)) { copyDir(sourcePath, destPath); console.log(`Copied directory: ${dir}`); } }); // Install dependencies console.log('Installing required dependencies...'); const { execSync } = require('child_process'); try { // Read the package.json file from the package const packageJsonPath = path.join(packageRoot, 'package.json'); const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); // Get the devDependencies const devDependencies = packageJson.devDependencies || {}; // Create a temporary package.json with just the devDependencies if it doesn't exist const userPackageJsonPath = path.join(userProjectRoot, 'package.json'); let userPackageJson = {}; if (fs.existsSync(userPackageJsonPath)) { // Read existing package.json userPackageJson = JSON.parse(fs.readFileSync(userPackageJsonPath, 'utf8')); // Merge devDependencies userPackageJson.devDependencies = { ...(userPackageJson.devDependencies || {}), ...devDependencies, }; // Write updated package.json fs.writeFileSync(userPackageJsonPath, JSON.stringify(userPackageJson, null, 2)); } else { // Create a new package.json with minimal info and the devDependencies userPackageJson = { name: 'cypress-project', version: '1.0.0', description: 'Project using cypress-bootstrap', devDependencies: devDependencies, }; // Write new package.json fs.writeFileSync(userPackageJsonPath, JSON.stringify(userPackageJson, null, 2)); } console.log('Installing dependencies. This may take a few minutes...'); execSync('npm install', { cwd: userProjectRoot, stdio: 'inherit' }); console.log('Dependencies installed successfully!'); } catch (error) { console.error('Error installing dependencies:', error.message); console.log('Please run "npm install" manually to install the required dependencies.'); } console.log('Setup completed successfully!'); console.log('You can now modify the following files and directories:'); console.log('- cypress.config.ts'); console.log('- cypress/testbase/'); console.log('- cypress/testdata/'); console.log('- cypress/tests/'); console.log('- tsconfig.json'); console.log('- reporter-config.ts'); console.log('- .gitignore');