/** * generate-test-plan.js * Generates a self-contained, fully inline-styled HTML Test Plan * for manual execution by testers. * * Output: output/testplans/YYYY-MM-DD_HH-MM-SS_{baseName}.html */ const fs = require('fs'); const path = require('path'); const OUTPUT_DIR = path.join(__dirname, '..', '..', 'output', 'testplans'); function generateTestPlan(selectedTests, baseName = 'Manual-Test-Plan') { if (!Array.isArray(selectedTests) || selectedTests.length === 0) { throw new Error('No test cases selected for the Test Plan'); } // Ensure output directory exists if (!fs.existsSync(OUTPUT_DIR)) { fs.mkdirSync(OUTPUT_DIR, { recursive: true }); } // Generate timestamped filename const now = new Date(); const timestamp = now.toISOString().slice(0, 19).replace(/:/g, '-').replace('T', '_'); const safeBase = baseName.replace(/[^a-zA-Z0-9-_]/g, '').slice(0, 60) || 'Manual-Test-Plan'; const filename = `${timestamp}_${safeBase}.html`; const finalPath = path.join(OUTPUT_DIR, filename); // Group tests by group const grouped = {}; selectedTests.forEach(test => { const g = test.group || 'Other'; if (!grouped[g]) grouped[g] = []; grouped[g].push(test); }); const groups = Object.keys(grouped).sort(); // Build HTML const html = ` Manual Test Plan - ${safeBase}

Manual Test Plan

${safeBase} — Generated on ${now.toLocaleString()}
Total cases: ${selectedTests.length}
${groups.map(group => ` ${grouped[group].map(test => { const expected = test.description || ''; const stepsHtml = (test.steps || []).map((s, i) => `
  • ${escapeHtml(s)}
  • `).join(''); const depsHtml = (test.dependencies || []).map(d => `
    ${escapeHtml(d.label)}: ${escapeHtml(d.value)}
    `).join(''); return ` `; }).join('')} `).join('')}
    Test ID Description & Expected Result Steps Severity Result / Comments
    ${group}
    ${escapeHtml(test.id)} ${escapeHtml(test.description || '')}
    Expected Result
      ${stepsHtml}
    ${depsHtml ? `
    Dependencies
    ${depsHtml}
    ` : ''}
    Status
    Actual Result / Comments

    Generated by QA Automation Test Plan Editor • All results and comments should be filled by the tester.

    `; fs.writeFileSync(finalPath, html); console.log(`✅ Manual Test Plan generated: ${finalPath}`); return finalPath; } function escapeHtml(str) { if (!str) return ''; return String(str) .replace(/&/g, '&') .replace(//g, '>') .replace(/"/g, '"'); } module.exports = { generateTestPlan };