UNPKG

arda-site-scan

Version:

A standalone CLI tool for comprehensive website analysis including screenshots, SEO, and accessibility testing using Playwright

206 lines 7.81 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.StandardTestOutputHandler = void 0; const path_1 = __importDefault(require("path")); const fs_1 = require("fs"); const chalk_1 = __importDefault(require("chalk")); const test_output_types_js_1 = require("../types/test-output-types.js"); /** * Centralized handler for all test output operations * Implements DRY principles and standardized file management */ class StandardTestOutputHandler { outputDir; constructor(outputDir = 'arda-site-scan-sessions') { this.outputDir = outputDir; } /** * Generate the appropriate output path for a test */ generateOutputPath(sessionId, testType, config, context) { const baseDir = path_1.default.join(this.outputDir, sessionId); // Generate filename from pattern const filename = this.generateFilename(testType, config, context); if (config.type === 'per-page') { if (!context.pageName) { throw new Error(`Page name is required for per-page test output: ${testType}`); } // Per-page tests go in page-specific subdirectories const pagePath = path_1.default.join(baseDir, context.pageName); if (config.subdirectory) { return path_1.default.join(pagePath, config.subdirectory, filename); } return path_1.default.join(pagePath, filename); } else { // Site-wide tests go in session root if (config.subdirectory) { return path_1.default.join(baseDir, config.subdirectory, filename); } return path_1.default.join(baseDir, filename); } } /** * Save content to the appropriate location */ async saveOutput(content, outputPath, config) { try { // Ensure directory exists await this.ensureOutputDirectory(outputPath); // Write file await fs_1.promises.writeFile(outputPath, content, 'utf8'); // Get file stats const stats = await fs_1.promises.stat(outputPath); console.log(chalk_1.default.green(` 📄 ${config.type === 'per-page' ? 'Page' : 'Site'} output saved: ${outputPath}`)); return { success: true, outputPath, fileSize: stats.size, metadata: { type: config.type, extension: config.fileExtension, mimeType: config.mimeType } }; } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); console.error(chalk_1.default.red(` ❌ Failed to save output: ${errorMessage}`)); return { success: false, error: errorMessage }; } } /** * Ensure the necessary directories exist for the output */ async ensureOutputDirectory(outputPath) { const dirPath = path_1.default.dirname(outputPath); await fs_1.promises.mkdir(dirPath, { recursive: true }); } /** * Get relative path for use in reports and links */ getRelativePath(outputPath, basePath) { return path_1.default.relative(basePath, outputPath); } /** * Generate standardized filename from pattern and context */ generateFilename(testType, config, context) { const pattern = config.filenamePattern || testType; let filename = test_output_types_js_1.OutputTypeUtils.replacePlaceholders(pattern, { pageName: context.pageName, testType: testType, viewport: context.viewport, ...context.additionalData }); // Ensure filename is safe for filesystem filename = this.sanitizeFilename(filename); return `${filename}.${config.fileExtension}`; } /** * Sanitize filename for cross-platform compatibility */ sanitizeFilename(filename) { return filename .replace(/[<>:"/\\|?*]/g, '-') // Replace invalid characters .replace(/\s+/g, '-') // Replace spaces with hyphens .replace(/-+/g, '-') // Replace multiple hyphens with single .replace(/^-|-$/g, '') // Remove leading/trailing hyphens .toLowerCase(); } /** * Create a standardized test result with output information */ static createTestResult(testType, status, outputResult, error) { const config = test_output_types_js_1.OUTPUT_CONFIGURATIONS[testType]; return { testType, status, startTime: new Date(), endTime: status !== 'pending' ? new Date() : undefined, outputPath: outputResult?.outputPath, outputType: config?.type, error }; } /** * Update an existing test result with completion information */ static completeTestResult(testResult, status, outputResult, error) { return { ...testResult, status, endTime: new Date(), outputPath: outputResult?.outputPath, error }; } /** * Get page name from URL (utility method) */ static getPageNameFromUrl(url) { try { const urlObj = new URL(url); const pathSegments = urlObj.pathname.split('/').filter(segment => segment.length > 0); if (pathSegments.length === 0) { return 'home'; } return pathSegments.join('-').toLowerCase().replace(/[^a-z0-9-]/g, '-'); } catch (error) { return 'unknown-page'; } } /** * Filter test results by output type */ static filterResultsByOutputType(results, outputType) { return results.filter(result => { const config = test_output_types_js_1.OUTPUT_CONFIGURATIONS[result.testType]; return config?.type === outputType; }); } /** * Group per-page results by page */ static groupPerPageResultsByPage(results) { const perPageResults = this.filterResultsByOutputType(results, 'per-page'); const groupedResults = new Map(); for (const result of perPageResults) { if (!result.outputPath) continue; // Extract page name from output path const pathParts = result.outputPath.split(path_1.default.sep); const sessionIndex = pathParts.findIndex(part => part.match(/^\d{2}-\d{2}-\d{4}_\d{2}-\d{2}$/)); if (sessionIndex >= 0 && pathParts.length > sessionIndex + 1) { const pageName = pathParts[sessionIndex + 1]; if (!groupedResults.has(pageName)) { groupedResults.set(pageName, []); } groupedResults.get(pageName).push(result); } } return groupedResults; } /** * Validate output configuration and provide helpful error messages */ static validateConfiguration(testType) { const config = test_output_types_js_1.OUTPUT_CONFIGURATIONS[testType]; if (!config) { return { valid: false, errors: [`No output configuration found for test type: ${testType}`] }; } return test_output_types_js_1.OutputTypeUtils.validateOutputConfig(config); } } exports.StandardTestOutputHandler = StandardTestOutputHandler; //# sourceMappingURL=test-output-handler.js.map