Files
2026-05-26 00:42:42 +02:00

115 lines
3.6 KiB
JavaScript

/**
* save-testcases.js
*
* Writes an array of legacy-shaped testcases back to the individual YAML files.
* Steps are kept simple (action + expected + optional notes). Automation decision lives at testcase level.
*
* This is part of the transition so that the editor can save directly to YAML.
*/
const fs = require('fs');
const path = require('path');
const yaml = require('js-yaml');
const TESTCASES_ROOT = path.join(__dirname, '..', '..', 'testcases');
function getYamlPath(legacyTest) {
const top = legacyTest.module || 'unknown'; // core or pbx (top level per new structure)
const rawGroup = legacyTest.group || 'unknown';
const group = rawGroup.replace(/^core-|^pbx-/, '');
return path.join(TESTCASES_ROOT, top, group, `${legacyTest.id}.yaml`);
}
function buildCanonicalDoc(legacy, existing = {}) {
const cf = legacy.custom_fields || existing.custom_fields || {};
// Steps are now simple: action + expected + optional notes (no per-step automation flags)
let steps = [];
const incomingSteps = legacy.steps || [];
if (incomingSteps.length > 0 && typeof incomingSteps[0] === 'object' && incomingSteps[0] !== null) {
steps = incomingSteps.map(s => {
const step = {
action: s.action || '',
expected: s.expected || '',
};
if (s.notes) step.notes = s.notes;
return step;
});
} else {
// Legacy flat strings
steps = incomingSteps.map((action, i) => {
const prev = (existing.steps && existing.steps[i]) || {};
const step = {
action: action,
expected: prev.expected || '',
};
if (prev.notes) step.notes = prev.notes;
return step;
});
}
const doc = {
id: legacy.id,
module: legacy.module,
group: legacy.group,
title: legacy.description || legacy.title,
description: legacy.description || legacy.title,
priority: existing.priority || 'Medium',
tags: existing.tags || [],
references: existing.references || [],
dependencies: legacy.dependencies || existing.dependencies || [],
preconditions: existing.preconditions || [],
postconditions: existing.postconditions || [],
steps,
automation_status: legacy.status,
reason_not_automatable: legacy.reason_not_automatable || existing.reason_not_automatable || undefined,
file: legacy.file || existing.file || null,
custom_fields: {
...cf,
original_action: legacy.action,
}
};
// Carry over legacy fields the UI might still send
if (legacy.manualReason) doc.custom_fields.manualReason = legacy.manualReason;
if (legacy.partialNotes) doc.custom_fields.partialNotes = legacy.partialNotes;
// Keep high-level summaries if present
if (legacy.automatable) doc.automatable = legacy.automatable;
if (legacy.notYet) doc.notYet = legacy.notYet;
return doc;
}
function saveTestcases(legacyArray) {
for (const test of legacyArray) {
if (!test || !test.id) continue;
const filePath = getYamlPath(test);
const dir = path.dirname(filePath);
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
}
let existing = {};
if (fs.existsSync(filePath)) {
try {
const raw = fs.readFileSync(filePath, 'utf8');
existing = yaml.load(raw) || {};
} catch (e) {
// ignore, we'll overwrite
}
}
const doc = buildCanonicalDoc(test, existing);
const header = `# Updated via Autotest Editor - ${new Date().toISOString()}\n# Source of truth: this YAML file\n\n`;
const content = header + yaml.dump(doc, { lineWidth: 100, noRefs: true });
fs.writeFileSync(filePath, content, 'utf8');
}
}
module.exports = { saveTestcases, getYamlPath };