UNPKG

tdpw

Version:

CLI tool for uploading Playwright test reports to TestDino platform with Azure storage support

171 lines (167 loc) 6.76 kB
"use strict"; /** * CLI argument parser using Commander.js */ Object.defineProperty(exports, "__esModule", { value: true }); exports.cliParser = exports.CliParser = void 0; const commander_1 = require("commander"); const zod_1 = require("zod"); const types_1 = require("../types"); /** * CLI argument parser and validator */ class CliParser { program; constructor() { this.program = new commander_1.Command(); this.setupProgram(); } /** * Configure the CLI program with all options and metadata */ setupProgram() { this.program .name('tdpw') .description('Upload Playwright test reports to TestDino platform') .version('1.0.0') .usage('<report-directory> [options]') .argument('<report-directory>', 'Directory containing Playwright test reports (e.g., ./playwright-report)') .option('-t, --token <value>', 'TestDino API token (required, can be set via TESTDINO_TOKEN env var)') .option('--upload-images', 'Upload image attachments (screenshots) to TestDino server', false) .option('--upload-videos', 'Upload video attachments to TestDino server', false) .option('--upload-html', 'Upload HTML reports with images and videos to TestDino server', false) .option('--upload-traces', 'Upload trace files to TestDino server (not implemented yet)', false) .option('--json-report <path>', 'Specific path to JSON report file (auto-detected if not provided)') .option('--html-report <path>', 'Specific path to HTML report directory (auto-detected if not provided)') .option('--trace-dir <path>', 'Specific path to trace files directory (auto-detected if not provided)') .option('-v, --verbose', 'Enable verbose logging for debugging', false) .option('--dry-run', 'Validate configuration and discover reports without uploading', false) .addHelpText('after', ` Examples: $ npx tdpw ./playwright-report --token="trx_dev_abc123..." $ npx tdpw ./test-results --upload-images $ npx tdpw ./test-results --upload-html $ npx tdpw ./reports --upload-images --upload-videos --verbose $ npx tdpw ./custom --json-report ./custom/results.json --dry-run Flag Combinations: No flags: Only JSON report uploaded --upload-images: JSON + image attachments --upload-videos: JSON + video attachments --upload-images --upload-videos: JSON + images + videos --upload-html: JSON + HTML + images + videos (complete bundle) Environment Variables: TESTDINO_API_URL API endpoint (development only) TESTDINO_TOKEN API authentication token TESTDINO_UPLOAD_IMAGES Upload image attachments (true/false) TESTDINO_UPLOAD_VIDEOS Upload video attachments (true/false) TESTDINO_UPLOAD_HTML Upload HTML reports (true/false) TESTDINO_UPLOAD_TRACES Upload trace files (true/false) TESTDINO_VERBOSE Enable verbose logging (true/false) Token Format: API tokens must follow the format: trx_{environment}_{64-char-hex} Example: trx_development_a1b2c3d4e5f6... For more information, visit: https://docs.testdino.com/cli `); // Add error handling for unknown options this.program.on('option:unknown', (option) => { throw new types_1.ValidationError(`Unknown option: ${option}. Use --help to see available options.`); }); } /** * Parse and validate CLI arguments */ parseArguments(args = process.argv) { try { // Parse arguments using Commander this.program.parse(args); const options = this.program.opts(); const reportDirectory = this.program.args[0]; // Build CLI options object const cliOptions = { reportDirectory, token: options.token, uploadImages: options.uploadImages, uploadVideos: options.uploadVideos, uploadHtml: options.uploadHtml, uploadTraces: options.uploadTraces, jsonReport: options.jsonReport, htmlReport: options.htmlReport, traceDir: options.traceDir, verbose: options.verbose, dryRun: options.dryRun, }; // Validate using Zod schema const validatedOptions = types_1.CLIOptionsSchema.parse(cliOptions); // Log parsed options (with token masked) if verbose if (validatedOptions.verbose) { console.log('✅ Parsed CLI options:', { ...validatedOptions, token: (0, types_1.maskToken)(validatedOptions.token), }); } return validatedOptions; } catch (error) { if (error instanceof zod_1.z.ZodError) { const issues = error.issues.map(issue => { const field = issue.path.join('.'); return `${field}: ${issue.message}`; }); throw new types_1.ValidationError(`Invalid arguments: ${issues.join(', ')}`); } // Re-throw other errors as-is throw error; } } /** * Display help information */ showHelp() { this.program.help(); } /** * Get the version string */ getVersion() { return this.program.version() || '1.0.0'; } /** * Validate that required arguments are present */ validateRequiredArgs(options) { const errors = []; if (!options.reportDirectory) { errors.push('Report directory is required'); } if (!options.token) { errors.push('API token is required (use --token or TESTDINO_TOKEN env var)'); } if (errors.length > 0) { throw new types_1.ValidationError(`Missing required arguments: ${errors.join(', ')}`); } } /** * Enhanced parse with better error handling */ parseWithErrorHandling(args = process.argv) { try { const options = this.parseArguments(args); this.validateRequiredArgs(options); return options; } catch (error) { if (error instanceof types_1.ValidationError) { console.error(`❌ ${error.message}`); console.error('\nUse --help for usage information.'); process.exit(1); } throw error; } } } exports.CliParser = CliParser; /** * Create and export parser instance */ exports.cliParser = new CliParser(); //# sourceMappingURL=parser.js.map