k6-cucumber-steps
Version:
Generate k6 test scripts from Cucumber feature files
224 lines (207 loc) • 8.65 kB
JavaScript
;
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