#!/usr/bin/env node /** * One-time script to populate reasonable 'expected' results * for all test case steps that currently have empty expected values. * * Run with: node server/scripts/populate-expected-results.js */ const fs = require('fs'); const path = require('path'); const yaml = require('js-yaml'); const TESTCASES_ROOT = path.join(__dirname, '..', '..', 'testcases'); // Heuristics for expected results based on action text function getExpectedForAction(action) { const a = action.toLowerCase(); if (a.includes('open admin portal') || a.includes('repository url in browser')) { return 'The admin portal or repository page loads successfully without errors, security warnings, or redirects.'; } if (a.includes('navigate to the download') || a.includes('documentation portal')) { return 'The documentation or downloads section is displayed correctly and the relevant content area is accessible.'; } if (a.includes('search or locate the relevant file')) { return 'The target file or link matching the filename pattern is found and listed correctly.'; } if (a.includes('assert presence and visibility of the expected document')) { return 'The document is visible, has the correct title, and its content is accessible for verification.'; } if (a.includes('log in to the admin portal')) { return 'Authentication succeeds using the provided credentials and the user is taken to the main dashboard.'; } if (a.includes('navigate to the relevant settings section')) { return 'The correct configuration page or section for the feature is displayed.'; } if (a.includes('read current configuration values')) { return 'Current configuration values are successfully retrieved via the UI or API and match the known baseline.'; } if (a.includes('execute the main verification or configuration action')) { return 'The primary action described in the test completes successfully and produces the expected state or output.'; } if (a.includes('capture evidence')) { return 'Relevant evidence (screenshot, log, or API response) is successfully captured and can be reviewed.'; } if (a.includes('assert expected outcome')) { return 'All verification assertions pass and the system is confirmed to be in the expected final state.'; } // PBX / Telephony specific if (a.includes('ensure sip endpoints') || a.includes('softphones are registered')) { return 'All required SIP endpoints show as registered with the correct status in the PBX.'; } if (a.includes('initiate or receive call using the required scenario')) { return 'The call is successfully established between the endpoints with ringing and connection confirmed.'; } if (a.includes('verify audio path, signaling, and media parameters')) { return 'Two-way audio is clear and bidirectional. Signaling (SIP) is correct and media parameters (codec, RTP/RTCP) match expectations.'; } if (a.includes('prepare clean or previous-version vm')) { return 'A clean or appropriately versioned VM/image is powered on and ready for the test procedure.'; } if (a.includes('perform installation or upgrade procedure')) { return 'The installation or upgrade procedure completes without errors and the expected new version is active.'; } if (a.includes('post-install verification via portal')) { return 'Core services are running, the admin portal is reachable, and basic post-install checks pass.'; } // Generic fallback return 'The action completes successfully and the system reaches the expected state described in the test.'; } function processSteps(steps) { if (!Array.isArray(steps)) return { steps, changed: false }; let changed = false; const newSteps = steps.map(step => { if (typeof step === 'string') { // Legacy string step - convert to object with estimated expected changed = true; return { action: step, expected: getExpectedForAction(step) }; } if (step && typeof step === 'object') { if (!step.expected || step.expected.trim() === '') { changed = true; return { ...step, expected: getExpectedForAction(step.action || '') }; } } return step; }); return { steps: newSteps, changed }; } function findYamlFiles(dir) { const results = []; const entries = fs.readdirSync(dir, { withFileTypes: true }); for (const entry of entries) { const fullPath = path.join(dir, entry.name); if (entry.isDirectory()) { results.push(...findYamlFiles(fullPath)); } else if (entry.name.endsWith('.yaml') && !entry.name.startsWith('SCHEMA')) { results.push(fullPath); } } return results; } function main() { console.log('Populating estimated "expected" results for test case steps...\n'); const yamlFiles = findYamlFiles(TESTCASES_ROOT); let updatedCount = 0; for (const filePath of yamlFiles) { try { const content = fs.readFileSync(filePath, 'utf8'); const doc = yaml.load(content); if (!doc || !doc.steps || !Array.isArray(doc.steps)) { continue; } const { steps: newSteps, changed } = processSteps(doc.steps); if (changed) { doc.steps = newSteps; const header = `# Updated via Autotest Editor - ${new Date().toISOString()}\n# Source of truth: this YAML file\n# Note: Expected results estimated based on step actions\n\n`; const newContent = header + yaml.dump(doc, { lineWidth: 100, noRefs: true }); fs.writeFileSync(filePath, newContent, 'utf8'); console.log(`✓ Updated: ${path.relative(TESTCASES_ROOT, filePath)}`); updatedCount++; } } catch (err) { console.error(`✗ Error processing ${filePath}: ${err.message}`); } } console.log(`\nDone. Updated ${updatedCount} test case file(s).`); } main();