Files
autotest/web/tester-plan.html
T

155 lines
6.0 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tester - Test Plan Editor</title>
<style>
body { font-family: system-ui, -apple-system, sans-serif; background: #0b1120; color: #e2e8f0; margin: 0; padding: 20px; }
.container { max-width: 1400px; margin: 0 auto; }
h1 { color: #f59e0b; }
.plan-header { background: #1e2937; padding: 16px; border-radius: 8px; margin-bottom: 20px; }
.test-card { background: #1e2937; border: 1px solid #334155; border-radius: 8px; padding: 16px; margin-bottom: 16px; }
.test-header { font-weight: 600; color: #f59e0b; margin-bottom: 8px; }
textarea, select, input { background: #0f172a; border: 1px solid #334155; color: #e2e8f0; padding: 8px; border-radius: 4px; width: 100%; box-sizing: border-box; }
.field { margin-bottom: 10px; }
.label { font-size: 12px; color: #94a3b8; margin-bottom: 4px; display: block; }
.status-pass { color: #4ade80; }
.status-fail { color: #f87171; }
.auto-save { font-size: 12px; color: #64748b; }
</style>
</head>
<body>
<div class="container">
<div class="plan-header">
<h1 id="planName"></h1>
<div id="planMeta" style="font-size:13px; color:#94a3b8;"></div>
<div class="auto-save" id="saveStatus"></div>
</div>
<div id="testsContainer"></div>
</div>
<script>
const urlParams = new URLSearchParams(window.location.search);
const planId = urlParams.get('plan');
let plan = null;
let saveTimeout = null;
async function loadPlan() {
if (!planId) {
document.body.innerHTML = '<h1>No plan specified. Use ?plan=ID</h1>';
return;
}
const res = await fetch(`/api/test-plans/${planId}`);
if (!res.ok) {
document.body.innerHTML = '<h1>Plan not found</h1>';
return;
}
plan = await res.json();
document.getElementById('planName').textContent = plan.name;
document.getElementById('planMeta').textContent = `Created: ${new Date(plan.createdAt).toLocaleString()}${plan.tests.length} tests`;
renderTests();
}
function renderTests() {
const container = document.getElementById('testsContainer');
container.innerHTML = '';
plan.tests.forEach((test, index) => {
const div = document.createElement('div');
div.className = 'test-card';
div.innerHTML = `
<div class="test-header">${test.id}</div>
<div><strong>${test.description}</strong></div>
<div style="margin: 8px 0; font-size:12px; color:#94a3b8;">Group: ${test.group}</div>
<div class="field">
<span class="label">Steps</span>
<div style="font-size:12px; white-space: pre-line; background:#0f172a; padding:8px; border-radius:4px;">
${(test.steps || []).map(s => '• ' + s).join('\n')}
</div>
</div>
<div class="field">
<span class="label">Expected Result</span>
<textarea data-field="expectedResult" data-index="${index}">${test.expectedResult || ''}</textarea>
</div>
<div style="display:flex; gap:12px;">
<div class="field" style="flex:1;">
<span class="label">Severity</span>
<select data-field="severity" data-index="${index}">
<option ${test.severity === 'Low' ? 'selected' : ''}>Low</option>
<option ${test.severity === 'Medium' ? 'selected' : ''}>Medium</option>
<option ${test.severity === 'High' ? 'selected' : ''}>High</option>
<option ${test.severity === 'Critical' ? 'selected' : ''}>Critical</option>
</select>
</div>
<div class="field" style="flex:1;">
<span class="label">Status</span>
<select data-field="testerStatus" data-index="${index}">
<option ${test.testerStatus === 'N/A' ? 'selected' : ''}>N/A</option>
<option ${test.testerStatus === 'Pass' ? 'selected' : ''}>Pass</option>
<option ${test.testerStatus === 'Fail' ? 'selected' : ''}>Fail</option>
<option ${test.testerStatus === 'Blocked' ? 'selected' : ''}>Blocked</option>
</select>
</div>
</div>
<div class="field">
<span class="label">Actual Result / Comments</span>
<textarea data-field="actualResult" data-index="${index}" style="min-height:60px;">${test.actualResult || ''}</textarea>
</div>
<div class="field">
<span class="label">Additional Comments</span>
<textarea data-field="comments" data-index="${index}">${test.comments || ''}</textarea>
</div>
`;
// Attach auto-save listeners
div.querySelectorAll('textarea, select').forEach(el => {
el.addEventListener('input', () => scheduleSave(index, el.dataset.field, el.value));
el.addEventListener('change', () => scheduleSave(index, el.dataset.field, el.value));
});
container.appendChild(div);
});
}
function scheduleSave(testIndex, field, value) {
plan.tests[testIndex][field] = value;
document.getElementById('saveStatus').textContent = 'Saving...';
clearTimeout(saveTimeout);
saveTimeout = setTimeout(async () => {
try {
const res = await fetch(`/api/test-plans/${planId}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(plan)
});
if (res.ok) {
document.getElementById('saveStatus').textContent = `Auto-saved at ${new Date().toLocaleTimeString()}`;
setTimeout(() => {
const el = document.getElementById('saveStatus');
if (el) el.textContent = '';
}, 2000);
}
} catch (e) {
document.getElementById('saveStatus').textContent = 'Save failed';
}
}, 800);
}
loadPlan();
</script>
</body>
</html>