UNPKG

k6-cucumber-steps

Version:

Generate k6 test scripts from Cucumber feature files

224 lines (207 loc) 8.65 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ProjectGenerator = void 0; // src/generators/project.generator.ts const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); const sample_features_generator_1 = require("./samples/sample-features.generator"); const sample_steps_generator_1 = require("./samples/sample-steps.generator"); class ProjectGenerator { generateProjectStructure(config, outputPath) { // Create main directories this.createDirectory(path_1.default.join(outputPath, "features")); this.createDirectory(path_1.default.join(outputPath, "steps")); this.createDirectory(path_1.default.join(outputPath, "generated")); this.createDirectory(path_1.default.join(outputPath, "data")); this.createDirectory(path_1.default.join(outputPath, "reports")); fs_1.default.mkdirSync(path_1.default.join(outputPath, "data"), { recursive: true }); // Generate package.json this.generatePackageJson(outputPath, config); // Generate README this.generateReadme(outputPath, config); // Generate sample feature files const featuresGenerator = new sample_features_generator_1.SampleFeaturesGenerator(); featuresGenerator.generate(outputPath); // Generate global types for k6 + browser extensions this.generateGlobalTypes(outputPath); // Generate sample step definitions const stepsGenerator = new sample_steps_generator_1.SampleStepsGenerator(); stepsGenerator.generate(outputPath, config); // Generate .env.example file this.generateEnvExample(outputPath); // Generate gitignore this.generateGitignore(outputPath); // Generate tsconfig if TypeScript if (config.language === "ts") { this.generateTsConfig(outputPath); } } createDirectory(dirPath) { if (!fs_1.default.existsSync(dirPath)) { fs_1.default.mkdirSync(dirPath, { recursive: true }); } } generateGlobalTypes(outputPath) { const content = `// Auto-generated by k6-cucumber-steps export {}; declare global { var savedTokens: Record<string, any>; var storedAliases: Record<string, any>; var lastResponse: any; var exportedTokens: Record<string, any>; var baseUrl: string; var lastPostData: string; } `; fs_1.default.writeFileSync(path_1.default.join(outputPath, "global.types.d.ts"), content); } generatePackageJson(outputPath, config) { const pkgPath = path_1.default.join(outputPath, "package.json"); let pkg = {}; // Load existing package.json if it exists if (fs_1.default.existsSync(pkgPath)) { try { pkg = JSON.parse(fs_1.default.readFileSync(pkgPath, "utf8")); console.log("📦 Detected existing package.json — merging..."); } catch (e) { console.warn("⚠️ Invalid package.json. Creating new one."); pkg = {}; } } // Ensure scripts object exists pkg.scripts = pkg.scripts || {}; // Add/merge our scripts (do NOT replace entire scripts object) const lang = config.language === "ts" ? "ts" : "js"; const newScripts = { test: `k6 run generated/test.generated.${lang}`, "test:env": "npx dotenv-cli -- k6 run generated/test.generated.ts", "test:ui": `K6_BROWSER_ENABLED=true k6 run generated/test.generated.${lang}`, "test:ui:env": "K6_BROWSER_ENABLED=true npx dotenv-cli -- k6 run generated/test.generated.ts", "test:ui:headed": `K6_BROWSER_HEADLESS=false K6_BROWSER_ENABLED=true k6 run generated/test.generated.${lang}`, "test:ui:headed:env": "K6_BROWSER_HEADLESS=false K6_BROWSER_ENABLED=true npx dotenv-cli -- k6 run generated/test.generated.ts", "test:api": `K6_BROWSER_ENABLED=false k6 run generated/test.generated.${lang}`, "test:api:env": "K6_BROWSER_ENABLED=false npx dotenv-cli -- k6 run generated/test.generated.ts", generate: `k6-cucumber-steps generate -l ${lang}`, "generate:ui": `k6-cucumber-steps generate -l ${lang} --tags browser`, "generate:api": `k6-cucumber-steps generate -l ${lang} --exclude-tags browser`, }; // Merge: only add/overwrite our scripts, keep others Object.assign(pkg.scripts, newScripts); // Ensure dependencies objects exist pkg.devDependencies = pkg.devDependencies || {}; pkg.dependencies = pkg.dependencies || {}; // Add TypeScript if needed if (config.language === "ts" && !pkg.devDependencies["typescript"]) { pkg.devDependencies["typescript"] = "^5.0.0"; } // Add dotenv-cli for environment variable support pkg.devDependencies["dotenv-cli"] = "^11.0.0"; // Update @types/k6 to latest stable pkg.devDependencies["@types/k6"] = "^1.6.0"; pkg.devDependencies["@types/node"] = "^20.19.34"; // Set top-level fields (only if not already set) pkg.name = pkg.name || "k6-cucumber-test-project"; pkg.version = pkg.version || "1.0.0"; pkg.description = pkg.description || "k6 test project with Cucumber integration"; pkg.main = pkg.main || (config.language === "ts" ? "src/test.ts" : "test.js"); pkg.author = pkg.author || config.author; pkg.license = pkg.license || "MIT"; // Write back fs_1.default.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n"); } generateReadme(outputPath, config) { const readmeContent = `# K6 Cucumber Test Project Generated with k6-cucumber-steps by ${config.author} ## Setup \`\`\`bash npm install \`\`\` ## Running Tests ### Generate k6 scripts from features: \`\`\`bash # Generate all tests npm run generate # Generate only UI/browser tests (tagged @browser) npm run generate:ui # Generate only API tests (non-browser) npm run generate:api \`\`\` ### Run tests: \`\`\`bash # Run all tests npm test # Run only UI/browser tests npm run test:ui # Run only API tests npm run test:api \`\`\` ## Project Structure - \`features/\` - Gherkin feature files - \`sample.feature\` - API testing examples - \`authSample.feature\` - Authentication workflows - \`browserSample.feature\` - Browser automation examples - \`steps/\` - Step definition implementations - \`generated/\` - Generated k6 scripts - \`data/\` - Runtime token storage (auto-generated) - \`reports/\` - HTML and JSON test reports ## Safe Initialization This project was initialized with \`k6-cucumber-steps init\`. Existing project files and dependencies were preserved. `; fs_1.default.writeFileSync(path_1.default.join(outputPath, "README.md"), readmeContent); } generateGitignore(outputPath) { const gitignoreContent = `node_modules/ *.html dist/ build/ reports/ data/*.json .nyc_output/ coverage/ .env `; fs_1.default.writeFileSync(path_1.default.join(outputPath, ".gitignore"), gitignoreContent); } generateTsConfig(outputPath) { const tsconfig = { compilerOptions: { target: "ES2020", module: "commonjs", strict: true, esModuleInterop: true, skipLibCheck: true, forceConsistentCasingInFileNames: true, types: ["k6", "node"], allowImportingTsExtensions: true, noEmit: true, }, include: ["src/**/*", "steps/**/*", "**/*.ts", "**/*.d.ts"], exclude: ["node_modules"], }; fs_1.default.writeFileSync(path_1.default.join(outputPath, "tsconfig.json"), JSON.stringify(tsconfig, null, 2)); } generateEnvExample(outputPath) { const envExampleContent = `# Base URLs API_BASE_URL=https://jsonplaceholder.typicode.com AUTH_BASE_URL=https://demoqa.com # Test User Credentials TEST_USER_USERNAME=your_test_username TEST_USER_PASSWORD=your_test_password # Post Data POST_TITLE=My Test Post # OAuth2 Client Credentials (if applicable) CLIENT_ID=your_client_id CLIENT_SECRET=your_client_secret `; fs_1.default.writeFileSync(path_1.default.join(outputPath, ".env.example"), envExampleContent); } } exports.ProjectGenerator = ProjectGenerator; //# sourceMappingURL=project.generator.js.map